gpt4 book ai didi

javascript - 一段时间后 Canvas 开始滞后

转载 作者:行者123 更新时间:2023-12-03 07:02:24 26 4
gpt4 key购买 nike

再现:将鼠标聚焦在 Canvas 上,然后将鼠标旋转约 15 秒。一开始你会发现一切都很顺利。一段时间后,它开始失去平滑度并变得非常滞后。

部分js函数来自以下答案

Make moving Rect more smooth

var canvas = document.getElementById('canvas');
var ctx = document.getElementById('canvas').getContext('2d');

var x;
var y;

var tx = tx || 0;
var ty = ty || 0;

var xDir;
var yDir;

function followMouse(e) {
x = e.offsetX;
y = e.offsetY;
moveObject();
}

function moveObject() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
var scale = 0.2 * Math.max(canvas.width, canvas.height);
xDir = 0;
yDir = 0;
xDir = (x - tx) / scale;
yDir = (y - ty) / scale;
tx = tx != x ? tx + xDir : tx;
ty = ty != y ? ty + yDir : ty;
ctx.fillRect(tx - 25, ty + 25, 50, 10);
if (tx != x || ty != y) {
window.requestAnimationFrame(moveObject);
}
}

function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
};

canvas.addEventListener('mousemove', _.throttle(function(e) {
followMouse(e);
}, 30));

window.addEventListener('resize', resizeCanvas, false);

resizeCanvas();
html,
body {
margin: 0;
height: 100%;
}

canvas {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<canvas id="canvas"></canvas>

最佳答案

每次mousemove都会启动一个新的循环。这些循环会累积并最终减慢速度。

要解决这个问题,您可以通过执行以下操作来实现 cancelAnimationFrame():

...
var timer;

function followMouse(e) {
x = e.offsetX;
y = e.offsetY;
cancelAnimationFrame(timer);
moveObject();
}

然后将计时器引用存储在主循环中:

...
timer = requestAnimationFrame(moveObject);

这将中止当前的帧更新请求,并允许您在不累积调用的情况下启动新循环。

因此,您还必须初始化 xy,因为它们在鼠标移动之前不会初始化(这当然不能保证)。

var x = 0;
var y = 0;

注意:此修正的副作用是现在每帧仅计算一次运动。累积后,每帧都会多次计算运动。要进行补偿,请将比例调整为较低的值(如下所示)。

修改后的示例

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

var x = 0;
var y = 0;

var tx = tx || 0;
var ty = ty || 0;

var xDir;
var yDir;

var timer;

function followMouse(e) {
x = e.clientX;
y = e.clientY;
cancelAnimationFrame(timer);
moveObject();
}

function moveObject() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
var scale = 0.02 * Math.max(canvas.width, canvas.height);
xDir = 0;
yDir = 0;
xDir = (x - tx) / scale;
yDir = (y - ty) / scale;
tx = tx != x ? tx + xDir : tx;
ty = ty != y ? ty + yDir : ty;
ctx.fillRect(tx - 25, ty + 25, 50, 10);
if (tx != x || ty != y) {
timer = requestAnimationFrame(moveObject);
}
}

function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
};

canvas.addEventListener('mousemove', _.throttle(function(e) {
followMouse(e);
}, 30));

window.addEventListener('resize', resizeCanvas, false);

resizeCanvas();
html,
body {
margin: 0;
height: 100%;
}

canvas {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<canvas id="canvas"></canvas>

关于javascript - 一段时间后 Canvas 开始滞后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36983189/

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