2013-12-03 8 views
2

Я создаю анимацию, используя javascript и холст. Как я могу разрешить пользователю указывать порядок отображения кадров и изменять скорость, с которой они отображаются. Это то, что я до сих порJavascript Canvas Animations

(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"; 

}()); 

ответ

2

Rq: Вы можете удалить код, определяющий requestAnimationFrame браузер не поддерживает его, так как 1) SetTimeout слишком неточны и 2) браузер поддерживает Canvas будет moooost скорее реализовать его, так полипол.

Чтобы изменить анимацию монеты, вам необходимо иметь спрайт-обновление, которое принимает параметр времени (dt, время, прошедшее с момента последнего кадра). Итак, вычислите время в цикле обновления: вычислите время игры и текущий фрейм dt (то, что вы сделали для rAF, можно повторно использовать здесь).

Затем вам нужно каким-то образом сохранить данные о длинах кадров/кадров в вашем спрайте.

Вы можете использовать массив объектов {duration:, frame:}.
Мне лично нравится массив, подобный этому: [duration1, frameIndex1, duration2, frameIndex2, ...] (быстрее и без справки, если вы скопируете его с помощью среза (0).).

Затем во время обновления монеты вам придется обрабатывать текущую временную позицию вместо количества отсчетов и «съедать» столько времени, сколько вы можете, если у вас есть под рукой, чтобы найти следующий кадр.

Теперь, чтобы подойти к вашему самому вопросу, чтобы отредактировать анимацию, я бы использовал отдельный холст под вашим холстом дисплея и пучок кнопок для изменения вещей. я сделал очень простой jsbin, это выглядит следующим образом:

enter image description here

jsbin здесь: http://jsbin.com/IjAtOxe/1/edit?js,output