Moving An Image Across A Html Canvas
Solution 1:
This question is 5 years old, but since we now have requestAnimationFrame()
method, here's an approach for that using vanilla JavaScript:
var imgTag = new Image(),
canvas = document.getElementById('icanvas'),
ctx = canvas.getContext("2d"),
x = canvas.width,
y = 0;
imgTag.onload = animate;
imgTag.src = "http://i.stack.imgur.com/Rk0DW.png"; // load image
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height); // clear canvas
ctx.drawImage(imgTag, x, y); // draw image at current position
x -= 4;
if (x > 250) requestAnimationFrame(animate) // loop
}
<canvas id="icanvas" width=640 height=180></canvas>
Solution 2:
drawImage()
enables to define which part of the source image to draw on target canvas. I would suggest for each moveImg()
calculate the previous image position, overwrite the previous image with that part of imgBkg
, then draw the new image. Supposedly this will save some computing power.
Solution 3:
For lag free animations,i generally use kinetic.js.
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var hexagon = new Kinetic.RegularPolygon({
x: stage.width()/2,
y: stage.height()/2,
sides: 6,
radius: 70,
fill: 'red',
stroke: 'black',
strokeWidth: 4
});
layer.add(hexagon);
stage.add(layer);
var amplitude = 150;
var period = 2000;
// in ms
var centerX = stage.width()/2;
var anim = new Kinetic.Animation(function(frame) {
hexagon.setX(amplitude * Math.sin(frame.time * 2 * Math.PI / period) + centerX);
}, layer);
anim.start();
Here's the example,if you wanna take a look.
http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-animate-position-tutorial/
Why i suggest this is because,setInterval or setTimeout a particular function causes issues when large amount of simultaneous animations take place,but kinetic.Animation deals with framerates more intelligently.
Solution 4:
Explaining window.requestAnimationFrame()
with an example
In the following snippet I'm using an image for the piece that is going to be animated.
I'll be honest... window.requestAnimationFrame()
wasn't easy for me to understand, that is why I coded it as clear and intuitive as possible. So that you may struggle less than I did to get my head around it.
const canvas = document.getElementById('root'),
btn = document.getElementById('btn'),
ctx = canvas.getContext('2d'),
brickImage = new Image();
brickImage.src = "https://i.stack.imgur.com/YreH6.png";
var piece = {
image: brickImage,
x: 0,
y: 70,
width: 70
};
btn.addEventListener('click', start); // When btn is clicked execute start()
function start(){
if(btn.value === 'start'){
btn.value = 'animation started';
brickImage.onload = window.requestAnimationFrame(gameLoop); // Start gameLoop()
}
}
function gameLoop(){
ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear canvas
ctx.drawImage(piece.image, piece.x, piece.y); // Draw at coordinates x and y
pieceRightSide = piece.x + piece.width;
if(pieceRightSide < canvas.width){ // Brick stops when it gets to the right border
piece.x += 1;
}
window.requestAnimationFrame(gameLoop); // Needed to keep looping
}
<input id="btn" type="button" value="start" />
<p>
<canvas id="root" width="400" style="border:1px solid grey">
A key point
Inside the start() function we have:
brickImage.onload = window.requestAnimationFrame(gameLoop);
This could also be written like: window.requestAnimationFrame(gameLoop);
and it would probably work, but I'm adding the brickImage.onload
to make sure that the image has loaded first. If not it could cause some issues.
Note: window.requestAnimationFrame()
usually loops at 60 times per second.
Post a Comment for "Moving An Image Across A Html Canvas"