canvas上下文-缓存window.requestAnimationFrame回调函数的变量值

时间:2018-07-27 15:54:14

标签: javascript variables callback

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(); 
}

此处的目标是使圆圈不断扩大,并随机放置在画布中但在一定范围内。因此,这里的问题是window.requestAnimationFrame(circle)将递归地点燃circle(),直到可变半径达到60。但是由于circle()是一个单独的函数,因此x和y是不确定的。所以我想我需要缓存x和y的初始值并将其传递给回调?

1 个答案:

答案 0 :(得分:1)

这是一个最小的例子:

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()循环,则是有问题的。

我更喜欢按照本repl中的说明进行设计,虽然我对此感到有些困惑,但是圆形实体是可渲染对象,具有一组自己的封装属性,并且运行着一个主要的动画循环一切。