Draw a text underneath a circle - javascript

I'm drawing a circle using html5 canvas and js.
var canvas = document.getElementById(key);
var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var radius = 35;
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.fillStyle = 'red';
context.fill();
context.stroke();
I also want to draw a text right underneath it. I tried this:
context.closePath();
context.fill();
context.fillStyle = "black";
context.font = "bold 11";
context.textBaseline = "top";
context.fillText('Hello', 100-radius/4 ,100-radius/2);
But it was drawn in the right-bottom corner for some reason, whereas I wanted exactly under the circle.

Set textAlign to center, then add radius to y position:
var spacing = 5;
context.textAlign = "center";
context.textBaseline = "top";
context.fillText('Hello', centerX, centerY + radius + spacing);

Your text alignment and coordinates for the text are wrong.
var margin = 10; // Increase the margin add space between Circle & text
context.textBaseline = "top";
context.textAlign = "center";
context.fillText('Hello', centerX , centerY + radius + margin);
JSFiddle with desired outcome

Related

Why does my canvas spinwheel gets cut off on setting lineWidth?

This is my draw function for the canvas:
const drawSector = (sector, i) => {
const ang = arc * i;
ctx.save();
// COLOR
ctx.lineWidth = 10;
ctx.strokeStyle = "#ECBA3F";
ctx.beginPath();
ctx.fillStyle = sector.color;
ctx.moveTo(rad, rad);
ctx.arc(rad, rad, rad, ang, ang + arc);
ctx.lineTo(rad, rad);
ctx.fill();
ctx.stroke();
// TEXT
ctx.translate(rad, rad);
ctx.rotate(ang + arc / 2);
ctx.textAlign = "right";
ctx.fillStyle = "#000";
ctx.font = "bold 10px sans-serif";
ctx.fillText(sector.label, rad - 10, 10);
//
ctx.restore();
};
Here's my sandbox
As soon as I set a linewidth on the canvas, part of the edges get cutoff seemingly as if the canvas width and height don't take the linewidth into account. How do I fix this?
Also is there a way I can rotate the text inside the arcs so that they stack rather than just being in a single line. Perhaps something like the below image?

Blurry text still in canvas

I am using Konva and creating a html canvas object and setting it as my shape's image.
I am drawing the width and height of this image shape inside its canvas (across the top and down the left) and this image is also scalable so I am trying to solve blurry text problems which arise when my shape (canvas) is rotated or scaled using Konva transformer.
By reading up on this problem I have come up with the following code which has nearly fixed the problem for me but I am still not getting crisp text when the shape is resized out of its initial ratio - so if I drag to resize only width or height then my text starts getting blurry again but if I scale by dragging the corner of Transformer or resize some width and then some height my Font is crisp.
Can anyone explain why this is still happening please?
function fillRectangle(isHover)
{
if(lastItem)//last touched or last added shape
{
var lastWidth = ""+parseInt(lastItem.getClientRect().width);
var lastHeight = ""+parseInt(lastItem.getClientRect().height);
if(parseInt(lastItem.getClientRect().width) != lastItem.originalWidth)
{
var oldWidth = lastItem.getClientRect().width;
var oldHeight = lastItem.getClientRect().height;
lastItem.actual_canvas.width = oldWidth ;//* ratio;
lastItem.actual_canvas.height = oldHeight ;//* ratio;
}
var ctx = lastItem.canvas; //canvas contains the ctx
ctx.clearRect(0, 0, lastItem.actual_canvas.width, lastItem.actual_canvas.height);
ctx.fillStyle="#fff";
if(lastItem.isColliding)
ctx.fillStyle = 'red';
else if(isHover)
ctx.fillStyle = 'black';
ctx.fillRect(0,0,lastItem.originalWidth * (lastItem.actual_canvas.width / lastItem.originalWidth), lastItem.originalHeight * (lastItem.actual_canvas.height / lastItem.originalHeight));
ctx.stroke();
ctx.save();
if( isHover || lastItem.isColliding)
ctx.fillStyle = 'red';
else
ctx.fillStyle = 'black';
var posX = (lastItem.actual_canvas.width/2);
var posY = (lastItem.actual_canvas.height/2);
if(lastItem.rotation() == 90 || lastItem.rotation() == 270)
{
var fontSize = 12 * (lastItem.actual_canvas.width / lastItem.originalWidth);
ctx.font = fontSize+"px sans-serif";
ctx.textBaseline = 'top';
ctx.textAlign = 'center';
ctx.fillText(lastWidth,posX, 2);
ctx.translate( 0, 0 );
ctx.save();
ctx.rotate(Math.PI/2 );
ctx.textBaseline = 'middle';
ctx.textAlign = 'center';
ctx.fillText(lastHeight,posY,-(lastItem.actual_canvas.width/15));
ctx.save();
ctx.restore();
}
else//roation must be 0 or 180
{
var fontSize = 12 * (lastItem.actual_canvas.width / lastItem.originalWidth);
ctx.font = fontSize+"px sans-serif";
ctx.textBaseline = 'top';
ctx.textAlign = 'center';
ctx.fillText(lastWidth,posX, 2);
ctx.translate( 0, 0 );
ctx.save();
ctx.rotate(Math.PI/2 );
ctx.textBaseline = 'middle';
ctx.textAlign = 'center';
ctx.fillText(lastHeight,posY,-(lastItem.actual_canvas.width/15));
ctx.save();
ctx.restore();
}
layer.draw();
}
else
console.log("lastitem is null");
}
image of blurry text problem
The canvas will automatically blur graphics that are given coordinates that are decimals.
Try rounding/casting them to the nearest integer.
ctx.fillText("Text",xPos | 0,yPos | 0);
ctx.fillText("Text",parseInt(xPos),parseInt(yPos));

