gpt4 book ai didi

jquery - 为什么这个 Canvas 动画运行时断断续续?

转载 作者:行者123 更新时间:2023-12-01 08:04:26 24 4
gpt4 key购买 nike

我认为我重新加载图像的次数太多,或者循环中有错误,但这是我的第一个 Canvas 项目,所以我不确定如何处理调用和方法。有人介意帮我一下或解释一下吗?

顺便说一句;我需要网站上具有不同模式的这些,因此需要向量。我在“wave”div 内使用了另外三个 animateC() 函数,它们具有不同的名称和向量位置(否则它们是相同的)和不同的 Canvas ( <canvas id="CSCanvas" width="2800" height="2000"></canvas> )。这是正确的方法吗?

The JSDfiddle is right this way.

这是脚本..

$(document).ready(function(){

var offset = 0;
var offset2= 0;
var delta = 1;
var delta2 = .5;
var wavesCanvas = [ 'CCanvas', 'CSCanvas', 'SCanvas', 'SSCanvas' ];
var wavesIMG = ['wt1', 'shadow', 'wt2', 'shadow'];

function animateC() {
var wavevar=0;
var imgname=wavesIMG[wavevar];
var canvasname=wavesCanvas[wavevar];
var Ccanvas = document.getElementById(canvasname);
var Ccontext = Ccanvas.getContext('2d');

var pattern = new Image();
pattern.onload = function(){
Ccontext.clearRect(0,0,Ccanvas.width,Ccanvas.height);
Ccontext.save();
Ccontext.translate(-offset, 0);
Ccontext.beginPath();
Ccontext.moveTo(0, Ccanvas.height);
Ccontext.lineTo(0, 0);
var waux=120;
for(i=0;i<50;i++){
Ccontext.quadraticCurveTo(5+(waux*i), 0, (10+(waux*i)), 6);
Ccontext.quadraticCurveTo((60+(waux*i)), 56, (120+(waux*i)), 6);
}
Ccontext.lineTo(Ccanvas.width, Ccanvas.height);
Ccontext.closePath();
var fillP = Ccontext.createPattern(pattern,'repeat');
Ccontext.fillStyle = fillP;
Ccontext.fill();
};
pattern.src= './images/'+imgname+'.png';
Ccontext.restore();
offset += delta;
if (offset > 120) offset=0;
requestAnimationFrame(animateC);
}


window.requestAnimationFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 3000 / 60);
};
})();

animateC();
});

..这是 HTML..

<div id='wave'>
<canvas id="CCanvas" width="2800" height="2000"></canvas>
</div>

最佳答案

原因

由于多种原因,它运行不稳定:

  • 设置每次加载图像
  • 每次都会查找 Canvas ID
  • 每次都会请求 2D 上下文
  • 每次都会创建并设置模式
  • Canvas 很大(2800 x 2000,你有四个)

整个代码需要重构以预先分配图像、图案、 Canvas 和上下文。

我必须重写大部分代码,但我在这里展示了一个小示例,说明如何预分配一些资源。它有一点帮助,但由于 Canvas 的大小和数量,它可能不会那么明显。

在您的模式加载器上( fiddle 中只有一个),您需要在加载图像后启动所有内容:

pattern.onload = loadDone;
pattern.src = '...';

在处理程序上,您可以获取 Canvas 、上下文并分配模式,然后调用动画循环:

var aCanvas = [];
var aCtx = [];
var aPattern = [];

function loadDone() {
for(var i = 0; i < wavesCanvas.length; i++) {
var Ccanvas = document.getElementById(wavesCanvas[i]);
var Ccontext = Ccanvas.getContext('2d');
var fillP = Ccontext.createPattern(pattern, 'repeat');
aCanvas.push(Ccanvas);
aCtx.push(Ccontext);
aPattern.push(fillP);
}
animateC();
}

现在在动画循环中您只需获取已存储的资源:

function animateC() {
var wavevar = 0;
var Ccanvas = aCanvas[wavevar];
var Ccontext = aCtx[wavevar];
...

我用这些更改更新了 fiddle :
http://jsfiddle.net/AbdiasSoftware/6FRa9/3/

建议

使用 Canvas 层很好,但由于它们太大,这将需要大量内存。在这种情况下,原始内存要求是:

2800 x 2000 x 4 (RGBA) x 4 (Canvases) = 89 600 000 bytes, or ~84 mb.

即 84 MB 需要每秒更新 60 次,所需带宽为每秒 5 GB(除了浏览器中的其他数据)。无论如何,理论上是这样。

因此,最好将所有内容都绘制在一张 Canvas 上。您可以通过这样的重构来做到这一点:

function drawWave() { ... }

function animation() {

ctx.translate(offset1x, offset1y);
drawWave();
ctx.translate(-offset1x, -offset1y); //reset

ctx.translate(offset2x, offset2y);
drawWave();
ctx.translate(-offset2x, -offset2y); //reset

// ...
}

或者更好:直接使用 drawWave 函数的偏移量作为 x 和 y 起点。

关于jquery - 为什么这个 Canvas 动画运行时断断续续?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17623355/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com