Reputation: 3517
EDIT: For clarity, the question is why doesn't the code below work as expected (why does it not animate for the duration of the while loop), how can I improve it and how can I red in the unit that it should travel via a user input slider.
My aim is to have shape animates it's way down the screen. A button will start and stop the animation. There will also be an input for the rate of change or speed at which it travels.
I can make it continuously travel down the screen but the following code doesn't work - I've used ble as a test variable, in the final scenario I'd hope that this would be replaced with something similar to while(stop != true)
or something similar.
startDescent.onclick = function(){
startDescent.disabled = true; //prevent it being clicked again
//animation process
var ble = 1;
while(ble < 10){
console.log(ble);
testDrillbit.animate('top', '+=1',{
duration: 1000,
onChange: canvas.renderAll.bind(canvas),
onComplete: function(){
startDescent.disabled = false;
}
});
ble++;
}
};
the +=1 increment should also read in from a user input box, any suggestions on how to achieve this would also be very welcome. Thanks for all and any help.
Upvotes: 0
Views: 2916
Reputation: 46
I believe you are making use of Fabric JS to provide the animation logic. My answer is based on that assumption.
The issue has to do with your intepretation of how the animate function works. It is not a synchronous call. So your loop will essentially initialize the animate action 10 times, not execute 10 animations. Given that the action you defined was to move object "testDrillBit" down 1 pixel over a period of 1 seconds, it would probably appear like nothing happened.
To approximate the operation you are trying to perform, you would need to employ a callback that basically indicates when the animation is complete, do it again, until the user hits their "stop" button. This would probably cause a jerky animation though. Alternatively you can set an arbitrarly large endpoint for the animation and add an abort handler, but you would then need to determine your rate of change (pixels/time) to come up with the right duration.
It's not clear that this library is appropriate for your implementation, but I cannot offer an alternative at this time. The code example below illustrates the second option while illustrating the points you had asked for, a stop mechanism, arbitray rate of change etc. The significant change is rather than specifying +=1 for the rate of change, we alter the duration it takes for the animation to complete and animate over a larger distance (in this case the canvas height).
First, we add a stop button and an input for our speed:
<button id="stop" disabled="true" onclick="stop=true;">Stop</button>
<form>
<input type="text" id="speed" value="10" />
</form>
Then, in our script box we make sure we can use these values and then employ them in the onclick handler.
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;
}
});
};
The above code should allow the user to alter the "speed" by stretching or shortening the amount of time to perform the animation. In addition you have your mechanism to stop the animation partway through the execution.
Upvotes: 3