我正在开发一个有趣的项目,暗示创造"不完美"通过用线条绘制圆圈并为其点设置动画以产生令人愉悦的效果。
这些点应该在离开和靠近圆心的位置之间交替,以说明:
我认为我能够做到这一点,问题是当我尝试在画布中渲染它时,渲染抖动就像疯了一样,你可以在这个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
)时它开始变得混乱,动画应该在这些和它们的初始值之间交替,但只有一半的渲染完成它。
数学错了吗?代码错了吗?或者只是我的电脑无法处理渲染?
我无法弄明白,提前谢谢!
答案 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);