Draw vertical line between circles in canvas

I want draw a vertical line between circles in my project.
and these are my codes:
html:
<div id="ways" style="width:1000px;margin:0 auto;height:100%;">
<div id="row1">
<div id="col11" class="r1"><canvas id="col111" width="578" height="200"></canvas></div>
<div id="col12" class="r1"><canvas id="col112" width="578" height="200"></canvas></div>
<div id="col13" class="r1"><canvas id="col113" width="578" height="200"></canvas></div>
</div>
<div id="row2">
<div id="col21" class="r1"><canvas id="col221" width="578" height="200"></canvas></div>
<div id="col22" class="r1"><canvas id="col222" width="578" height="200"></canvas></div>
<div id="col23" class="r1"><canvas id="col223" width="578" height="200"></canvas></div>
</div>
<div id="row3">
<div id="col31" class="r1"><canvas id="col331" width="578" height="200"></canvas></div>
<div id="col32" class="r1"><canvas id="col332" width="578" height="200"></canvas></div>
<div id="col33" class="r1"><canvas id="col333" width="578" height="200"></canvas></div>
</div>
</div>
and theses are js code:
var canvas = document.getElementById('col111');
var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var radius = 70;
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.fillStyle = 'green';
context.fill();
context.lineWidth = 5;
context.strokeStyle = '#003300';
context.stroke();
var canvas = document.getElementById('col112');
var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var radius = 70;
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.fillStyle = 'green';
context.fill();
context.lineWidth = 5;
context.strokeStyle = '#003300';
context.stroke();
var canvas = document.getElementById('col113');
var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var radius = 70;
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.fillStyle = 'green';
context.fill();
context.lineWidth = 5;
context.strokeStyle = '#003300';
context.stroke();
var canvas = document.getElementById('col221');
var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var radius = 70;
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.fillStyle = 'green';
context.fill();
context.lineWidth = 5;
context.strokeStyle = '#003300';
context.stroke();
var canvas = document.getElementById('col222');
var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var radius = 70;
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.fillStyle = 'green';
context.fill();
context.lineWidth = 5;
context.strokeStyle = '#003300';
context.stroke();
var canvas = document.getElementById('col223');
var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var radius = 70;
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.fillStyle = 'green';
context.fill();
context.lineWidth = 5;
context.strokeStyle = '#003300';
context.stroke();
How I can draw a vertical line between circles? when I tried to do this become this image:
and this is my js code:
var canvas = document.getElementById('col221');
var context = canvas.getContext('2d');
context.beginPath();
context.moveTo(290, -100);
context.lineTo(290, 80);
context.stroke();
please help for this problem!
thank u!
I'm not sure why you're opting to use multiple canvases but I have implemented a more generic solution in my fiddle here.
It uses two loops defined as:
for (var i = 0; i < rows; i++) {
for (var j = 0; j < cols; j++) {
...
}
}
This makes it more flexible as you can specify the rows and columns in the script. The rest is just knowing what your offsets are!
The code to implement the circle is largely untouched, but the fun is when to draw a line:
if (j != cols - 1) {
// Draw horizontal line
var hLineX = x + radius;
var hLineY = y;
context.moveTo(hLineX, hLineY);
context.lineTo(hLineX + distance + lineWidth, hLineY);
}
if (i > 0) {
// Draw vertical line
var vLineY = y - radius - distance - lineWidth;
context.moveTo(x, vLineY);
context.lineTo(x, vLineY + distance + lineWidth);
}
All this is saying is that you should draw a horizontal line on every column except for the last one. This works pretty well, even when you have one row by one column. You also want to draw a vertical line when there is more than one row, and offset it so it looks like it joins onto the previous row.
EDIT: Noticed you have different x and y distances, so I modified the fiddle to account for this.

