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\$
3
  • \$\begingroup\$ here's a hint, first translate the dot to the center, then zoom, then translate back (it works for rotations as well) \$\endgroup\$ Oct 31, 2014 at 0:45
  • \$\begingroup\$ @ratchetfreak what do you mean by translate? \$\endgroup\$
    – Dave
    Oct 31, 2014 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, 2014 at 19:53

2 Answers 2

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).

\$\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;
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .