2
\$\begingroup\$

I have a simple zoom feature which lets the user zoom in and out. I'm having an issue how ever when i zoom out the object gets smaller to the point that the boundaries become broken.

The idea is the red dot stays inside the circle but the red dot never moves, its stationary in position and size.

This for example is correct because the red dot is inside the circle: enter image description here

Now if i zoom out and make the circle smaller the red dot ends up outside the circle like so:

enter image description here

The problem i have, is i don't know how to offset the circle to keep the red dot inside of the circle regardless of zooming scale. I have a working example here: http://jsfiddle.net/3wr885so/ if you zoom out you'll find the circle doesn't fix its offset to keep everything in the right place.

The two relevant functions I used for zooming and drawing are below:

Zoom function

function zoomObj(e){
var delta       = e.wheelDelta,
    mousePos    = {};
    mousePos.x  = e.pagex;
    mousePos.y  = e.pageY;
var range = zoom.percentVal * zoom.modifier;
if(delta == 120){         //scroll in
    var endVal = zoom.position + range;
} else {                  //scroll out
    var endVal = zoom.position - range;
}  

zoom.position = endVal;
zoom.percent = (zoom.position/zoom.range) * 100;    

//need to set offsets to correct for new zoom here
}

Game Loop

function start(){
    var radius = obj.radius/100*zoom.percent;
    if(radius < 0){ radius = 0; }
    ctx.clearRect(0,0,canvas.width,canvas.height);
    ctx.beginPath();
    ctx.arc(camera.offsetX, camera.offsetY, radius ,0,2*Math.PI, false);
    ctx.restore();
    ctx.lineWidth = 1;
    ctx.strokeStyle = 'black';
    ctx.stroke();


    ctx.setTransform(1, 0, 0, 1, 0, 0);
    ctx.beginPath();
    ctx.fillStyle = 'red';
    ctx.fillRect(canvas.width/2-5,canvas.height/2-5,10,10); 
    ctx.stroke();

}

Any suggestions how i fix this problem :) ?

\$\endgroup\$
  • \$\begingroup\$ here's a hint, first translate the dot to the center, then zoom, then translate back (it works for rotations as well) \$\endgroup\$ – ratchet freak Oct 31 '14 at 0:45
  • \$\begingroup\$ @ratchetfreak what do you mean by translate? \$\endgroup\$ – Dave Oct 31 '14 at 3:56
  • \$\begingroup\$ I am not sure I understand the problem, can't you simply check the angle between the center of the circle and the red dot and the distance between them in % of the circle's radius and then simply draw a bigger or smaller circle as needed with the red dot in the same place? \$\endgroup\$ – AturSams Oct 31 '14 at 19:53
1
\$\begingroup\$

while zooming out, check if distance of red-dot and center of circle is more than circle's radius. (Lets call this distance, d)

if so happened, move the circle in direction of V vector ( V = red-dot.position - circle.position`) for x unit. (x= d-circle's radius).

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

I didn't read your code but I think what you're looking for is something like this:

var currentZoom, //The zoom %
circleCenterX, circleCenterY, // The circles center for viewing
dotX, dotY // The dots center for vieweing

function zoomInOrOut(delta) // To zoom out use a negative value
{
  if (delta < 0 && currentZoom <= 1.0) return;
  // Constraint - offsetX^2 + offsetY^2 has to be <= circleRadius^2
  var oldZoom = currentZoom,
  offsetX = circleCenterX - dotX,
  offsetY = circleCenterY - dotY;
  currentZoom += delta;
  ratio = currentZoom / oldZoom;

  circleCenterX = dotX + offsetX * ratio;
  circleCenterY = dotY + offsetY * ratio;
}
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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