在测试应用程序中,我有一个带有一个简单矩形的画布.方法绘制每100ms调用一次.
正如你可以从代码中看到的,我使用鼠标滚轮来缩放所有内容.现在发生的是,一切都是缩放的,但是当矩形为10像素,10像素时,我将鼠标放在它上面,缩放后矩形不再位于鼠标下方. (这当然是正确的,因为所有单位都放大了.
但是我想要的是,mouseposition是像谷歌地图中的“缩放动作的中心”,所以在缩放之前,鼠标下的内容也是在鼠标之前.我做了几个翻译,但我不知道如何做到这一点.
提前致谢.
这是我的代码:
<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,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,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>
解决方法
这实际上是一个不平凡的数学问题,通常被称为“缩放点”
<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>