2011-07-21 13 views
14

W aplikacji testowej mam płótno z prostym prostokątem. Metoda narysowana jest wywoływana co 100ms.Powiększanie płótnem

jak widać z kodu używam kółka myszy, aby skalować wszystko. Teraz dzieje się tak, że wszystko jest skalowane, ale to znaczy, kiedy prostokąt ma 10 pikseli, 10 pikseli i mysz po prawej stronie, prostokąt nie znajduje się już pod myszą po skalowaniu. (Co jest oczywiście słuszne, ponieważ wszystkie jednostki są skalowane do.

Ale to, co chcę, to, że położenie myszy jest "środkiem powiększania" jak na mapach google, więc zawartość, która jest pod myszą przed ... skalowanie, jest pod mysz potem jak dobrze zrobiłem kilka próbami z tłumaczenia, ale nie mogę dowiedzieć się, jak to zrobić

góry dziękuję

Oto mój kod:

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

Odpowiedz

11

To właściwie nietrywialne pytanie matematyczne, nas znany jako "punkt przybliżenia"

Zobacz, gdzie inny użytkownik płótna chciał zrobić to samo i znalazł sposób.

<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

dziękuję ... przyjrzę mu się bliżej. Cieszę się, że to nie nietrywialna rzecz matematyczna, którą rysowałem na papierze i nie mogłem po prostu dowiedzieć się, jak to obliczyć :-D – Chris

+0

Awesome! Dzięki, że działa bardzo dobrze! – Chris

Powiązane problemy