一种在画布中“切换”图像的方法,就好像它是 gif

Posted

技术标签:

【中文标题】一种在画布中“切换”图像的方法,就好像它是 gif【英文标题】:A way to "toggle" image in canvas as if it was gif 【发布时间】:2016-03-01 23:31:51 【问题描述】:

我正在寻找一种简单的方法,如果有的话,在画布 (hmtl5/js) 上为图像设置动画(切换、滑动、像 gif 一样)时,我正在为拼贴制作一个游戏,我想要这些图像看起来像动画(假精灵),因为 javascript 不支持 gif。

我的图片是这样插入的:

var playerReady = false;
var playerImage = new Image();
playerImage.onload = function () 
    playerReady = true;
;
playerImage.src = "images/ship.png";

【问题讨论】:

【参考方案1】:

我们的想法是获取一系列图像(可能一次在 spritesheet 上),然后使用定时动画循环在画布上按顺序显示系列中的每个图像。 显示 == 1. 清除画布,2. 绘制下一个精灵。

这是带注释的示例代码和演示:

// 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
               );

body background-color: white; 
canvasborder:1px solid red;
<h4>"Playing" a series of sprites.</h4>
<canvas id="canvas" width=300 height=300></canvas>

【讨论】:

精灵表很好。投票赞成。很遗憾,因为我花了很长时间才创建了一个详细的答案,但你的答案简短而简洁,是一个更好的答案。 谢谢!您在 SO 商店的“画布部分”做出了很好的贡献。继续努力:-)

以上是关于一种在画布中“切换”图像的方法,就好像它是 gif的主要内容,如果未能解决你的问题,请参考以下文章

将画布导出为 .gif 图像 [重复]

如何使用 html5 画布扭曲图像以创建在风中飘扬的旗帜效果

怎么让gif格式的图片旋转90度

有没有一种不用图像就可以用 HTML5 画布和 javascript 动态绘制云的好方法?

一种在大型 Xcode 项目中查找孤立图像的方法

如何在 Android 中从 JPEG 创建动画 GIF(开发)