如何优化此代码以渲染正弦波,而不会在画布重新绘制时发生模糊
var canvas = document.getElementById("sinewave");
var points = {};
var counter = 0;
var intensity = 0;
function f(x, intensity) {
return intensity * Math.sin(0.25 * x) + 100;
}
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.strokeStyle = '#fff';
ctx.lineWidth = 2;
var x = 0,
y = f(0,0);
var timeout = setInterval(function() {
if(counter < 400) {
ctx.beginPath();
ctx.moveTo(x, y);
x += 1;
y = f(x, intensity);
points[x] = y;
ctx.lineTo(x, y);
ctx.stroke();
if (x > 1000) {
clearInterval(timeout);
}
} else {
ctx.clearRect(0, 0, 400, 200);
ctx.beginPath();
points[x] = y;
x += 1;
y = f(x, intensity);
for(var i = 0; i < 400; i++) {
ctx.lineTo(i, points[i + counter - 400]);
}
ctx.stroke();
}
counter++;
}, 5);
}
答案 0 :(得分:0)
一些想法:
因为x == 0&amp;强度== 0前400个图形成一条直线(?)。
您的setInterval时间太短(5毫秒)。屏幕只刷新大约每17毫秒,因此您正在累积间隔调用,浏览器将徒劳地尝试填充。 (你被堵塞了!)。
使用new(ish)requestAnimationFrame而不是setInterval,因为requestAnimationFrame可以更好地与显示硬件集成。
以下是重构代码示例和演示:http://jsfiddle.net/m1erickson/MZ7Ap/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: black; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
ctx.strokeStyle = '#fff';
ctx.lineWidth = 2;
var points = {};
var counter = 0;
var intensity = 2;
var x = 0;
var y = fz(0,0);
animate();
function fz(x, intensity) {
return intensity * Math.sin(0.25 * x) + 100;
}
function animate(time){
requestAnimationFrame(animate);
draw(counter);
counter++;
}
function draw(counter){
if(counter < 400) {
ctx.beginPath();
ctx.moveTo(x, y);
x += 1;
y = fz(x, intensity);
points[x] = y;
ctx.lineTo(x, y);
ctx.stroke();
if (x > 1000) {
clearInterval(timeout);
}
} else {
ctx.clearRect(0, 0, 400, 200);
ctx.beginPath();
points[x] = y;
x += 1;
y = fz(x, intensity);
for(var i = 0; i < 400; i++) {
ctx.lineTo(i, points[i + counter - 400]);
}
ctx.stroke();
}
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=900 height=300></canvas>
</body>
</html>