2011-07-21 15 views
14

En una aplicación de prueba, tengo un lienzo con un rectángulo simple. El método dibuja se llama cada 100 ms.Zoom con lienzo

Como puede ver en el código, estoy usando la rueda del mouse para escalar todo. Lo que sucede ahora es que todo está escalado, pero es decir, cuando el rectángulo está a 10px, 10px y tengo el mouse sobre él, el rectángulo ya no está debajo del mouse después de escalar. (Lo cual es lógico porque todas las unidades se amplían hasta

Pero lo que quiero es que la posición de la mouse sea el "centro de la acción de acercamiento" como en google maps para que el contenido esté debajo del mouse antes ... escalamiento, está bajo el ratón después también hice algunos intentos con la traducción, pero no puedo averiguar, cómo hacer que

Gracias de antemano

Aquí está mi código:

<script type="text/javascript"> 
     var scroll = 0; 
     var scale = 1.0; 


        /** This is high-level function. 
     * It must react to delta being more/less than zero. 
     */ 
     function handle(delta) { 

       var canvas = document.getElementById("myCanvas"); 
       var ctx = canvas.getContext("2d"); 

       scroll = delta; 
       if(scroll > 0) 
       { 
        scale += 0.2; 
       } 
       if(scroll < 0) 
       { 
        scale -= 0.2; 
       } 


     } 

     /** Event handler for mouse wheel event. 
     */ 
     function wheel(event){ 
       var delta = 0; 
       if (!event) /* For IE. */ 
         event = window.event; 
       if (event.wheelDelta) { /* IE/Opera. */ 
         delta = event.wheelDelta/120; 
       } else if (event.detail) { /** Mozilla case. */ 
         /** In Mozilla, sign of delta is different than in IE. 
         * Also, delta is multiple of 3. 
         */ 
         delta = -event.detail/3; 
       } 
       /** If delta is nonzero, handle it. 
       * Basically, delta is now positive if wheel was scrolled up, 
       * and negative, if wheel was scrolled down. 
       */ 
       if (delta) 
         handle(delta); 
       /** Prevent default actions caused by mouse wheel. 
       * That might be ugly, but we handle scrolls somehow 
       * anyway, so don't bother here.. 
       */ 
       if (event.preventDefault) 
         event.preventDefault(); 
      event.returnValue = false; 
     } 

     /** Initialization code. 
     * If you use your own event management code, change it as required. 
     */ 
     if (window.addEventListener) 
       /** DOMMouseScroll is for mozilla. */ 
       window.addEventListener('DOMMouseScroll', wheel, false); 
     /** IE/Opera. */ 
     window.onmousewheel = document.onmousewheel = wheel; 

     var drawX = 0; 
     var drawY = 0; 
     var overX = 0; 
     var overY = 0; 

     function startCanvas() 
     { 
      var myCanvas = document.getElementById("myCanvas"); 
      var ctx = myCanvas.getContext("2d"); 
      ctx.canvas.width = window.innerWidth; 
      ctx.canvas.height = window.innerHeight;     
      setInterval(draw,100); 
     } 

     function draw() 
     { 
      var canvas = document.getElementById("myCanvas"); 
      var ctx = canvas.getContext("2d"); 

      ctx.clearRect(0,0,window.innerWidth,window.innerHeight); 
      ctx.save(); 
      ctx.scale(scale,scale); 
      ctx.fillRect(drawX,drawY,20,20); 
      //ctx.translate(-scale,-scale); 
      ctx.restore(); 
      ctx.font="20pt Arial"; 
      ctx.fillText(scale+":"+drawX,0,150);     
     } 

     function canvasClick(event) 
     { 
      console.log(event.layerX+"/"+scale); 
      drawX = event.layerX/scale; 
      drawY = event.layerY/scale; 
     } 

     function canvasOver(event) 
     { 
      console.log("over"); 
      overX = event.layerX; 
      overY = event.layerY; 
     } 

    </script> 

Respuesta

11

En realidad, es una pregunta matemática no trivial, nosotros ually conocido como un "punto de acercamiento"

Eche un vistazo a here donde otro usuario de lienzo quería hacer lo mismo y encontró una manera.

<canvas id="canvas" width="800" height="600"></canvas> 
<script type="text/javascript"> 
var canvas = document.getElementById("canvas"); 
var context = canvas.getContext("2d"); 
var scale = 1; 
var originx = 0; 
var originy = 0; 

function draw(){ 
    context.fillStyle = "white"; 
    context.fillRect(originx,originy,800/scale,600/scale); 
    context.fillStyle = "black"; 
    context.fillRect(50,50,100,100); 
} 
setInterval(draw,100); 

canvas.onmousewheel = function (event){ 
    var mousex = event.clientX - canvas.offsetLeft; 
    var mousey = event.clientY - canvas.offsetTop; 
    var wheel = event.wheelDelta/120;//n or -n 

    var zoom = 1 + wheel/2; 

    context.translate(
     originx, 
     originy 
    ); 
    context.scale(zoom,zoom); 
    context.translate(
     -(mousex/scale + originx - mousex/(scale * zoom)), 
     -(mousey/scale + originy - mousey/(scale * zoom)) 
    ); 

    originx = (mousex/scale + originx - mousex/(scale * zoom)); 
    originy = (mousey/scale + originy - mousey/(scale * zoom)); 
    scale *= zoom; 
} 

</script> 
+0

gracias ... lo echaré un vistazo más de cerca. Me alegra oír que es algo matemático no trivial. Estaba dibujando en papel y no podía encontrar la forma de calcularlo :-D – Chris

+0

¡Impresionante! Gracias que funcionó muy bien! – Chris