Reputation: 13
I am trying to make a code learning app (like scratch but not block based) where users write code to create games and animations. I have given them a series of commands which they can use in any desired order to create an animation sequence on multiple characters. So far, I have no issues applying animations on a single character. However when two or more characters (two divs) come in a picture, the animations are executed parallelly instead of sequentially
example:
$("#div1").turnLeft();
$("#div1").moveForward()
$("#div2").moveForward () // this should run when first two are complete
$("#div3").moveForward() // this should run when first three are complete
The challenge is the order of commands is not fixed. User may use commands in any order. How do I make sure the commands entered by users are run one after another?
Thanks
Upvotes: 1
Views: 112
Reputation: 28621
You can use jquery's queue to queue animations against a different element, then they all queue in a single queue.
Adapting this answer and the info on the jquery help applying this to "body" gives you:
$.fn.moveToX = function(pos) {
var el = $(this);
$("body").queue(
function() {
el.animate({
left: pos + "px"
}, 500, () => {
$.dequeue(this);
});
});
}
$.fn.moveToY = function(pos) {
var el = $(this);
$("body").queue(
function() {
el.animate({
top: pos + "px"
}, 500, () => {
$.dequeue(this);
});
});
}
$("#d1").moveToX(100);
$("#d2").moveToX(200);
$("#d1").moveToY(50);
$("#d2").moveToY(100);
$("#d1").moveToX(0);
$("#d2").moveToX(0);
$("#d1").moveToY(0);
$("#d2").moveToY(0);
div {
position: absolute;
width: 50px;
height: 50px;
border: 1px solid magenta;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='d1'>1</div>
<div id='d2'>2</div>
To have multiple "single" queues (ie multiple queues that can have different elements applied to them (to give parallel animations)) you can supply the "queue[name]" parameter, eg:
$("body").queue("q1", function() { ...
$("body").queue("q2", function() { ...
so your move
methods can be easily extended to provide parallel animations
$.fn.moveToX = function(pos, q) {
var el = $(this);
$("body").queue(
q || "fx",
function() {
el.animate({
left: pos + "px"
}, 500, () => {
$.dequeue(this, q);
});
});
}
$.fn.moveToY = function(pos, q) {
var el = $(this);
$("body").queue(
q || "fx",
function() {
el.animate({
top: pos + "px"
}, 500, () => {
$.dequeue(this, q);
});
});
}
$("#d1").moveToX(100);
$("#d2").moveToX(200);
$("#d1").moveToY(50);
$("#d2").moveToY(100);
$("#d1").moveToX(0);
$("#d2").moveToX(0);
$("#d1").moveToY(0);
$("#d2").moveToY(0);
$("#d3").moveToX(250, "q3");
$("#d3").moveToY(50, "q3");
$("#d3").moveToX(300, "q3");
$("#d3").moveToY(0, "q3");
$("body").dequeue("q3"); // queue "fx" auto dequeues
div {
position: absolute;
width: 50px;
height: 50px;
border: 1px solid magenta;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='d1'>1</div>
<div id='d2'>2</div>
<div id='d3' style='left:300px;'>3</div>
Upvotes: 0
Reputation: 633
you must do it in call back function of each animation
$("#div1").animate({...},()=>{
$("#div1").animate({...},()=>{
$("#div2").animate({...},()=>{
$("#div3").animate({...})
})
})
});
this is a simple sample for more explain:
$("button").click(function(){
$("div").animate({
left: '250px',
opacity: '0.5',
height: '150px',
width: '150px'
},()=>{alert("finish")});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>Start Animation</button>
<p>By default, all HTML elements have a static position, and cannot be moved. To manipulate the position, remember to first set the CSS position property of the element to relative, fixed, or absolute!</p>
<div style="background:#98bf21;height:100px;width:100px;position:absolute;"></div>
Upvotes: 1