具有多个setTimeout的JavaScript动画 [英] JavaScript animation with multiple setTimeout

查看:190
本文介绍了具有多个setTimeout的JavaScript动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要使​​用setTimeout为3个不同的形状做动画,我的问题是如何使用多个setTimeout来动画3种不同的形状也有一个更好的方法,这可能使用setInterval

  window.onload = draw; 
var x = 5;
var y = 5;

radius = 50;

var x2 = 50;
var y2 = 120;

var x3 = 53;
var y3 = 230;
var context;

var loopTimer;

function draw(){
var canvas = document.getElementById('canvas');
context = canvas.getContext('2d');
context.save();
context.clearRect(0,0720,550);

rectangle(x,y);
circle(x2,y2);
circle2(x3,y3);

}

function rectangle(x,y){
//绘制矩形
context.fillStyle =rgba(93,119,188,237);
context.clearRect(0,0720,550);
context.rect(x,y,50,50);
context.fill();
context.lineWidth = 7;
context.strokeStyle ='yellow';
context.stroke();
x + = 1;
loopTimer = setTimeout('rectangle('+ x +','+ y +')',50);
}

函数圈(x2,y2){
// darwong a circle
context.beginPath();
context.clearRect(0,0720,550);
context.fillStyle =#0000ff;
//在画布上的当前坐标处绘制半径为20的圆。
context.arc(x2,y2,radius,0,Math.PI * 2,true);
context.closePath();
context.fill();
x2 + = 1;
loopTimer = setTimeout('circle('+ x2 +','+ y2 +')',20);
}

function circle2(x3,y3){
//绘制第二个圆
context.beginPath();
context.clearRect(0,0720,550);
context.fillStyle ='green';
context.arc(x3,y3,radius,0,Math.PI * 2,true);
context.closePath();
context.fill();
context.lineWidth = 5; //边界绕圈
context.strokeStyle ='red';
context.stroke();
x3 + = 1;
loopTimer = setTimeout('circle2('+ x3 +','+ y3 +')',20)
}


解决方案



当进行数字动画时,不需要多个单独的计时器。



关键是将属性绑定到对象



其逻辑步骤是创建自定义对象,我们可以收集这些信息并使用更新函数在循环中的单个步骤中为我们执行所有更新。



示例



此处的在线演示



创建一个对象集合,其中存储所有对象:

  var animObjects = [] 

没有什么好看的 - 只是一个数组。



单个循环



为了显示这么简单,我将首先显示循环本身,然后剖析对象。循环简单地遍历我们的集合,并对每个对象调用 update 方法:

  function loop(){

///重绘所有对象之前清除canvas
ctx.clearRect(0,0,demo.width,demo.height);

///循环通过对象集合并更新每个对象
for(var i = 0,animObject; animObject = animObjects [i]; i ++){
animObject.update ();
}

///使用this而不是setTimeout / setInterval(!)
requestAnimationFrame(loop);
}



现在,你注意到我们使用 requestAnimationFrame (rAF)而不是 setTimeout setInterval 。 rAF允许我们同步到监视器的更新频率,而 setTimout / setInterval 不能。此外,rAF的工作效率比其他两个,如果我们需要动画很多东西,这将有利于我们。



动画对象



现在让我们来看看对象,我们只需要调用更新和动画的东西呢?



如前所述,我们创建一个动画圆对象简单地通过调用:

  var animObject = new animCircle(context,x,y,radius,color,stepX,stepY ); 

这允许我们设置要使用的上下文(如果我们使用几层canvas) ,起始位置,颜色和每帧的步数。请注意,这些属性可以在动画期间更改(例如更改半径和颜色)。



对象本身如下 -

 函数animCircle(ctx,x,y,r,color,stepX,stepY){

///保持引用'this'外部调用的上下文
var me = this;

///使参数公开,所以我们可以改变它们
this.x = x;
this.y = y;
this.radius = r;
this.color = color;
this.stepX = stepX;
this.stepY = stepY;

///这将通过增加x和y来更新对象
this.update = function(){

me.x + = me.stepX;
me.y + = me.stepY;

///可以在这里插入额外的更新

render();
}

///这将使用当前设置绘制对象
function render(){
ctx.beginPath();
ctx.arc(me.x,me.y,me.radius,0,2 * Math.PI);
ctx.closePath();
ctx.fillStyle = me.color;
ctx.fill();
}
return this;
}

这就是它的全部!



对象 update()方法将为我们做所有的计算,并调用内部 render()方法。



您可以在各种位置和速度创建许多这些对象,并从单个循环中动画制作所有对象。



我只为圆圈创建了一个对象,以保持简单。你应该能够创建一个矩形对象,你有什么使用它作为基础。你当然可以扩展对象以跟踪其他事情,如笔触颜色,角度等。



