var canvas;
var context;
var screenH;
var screenW;
var radius = 20;
$('document').ready(function(){
// Get the canvas
canvas = $('#heatmap');
// Calculate the screen size
screenH = canvas.height();
screenW = canvas.width();
// Fill out the canvas
canvas.attr('height', screenH);
canvas.attr('width', screenW);
context = canvas[0].getContext('2d');
var x = Math.round( (Math.random()*(.75-.25)+.25) * screenW);
var y = Math.round( (Math.random()*(.65-.35)+.35) * screenH);
circle(canvas, x, y);
})
function circle(canvas, x, y){
context.save();
context.beginPath();
context.arc(x,y,radius,0,2*Math.PI);
context.closePath();
radius += 1;
if(radius < 61){
window.requestAnimationFrame(circle)
}
context.fill();
context.restore();
}
这里的目标是让圆圈不断增长,并在 Canvas 内随机放置,但在一定范围内。所以这里的问题是 window.requestAnimationFrame(circle)
会递归地点燃circle(),直到变量 radius 达到 60。但是由于 circle()
是一个单独的函数, x 和y 未定义。所以我想我需要缓存 x 和 y 的初始值并将其传递到回调中?
最佳答案
这是一个最小的示例:
var radius = 20;
var canvas = document.createElement("canvas");
var ctx = canvas.getContext('2d');
document.body.appendChild(canvas);
canvas.height = innerHeight;
canvas.width = innerWidth;
var x = (Math.random() * (0.75 - 0.25) + 0.25) * canvas.width;
var y = (Math.random() * (0.65 - 0.35) + 0.35) * canvas.height;
circle(ctx, x, y, radius);
function circle(ctx, x, y, radius) {
(function animate() {
ctx.beginPath();
ctx.arc(x, y, radius++, 0, 2 * Math.PI);
ctx.fill();
if (radius < 61) {
window.requestAnimationFrame(animate);
}
})();
}
您的原始代码中存在一些无效的 JS(canvas.height()
不是函数),因此请随时将我的样板恢复为您正在使用的内容。将半径以及 x 和 y 传递到circle()
函数中也是有意义的,但您可以放弃它。
即使进行了这些更改,这种设计对我来说也没有多大意义。通常,动画循环将独立于任何单独的渲染实体,例如圆形,它应该是带有draw()
例程的对象。目前的代码有点意味着您可以制作 2000 个独立的圆圈,如果每个圆圈都有自己的 requestAnimationFrame()
循环在内部运行,那么这是有问题的。
我更喜欢像 fiddle 中所示的设计,我对此有点得意忘形,但圆形实体是可渲染的对象,具有自己的一组封装属性,并且有一个主动画循环运行所有内容。
关于javascript - canvas 上下文 - 缓存 window.requestAnimationFrame 回调函数的变量值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51561522/