Javascript画布动画

Javascript画布动画,javascript,animation,canvas,Javascript,Animation,Canvas,我正在使用javascript和画布创建动画。如何允许用户指定帧的显示顺序并更改帧的显示速度。这就是我目前所拥有的 (function() { var lastTime = 0; var vendors = ['ms', 'moz', 'webkit', 'o']; for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { window.requestAnimationFr

我正在使用javascript和画布创建动画。如何允许用户指定帧的显示顺序并更改帧的显示速度。这就是我目前所拥有的

(function() {

var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
    window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
    window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] 
                               || window[vendors[x]+'CancelRequestAnimationFrame'];
}

if (!window.requestAnimationFrame)
    window.requestAnimationFrame = function(callback, element) {
        var currTime = new Date().getTime();
        var timeToCall = Math.max(0, 16 - (currTime - lastTime));
        var id = window.setTimeout(function() { callback(currTime + timeToCall); }, 
          timeToCall);
        lastTime = currTime + timeToCall;
        return id;
    };

if (!window.cancelAnimationFrame)
    window.cancelAnimationFrame = function(id) {
        clearTimeout(id);
    };
}());

(function () {

var coin,
    coinImage,
    canvas;                 

function gameLoop () {

  window.requestAnimationFrame(gameLoop);

  coin.update();
  coin.render();
}

function sprite (options) {

    var that = {},
        frameIndex = 0,
        tickCount = 0,
        ticksPerFrame = options.ticksPerFrame || 0,
        numberOfFrames = options.numberOfFrames || 1;

    that.context = options.context;
    that.width = options.width;
    that.height = options.height;
    that.image = options.image;

    that.update = function () {

        tickCount += 1;

        if (tickCount > ticksPerFrame) {

            tickCount = 0;

            // If the current frame index is in range
            if (frameIndex < numberOfFrames - 1) {  
                // Go to the next frame
                frameIndex += 1;
            } else {
                frameIndex = 0;
            }
        }
    };

    that.render = function () {

      // Clear the canvas
      that.context.clearRect(0, 0, that.width, that.height);

      // Draw the animation
      that.context.drawImage(
        that.image,
        frameIndex * that.width / numberOfFrames,
        0,
        that.width / numberOfFrames,
        that.height,
        0,
        0,
        that.width / numberOfFrames,
        that.height);
    };

    return that;
}

// Get canvas
canvas = document.getElementById("coinAnimation");
canvas.width = 500;
canvas.height = 500;


// Create sprite sheet
coinImage = new Image();    

// Create sprite
coin = sprite({
    context: canvas.getContext("2d"),
    width: 500,
    height:72,
    image: coinImage,
    numberOfFrames: 10,
    ticksPerFrame: 4
});

// Load sprite sheet
coinImage.addEventListener("load", gameLoop);
coinImage.src = "sprite.png";

 } ());
(函数(){
var lastTime=0;
var供应商=['ms','moz','webkit','o'];
对于(var x=0;x滴答声帧){
滴答数=0;
//如果当前帧索引在范围内
如果(frameIndex
Rq:您可能会删除为不支持它的浏览器定义requestAnimationFrame的代码,因为1)setTimeout太不准确,2)支持画布的浏览器很可能无法实现它,因此polyfill就足够了

要更改硬币动画,您需要使用时间参数(dt,自上一帧以来经过的时间)进行精灵更新。因此,计算更新循环中的时间:让它计算游戏时间和当前帧的dt(你为rAF所做的可以在这里重用)

然后,您需要某种方法在您的精灵中存储帧/帧持续时间数据

您可以使用{duration:,frame:}对象数组。
我个人喜欢这样的数组:[duration1,frameIndex1,duration2,frameIndex2,…](如果使用切片(0)复制它,速度更快,并且没有引用问题)

然后在硬币的更新过程中,你必须处理当前的时间位置,而不是滴答数,并且用你手头的dt“吃掉”尽可能多的持续时间,以找到下一帧

现在来回答你的问题,为了编辑动画,我将在你的显示画布下面使用一个单独的画布,和一组按钮来改变事情。 我做了一个非常简单的jsbin,它看起来像这样:

jsbin在这里: