How can I fill a text at the end of my arc? - html

I'm trying to place a text inside my semi circle, graph. I simplified the arc for you context.arc(92.5, 92.5, 72.5, 3.141592653589793, 3.7699111843077517, false); I want to place a value 2 at the end of arc, since the arc represents 20% of overall value.
So far I have tried is
context.translate(centerX, centerY);
context.save();
context.translate(x, y);
context.fillText('2', 0, 3);
context.restore();
I tried to find x and y interception point using (𝑥−ℎ)2+(𝑦−𝑘)2=𝑟2. But I can't place the text at the end of arc. Can some one please help me to solve this? Thank you.

You will need to find the point where the arc ends:
let x = center.x + radius * Math.cos(endArc);
let y = center.y + radius * Math.sin(endArc);
In this case the center of the circle is in the point {x:92.5,y:92.5}, the radius is 72.5. and the end arc is 3.7699111843077517.
I hope this is what you were asking.
const ctx = canvas.getContext("2d");
let cw = canvas.width = 200;
let ch= canvas.height = 200;
ctx.beginPath();
ctx.arc(92.5, 92.5, 72.5, 3.141592653589793, 3.7699111843077517, false);
ctx.stroke();
//find the point where the arc ends
let x = 92.5 + 72.5 * Math.cos(3.7699111843077517);
let y = 92.5 + 72.5 * Math.sin(3.7699111843077517);
// draw the text
ctx.font="12px Arial";
ctx.textAlign="center";
ctx.textBaseline="bottom";
ctx.fillText("2",x,y);
canvas{border:1px solid}
<canvas id="canvas"></canvas>

Related

HTML5 canvas how to split circle to X parts

I need split circle to X parts without white center
I have already this code: http://jsfiddle.net/U2tPJ/78/
I get this result:
I need finish result like this (without white center):
Since what you want is to fill a part of the circle, use fill(), not stroke().
• The shape you want to draw (a pie) starts in the circle center :
ctx.moveTo(x,y);
Then follow the arc :
context.arc(x, y, radius, i*pieAngle, (i+1)*pieAngle, false);
Then fill().
• Notice that the segmentDepth you were using was in fact an angle in degree. To clarify i used :
// size of a pie : it is an angle in radians
var pieAngle = 2 * Math.PI / hours;
• Lastly i used hsl colors to easily get a bunch of colors different for each hour :
var hueValue = i * 15;
context.fillStyle = 'hsl(' + hueValue + ',70%, 60%)';
result look this way :
draw code
function drawSegments(radius) {
for (var i = 0; i < hours; i++) {
context.beginPath();
context.moveTo(x, y);
context.arc(x, y, radius, i*pieAngle, (i+1)*pieAngle, false);
context.lineWidth = segmentDepth;
var hueValue = i * 15;
context.fillStyle = 'hsl(' + hueValue + ',70%, 60%)';
// '#'+(Math.random()*0xFFFFFF<<0).toString(16);
context.fill();
context.lineWidth = 2;
context.strokeStyle = '#444';
context.stroke();
}
}
fiddle : http://jsfiddle.net/gamealchemist/U2tPJ/79/
The width of the ring is controlled by the line context.lineWidth = segmentDepth;. It seems like you forgot that the line width goes into both directions. To make the ring go to the center, change it to segmentDepth * 2. However, this will also make the whole graphic twice as big, so you might want to compensate by reducing the segmentDepth.

Circle Animation

Can someone help me a little bit with thath canvas, i am learning it and cant manage to make a circle which when r comes to 100 it goes back to 0 animation. So its some kind of a zooming image.
I draw a circle like this:
<canvas id="myCanvas" width="578" height="200"></canvas>
<script>
var canvas = document.getElementById('myCanvas');
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();
</script>
Now how i can animate this now with canvas thath when it radius reaches 100 it goes instantly back to 0 and then it goes again to 100.
Thanks
Look at math sinus function http://www.digitalmedia.cz/shared/clanky/438/graf.gif
Lets take advantage on that its value is going to 1 and then goes back to 0 for angles between 0 and PI
var period = 500; // [miliseconds]
var linearMod = Date.now() % period / period; // this goes from 0 to 1
var mod = Math.sin(linearMod * Math.PI); // and here with simple easing we create
// bouncing
var r = someRadius * mod; // voila
With this approach you are additionally gaining simple sinusoidal easing which feels much more dynamic.
Here is a little fiddle for you http://jsfiddle.net/rezoner/6acF9/
You dont have to base linearMod upon time - you can assign it to a slider control or whatever you wish.

HTML5: Fill circle/arc by percentage

