动画/移动 canvas 已由 putImageData 放置的图像
Animating / Move canvas image that has been placed by putImageData
我有一个已解码的 jpeg 图像,我正在使用 putImageData 将其写入 canvas。然后可以移动此图像吗?我找不到任何关于它的文档。
我的想法是,我将使用 dirtyX 和 dirtyY 裁剪解码图像的某个部分,现在我想裁剪图像的另一部分。我正在使用像 spritesheet 一样的解码图像。
是和否:-)
由于 canvas 以即时模式绘制,因此它不知道您在 canvas 上绘制了图像。因此,您不能一次在 canvas 上绘制它并四处移动绘制的图像。您将必须在新位置的每个动画帧中手动重绘完整图像。
正如 Jonas Grumann 解释的那样,您可以使用 requestAnimationFrame()
来做到这一点。
使用drawImage
的剪辑版本将你的个人精灵绘制到canvas
(不要使用 getImageData 和 putImageData 进行裁剪,因为 drawImage 更容易和更快。)
如果您想将解码后的图像用作 spritesheet,则可以使用 canvas 的 context.drawImage
剪辑版本来剪辑 spritesheet 的特定子部分并将其绘制到canvas.
这是关于 drawImage
的剪辑版本的先前 SO post。
HTML / Java Script Canvas - how to draw an image between source and destination points?
这是示例代码和演示:
请注意,canvas 上的 "move" 精灵的方法是清除 canvas 并在新位置重新绘制所需的精灵。 (您不能 "move" canvas 上的现有绘图)。
$(window).load(function(){
// canvas related variables
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
// animation related variables
var lastFlap,lastMove;
// define a bird object
// x,y are the position of the bird on the canvas
// spriteX,spriteY is the position of the first desired
// sprite image on the spritesheet
// width,height is the size of 1 sprite image
// currentFrame is the index of which of the sprite images to display
// currentDirection. The sprite plays forward and then backward to
// accomplish 1 flap. This determines if the next frame index will
// be increased (play forward) or decreased (play backward)
var bird={
x:30,
y:30,
spriteX:0,
spriteY:52,
width:51,
height:51,
frames:4,
currentFrame:0,
currentDirection:1
}
// load the spritesheet and start the animation
var spritesheet=new Image();
spritesheet.onload=start;
spritesheet.src="https://dl.dropboxusercontent.com/u/139992952/multple/birdSpritesheet.png";
function start(){
requestAnimationFrame(animate);
}
function animate(time){
// request another animation frame
if(bird.x<canvas.width){
requestAnimationFrame(animate);
}
// if the lastFlap or lastMove times don't aren't set, then set them
if(!lastFlap){lastFlap=time;}
if(!lastMove){lastMove=time;}
// calculate the elapsed times since the last flap and the last move
var elapsedFlap=time-lastFlap;
var elapsedMove=time-lastMove;
// if 50ms have elapsed, advance to the next image in this sprite
if(elapsedFlap>50){
// advance to next sprite on the spritesheet (flap)
bird.currentFrame+=bird.currentDirection;
// clamp bird.currentFrame between 0-3 (0,1,2,3)
// (because there are 4 images that make up the whole bird sprite)
if(bird.currentFrame<0 || bird.currentFrame>bird.frames-1){
bird.currentDirection*=-1;
bird.currentFrame+=bird.currentDirection;
}
// reset the flap timer
lastFlap=time;
}
// locate the current sprite from the spritesheet
var sx=bird.spriteX+bird.currentFrame*bird.width;
var sy=bird.spriteY;
// if 100ms have elapsed, move the bird across the canvas
if(elapsedMove>100){
bird.x+=3;
lastMove=time;
}
// clear the whole canvas
ctx.clearRect(0,0,canvas.width,canvas.height);
// draw the current part of the bird sprite at the current bird.x
ctx.drawImage(spritesheet,
sx,sy,bird.width,bird.height,
bird.x,bird.y,bird.width,bird.height
);
}
}); // end $(function(){});
body{ background-color: white; }
canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>The canvas animating a clipped sprite</h4>
<canvas id="canvas" width=300 height=100></canvas>
<br>
<h4>The spritesheet</h4>
<img id=spritesheet src='https://dl.dropboxusercontent.com/u/139992952/multple/birdSpritesheet.png'>
我有一个已解码的 jpeg 图像,我正在使用 putImageData 将其写入 canvas。然后可以移动此图像吗?我找不到任何关于它的文档。
我的想法是,我将使用 dirtyX 和 dirtyY 裁剪解码图像的某个部分,现在我想裁剪图像的另一部分。我正在使用像 spritesheet 一样的解码图像。
是和否:-)
由于 canvas 以即时模式绘制,因此它不知道您在 canvas 上绘制了图像。因此,您不能一次在 canvas 上绘制它并四处移动绘制的图像。您将必须在新位置的每个动画帧中手动重绘完整图像。
正如 Jonas Grumann 解释的那样,您可以使用 requestAnimationFrame()
来做到这一点。
使用drawImage
的剪辑版本将你的个人精灵绘制到canvas
(不要使用 getImageData 和 putImageData 进行裁剪,因为 drawImage 更容易和更快。)
如果您想将解码后的图像用作 spritesheet,则可以使用 canvas 的 context.drawImage
剪辑版本来剪辑 spritesheet 的特定子部分并将其绘制到canvas.
这是关于 drawImage
的剪辑版本的先前 SO post。
HTML / Java Script Canvas - how to draw an image between source and destination points?
这是示例代码和演示:
请注意,canvas 上的 "move" 精灵的方法是清除 canvas 并在新位置重新绘制所需的精灵。 (您不能 "move" canvas 上的现有绘图)。
$(window).load(function(){
// canvas related variables
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
// animation related variables
var lastFlap,lastMove;
// define a bird object
// x,y are the position of the bird on the canvas
// spriteX,spriteY is the position of the first desired
// sprite image on the spritesheet
// width,height is the size of 1 sprite image
// currentFrame is the index of which of the sprite images to display
// currentDirection. The sprite plays forward and then backward to
// accomplish 1 flap. This determines if the next frame index will
// be increased (play forward) or decreased (play backward)
var bird={
x:30,
y:30,
spriteX:0,
spriteY:52,
width:51,
height:51,
frames:4,
currentFrame:0,
currentDirection:1
}
// load the spritesheet and start the animation
var spritesheet=new Image();
spritesheet.onload=start;
spritesheet.src="https://dl.dropboxusercontent.com/u/139992952/multple/birdSpritesheet.png";
function start(){
requestAnimationFrame(animate);
}
function animate(time){
// request another animation frame
if(bird.x<canvas.width){
requestAnimationFrame(animate);
}
// if the lastFlap or lastMove times don't aren't set, then set them
if(!lastFlap){lastFlap=time;}
if(!lastMove){lastMove=time;}
// calculate the elapsed times since the last flap and the last move
var elapsedFlap=time-lastFlap;
var elapsedMove=time-lastMove;
// if 50ms have elapsed, advance to the next image in this sprite
if(elapsedFlap>50){
// advance to next sprite on the spritesheet (flap)
bird.currentFrame+=bird.currentDirection;
// clamp bird.currentFrame between 0-3 (0,1,2,3)
// (because there are 4 images that make up the whole bird sprite)
if(bird.currentFrame<0 || bird.currentFrame>bird.frames-1){
bird.currentDirection*=-1;
bird.currentFrame+=bird.currentDirection;
}
// reset the flap timer
lastFlap=time;
}
// locate the current sprite from the spritesheet
var sx=bird.spriteX+bird.currentFrame*bird.width;
var sy=bird.spriteY;
// if 100ms have elapsed, move the bird across the canvas
if(elapsedMove>100){
bird.x+=3;
lastMove=time;
}
// clear the whole canvas
ctx.clearRect(0,0,canvas.width,canvas.height);
// draw the current part of the bird sprite at the current bird.x
ctx.drawImage(spritesheet,
sx,sy,bird.width,bird.height,
bird.x,bird.y,bird.width,bird.height
);
}
}); // end $(function(){});
body{ background-color: white; }
canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>The canvas animating a clipped sprite</h4>
<canvas id="canvas" width=300 height=100></canvas>
<br>
<h4>The spritesheet</h4>
<img id=spritesheet src='https://dl.dropboxusercontent.com/u/139992952/multple/birdSpritesheet.png'>