user3235729
user3235729

Reputation: 13

Run animations sequentially on multiple divs without timeout

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

Answers (2)

fdomn-m
fdomn-m

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

Mehrzad Tejareh
Mehrzad Tejareh

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

Related Questions