0

I'm trying to rotate an element around another element. I've put this code together, and even though the code works fine, I have a little problem with the element's rotation. It's not very accurate. The blue dot leaves the orbit when at the bottom.

I've played with the code but couldn't fix it. You can check the fiddle example.

rotateObj function taken from Felix Eve's answer.

function markCircleCenter(circ, orig) {
    if (typeof circ == "string") {
        var elm = document.getElementById(circ);
    } else { var circle = circ; }
    if (typeof orig == "string") {
        var mark = document.getElementById(orig);
    } else { var elm = orig; }
    var width       = parseInt(window.getComputedStyle(elm).width, 10);
    var height      = parseInt(window.getComputedStyle(elm).height, 10);
    var top         = parseInt(window.getComputedStyle(elm).top, 10);
    var left        = parseInt(window.getComputedStyle(elm).left, 10);
    var markWidth   = parseInt(window.getComputedStyle(mark).width, 10);
    var markHeight  = parseInt(window.getComputedStyle(mark).height, 10);
    var circle = {
        circle: elm,
        x: width/2 + left,
        y: height/2 + top,
    };
    mark.style.position = "absolute";
    mark.style.top      = circle.y - markWidth/2 + "px";
    mark.style.left     = circle.x - markHeight/2 + "px";
    document.body.insertBefore(mark, elm.nextSibling);
    return circle;
}

function placeObjIntoOrbit(obj) {
    if (typeof obj == "string") {
        var obj = document.getElementById(obj);
    } else { var obj = obj; }
    var objPos = {
        obj: obj,
        x: origin.x,
        y: parseInt(window.getComputedStyle(origin.circle).top, 10) - parseInt(window.getComputedStyle(obj).width, 10) / 2,
    };
    obj.style.position  = "absolute";
    obj.style.top       = objPos.y  + "px";
    obj.style.left      = objPos.x  + "px";
    return objPos;
}

function rotateObj(pointX, pointY, originX, originY, angle) {
    var angle = angle * Math.PI / 180.0;
    return {
        x: Math.cos(angle) * (pointX-originX) - Math.sin(angle) * (pointY-originY) + originX,
        y: Math.sin(angle) * (pointX-originX) + Math.cos(angle) * (pointY-originY) + originY,
    };
}

var angle   = 0;
var origin  = markCircleCenter("circle", "origin");
var point   = placeObjIntoOrbit("point");

function spin() {
    if (angle >= 360) { angle = 0; }
    angle += 2;
    var newCoor = rotateObj(point.x, point.y, origin.x, origin.y, angle);
    point.obj.style.left = newCoor.x + "px";
    point.obj.style.top  = newCoor.y + "px";
}
setInterval("spin('point')", 1000/30);
Community
  • 1
  • 1
akinuri
  • 10,690
  • 10
  • 65
  • 102
  • Hi. Asking people to spot errors in your code is not especially productive. You should use the debugger (or add print statements) to isolate the problem, by tracing the progress of your program, and comparing it to what you expect to happen. As soon as the two diverge, then you've found your problem. (And then if necessary, you should construct a [minimal test-case](http://stackoverflow.com/help/mcve).) – Oliver Charlesworth Apr 13 '14 at 20:51

1 Answers1

1

You are computing the center of the point but positioning it using its top-left point. You need to take the dimension of the point into account when you position it. Try changing the last two lines in function spin() to:

point.obj.style.left = (newCoor.x - 4) + "px";
point.obj.style.top  = (newCoor.y - 4) + "px";

(You should get rid of the "- 4" and substitute half the width and height of the point, but this gets the idea across more tersely.)

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • After seeing your answer I went over my code once again, and it turns out that I was using the same coordinates for both positioning the dot in the circle and rotation origin. Fixed it now. [**Fiddle**](http://jsfiddle.net/akinuri/rxMFU/1/) – akinuri Apr 13 '14 at 23:45