问题
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();
}
回答1:
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>
来源:https://stackoverflow.com/questions/32209293/create-animation-with-circles-time-dependent