Here is my pseudo code:
var percentage = 0.781743; // no specific length
var degrees = percentage * 360.0;
var radians = degrees * Math.PI / 180.0;
var x = 50;
var y = 50;
var r = 30;
var s = 1.5 * Math.PI;
var context = canvas.getContext('2d');
context.beginPath();
context.lineWidth = 5;
context.arc(x, y, r, s, radians, false);
context.closePath();
context.stroke();
I'm using the KineticJS library to control the shapes I make and redraw them as necessary. My problem is that the above code does not work at all. I assume I have the math incorrect, because if I change radians to something like 4.0 * Math.PI is draws the entire circle.
I've been using HTML5 Canvas Arc Tutorial for reference.
Your code works just fine, but you have a starting angle that ought to be zero to get what you expect. Here's working code:
http://jsfiddle.net/HETvZ/
I think your confusion is from what starting angle does. It does not mean that it starts at that point and then adds endAngle radians to it. It means that the angle starts at that point and ends at the endAngle radians point absolutely.
So if you startAngle was 1.0 and endAngle was 1.3, you'd only see an arc of 0.3 radians.
If you want it to work the way you're thinking, you're going to have add the startAngle to your endAngle:
context.arc(x, y, r, s, radians+s, false);
Like in this example: http://jsfiddle.net/HETvZ/5/
Your code is just fine. you need to have:
s=0 i.e. starting point must be zero.
and if you want circle to start drawing at top you can use:
context.rotate(-90 * Math.PI / 180);
but after rotating you will have to check arc()'s x,y arguments. i used it like:
context.rotate(-90 * Math.PI / 180);
context.arc(-200, 200, 150, startPoint, radian, false);
context.lineWidth = 20;
context.strokeStyle = '#b3e5fc';
context.stroke();
context.closePath();
after this i needed to display percentage in text form so i did:
context.rotate(90 * Math.PI / 180);
context.fillStyle = '#1aa8ff';
context.textAlign = 'center';
context.font = "bold 76px Verdana";;
context.textBaseline = "middle";
context.fillText("50%", 200, 200);

How to draw an irregular/hand-drawn line using svg/canvas?

I want to draw a vertical line that is resizable (based on the page content), but that appears to be hand drawn, rather than straight.
I'm currently thinking of using SVG or Canvas to achieve this. The line will run down the side of my webpage, hence needs to be scalable between the top and bottom of the container. How can I achieve this?
So you want to draw a line with jitter?
Try drawing a bunch of successive Bezier curves, with all of the Y-axis point parts equally spaced, and randomize the x values by some amount.
Here's an example to get you started:
var can = document.getElementById('canvas1');
var ctx = can.getContext('2d');
function addJitteryBezier(fromx, fromy, tox, toy) {
var diffx = tox - fromx;
var diffy = toy - fromy;
var neg = Math.random()*diffy/5; // so the x value can go positive or negative from the typical
ctx.bezierCurveTo(
-neg + fromx + 2*(Math.random()*diffy/8), fromy + .3*diffy,
-neg + fromx + 2*(Math.random()*diffy/8), fromy + .6*diffy,
tox, toy
);
}
ctx.beginPath();
ctx.moveTo(50,0);
var i = 0;
while (i < 500) {
addJitteryBezier(50, i, 50, i+50);
i+= 50;
}
ctx.stroke();
<canvas id="canvas1" width="500" height="500"></canvas>
http://jsfiddle.net/GfGVE/9/

draw square and rotate it?

how come this doesn't work? does rotate only work with images?
context.moveTo(60,60);
context.lineTo(200,60);
context.lineTo(200,200);
context.lineTo(60,200);
context.lineTo(60,60);
context.stroke();
context.rotate(45 * Math.PI / 180);
context.restore();
You are rotating the whole canvas when you use context.rotate, and since the pivot point is defaulted at the coordinates (0, 0), your square sometimes will be drawn out of bounds.
By moving the pivot point to the middle of the square, you can then rotate it successfully.
Note: Make sure you rotate the canvas before you draw the square.
// pivot point coordinates = the center of the square
var cx = 130; // (60+200)/2
var cy = 130; // (60+200)/2
// Note that the x and y values of the square
// are relative to the pivot point.
var x = -70; // cx + x = 130 - 70 = 60
var y = -70; // cy + y = 130 - 70 = 60
var w = 140; // (cx + x) + w = 60 + w = 200
var h = 140; // (cy + y) + h = 60 + h = 200
var deg = 45;
context.save();
context.translate(cx, cy);
context.rotate(deg * Math.PI/180);
context.fillRect(x, y, w, h);
context.restore();
Explanation:
context.save(); saves the current state of the coordinate system.
context.translate(cx, cy); moves the pivot point.
context.rotate(deg * Math.PI/180); rotates the square to deg degrees (Note that the parameter is in radians, not degrees)
context.fillRect( x, y, w, h ); draws the square
context.restore(); restores the last state of the coordinate system.
Here is a JS Fiddle example.
Here is another JS Fiddle example that features a HTML5 slider.