Starting from a W3School example I've created a canvas timer clock.
I would like to fill with another color (Yellow), the area where the hand is passed.
The clock is available here: https://jsfiddle.net/nzexyd6j/1/
And here is the code:
<canvas id="canvas" width="400" height="400" style="background-color:#fff">
</canvas>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var radius = canvas.height /2;
var minuti = 3;
var tempoInit = minuti * 60;
var tempo = tempoInit;
//var tempo = 180;
var lancetta;
ctx.translate(radius, radius);
radius = radius * 0.90
setInterval(drawClock, 1000);
function drawClock() {
drawFace(ctx, radius);
// drawNumbers(ctx, radius);
drawTime(ctx, radius);
}
//f2634a
function drawFace(ctx, radius) {
var grad;
ctx.beginPath();
ctx.arc(0, 0, radius, 0, 2*Math.PI);
ctx.fillStyle = '#fff';
ctx.fill();
grad = ctx.createRadialGradient(0,0,radius*0.95, 0,0,radius*1.05);
grad.addColorStop(0, '#f2634a');
grad.addColorStop(1, '#f2634a');
ctx.strokeStyle = grad;
ctx.lineWidth = radius*0.1;
ctx.stroke();
ctx.beginPath();
ctx.arc(0, 0, radius*0.1, 0, 2*Math.PI);
ctx.fillStyle = '#f2634a';
// ctx.fill();
}
function drawNumbers(ctx, radius) {
var ang;
var num;
ctx.font = radius*0.15 + "px arial";
ctx.textBaseline="middle";
ctx.textAlign="center";
for(num = 1; num < (minuti + 1); num++){
ang = (num * Math.PI / minuti ) * 2;
ctx.rotate(ang);
ctx.translate(0, -radius*0.85);
ctx.rotate(-ang);
ctx.fillText(num.toString(), 0, 0);
ctx.rotate(ang);
ctx.translate(0, radius*0.85);
ctx.rotate(-ang);
}
}
function drawTime(ctx, radius){
tempo--;
lancetta = (tempo*Math.PI/tempoInit) * 2;
drawHand(ctx, lancetta, radius*1, radius*0.07);
drawHand(ctx, (180*Math.PI/tempoInit) * 2, radius*1, radius*0.07);
}
function drawHand(ctx, pos, length, width) {
ctx.beginPath();
ctx.lineWidth = width;
ctx.lineCap = "round";
ctx.moveTo(0,0);
ctx.rotate(pos);
ctx.lineTo(0, -length);
ctx.stroke();
ctx.rotate(-pos);
}
I've tried using lineWidth, but without success.
Do you have any suggestions?
How it works: First, select the canvas by using the querySelector() method. Next, get the 2D drawing context if the canvas API is supported. Then, set the stroke, fill, and line width by using the strokeStyle , fillStyle , and lineWidth property of the 2D drawing context.
To create a semicircle with HTML5 Canvas, we can create an arc using the arc() method and define the ending angle has startAngle + PI.
To draw arcs or circles, we use the arc() or arcTo() methods. Draws an arc which is centered at (x, y) position with radius r starting at startAngle and ending at endAngle going in the given direction indicated by counterclockwise (defaulting to clockwise).
Your clock seems to be running backwards?!
Anyway, you want to fill a wedge based on how many clock minutes have elapsed.
So given a time in clock minutes, this function returns the angle at that clock time.
// given minutes (a minute-hand on a clock)
// return the associated angle in radians
function minutesToAngle(minutes){
var twelveOClock=-Math.PI/2;
var fullCircle=Math.PI*2;
return(twelveOClock+fullCircle*(minutes/60));
}
The returned angle is in radians, which is the unit-of-measure used to draw an arc on the canvas.
To draw a wedge, you simply fill an arc from the arc's centerpoint like this:
function fillWedge(cx,cy,radius,startAngle,endAngle,fillcolor){
ctx.beginPath();
ctx.moveTo(cx,cy);
ctx.arc(cx,cy,radius,startAngle,endAngle);
ctx.closePath();
ctx.fillStyle=fillcolor;
ctx.fill();
}
Putting the 2 functions together, you can fill your elapsed time like this:
// fill 5 elapsed minutes
var cx=canvas.width/2; // or your clock's centerX
var cy=canvas.height/2; // or your clock's centerY
var radius=Math.min(canvas.width,canvas.height)*.90; // or your clock's radius
var startMinutes=0; // start at 12 o'clock
var endMinutes=5; // end at 5 minutes past 12
var startAngle=minutesToAngle(0); // the angle at 12 o'clock
var endAngle=minutesToAngle(5); // the angle at 5 minutes past 12
// fill the wedge for 5 elapsed minutes
fillWedge(cx,cy,radius,startAngle,endAngle,'gold');
By adding these 2 functions to your existing code, you can:
Example code and a Demo:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var cx=cw/2;
var cy=ch/2;
var radius=135;
var minutes=0;
var minutesIncrement=0.334;
animate();
function animate(time){
ctx.clearRect(0,0,cw,ch);
ctx.beginPath();
ctx.arc(cx,cy,radius,0,Math.PI*2);
ctx.strokeStyle='indianred';
ctx.lineWidth=10;
ctx.lineJoin='round';
ctx.stroke();
fillWedge(cx,cy,radius,minutesToAngle(0),minutesToAngle(minutes),'gold');
ctx.stroke();
minutes+=minutesIncrement;
if(minutes>60){minutes=0;}
requestAnimationFrame(animate);
}
var cx=canvas.width/2;
var cy=canvas.height/2;
var radius=Math.min(canvas.width,canvas.height)*.90/2;
var startMinutes=0; // start at 12 o'clock
var endMinutes=5; // end at 5 minutes past 12
var startAngle=minutesToAngle(0); // the angle at 12 o'clock
var endAngle=minutesToAngle(5); // the angle at 5 minutes past 12
// fill the wedge for 5 elapsed minutes
fillWedge(cx,cy,radius,startAngle,endAngle,'gold');
function fillWedge(cx,cy,radius,startAngle,endAngle,fillcolor){
ctx.beginPath();
ctx.moveTo(cx,cy);
ctx.arc(cx,cy,radius,startAngle,endAngle);
ctx.closePath();
ctx.fillStyle=fillcolor;
ctx.fill();
}
function minutesToAngle(minutes){
var twelveOClock=-Math.PI/2;
var fullCircle=Math.PI*2;
return(twelveOClock+fullCircle*(minutes/60));
}
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=300 height=300></canvas>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With