【发布时间】:2015-02-01 23:04:01
【问题描述】:
我正在尝试用 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 ;
}
【问题讨论】:
-
你为什么要清除单点?只需在每次重绘之前清除整个画布即可。
-
我确实尝试过,但它会产生闪烁效果。
-
正如Bergi 所说,清除整个画布。另外,不要将计时器设置为低于 16 毫秒(您的是 1 毫秒),因为浏览器刷新显示的速度不会超过 16 毫秒。由于您的正弦波是不变的,因此请考虑预渲染正弦波的图像,并通过在每一帧期间更改其 X 坐标来在画布上“动画化”该图像。
-
正弦波是不同的......它具有幅度和频率控制
-
请注意,绿色、红色注释未在代码中实现。 y 的两个公式是相同的,每个只是 y=-70y+100。正如其他人所说,不是将 [-1,1] 范围正弦数据的大小调整为每帧 [30,170],只需在初始化时执行此操作并将扩大的范围保存在正弦波数组中。直接操作像素,而不是使用填充和清除。在初始化时使用 context.getImageData 或 context.createImageData (pick) 一次,然后使用帧所需的像素值操作返回对象的 .data 数组。在帧结束时使用 context.putImageData。
标签: javascript html canvas