Search code examples
javascripthtmlrotationkineticjs

kinectJs Rotation of two images


I have 2 images that are the upper arm and forearm. The upper arms rotates around a point and the forearm rotates round this same point.

How can i rotate the forearm when i rotate the upper arm?

if i rotate the upperarm 12 degress,then i must move the forearm to the rotation point of the upper arm and then rotate it but i cant seem to get the forearm to move back into postion after the rotation. What am i doing wrong.

code im using for a kinectjs event;

//upper rotate
        upperArmImg.on('mousedown',function(evt) {  


            upperArmImg.rotateDeg(12);          

            p.x=upperArmImg.x();
            p.y=upperArmImg.y();            


            //move the formarm to center of rotation
            foreArmImg.setPosition(p);
            foreArmImg.rotateDeg(12);

            //move it back some ???                 
            foreArmImg.move(100,100);               


            stage.draw();
        });

Solution

  • The key to joint movements is putting all arm parts in a group and then setting proper offset points.

    The importance of an offset point is that they set where any arm part will rotate (==rotation point)

    Here's an outline of how to add kinetic motion to an upper and lower arm:

    • Put the upper and lower arm in a group

    • Set the group, upper & lower offsets (==rotation points) to { x:0, y:armDiameter/2 }

    • To rotate the upper arm, change the groups rotation

    • To rotate the lower arm, change the lower arm rotation

    Group Rotation == 0 degrees, Lower rotation == 0 degrees

    enter image description here

    Group Rotation == 50 degrees, Lower rotation == 0 degrees

    enter image description here

    Group Rotation == 50 degrees, Lower rotation == 65 degrees

    enter image description here

    Here's example code and a Demo:

    var stage = new Kinetic.Stage({
      container: 'container',
      width: 350,
      height: 350
    });
    var layer = new Kinetic.Layer();
    stage.add(layer);
    
    
    
    var lastWidth = 0;
    var baseGroup = new Kinetic.Group({
      x: 50,
      y: 200,
      draggable: true
    });
    layer.add(baseGroup);
    var lastParent = baseGroup;
    
    var appendages = [];
    appendages.push({
      name: 'shoulder',
      width: 50,
      diameter: 20,
      fill: 'brown'
    });
    appendages.push({
      name: 'elbow',
      width: 80,
      diameter: 20,
      fill: 'peru'
    });
    appendages.push({
      name: 'hand',
      width: 30,
      diameter: 20,
      fill: 'tan'
    });
    appendages.push({
      name: 'finger',
      width: 15,
      diameter: 20,
      fill: 'wheat'
    });
    
    for (var i = 0; i < appendages.length; i++) {
    
      lastParent = addAppendage(i);
      appendages[i].group = lastParent;
    
      var appendage = appendages[i];
      var html = "Rotate " + appendage.name + ":";
      html += "<input id=" + appendage.name;
      html += " data-apindex='" + i + "'";
      html += " class='apRange' type=range min=0 max=90 value=0><br>";
      $('body').append(html);
    
    }
    
    
    $('.apRange').change(function() {
      var appendageIndex = parseInt($(this).data('apindex'));
      appendages[appendageIndex].group.rotation(-parseInt($(this).val()));
      layer.draw();
    });
    
    
    
    
    function addAppendage(i) {
    
      var appendage = appendages[i];
      var d2 = appendage.diameter / 2;
    
      // new group for this appendage
      var newGroup = new Kinetic.Group({
        x: lastWidth,
        y: 0,
        rotation: 0,
        offset: {
          x: 0,
          y: 0
        },
      });
      newGroup.appendageIndex = i;
      lastParent.add(newGroup);
    
      // new appendage
      var a = new Kinetic.Rect({
        x: 0,
        y: 0,
        width: appendage.width,
        height: d2 * 2,
        fill: appendage.fill,
        stroke: 'black',
        offset: {
          x: 0,
          y: d2
        },
      });
      newGroup.add(a);
    
      // new joint indicator
      var j = new Kinetic.Circle({
        x: 0,
        y: 0,
        radius: d2 / 2,
        fill: "red",
        offset: {
          x: 0,
          y: 0
        },
      });
      newGroup.add(j);
    
      // display new objects
      layer.draw();
    
      // save width for next loop
      lastWidth = appendage.width;
    
      // return latest group
      return (newGroup);
    }
    body {
      padding: 20px;
    }
    #container {
      border: solid 1px #ccc;
      margin-top: 10px;
      width: 350px;
      height: 350px;
    }
    <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v5.1.0.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <div id="container"></div>