Multiple Javascript Clocks - javascript

I followed a tutorial for building a JS analogue clock and now I'd like to create an identical second clock on the page to experiment with.
When I've tried adding a second clock it overwrites the first clock - I believe this is because the variables ctx and radius are set globally.
Working example:
var canvas = document.getElementById("cambs_clock");
var ctx = canvas.getContext("2d");
var radius = canvas.height / 2;
ctx.translate(radius, radius);
radius = radius * 0.90;
//drawClock();
setInterval(drawClock, 1000);
function drawClock()
{
drawFace(ctx, radius);
drawNumbers(ctx, radius);
drawTime(ctx, radius);
}
I tried turning the block of code that generates the ctx and radius variables into a function and adding params to the drawClock function but that resulted in no clocks being drawn whatsoever:
function setupClock(clock)
{
var canvas = document.getElementById("cambs_clock");
var ctx = canvas.getContext("2d");
var radius = canvas.height / 2;
ctx.translate(radius, radius);
radius = radius * 0.90;
setInterval(drawClock(ctx, radius), 1000);
}
//drawClock();
//setInterval(drawClock, 1000);
setupClock();
function drawClock(ctx,radius)
{
drawFace(ctx, radius);
drawNumbers(ctx, radius);
drawTime(ctx, radius);
}
function drawFace(ctx, radius) {
var grad;
ctx.beginPath();
ctx.arc(0, 0, radius, 0, 2 * Math.PI);
ctx.fillStyle = 'red';
ctx.fill();
grad = ctx.createRadialGradient(0, 0 ,radius * 0.95, 0, 0, radius * 1.05);
grad.addColorStop(0, '#333');
grad.addColorStop(0.5, 'black');
grad.addColorStop(1, '#333');
ctx.strokeStyle = grad;
ctx.lineWidth = radius*0.05;
ctx.stroke();
ctx.beginPath();
ctx.arc(0, 0, radius * 0.1, 0, 2 * Math.PI);
ctx.fillStyle = '#333';
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 < 13; num++){
ang = num * Math.PI / 6;
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){
var now = new Date();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
//hour
hour = hour%12;
hour = (hour*Math.PI/6)+(minute*Math.PI/(6*60))+(second*Math.PI/(360*60));
drawHand(ctx, hour, radius*0.5, radius*0.07);
//minute
minute = (minute*Math.PI/30)+(second*Math.PI/(30*60));
drawHand(ctx, minute, radius*0.8, radius*0.07);
// second
second = (second*Math.PI/30);
drawHand(ctx, second, radius*0.9, radius*0.02);
}
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);
}
</script>
The above code results in no clocks being drawn.
How would I be able to expand this code to accommodate multiple clocks?
(The end game is to have several clocks for different timezones in case that makes a difference)

You have tried the following:
function setupClock(clock)
{
var canvas = document.getElementById("cambs_clock");
var ctx = canvas.getContext("2d");
var radius = canvas.height / 2;
ctx.translate(radius, radius);
radius = radius * 0.90;
setInterval(() => drawClock(ctx, radius), 1000);
}
setupClock();
Notice that that function has an argument, clock which is not used. Furthermore, with document.getElementById("cambs_clock"); you always target the same canvas. So what you need in your case are two canvas's like
<canvas id="clock1"></canvas>
<canvas id="clock2"></canvas>
And the following script
function setupClock(clock)
{
var canvas = document.getElementById(clock);
var ctx = canvas.getContext("2d");
var radius = canvas.height / 2;
ctx.translate(radius, radius);
radius = radius * 0.90;
setInterval(drawClock(ctx, radius), 1000);
}
setupClock('clock1');
setupClock('clock2');
You can pass the radius as well as an argument if you like:
function setupClock(clock, radius) { ... }
setupClock('clock2', 20);
Endless possibilities, good luck!

Change
setInterval(drawClock(ctx, radius), 1000);
to
setInterval(() => {
drawClock(ctx, radius);
}, 1000);

Related

Rotate circle around triangle canvas