Trying to make 2 happy/sad faces with canvas

I'm currently trying to make 1 happy face and 1 sad face with canvas but the problem is I can't get 2 faces to appear, only one.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My Site's Title</title>
</head>
<body>
<canvas id="myDrawing" width="800" height="200" style="border:1px solid #EEE">
</canvas>
<script>
var canvas = document.getElementById("myDrawing");
var ctx = canvas.getContext("2d");
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius = 75;
var startAngle = 0;
var endAngle = 2 * Math.PI;
function drawFace() {
ctx.beginPath();
ctx.arc(x, y, radius, startAngle, endAngle);
ctx.stroke();
ctx.fillStyle = "yellow";
ctx.fill();
}
function drawSmile(){
var x = canvas.width / 2;
var y = 150
var radius = 40;
var startAngle = 1.1 * Math.PI;
var endAngle = 1.9 * Math.PI;
ctx.beginPath();
ctx.arc(x, y, radius, startAngle, endAngle);
ctx.lineWidth = 7;
// line color
ctx.strokeStyle = 'black';
ctx.stroke();
}
function drawEyes(){
var centerX = 40;
var centerY = 0;
var radius = 10;
// save state
ctx.save();
// translate context so height is 1/3'rd from top of enclosing circle
ctx.translate(canvas.width / 2, canvas.height / 3);
// scale context horizontally by 50%
ctx.scale(.5, 1);
// draw circle which will be stretched into an oval
ctx.beginPath();
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
// restore to original state
ctx.restore();
// apply styling
ctx.fillStyle = 'black';
ctx.fill();
ctx.lineWidth = 2;
ctx.strokeStyle = 'black';
ctx.stroke();
//left eye
var centerX = -40;
var centerY = 0;
var radius = 10;
// save state
ctx.save();
// translate context so height is 1/3'rd from top of enclosing circle
ctx.translate(canvas.width / 2, canvas.height / 3);
// scale context horizontally by 50%
ctx.scale(.5, 1);
// draw circle which will be stretched into an oval
ctx.beginPath();
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
// restore to original state
ctx.restore();
// apply styling
ctx.fillStyle = 'black';
ctx.fill();
ctx.lineWidth = 2;
ctx.strokeStyle = 'black';
ctx.stroke();
}
drawFace()
function drawHappyFace(){
drawFace();
drawEyes();
drawSmile();
}
drawHappyFace();
// SECOND FACE - HAPPY FACE
<canvas id="canvas" width="200" height="200" style="border:1px solid #EEE">
</canvas>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius = 75;
var startAngle = 0;
var endAngle = 2 * Math.PI;
function drawFace() {
ctx.beginPath();
ctx.arc(x, y, radius, startAngle, endAngle);
ctx.stroke();
ctx.fillStyle = "yellow";
ctx.fill();
}
function drawSmile(){
var x = canvas.width / 2;
var y = 150
var radius = 40;
var startAngle = 1.9 * Math.PI;
var endAngle = 1.1 * Math.PI;
ctx.beginPath();
ctx.arc(x, y, radius, startAngle, endAngle);
ctx.lineWidth = 7;
// line color
ctx.strokeStyle = 'black';
ctx.stroke();
}
function drawEyes(){
var centerX = 40;
var centerY = 0;
var radius = 10;
// save state
ctx.save();
// translate context so height is 1/3'rd from top of enclosing circle
ctx.translate(canvas.width / 2, canvas.height / 3);
// scale context horizontally by 50%
ctx.scale(.5, 1);
// draw circle which will be stretched into an oval
ctx.beginPath();
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
// restore to original state
ctx.restore();
// apply styling
ctx.fillStyle = 'black';
ctx.fill();
ctx.lineWidth = 2;
ctx.strokeStyle = 'black';
ctx.stroke();
//left eye
var centerX = -40;
var centerY = 0;
var radius = 10;
// save state
ctx.save();
// translate context so height is 1/3'rd from top of enclosing circle
ctx.translate(canvas.width / 2, canvas.height / 3);
// scale context horizontally by 50%
ctx.scale(.5, 1);
// draw circle which will be stretched into an oval
ctx.beginPath();
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
// restore to original state
ctx.restore();
// apply styling
ctx.fillStyle = 'black';
ctx.fill();
ctx.lineWidth = 2;
ctx.strokeStyle = 'black';
ctx.stroke();
}
drawFace()
function drawHappyFace(){
drawFace();
drawEyes();
drawSmile();
}
drawHappyFace();
</script>
</body>
</html>
</body>
</html>
I cna only get one of the faces to appear at once, for some reason, but I want both at the same time!
you can't have multiple functions with the same name because the second one overrides (hides) the first one; doesn't matter if they are in the same <script> tag or not (they can even be in different files)
change the name of the functions for the second face if you are such a beginner, but you should provide arguments to the function which will let you choose between multiple canvases and shapes using single function
it can look like this:
http://jsfiddle.net/Y5rUH/2/

