我试图将整个画布分成20个相等的列,并分别在y轴上设置动画。目标是创建类似于here的类似波形滚动动画。首先,我尝试使用php生成的带有文本的图像来创建wave滚动效果,并尝试在单个div中将其作为背景图像进行动画处理。从技术上讲它可以正常工作,但是性能和页面加载时间却非常糟糕。现在,我想用画布创建它:我已经在其中包含所有图像和文本的内容,并尝试对其进行动画处理。我试图用getImageData()将整个内容保存在列(矩形)中,然后用ImageData创建了创建的矩形,并以循环的方式重新绘制它们,但是性能仍然很糟糕,尤其是在移动设备上。动画循环如下所示:
var animate = function(index, y) {
// The calculations required for the step function
var start = new Date().getTime();
var end = start + duration;
var current = rectangles[index].y;
var distance = y - current;
var step = function() {
// get our current progress
var timestamp = new Date().getTime();
var progress = Math.min((duration - (end - timestamp)) / duration, 1);
context.clearRect(rectangles[index].x, rectangles[index].y, columnWidth, canvas.height);
// update the rectangles y property
rectangles[index].y = current + (distance * progress);
context.putImageData(rectangles[index].imgData, rectangles[index].x, rectangles[index].y);
// if animation hasn't finished, repeat the step.
if (progress < 1)
requestAnimationFrame(step);
};
// start the animation
return step();
};
现在的问题是:如何将整个画布分成相等的列,并使其在y轴上具有良好的动画效果?有什么建议么?也许在Pixi.js / Greensock的帮助下?提前致谢!
最佳答案
不要使用getImageData和setImageData进行动画处理。画布是图像,可以像任何图像一样渲染。
做你想做的
创建画布的第二个副本,并使用该画布作为要渲染的条纹的来源。
例。
const slices = 20;
var widthStep;
var canvas = document.createElement("canvas");
var canvas1 = document.createElement("canvas");
canvas.style.position = "absolute";
canvas.style.top = canvas.style.left = "0px";
var ctx = canvas.getContext("2d");
var ctx1 = canvas1.getContext("2d");
var w = canvas.width;
var h = canvas.height;
function resize(){
canvas.width = canvas1.width = innerWidth;
canvas.height = canvas1.height = innerHeight;
w = canvas.width;
h = canvas.height;
ctx1.font = "64px arial black";
ctx1.textAlign = "center"
ctx1.textBaseLine = "middle";
ctx1.fillStyle = "blue";
ctx1.fillRect(0,0,w,h);
ctx1.fillStyle = "red";
ctx1.fillRect(50,50,w-100,h-100);
ctx1.fillStyle = "black";
ctx1.strokeStyle = "white";
ctx1.lineWidth = 5;
ctx1.lineJoin = "round";
ctx1.strokeText("Waves and canvas",w / 2, h / 2);
ctx1.fillText("Waves and canvas",w / 2, h / 2);
widthStep = Math.ceil(w / slices);
}
resize();
window.addEventListener("resize",resize);
document.body.appendChild(canvas);
function update(time){
var y;
var x = 0;
ctx.clearRect(0,0,canvas.width,canvas.height);
for(var i = 0; i < slices; i ++){
y = Math.sin(time / 500 + i / 5) * (w / 8);
y += Math.sin(time / 700 + i / 7) * (w / 13);
y += Math.sin(time / 300 + i / 3) * (w / 17);
ctx.drawImage(canvas1,x,0,widthStep,h,x,y,widthStep,h);
x += widthStep;
}
requestAnimationFrame(update);
}
requestAnimationFrame(update);