1

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

  • You might be able to use [async/await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) – James Oct 07 '20 at 14:07
  • Given your syntax to run sequentially, how *would* you make them move at the same time (in parallel)? – freedomn-m Oct 07 '20 at 14:13
  • Consider the "queue" option to animate: https://api.jquery.com/animate/#animate-properties-options. Give them all the same queue and they should run sequentially – freedomn-m Oct 07 '20 at 14:16
  • @freedomn-m : Would it be possible for you to give a crude example? I tried using queue : false/true. It doesn't work sequentially. – user3235729 Oct 07 '20 at 14:34
  • My bad - on trying it out custom queues don't work the way they're described - it's not animations per queue, it's animations per queue-per-element. :( Here's a question that sums up the problem with (unhelpful) solutions: https://stackoverflow.com/questions/18499000/using-jquery-queue-with-multiple-element-animations – freedomn-m Oct 07 '20 at 15:33

2 Answers2

1

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>
Mehrzad Tejareh
  • 635
  • 5
  • 21
0

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>
freedomn-m
  • 27,664
  • 8
  • 35
  • 57
  • 1
    BRILLIANT !!! Can't thank you enough for this. Its working perfectly and I also understood how queue works now. You saved my hours. Thanks Freedomn-m – user3235729 Oct 07 '20 at 18:22