我想我正在重新加载图像太多次或者我的循环中出现错误,但这是我的第一个canvas项目,所以我不知道如何处理调用和方法。有人介意给我一个手或解释一下吗?
顺便说一句;我需要在网站上使用不同的模式,因此矢量。我正在使用另外三个animateC()函数,它们具有不同的名称和矢量位置(否则它们是相同的)和不同的画布(<canvas id="CSCanvas" width="2800" height="2000"></canvas>
)在'wave'div中。这是正确的方法吗?
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>
答案 0 :(得分:3)
由于种种原因,它起伏不定:
需要对整个代码进行重新分解,以预先分配图像,模式,画布和上下文。
我必须重写大部分代码,但我在这里展示了一个如何预先分配一些资源的例子。它有点帮助,但由于画布的大小和数量,它可能不会那么引人注目。
在你的模式加载器(小提琴中只有一个)你需要在加载图像后启动所有内容:
pattern.onload = loadDone;
pattern.src = '...';
在处理程序上,您可以获取画布,上下文和分配模式,然后调用动画循环:
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];
...
我用这些改变更新了小提琴:
http://jsfiddle.net/AbdiasSoftware/6FRa9/3/
使用画布层很好,但是由于它们太大,这需要大量内存。在这种情况下,原始内存要求是:
2800 x 2000 x 4 (RGBA) x 4 (Canvases) = 89 600 000 bytes, or ~84 mb.
这是84 MB,需要每秒更新60次,所需带宽为每秒5 gb(除了浏览器中的其他数据)。理论上无论如何。
因此,最好在一个画布上绘制所有内容。你可以通过像这样重新制作来做到这一点:
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起点。