draw circle in canvas with click option

I write this javascript code :
<script>
var canvas = document.getElementById("canvas");
var canvasOffset = $("#canvas").offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;
function handleMouseDown(e) {
mouseX = parseInt(e.clientX - offsetX);
mouseY = parseInt(e.clientY - offsetY);
$("#downlog").html("Down: " + mouseX + " / " + mouseY);
}
$("#canvas").mousedown(function(e) {
handleMouseDown(e);
});
</script>
in this code , I detect a coordinate with mouse click .
I want draw a circle around the this coordinate that when I click on circle , do something (for ex. open google.com)
note : I do this with jquery in html 4 and with area map , but I do not have any idea in canvas .
I can't tell if you want to draw a circle, detect a mouse click in a circle or both.
Draw a circle:
var context=canvas.getContext("2d");
ctx.beginPath();
//Draw a circle around a mouse click
//ctx.arc(x-position, y-position, radius, start-angle, end-angle);
ctx.arc(mouseX, mouseY, 30, 0, 2*Math.PI);
ctx.stroke();
Detect a mouse click within a circle:
//circleX and circleY are the coordinats of the center
var y = mouseY - circleY;
var x = mouseX - circleX;
var dist = Math.sqrt(y*y + x*x);
if (dist < circleRadius) {
// Do whatever you want to do
}
var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var radius = 70;
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.fillStyle = 'green';
context.fill();
context.lineWidth = 5;
context.strokeStyle = '#003300';
context.stroke();

Categories

Resources