雪碧动画 clearRect 替代方案?

Posted

技术标签:

【中文标题】雪碧动画 clearRect 替代方案?【英文标题】:Sprite Animation clearRect alternative? 【发布时间】:2017-10-13 06:20:31 【问题描述】:

什么? 我正在尝试使用画布和 javascript 在网格顶部显示动画,该动画也必须使用 JavaScript 绘制。 https://jsfiddle.net/cp1wqeeg/6/

问题! 为了删除动画的前几帧,我使用了 clearRect()。然而,这打破了我不想要的网格:(

JSFiddle: https://jsfiddle.net/cp1wqeeg/5

ctx.clearRect(50, 100, width, height);

问题如何在不破坏精灵背后的网格的情况下删除动画的前几帧?

【问题讨论】:

我相信您必须清除所有内容然后重新绘制网格 【参考方案1】:

这里的常用动作是清除所有并重新绘制所有内容。 但是,如果例如在您的情况下,您的背景没有改变,这可能会变得很麻烦。

在这种情况下,一个简单的解决方案是使用屏幕外画布,它将充当图层。

首先,您在初始化阶段在此屏幕外画布上绘制网格。 然后在您的循环中,您只需使用drawImage 方法在主上下文上绘制您的屏幕外画布。

var canvas = document.getElementById("myCanvas"),
ctx = canvas.getContext("2d"),

fov = 300,
viewDist = 5,
w = canvas.width / 2,
h = canvas.height / 2,
// here we create an offscreen canvas for the grid only
gridCtx = canvas.cloneNode().getContext('2d'),
angle = 0,
i, p1, p2,
grid = 5;

function initGrid()
/// create vertical lines on the off-screen canvas
for(i = -grid; i <= grid; i++) 
  p1 = rotateX(i, -grid);
  p2 = rotateX(i, grid);
  gridCtx.moveTo(p1[0], p1[1]);
  gridCtx.lineTo(p2[0], p2[1]);
  i++;

/// create horizontal lines
for(i = -grid; i <= grid; i++) 
  p1 = rotateX(-grid, i);
  p2 = rotateX(grid, i);
  gridCtx.moveTo(p1[0], p1[1]);
  gridCtx.lineTo(p2[0], p2[1]);

gridCtx.stroke();


function rotateX(x, y) 
  var rd, ca, sa, ry, rz, f;
  rd = angle * Math.PI / 180;
  ca = Math.cos(rd);
  sa = Math.sin(rd);

  ry = y * ca;
  rz = y * sa;

  f = fov / (viewDist + rz);
  x = x * f + w;
  y = ry * f + h;

  return [x, y];
	

initGrid();
var width = 200,
height = 200,
frames = 2,
currentFrame = 0,     
	
imageSprite = new Image()
imageSprite.src = 'https://s27.postimg.org/eg1cjz6cz/sprite.png';
	 
var drawSprite = function()
		ctx.clearRect(0,0,canvas.width, canvas.height);
    ctx.drawImage(gridCtx.canvas, 0,0); // now draw our grid canvas
		ctx.drawImage(imageSprite, 0, height * currentFrame, width, height, 50, 100, width, height);
		
		if (currentFrame == frames) 
		  currentFrame = 0;
		 else 
		  currentFrame++;
		

setInterval(drawSprite, 500);
&lt;canvas id="myCanvas" width="500" height="500" style="border:1px solid #c3c3c3;"&gt;&lt;/canvas&gt;

【讨论】:

谢谢。这可以解决问题,但我的实际场景中有更多图像,这造成了网格问题 - 它被绘制在其他图像之上。为了解决这个问题,我为网格创建了第二个画布 DOM,并相应地应用了 z-index 值。 jsfiddle.net/cp1wqeeg/8

以上是关于雪碧动画 clearRect 替代方案?的主要内容,如果未能解决你的问题,请参考以下文章

怎么设置canvas动画为背景

雪碧图布局

Canvas 动画原理与 fabric 实现

Canvas 动画原理与 fabric 实现

具有广泛浏览器支持的动画 gif 替代方案?

HTML5 Canvas动画效果实现原理