Search code examples
geometrykineticjsmove

Moving three circles to another position slowing down movement (KineticJS)


I am trying to move three circles, after they gradually fade in, to the top left of the page so that they overlap on a box. At the moment, I set a timeout, but it only works for the first circle and the movement is really fast. How can I move them all as a group and slow down the movement?

 <!DOCTYPE HTML>
   <html>
     <head>
       <style>
         body {
      margin: 0px;
      padding: 0px;
       background-color: #CCCCCC;
             }
    </style>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"></head>
<body>
 <div id="container"></div>

<script src="http://www.html5canvastutorials.com/libraries/kinetic-v4.3.1-beta2.js">        
 </script>
  <script>
var fadeIn = function(shape) {
 var o = shape.getOpacity();
  o = o + 0.05 >=0.5 ? 0.5 : o + 0.05;
shape.setOpacity(o);
shape.getLayer().draw();
if(o !== 0.4) {
    setTimeout(function() {
            fadeIn(shape).delay(3000*3);
        }, 720);
    }
  };
  var stage = new Kinetic.Stage({
    container: 'container',
    width: 800,
    height: 700

    //width: 578,
    //height: 200
  });

  var layer = new Kinetic.Layer();

  var circle = new Kinetic.Circle({
    x: stage.getWidth() / 2,
    y: stage.getHeight() / 2,
    radius: 70,
    fill: '#CCCCCC',
    stroke: 'yellow',
    strokeWidth: 8,
    opacity: 0.1

   });
  circle.hide();
   setTimeout(function() {
        circle.show();
        fadeIn(circle).delay(3000*3);
    }, 1720);

    layer.add(circle);


    var circle2 = new Kinetic.Circle({
    x: stage.getWidth() / 2.1,
    y: stage.getHeight() / 2.1,
    radius: 70,
    fill: '#CCCCCC',
    stroke: 'yellow',
    strokeWidth: 8,
    opacity: 0.1
  });
  circle2.hide();
   setTimeout(function() {
        circle2.show();
        fadeIn(circle2).delay(3000*3);
    }, 5600);

  // add the shape to the layer
  layer.add(circle2);

  var circle3 = new Kinetic.Circle({
    x: stage.getWidth() / 2.2,
    y: stage.getHeight() / 2.2,
    radius: 70,
    fill: '#CCCCCC',
    stroke: 'yellow',
    strokeWidth: 8,
    opacity: 0.1

    });
    circle3.hide();
   setTimeout(function() {
   circle3.show();
        fadeIn(circle3).delay(3000*3);
    }, 12000);

  // add the shape to the layer
  layer.add(circle3);

   // var boxGroup = new Kinetic.Group({
    //x: 10,
    //y: 10,
    //draggable: true
  //});
  var boxGroup = new Kinetic.Group({
    x: -250,
    y: -250,
    draggable: true
  });

    var box = new Kinetic.Rect({
    x: 10,
    y: 10,
    width: 100,
    height: 100,
    fill: '#CCCCCC',
    stroke: 'black'
  });

  boxGroup.add(box);
  layer.add(box);
  layer.add(boxGroup);

  // add the layer to the stage
  stage.add(layer);

  setTimeout(function() {
   circle.moveTo(boxGroup).delay(5000*3);
   circle2.moveTo(boxGroup).delay(5000*3);
   circle3.moveTo(boxGroup).delay(5000*3);
    }, 24000);

  </script>
 </body>


Solution

  • http://jsfiddle.net/SAnFM/9/

    KineticJS has a great transitionTo() function which you can call. It can animate any numerical property, like position or opacity. I created a fiddle to show this, as setTimeout is a bit of an ancient function compared to what is built into the browsers nowadays with RequestAnimationFrame (all major browsers implement this nowadays and KineticJS has a built in fallback like most other libraries do)

    I cleaned up your code a little, removing comments and added an extra circle, for fun.

    but really all you need is:

    myShape.transitionTo({shape configuration, duration});
    

    For example:

    circle.transitionTo({
        x: box.getX(),  //coordinates to transition to
        y: box.getY(),
        opacity: 1,  
        duration: 1  // length of time for this animation in seconds, REQUIRED for animation to work
    });