我正在尝试用JavaScript设计旅行正弦波,但设计看起来很慢。主要瓶颈是画布清除的clearRect()
。
我该如何解决这个问题?
此外,我正在按ctx.fillRect(x, y,1,1)
绘制像素,但当我清除使用clearRect(x, y,1,1)
时,它会留下一些足迹。相反,我必须clearRect(x, y,5,5)
才能获得适当的清算。可以解决什么问题?
/******************************/
var x = 0;
var sineval = [];
var offset = 0;
var animFlag;
function init() {
for(var i=0; i<=1000; ++i){
sineval[i] = Math.sin(i*Math.PI/180);
}
// Call the sineWave() function repeatedly every 1 microseconds
animFlag = setInterval(sineWave, 1);
//sineWave();
}
function sineWave()
{ //console.log('Drawing Sine');
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
}
for(x=0 ; x<1000 ;++x){
// Find the sine of the angle
//var i = x % 361;
var y = sineval[x+offset];
// If the sine value is positive, map it above y = 100 and change the colour to blue
if(y >= 0)
{
y = 100 - (y-0) * 70;
ctx.fillStyle = "green";
}
// If the sine value is negative, map it below y = 100 and change the colour to red
if( y < 0 )
{
y = 100 + (0-y) * 70;
ctx.fillStyle = "green";
}
// We will use the fillRect method to draw the actual wave. The length and breath of the
if(x == 0) ctx.clearRect(0,y-1,5,5);
else ctx.clearRect(x,y,5,5);
ctx.fillRect(x, y,1,1 /*Math.sin(x * Math.PI/180) * 5, Math.sin(x * Math.PI/180 * 5)*/);
}
offset = (offset > 360) ? 0 : ++offset ;
}
答案 0 :(得分:2)
您需要稍微重构一下代码:
requestAnimationFrame
代替setInterval
fillRect()
替换为rect()
,并在内部for-loop之外执行一个fill()
使用1 ms的超时值可能会导致阻止浏览器,或者至少显着减慢浏览器的速度。考虑到监视器更新仅每16.7ms发生一次,这当然会浪费周期。如果要降低/提高正弦速度,可以减少/增加增量步长。
本质上:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var sineval = [];
var offset = 0;
init();
function init() {
for (var i = 0; i <= 1000; ++i) {
sineval.push(Math.sin(i * Math.PI / 180));
}
// Call the sineWave() function
sineWave();
}
function sineWave() {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.beginPath();
ctx.fillStyle = "green";
// draw positive part of sine wave here
for (var x = 0; x < 1000; x++) {
var y = sineval[x + offset];
if (y >= 0) {
y = 100 - (y - 0) * 70;
ctx.rect(x, y, 2, 2);
}
}
ctx.fill();
ctx.beginPath();
ctx.fillStyle = "red";
// draw negative part of sine wave here
for (var x = 0; x < 1000; x++) {
var y = sineval[x + offset];
if (y < 0) {
y = 100 - (y - 0) * 70;
ctx.rect(x, y, 2, 2);
}
}
ctx.fill();
offset = (offset > 360) ? 0 : ++offset;
requestAnimationFrame(sineWave);
}
&#13;
<canvas id="canvas" width=800 height=500></canvas>
&#13;
当然,如果您在<head>
中加载脚本,则需要将其包装在window.onload
块中,以便canvas元素可用。或者只是将脚本放在页面底部,如果还没有。