我也使对象从画布上弹起边缘为演示的缘故。请根据需要进行调整。


i am trying to animate 3 different shapes with setTimeout , my question is how can i use multiple setTimeout to animate 3 different shapes also is there a better way to do this maybe using setInterval

window.onload = draw;
var x = 5;
var y = 5;

radius = 50;

var x2 = 50;
var y2 = 120;

var x3 = 53;
var y3 = 230;
var context;

var loopTimer;

function draw(){
var canvas = document.getElementById('canvas');
 context = canvas.getContext('2d');
context.save();
context.clearRect(0,0,720,550);

rectangle(x,y);
circle(x2,y2);
circle2(x3,y3);

}

function rectangle(x,y){
//drawing a rectangle 
context.fillStyle = "rgba(93,119,188,237)";
context.clearRect(0,0,720,550);
context.rect(x, y, 50, 50);
context.fill();
context.lineWidth = 7;
context.strokeStyle = 'yellow';
context.stroke();
x += 1;
loopTimer = setTimeout('rectangle('+x+','+y+')',50);
}

function circle(x2,y2){
//darwong a circle
context.beginPath();
context.clearRect(0,0,720,550);
context.fillStyle = "#0000ff";  
//Draw a circle of radius 20 at the current coordinates on the canvas. 
context.arc(x2, y2, radius, 0, Math.PI*2, true); 
context.closePath();
context.fill();
x2 += 1;
loopTimer = setTimeout('circle('+x2+','+y2+')',20);
}

function circle2(x3,y3){
//drawing a second circle 
context.beginPath();
context.clearRect(0,0,720,550);
context.fillStyle = 'green';
context.arc(x3, y3, radius, 0, Math.PI*2, true); 
context.closePath();
context.fill();
context.lineWidth = 5;//border around the circle 
context.strokeStyle = 'red';
context.stroke();
x3 += 1;
loopTimer = setTimeout('circle2('+x3+','+y3+')',20);
}

解决方案

Animating objects

When doing digital animation there is never need for more than one single timer.

The key is to bind properties to the objects being animation such as its position, speed (or steps), color, shape and so forth.

The logic step therefor is to create custom objects that we can collect this information and use an update function to do all the updates for us in a single step within the loop.

Example

ONLINE DEMO HERE

Lets create an object collection where we store all our objects:

var animObjects = [];

Nothing fancy about that - just an array.

A single loop

To show how simple this can get I will show the loop itself first, then dissect the object. The loop simply iterates through our collection and calls the update method on each object:

function loop() {

    /// clear canvas before redrawing all objects   
    ctx.clearRect(0, 0, demo.width, demo.height);

    /// loop through the object collection and update each object
    for(var i = 0, animObject; animObject = animObjects[i]; i++) {
        animObject.update();
    }

    /// use this instead of setTimeout/setInterval (!)
    requestAnimationFrame(loop);
}

Now, you noticed probably that we used requestAnimationFrame (rAF) here instead of setTimeout or setInterval. rAF allows us to synchronize to the monitor's update frequency whereas setTimout/setInterval cannot. In addition rAF works more efficient than the other two which will benefit us if we need to animate a lot of stuff.

The animation object

Now lets take a look at the object, how come we only need to call update and things animate?

As we saw earlier we create a animated circle object simply by calling:

var animObject = new animCircle(context, x, y, radius, color, stepX, stepY);

This allows us to set which context we want to use (in case we use several layers of canvas), the start position, color and number of steps per frame. Note that these properties can be changed during the animation (e.g. change radius and color).

The object itself looks like this -

function animCircle(ctx, x, y, r, color, stepX, stepY) {

    /// keep a reference to 'this' context for external calls
    var me = this;

    /// make the parameters public so we can alter them
    this.x = x;
    this.y = y;
    this.radius = r;
    this.color = color;
    this.stepX = stepX;
    this.stepY = stepY;

    /// this will update the object by incrementing x and y
    this.update = function() {

        me.x += me.stepX;
        me.y += me.stepY;

        /// additional updates can be inserted here

        render();
    }

    /// and this takes care of drawing the object with current settings
    function render() {
        ctx.beginPath();
        ctx.arc(me.x, me.y, me.radius, 0, 2 * Math.PI);
        ctx.closePath();
        ctx.fillStyle = me.color;
        ctx.fill();
    }
    return this;
}

That's all there is to it!

The objects update() method will do all the calculations for us as well as call the internal render() method.

You can create many of these objects at various positions and speeds and animate all of them from a single loop.

I only created an object for the circle to keep things simple. You should be able to create an object for rectangle and what have you by using this as a base. You can of course extent the object to keep track of other things as well such as stroke color, angles and so forth.

I also made the objects bounce off the canvas' edges for the sake of demo. Please adjust as needed.

这篇关于具有多个setTimeout的JavaScript动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