I want to spin a circle around a triangle using canvas. Have this code from earlier, but here is the circle in the middle, and a rectangle spinning, i want the circle to spin and have a triangle in the middle. Can someone help?
Here is the JS code i have:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var cx = 100;
var cy = 100;
var rectWidth = 15;
var rectHeight = 10;
var rotation = 0;
requestAnimationFrame(animate);
function animate() {
requestAnimationFrame(animate);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.arc(cx, cy, 10, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
ctx.save();
ctx.translate(cx, cy);
ctx.rotate(rotation);
ctx.strokeRect(-rectWidth / 2 + 20, -rectHeight / 2, rectWidth, rectHeight);
ctx.restore();
rotation += Math.PI / 180;
}
<canvas id="canvas"></canvas>
I have edited your code to draw the requested shapes and added comments to describe, what i am doing in the snippet below.
var canvas = document.body.appendChild(document.createElement("canvas"));
var ctx = canvas.getContext("2d");
var cx = 100;
var cy = 100;
var rotation = 0;
requestAnimationFrame(animate);
function animate() {
//Clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
//Draw center figure
/*
ctx.beginPath();
ctx.arc(cx, cy, 10, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
*/
ctx.beginPath();
ctx.moveTo(cx - 10, cy - 10);
ctx.lineTo(cx, cy + 10);
ctx.lineTo(cx + 10, cy - 10);
ctx.closePath();
ctx.fill();
//Rotate canvas
ctx.save();
ctx.translate(cx, cy);
ctx.rotate(rotation);
//Draw rotating object
/*ctx.strokeRect(-rectWidth / 2 + 20, -rectHeight / 2, rectWidth, rectHeight);*/
ctx.beginPath();
ctx.arc(20, 0, 5, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
//Rotate canvas back
ctx.restore();
//Save rotation
rotation += Math.PI / 180;
//Request next frame
requestAnimationFrame(animate);
}
It sounds like you lack experience with HTML Canvas manipulation, so i would like to recommend some MDN's official canvas tutorial.
If you have further questions feel free to open new questions with more code-specific problems in the future.
Here is an alternative to moving objects without using the ctx.translate or the ctx.rotate
We can use Math.sin and Math.cos to move around in a circular or elliptical motion.
Once you understand this approach you open the door for many possibilities, for example you can make the spins relative to other objects.
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var rotation = 0;
setInterval(animate, 10);
function animate(rx, ry, speed) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
draw(120, 80, 1)
draw(240, 80, 10/3)
}
function draw(rx, ry, speed) {
var x = Math.cos(rotation) * 50 + rx
var y = Math.sin(rotation) * 50 + ry
ctx.beginPath()
ctx.arc(x, y, 20, 0, Math.PI * 2);
ctx.stroke();
for (var i = 1; i < 8; i++) {
x += Math.sin(rotation * i/speed) * 20
y += Math.cos(rotation * i/speed) * 20/i
ctx.beginPath()
ctx.arc(x, y, 8/i, 0, Math.PI * 2);
ctx.stroke();
}
rotation += Math.PI / 180;
}
<canvas id="canvas" height=170 width=400></canvas>
Try the following:
<code>
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cx=100;
var cy=100;
var rectWidth=15;
var rectHeight=10;
var rotation=0;
requestAnimationFrame(animate);
function animate(){
requestAnimationFrame(animate);
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.beginPath();
var radius = 8;
ctx.moveTo(cx - radius, cy + radius);
ctx.lineTo(cx, cy - radius);
ctx.lineTo(cx + radius , cy + radius);
ctx.lineTo(cx - radius, cy + radius);
ctx.fill();
ctx.save();
ctx.translate(cx,cy);
ctx.rotate(rotation);
ctx.strokeRect(-rectWidth/2+20,-rectHeight/2,rectWidth,rectHeight);
ctx.restore();
rotation+=Math.PI/180;
}
</code>

java script canvas clock rotate number in correct position

clock digit display incorrect position how to rotate correct position .
I think does not colculate correct angle of each digit.
these lines of code have error and here is calculate angle of each digit
any one finde the error and how to solve this
and how to calculate analog clock wise digit
for (var n = 1; n <=12; n++) {
var theta = (n - 12) * (Math.PI * 2) / 12;
var x = clockRadius * 0.7 * Math.cos(theta);
var y = clockRadius * 0.7 * Math.sin(theta);
ctx.fillText(n, x, y);
ctx.rotate(theta);
}
clock image here
clock clocke
<canvas id="canvas" width="150" height="150"></canvas>
<script>
function init(){
clock();
setInterval(clock, 1000);
}
function toRad(degrees) {
return degrees * (Math.PI / 180);
}
function clock(){
var ctx = document.getElementById('canvas').getContext('2d');
var clockRadius = 110;
ctx.save();
ctx.clearRect(0,0,150,150);
ctx.translate(75,75);
ctx.scale(0.4,0.4);
ctx.rotate(-Math.PI/2);
ctx.fillStyle = "white";
ctx.lineWidth = 8;
ctx.lineCap = "round";
ctx.font = '22px Helvetica,Arial,sans-serif';
ctx.fillStyle = '#fff';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
var now = new Date($("#datetime").val());
//alert(now);
var sec = now.getSeconds();
var min = now.getMinutes();
var hr = now.getHours();
hr = hr>=12 ? hr-12 : hr;
for (var n = 1; n <=12; n++) {
var theta = (n - 12) * (Math.PI * 2) / 12;
var x = clockRadius * 0.7 * Math.cos(theta);
var y = clockRadius * 0.7 * Math.sin(theta);
ctx.fillText(n, x, y);
ctx.rotate(theta );
}
ctx.strokeStyle = "white";
ctx.save();
for (var i=0; i < 12; i++){
ctx.beginPath();
ctx.rotate(Math.PI/6);
ctx.moveTo(100,0);
ctx.lineTo(120,0);
ctx.stroke();
}
ctx.restore();
// Minute marks
ctx.save();
ctx.lineWidth = 5;
for (i=0;i<60;i++){
if (i%5!=0) {
ctx.beginPath();
ctx.moveTo(117,0);
ctx.lineTo(120,0);
ctx.stroke();
}
ctx.rotate(Math.PI/30);
}
ctx.restore();
ctx.fillStyle = "black";
// write Hours
ctx.strokeStyle = "#4D514E";
ctx.save();
ctx.rotate( hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec )
ctx.lineWidth = 14;
ctx.beginPath();
ctx.moveTo(-20,0);
ctx.lineTo(80,0);
ctx.stroke();
ctx.restore();
// write Minutes
ctx.save();
ctx.rotate( (Math.PI/30)*min + (Math.PI/1800)*sec )
ctx.lineWidth = 10;
ctx.beginPath();
ctx.moveTo(-28,0);
ctx.lineTo(110,0);
ctx.stroke();
ctx.restore();
// Write seconds
ctx.save();
ctx.rotate(sec * Math.PI/30);
ctx.strokeStyle = "#D40000";
ctx.fillStyle = "#D40000";
ctx.lineWidth = 6;
ctx.beginPath();
ctx.moveTo(-30,0);
ctx.lineTo(110,0);
ctx.stroke();
ctx.beginPath();
ctx.arc(0,0,10,0,Math.PI*2,true);
ctx.fill();
ctx.beginPath();
ctx.arc(0,0,10,0,Math.PI*2,true);
ctx.stroke();
ctx.fillStyle = "rgba(0,0,0,0)";
ctx.arc(0,0,3,0,Math.PI*2,true);
ctx.fill();
ctx.restore();
ctx.beginPath();
ctx.lineWidth = 14;
ctx.strokeStyle = '#494545';
ctx.arc(0,0,142,0,Math.PI*2,true);
ctx.stroke();
ctx.restore();
} init();
</script>
You rotate the whole context in the line 7 of the clock function.
function clock(){
var ctx = document.getElementById('canvas').getContext('2d');
var clockRadius = 110;
ctx.save();
ctx.clearRect(0,0,150,150);
ctx.translate(75,75);
ctx.scale(0.4,0.4);
ctx.rotate(-Math.PI/2); // <-- remove this
ctx.fillStyle = "white";
...
You need to remove that. Instead of doing that you can just rotate when drawing the arms.
// write Hours
ctx.rotate( -Math.PI/2 + hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec )
// write Minutes
ctx.rotate( -Math.PI/2 + (Math.PI/30)*min + (Math.PI/1800)*sec )
// Write seconds
ctx.rotate( -Math.PI/2 + sec * Math.PI/30);
(and the codes for drawing digits will need a minor fix)
var theta = (n - 3) * (Math.PI * 2) / 12;
function init(){
clock();
setInterval(clock, 1000);
}
function toRad(degrees) {
return degrees * (Math.PI / 180);
}
function clock(){
var ctx = document.getElementById('canvas').getContext('2d');
var clockRadius = 110;
ctx.save();
ctx.clearRect(0,0,150,150);
ctx.translate(75,75);
ctx.scale(0.4,0.4);
ctx.fillStyle = "white";
ctx.lineWidth = 8;
ctx.lineCap = "round";
ctx.font = '22px Helvetica,Arial,sans-serif';
ctx.fillStyle = '#fff';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
var now = new Date('2000/1/1 ' + $("#datetime").val());
//alert(now);
var sec = now.getSeconds();
var min = now.getMinutes();
var hr = now.getHours();
hr = hr>=12 ? hr-12 : hr;
for (var n = 1; n <=12; n++) {
var theta = (n - 3) * (Math.PI * 2) / 12;
var x = clockRadius * 0.7 * Math.cos(theta);
var y = clockRadius * 0.7 * Math.sin(theta);
ctx.fillText(n, x, y);
}
ctx.strokeStyle = "white";
ctx.save();
for (var i=0; i < 12; i++){
ctx.beginPath();
ctx.rotate(Math.PI/6);
ctx.moveTo(100,0);
ctx.lineTo(120,0);
ctx.stroke();
}
ctx.restore();
// Minute marks
ctx.save();
ctx.lineWidth = 5;
for (i=0;i<60;i++){
if (i%5!=0) {
ctx.beginPath();
ctx.moveTo(117,0);
ctx.lineTo(120,0);
ctx.stroke();
}
ctx.rotate(Math.PI/30);
}
ctx.restore();
ctx.fillStyle = "black";
// write Hours
ctx.strokeStyle = "#4D514E";
ctx.save();
ctx.rotate( -Math.PI/2 + hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec )
ctx.lineWidth = 14;
ctx.beginPath();
ctx.moveTo(-20,0);
ctx.lineTo(80,0);
ctx.stroke();
ctx.restore();
// write Minutes
ctx.save();
ctx.rotate( -Math.PI/2 +(Math.PI/30)*min + (Math.PI/1800)*sec )
ctx.lineWidth = 10;
ctx.beginPath();
ctx.moveTo(-28,0);
ctx.lineTo(110,0);
ctx.stroke();
ctx.restore();
// Write seconds
ctx.save();
ctx.rotate(-Math.PI/2 +sec * Math.PI/30);
ctx.strokeStyle = "#D40000";
ctx.fillStyle = "#D40000";
ctx.lineWidth = 6;
ctx.beginPath();
ctx.moveTo(-30,0);
ctx.lineTo(110,0);
ctx.stroke();
ctx.beginPath();
ctx.arc(0,0,10,0,Math.PI*2,true);
ctx.fill();
ctx.beginPath();
ctx.arc(0,0,10,0,Math.PI*2,true);
ctx.stroke();
ctx.fillStyle = "rgba(0,0,0,0)";
ctx.arc(0,0,3,0,Math.PI*2,true);
ctx.fill();
ctx.restore();
ctx.beginPath();
ctx.lineWidth = 14;
ctx.strokeStyle = '#494545';
ctx.arc(0,0,142,0,Math.PI*2,true);
ctx.stroke();
ctx.restore();
} init();
canvas {
background: blue;
}
<input type="time" id="datetime" value="03:45:01">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvas" width="150" height="150"></canvas>
<script>
</script>
Since you call ctx.rotate(-Math.PI/2) at the beginning of your clock function, you need to rotate the digits back. To do this you'd need to translate context to a digit coordinates first, and then rotate the context by Math.PI/2.
Replace this part of code in your for loop:
ctx.fillText(n, x, y);
ctx.rotate(theta );
with this:
ctx.save();
ctx.translate(x, y);
ctx.rotate(Math.PI/2);
ctx.fillText(n, 0, 0);
ctx.restore();

Javascript skips first visualitation

I have 2 canvasses that visualize values from 2 different labels.
I wrote 2 almost the same javascripts and when I run my application. It skips the first visualitation and only shows the second one. Where is my mistake?
Here is my html code:-
<div><canvas id="canvas" width="300" height="300"></canvas></div>
<asp:Label ID="LblGauge" runat="server"></asp:Label>
<div><canvas id="canvas2" width="300" height="300"></canvas></div>
<asp:Label ID="LblGauge1" runat="server"></asp:Label>
And here are my 2 javascripts. The only difference now is the canvas/canvas2 and the lblgauge and lblgauge1. Even if I change all the variables in the second script it will still only show the second visualition.
<script>
window.onload = function () {
//canvas initialization
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
//dimensions
var W = canvas.width;
var H = canvas.height;
//Variables
var degrees = document.getElementById("LblGauge").textContent;
var new_degrees = 0;
var difference = 0;
var color = "lightgreen";
var bgcolor = "#222";
var text;
var animation_loop, redraw_loop;
function init() {
//Clear the canvas everytime a chart is drawn
ctx.clearRect(0, 0, W, H);
//Background 360 degree arc
ctx.beginPath();
ctx.strokeStyle = bgcolor;
ctx.lineWidth = 30;
ctx.arc(W / 2, H / 2, 100, 0, Math.PI * 2, false);
ctx.stroke();
//Angle in radians = angle in degrees * PI / 180
var radians = degrees * Math.PI / 180;
ctx.beginPath();
ctx.strokeStyle = color;
ctx.lineWidth = 30;
//the arc will start from the topmost end
ctx.arc(W / 2, H / 2, 100, 0 - 90 * Math.PI / 180, radians - 90 * Math.PI / 180, false);
ctx.stroke();
//Lets add the text
ctx.fillStyle = color;
ctx.font = "50px bebas";
text = Math.floor(degrees / 360 * 100) + "%";
text_width = ctx.measureText(text).width;
ctx.fillText(text, W / 2 - text_width / 2, H / 2 + 15);
}
function draw() {
//Cancel any movement animation if a new chart is requested
if (typeof animation_loop != undefined) clearInterval(animation_loop);
////time for each frame is 1sec / difference in degrees
animation_loop = setInterval(animate_to, 1000 / difference);
}
//function to make the chart move to new degrees
function animate_to() {
if (degrees == new_degrees)
if (degrees < new_degrees)
degrees++;
else
degrees--;
init();
}
draw();
}
</script>
<script>
window.onload = function () {
//canvas initialization
var canvas = document.getElementById("canvas2");
var ctx = canvas.getContext("2d");
//dimensions
var W = canvas.width;
var H = canvas.height;
//Variables
var degrees = document.getElementById("LblGauge1").textContent;
var new_degrees = 0;
var difference = 0;
var color = "lightgreen";
var bgcolor = "#222";
var text;
var animation_loop, redraw_loop;
function init() {
//Clear the canvas everytime a chart is drawn
ctx.clearRect(0, 0, W, H);
//Background 360 degree arc
ctx.beginPath();
ctx.strokeStyle = bgcolor;
ctx.lineWidth = 30;
ctx.arc(W / 2, H / 2, 100, 0, Math.PI * 2, false);
ctx.stroke();
//Angle in radians = angle in degrees * PI / 180
var radians = degrees * Math.PI / 180;
ctx.beginPath();
ctx.strokeStyle = color;
ctx.lineWidth = 30;
//the arc will start from the topmost end
ctx.arc(W / 2, H / 2, 100, 0 - 90 * Math.PI / 180, radians - 90 * Math.PI / 180, false);
ctx.stroke();
//Lets add the text
ctx.fillStyle = color;
ctx.font = "50px bebas";
text = Math.floor(degrees / 360 * 100) + "%";
text_width = ctx.measureText(text).width;
ctx.fillText(text, W / 2 - text_width / 2, H / 2 + 15);
}
function draw() {
//Cancel any movement animation if a new chart is requested
if (typeof animation_loop != undefined) clearInterval(animation_loop);
////time for each frame is 1sec / difference in degrees
animation_loop = setInterval(animate_to, 1000 / difference);
}
//function to make the chart move to new degrees
function animate_to() {
if (degrees == new_degrees)
if (degrees < new_degrees)
degrees++;
else
degrees--;
init();
}
draw();
}
</script>
Can somebody tell me how to change my code.
This is what the javascript shows me when it works.

Create animation with circles time dependent

Hi I try to make a animation. One of the 3 circles which become drawed when the function is called should move from right to left at first one random (yellow, blue or orange) circle should become drawed on the canvas then after 3 seconds the next random circle and then after 2,8 seconds and so far.
How can I do that? Now the circles become drawed every time again when the mainloop starts run again.
window.onload = window.onresize = function() {
var C = 1; // canvas width to viewport width ratio
var el = document.getElementById("myCanvas");
var viewportWidth = window.innerWidth;
var viewportHeight = window.innerHeight;
var canvasWidth = viewportWidth * C;
var canvasHeight = viewportHeight;
el.style.position = "fixed";
el.setAttribute("width", canvasWidth);
el.setAttribute("height", canvasHeight);
var x = canvasWidth / 100;
var y = canvasHeight / 100;
var ballx = canvasWidth / 100;
var n;
window.ctx = el.getContext("2d");
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
// draw triangles
function init() {
ballx;
return setInterval(main_loop, 1000);
}
function drawcircle1()
{
var radius = x * 5;
ctx.beginPath();
ctx.arc(ballx * 108, canvasHeight / 2, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'yellow';
ctx.fill();
}
function drawcircle2()
{
var radius = x * 5;
ctx.beginPath();
ctx.arc(ballx * 108, canvasHeight / 2, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'blue';
ctx.fill();
}
function drawcircle3()
{
var radius = x * 5;
ctx.beginPath();
ctx.arc(ballx * 105, canvasHeight / 2, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'orange';
ctx.fill();
}
function draw() {
var counterClockwise = false;
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
//first halfarc
ctx.beginPath();
ctx.arc(x * 80, y * 80, y * 10, 0 * Math.PI, 1 * Math.PI, counterClockwise);
ctx.lineWidth = y * 1;
ctx.strokeStyle = 'black';
ctx.stroke();
//second halfarc
ctx.beginPath();
ctx.arc(x * 50, y * 80, y * 10, 0 * Math.PI, 1 * Math.PI, counterClockwise);
ctx.lineWidth = y * 1;
ctx.strokeStyle = 'black';
ctx.stroke();
//third halfarc
ctx.beginPath();
ctx.arc(x * 20, y * 80, y * 10, 0 * Math.PI, 1 * Math.PI, counterClockwise);
ctx.lineWidth = y * 1;
ctx.strokeStyle = 'black';
ctx.stroke();
// draw stop button
ctx.beginPath();
ctx.moveTo(x * 87, y * 2);
ctx.lineTo(x * 87, y * 10);
ctx.lineWidth = x;
ctx.stroke();
ctx.beginPath();
ctx.moveTo(x * 95, y * 2);
ctx.lineTo(x * 95, y * 10);
ctx.lineWidth = x;
ctx.stroke();
function drawRandom(drawFunctions){
//generate a random index
var randomIndex = Math.floor(Math.random() * drawFunctions.length);
//call the function
drawFunctions[randomIndex]();
}
drawRandom([drawcircle1, drawcircle2, drawcircle3]);
}
function update() {
ballx -= 0.1;
if (ballx < 0) {
ballx = -radius;
}
}
function main_loop() {
draw();
update();
collisiondetection();
}
init();
function initi() {
console.log('init');
// Get a reference to our touch-sensitive element
var touchzone = document.getElementById("myCanvas");
// Add an event handler for the touchstart event
touchzone.addEventListener("mousedown", touchHandler, false);
}
function touchHandler(event) {
// Get a reference to our coordinates div
var can = document.getElementById("myCanvas");
// Write the coordinates of the touch to the div
if (event.pageX < x * 50 && event.pageY > y * 10) {
ballx += 1;
} else if (event.pageX > x * 50 && event.pageY > y * 10 ) {
ballx -= 1;
}
console.log(event, x, ballx);
draw();
}
initi();
draw();
}
I'm a bit confused by your code, but I think I understand that you want to know how to delay when each circle will start animating to the left.
Here's how to animate your yellow, blue & orange circles with different delays:
Define the 3 circles using javascript objects and store all definintions in an array.
Inside an animation loop:
Calculate how much time has elapsed since the animation began
Loop through each circle in the array
If a circle's delay time as elapsed, animate it leftward
When all 3 circles have moved offscreen-left, stop the animation loop.
Here's annotated code and a Demo:
// canvas related variables
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var canvasWidth=canvas.width;
var canvasHeight=canvas.height;
// predifine PI*2 because it's used often
var PI2=Math.PI*2;
// startTime is used to calculate elapsed time
var startTime;
// define 3 circles in javascript objects and put
// them in the arcs[] array
var arcs=[];
addArc(canvasWidth,canvasHeight/2,20,0,PI2,0,-1,'yellow');
addArc(canvasWidth,canvasHeight/2+40,20,0,PI2,3000,-1,'blue');
addArc(canvasWidth,canvasHeight/2+80,20,0,PI2,8000,-1,'orange');
// begin animating
requestAnimationFrame(animate);
function animate(time){
// set startTime if it isn't already set
if(!startTime){startTime=time;}
// calc elapsedTime
var elapsedTime=time-startTime;
// clear the canvas
ctx.clearRect(0,0,canvasWidth,canvasHeight);
// assume no further animating is necessary
// The for-loop may change the assumption
var continueAnimating=false;
for(var i=0;i<arcs.length;i++){
var arc=arcs[i];
// update this circle & report if it wasMoved
var wasMoved=update(arc,elapsedTime);
// if it wasMoved, then change assumption to continueAnimating
if(wasMoved){continueAnimating=true;}
// draw this arc at its current position
drawArc(arc);
}
// if update() reported that it moved something
// then request another animation loop
if(continueAnimating){
requestAnimationFrame(animate);
}else{
// otherwise report the animation is complete
alert('Animation is complete');
}
}
function update(arc,elapsedTime){
// has this arc's animation delay been reached by elapsedTime
if(elapsedTime>=arc.delay){
// is this arc still visible on the canvas
if(arc.cx>-arc.radius){
// if yes+yes, move this arc by the specified moveX
arc.cx+=arc.moveX;
// report that we moved this arc
return(true);
}
}
// report that we didn't move this arc
return(false);
}
// create a javascript object defining this arc
function addArc(cx,cy,radius,startAngle,endAngle,
animationDelay,moveByX,color){
arcs.push({
cx:cx,
cy:cy,
radius:radius,
start:startAngle,
end:endAngle,
// this "delay" property is what causes this
// circle to delay before it starts to animate
delay:animationDelay,
moveX:moveByX,
color:color,
});
}
// draw a given arc
function drawArc(a){
ctx.beginPath();
ctx.arc(a.cx,a.cy,a.radius,a.start,a.end);
ctx.fillStyle=a.color;
ctx.fill();
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=400 height=300></canvas>

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/

Categories

Resources