title: Kineticjs - free rotate on image
body: <p>I need help only having the anchors for rotating.  Right now there is five anchors and I don't know how to get rid of all of them except the rotate one.  I would also only like the anchors to show when the user hovers over the image</p>
  
  <p>Here is my code</p>
  
  <pre><code>&lt;html&gt;
  &lt;head&gt;
  &lt;style&gt;
  body {
  margin: 0px;
  padding: 0px;
  }
  &lt;/style&gt;
  &lt;/head&gt;
  &lt;body&gt;
  &lt;body onmousedown="return false;"&gt;
  &lt;div id="container"&gt;&lt;/div&gt;
  &lt;script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.7.4.min.js"&gt;     
  &lt;/script&gt;
  &lt;script&gt;
  
  function update(activeAnchor) {
  var group = activeAnchor.getParent();
  
  var topLeft = group.get('.topLeft')[0];
  var topRight = group.get('.topRight')[0];
  var bottomRight = group.get('.bottomRight')[0];
  var bottomLeft = group.get('.bottomLeft')[0];
  
  var rotateAnchor = group.get('.rotateAnchor')[0];
  var image = group.get('Image')[0];
  
  var anchorX = activeAnchor.getX();
  var anchorY = activeAnchor.getY();
  var imageWidth = image.getWidth();
  var imageHeight = image.getHeight();
  
  var offsetX = Math.abs((topLeft.getX() + bottomRight.getX() + 10) / 2);
  var offsetY = Math.abs((topLeft.getY() + bottomRight.getY() + 10) / 2);
  
  // update anchor positions
  switch (activeAnchor.getName()) {
      case 'rotateAnchor':
          group.setOffset(offsetX, offsetY);
          break;
      case 'topLeft':
          topRight.setY(anchorY);
          bottomLeft.setX(anchorX);
          break;
      case 'topRight':
          topLeft.setY(anchorY);
          bottomRight.setX(anchorX);
          break;
      case 'bottomRight':
          topRight.setX(anchorX);
          bottomLeft.setY(anchorY);
          break;
      case 'bottomLeft':
          topLeft.setX(anchorX);
          bottomRight.setY(anchorY);
          break;
  }
  rotateAnchor.setX(topRight.getX() + 5);
  rotateAnchor.setY(topRight.getY() + 20);
  
  image.setPosition((topLeft.getPosition().x + 20), (topLeft.getPosition().y + 20));
  var width = topRight.getX() - topLeft.getX() - 30;
  var height = bottomLeft.getY() - topLeft.getY() - 30;
  if (width &amp;&amp; height) {
      image.setSize(width, height);
  }
  }
  function addAnchor(group, x, y, name, dragBound) {
  var stage = group.getStage();
  var layer = group.getLayer();
  
  var anchor = new Kinetic.Circle({
                                  x: x,
                                  y: y,
                                  stroke: '#666',
                                  fill: '#ddd',
                                  strokeWidth: 2,
                                  radius: 8,
                                  name: name,
                                  draggable: true,
                                  dragOnTop: false
                                  });
  
  if (dragBound == 'rotate') {
      anchor.setAttrs({
                      dragBoundFunc: function (pos) {
                      return getRotatingAnchorBounds(pos, group);
                      }
                      });
  }
  
  anchor.on('dragmove', function() {
            update(this);
            layer.draw();
            });
  anchor.on('mousedown touchstart', function() {
            group.setDraggable(false);
            this.moveToTop();
            });
  anchor.on('dragend', function() {
            group.setDraggable(true);
            layer.draw();
            });
  // add hover styling
  anchor.on('mouseover', function() {
            var layer = this.getLayer();
            document.body.style.cursor = 'pointer';
            this.setStrokeWidth(4);
            layer.draw();
            });
  anchor.on('mouseout', function() {
            var layer = this.getLayer();
            document.body.style.cursor = 'default';
            this.setStrokeWidth(2);
            layer.draw();
            });
  
  group.add(anchor);
  }
  function loadImages(sources, callback) {
  var images = {};
  var loadedImages = 0;
  var numImages = 0;
  for(var src in sources) {
      numImages++;
  }
  for(var src in sources) {
      images[src] = new Image();
      images[src].onload = function() {
          if(++loadedImages &gt;= numImages) {
              callback(images);
          }
      };
      images[src].src = sources[src];
  }
  }
  function getRotatingAnchorBounds(pos, group) {
  var topLeft = group.get('.topLeft')[0];
  var bottomRight = group.get('.bottomRight')[0];
  var topRight = group.get('.topRight')[0];
  
  var absCenterX = Math.abs((topLeft.getAbsolutePosition().x + 5 +     bottomRight.getAbsolutePosition().x + 5) / 2);
  var absCenterY = Math.abs((topLeft.getAbsolutePosition().y + 5 + bottomRight.getAbsolutePosition().y + 5) / 2);
  
  var relCenterX = Math.abs((topLeft.getX() + bottomRight.getX()) / 2);
  var relCenterY = Math.abs((topLeft.getY() + bottomRight.getY()) / 2);
  
  var radius = distance(relCenterX, relCenterY, topRight.getX() + 5, topRight.getY() + 20);
  
  var scale = radius / distance(pos.x, pos.y, absCenterX, absCenterY);
  
  var realRotation = Math.round(degrees(angle(relCenterX, relCenterY, topRight.getX() + 5, topRight.getY() + 20)));
  var rotation = Math.round(degrees(angle(absCenterX, absCenterY, pos.x, pos.y)));
  rotation -= realRotation;
  
  group.setRotationDeg(rotation);
  
  return {
  y: Math.round((pos.y - absCenterY) * scale + absCenterY),
  x: Math.round((pos.x - absCenterX) * scale + absCenterX)
  };
  }
  function radians(degrees) { return degrees * (Math.PI / 180); }
  function degrees(radians) { return radians * (180 / Math.PI); }
  
  // Calculate the angle between two points.
  function angle(cx, cy, px, py) {
  var x = cx - px;
  var y = cy - py;
  return Math.atan2(-y, -x);
  }
  
  // Calculate the distance between two points.
  function distance(p1x, p1y, p2x, p2y) {
  return Math.sqrt(Math.pow((p2x - p1x), 2) + Math.pow((p2y - p1y), 2));
  }
  
  function initStage(images) {
  var stage = new Kinetic.Stage({
                                container: 'container',
                                width: 578,
                                height: 400
                                });
  var darthVaderGroup = new Kinetic.Group({
                                          x: 270,
                                          y: 100,
                                          draggable: true
                                          });
  var yodaGroup = new Kinetic.Group({
                                    x: 100,
                                    y: 110,
                                    draggable: true
                                    });
  var layer = new Kinetic.Layer();
  
  /*
   * go ahead and add the groups
   * to the layer and the layer to the
   * stage so that the groups have knowledge
   * of its layer and stage
   */
  layer.add(darthVaderGroup);
  layer.add(yodaGroup);
  stage.add(layer);
  
  // darth vader
  var darthVaderImg = new Kinetic.Image({
                                        x: 0,
                                        y: 0,
                                        image: images.darthVader,
                                        width: 200,
                                        height: 138,
                                        name: 'image'
                                        });
  
  darthVaderGroup.add(darthVaderImg);
  addAnchor(darthVaderGroup, -20, -20, 'topLeft', 'none');
  addAnchor(darthVaderGroup, 220, -20, 'topRight', 'none');
  addAnchor(darthVaderGroup, 220, 158, 'bottomRight', 'none');
  addAnchor(darthVaderGroup, -20, 158, 'bottomLeft','none');
  addAnchor(darthVaderGroup, 225, 0, 'rotateAnchor','rotate');
  
  darthVaderGroup.on('dragstart', function() {
                     this.moveToTop();
                     });
  stage.draw();
  }
  
  var sources = {
  darthVader: 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg'
  };
  loadImages(sources, initStage);
  
  &lt;/script&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>