3
\$\begingroup\$

I just started coding a simulation-like application. It's about our solar system. Right now, I'm working on rotating the moon. I have this constructor

function Mass(elm) {
    if (typeof elm == "string") {
        this.elm = document.getElementById(elm);
    } else {
        this.elm = elm;
    }
    this.width      = parseInt(window.getComputedStyle(this.elm).width, 10);
    this.height     = parseInt(window.getComputedStyle(this.elm).height, 10);
    this.top        = parseInt(window.getComputedStyle(this.elm).top, 10);
    this.left       = parseInt(window.getComputedStyle(this.elm).left, 10);
    this.radius     = this.width / 2;
    this.origin     = {
        x : this.left + this.width / 2,
        y : this.top + this.height / 2,
    };
    this.angle = 0;
    this.rotation   = function () {
        if (this.angle >= 360) { this.angle = 0; }
        this.angle += 1;
        this.elm.style.webkitTransform = "rotate(" + this.angle + "deg)";
    };
    this.rotate = function (mthd) {
        setInterval(mthd, 100);
    }
}
var moon = new Mass("moon");
moon.rotate("moon.rotation()");

The issue I'm having is this moon.rotate("moon.rotation()");. There are two methods, and the way I call them is um.. weird? I want to use a single method to rotate the object. Like moon.rotate().

I tried a few ways to put the code in just one method, but couldn't figure it out.

Fiddle


Even though I'm done with the problem mentioned in this question, I wanted to add something, the full code. In case if anyone is interested.

Fiddle

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

For one, you don't want to pass a string to setInterval(); better to use a function. You can bind that function to the object's context, so it'll call the right thing.

For another, aim for less ambiguous names. rotation should probably be updateRotation, since that's what it does. And rotate should likely be startRotating (and they you could have an equivalent stopRotating).

That be something like:

this.startRotating = function () {
  var self = this; // to maintain the object's context
  setInterval(function () {
    self.updateRotation();
  }, 100);
};

However, if you're planning to add more planets etc., it would probably be nicer to have one central timer that calls an update function on all your objects.

And I'd also define a "proper" prototype for all this, and extract some general logic/avoid repetition:

// extract this logic, since it's generally useful
function getElement(element) {
  if (typeof element == "string") {
    return document.getElementById(element);
  }
  return element;
}

function Mass(element, angularVelocity) { // added the rotation speed as an arg
  var computedStyle;

  this.element = getElement(element);

  // fetch this once
  computedStyle = window.getComputedStyle(this.element);

  this.width  = parseInt(computedStyle.width, 10);
  this.height = parseInt(computedStyle.height, 10);
  this.top    = parseInt(computedStyle.top, 10);
  this.left   = parseInt(computedStyle.left, 10);
  this.radius = this.width / 2;

  this.origin = {
    x: this.left + this.radius, // you just calculated the radius; might as well use it here
    y: this.top + this.radius
  };

  this.angularVelocity = angularVelocity;
  this.rotation = 0;
}

// make nice prototype
Mass.prototype = {
  update: function () {
    this.rotation = (this.rotation + this.angularVelocity) % 360;
    this.element.style.webkitTransform = "rotate(" + this.rotation + "deg)";
  }
};

// do the timer magic outside the object
var moon = new Mass("moon", 1.0),
    timer;

timer = setInterval(function () {
  moon.update();
}, 100);

fiddle

\$\endgroup\$
3
  • \$\begingroup\$ Thanks for the reply. I went over my code after seeing your examples. Fixed the problem now. Fiddle \$\endgroup\$
    – akinuri
    Apr 14, 2014 at 18:17
  • \$\begingroup\$ @akinuri You could just set a negative rotation speed, instead of having the ccw argument. The modulus trick (angle = (angle + speed) % 360) in the code above will work for negative values, so you can get rid of a lot of code \$\endgroup\$
    – Flambino
    Apr 14, 2014 at 19:51
  • \$\begingroup\$ Oh, indeed. Changed the code. Just few methods away from perfect. Gonna create a method to place the moon into earth's orbit. Fiddle \$\endgroup\$
    – akinuri
    Apr 14, 2014 at 20:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.