画布抖动了我渲染的一半

时间:2015-07-12 18:43:01

标签: javascript canvas

我正在开发一个有趣的项目,暗示创造"不完美"通过用线条绘制圆圈并为其点设置动画以产生令人愉悦的效果。

这些点应该在离开和靠近圆心的位置之间交替,以说明:

graphic representation of the idea

我认为我能够做到这一点,问题是当我尝试在画布中渲染它时,渲染抖动就像疯了一样,你可以在这个demo.中看到它

您可以在this video中查看它为我呈现的内容。如果你密切关注,渲染的右下半部分可以顺利运行,而左上角则只是...没有。

这就是我创建点的方式:

for (var i = 0; i < q; i++) {
    var a = toRad(aDiv * i);
    var e = rand(this.e, 1);
    var x = Math.cos(a) * (this.r * e) + this.x;
    var y = Math.sin(a) * (this.r * e) + this.y;
    this.points.push({
        x: x,
        y: y,
        initX: x,
        initY: y,
        reverseX: false,
        reverseY: false,
        finalX: x + 5 * Math.cos(a),
        finalY: y + 5 * Math.sin(a)
    }); 
}

不完美圆中的每个点都是使用一个角度和随机距离来计算的,它并不是特别相关(它依赖于一些参数)。

我认为当我分配最终值(finalX,finalY)时它开始变得混乱,动画应该在这些和它们的初始值之间交替,但只有一半的渲染完成它。

数学错了吗?代码错了吗?或者只是我的电脑无法处理渲染?

我无法弄明白,提前谢谢!

1 个答案:

答案 0 :(得分:3)

  

数学错了吗?代码错了吗?或者只是我的电脑无法处理渲染?

我认为你的动画功能并不关心经过的时间。简单地说动画发生得非常快。 requestAnimationFrame回调的次数通常是每秒60次,所以恰好发生了预期的事情。

我在这个fiddle中做了一些修正。此动画功能负责时间戳。此外,我在动画中制作了一个渐变,以便顺利地在最终位置和初始位置之间切换。

ImperfectCircle.prototype.animate = function (timestamp) {
    var factor = 4;
    var stepTime = 400;
    for (var i = 0, l = this.points.length; i < l; i++) {
        var point = this.points[i];
        var direction = Math.floor(timestamp/stepTime)%2;
        var stepProgress = timestamp % stepTime * 100 / stepTime;
        stepProgress = (direction == 0 ? stepProgress: 100 -stepProgress);
        point.x = point.initX + (Math.cos(point.angle) * stepProgress/100 * factor); 
        point.y = point.initY + (Math.sin(point.angle) * stepProgress/100 * factor);
    }
}

一步一步:

基于评论

// 1. Calculates the steps as int: Math.floor(timestamp/stepTime)
// 2. Modulo to know if even step or odd step: %2
var direction = Math.floor(timestamp/stepTime)%2;

// 1. Calculates the step progress: timestamp % stepTime
// 2. Convert it to a percentage: * 100 / stepTime
var stepProgress = timestamp % stepTime * 100 / stepTime;

// if odd invert the percentage. 
stepProgress = (direction == 0 ? stepProgress: 100 -stepProgress);

// recompute position based on step percentage
// factor is for fine adjustment.
point.x = point.initX + (Math.cos(point.angle) * stepProgress/100 * factor); 
point.y = point.initY + (Math.sin(point.angle) * stepProgress/100 * factor);