title: How do I effectively calculate zoom scale?
body: <p>I have a draggeable image contained within a box. You can zoom in and zoom out on the image in the box which will make the image larger or smaller but the box size remains the same. The box's height and width will vary as the browser is resized. The top and left values for the image will change as it is dragged around.</p>
  
  <p>I'm trying to keep whatever the point the box was centered on in the image, in the center. Kind of like how zoom on Google Maps works or the zoom on Mac OS X zooms.</p>
  
  <p>What I'm doing right now is calculating the center of the box (x = w/2, y = h/2) and then using the top and left values for the image to calculate the position of the image in the center of the box. (x -= left, y -= top).</p>
  
  <p>Then I zoom the image by growing or shrinking it and I use the scale change to adjust the coordinates (x = (x * (old_width/new_width), y = (y * (old_height/new_height)).</p>
  
  <p>I then reposition the image so that its center is what it was before zoom by grabbing the coordinates it is currently centered on (that changed with the resize) and adding the difference between the old center values and the new values to the top and left values (new_left = post_zoom_left + (old_center_x - new_center_x), new_top = post_zoom_top + (old_center_y - new_center_y).</p>
  
  <p>This works ok for zoom in, but zoom out seems to be somewhat off.</p>
  
  <p>Any suggestions?</p>
  
  <p>My code is below:</p>
  
  <pre><code>app.Puzzle_Viewer.prototype.set_view_dimensions = function () {
  
    var width, height, new_width, new_height, coordinates, x_scale,
      y_scale;
  
    coordinates = this.get_center_position();
    width = +this.container.width();
    height = +this.container.height();
    //code to figure out new width and height
    //snip ...
    x_scale = width/new_width;
    y_scale = height/new_height;
    coordinates.x = Math.round(coordinates.x * x_scale);
    coordinates.y = Math.round(coordinates.y * y_scale);
    //resize image to new_width &amp; new_height
    this.center_on_position(coordinates);
  };
  
  app.Puzzle_Viewer.prototype.get_center_position = function () {
  
    var top, left, bottom, right, x, y, container;
  
    right = +this.node.width();
    bottom = +this.node.height();
    x = Math.round(right/2);
    y = Math.round(bottom/2);
    container = this.container.get(0);
    left = container.style.left;
    top = container.style.top;
    left = left ? parseInt(left, 10) : 0;
    top  = top ? parseInt(top, 10) : 0;
    x -= left;
    y -= top;
    return {x: x, y: y, left: left, top: top};
  };
  
  app.Puzzle_Viewer.prototype.center_on_position = function (coordinates) {
  
    var current_center, x, y, container;
  
    current_center = this.get_center_position();
    x = current_center.left + coordinates.x - current_center.x;
    y = current_center.top + coordinates.y - current_center.y;
    container = this.container.get(0);
    container.style.left = x + "px";
    container.style.top = y + "px";
  };
  </code></pre>