我相信您正在使用 Fabric JS 来提供动画逻辑。我的回答是基于这个假设。
这个问题与您对 animate 函数如何工作的解释有关。它不是同步调用。所以你的循环基本上会初始化动画动作 10 次,而不是执行 10 次动画。鉴于您定义的操作是在 1 秒内将对象“testDrillBit”向下移动 1 个像素,它可能看起来就像什么都没发生。
为了近似您尝试执行的操作,您需要使用一个回调,该回调基本上指示动画何时完成,再做一次,直到用户点击他们的“停止”按钮。不过,这可能会导致生涩的动画。或者,您可以为动画设置一个任意大的端点并添加一个中止处理程序,但是您需要确定您的变化率(像素/时间)以得出正确的持续时间。
目前尚不清楚该库是否适合您的实现,但我目前无法提供替代方案。下面的代码示例说明了第二个选项,同时说明了您所要求的点、停止机制、任意变化率等。显着的变化不是为变化率指定 +=1,而是改变它所需的持续时间动画完成并在更大的距离上设置动画(在本例中为画布高度)。
首先,我们为我们的速度添加一个停止按钮和一个输入:
<button id="stop" disabled="true" onclick="stop=true;">Stop</button>
<form>
<input type="text" id="speed" value="10" />
</form>
然后,在我们的脚本框中,我们确保我们可以使用这些值,然后在 onclick 处理程序中使用它们。
var stopBtn = document.getElementById('stop');
var speedBox = document.getElementById('speed');
var stop = false;
startDescent.onclick = function() {
// Get our speed, in case the user changes it. Speed here is actually the duration
// of the animation, not a true velocity. But, we can do something like entering 0.5
// and "slow down" the animation
var speed = 10000 / (new Number(speedBox.value));
stop = false; // ensure that we won't abort immediately
stopBtn.disabled = false; // enable the stop button
startDescent.disabled = true;
// I chose canvas.height as an arbitrary fixed distance. Not this won't stop the
// the element from rolling out of the canvas, its just a fixed value.
// The significant change is the addition of the "abort" function which basically
// polls our stop variable to determine whether the animation should be aborted.
testDrillbit.animate('top', "+="+canvas.height, {
duration: speed,
abort: function () {
// If the user has clicked the stop button, flip our buttons
if (stop) {
startDescent.disabled = false;
stopBtn.disabled = true;
}
return stop;
},
onChange: canvas.renderAll.bind(canvas),
onComplete: function() {
startDescent.disabled = false;
stopBtn.disabled = true;
}
});
};
上面的代码应该允许用户通过拉伸或缩短执行动画的时间来改变“速度”。此外,您还有在执行过程中停止动画的机制。