在测试应用程序中,我有一个带有简单矩形的画布。方法 draw 每100ms调用一次。
从代码中我可以看到我正在使用鼠标滚轮来缩放所有内容。现在发生的是,一切都被缩放,但是当矩形是10px,10px并且我的鼠标正好在它上面时,矩形在缩放后不再在鼠标下面。 (这当然是正确的,因为所有单位都按比例扩大。
但我想要的是,鼠标位置是谷歌地图中的“缩放动作的中心”,因此缩放前鼠标下的内容也在鼠标之下。我做了一些翻译尝试,但我想不通,怎么做。
提前致谢。
这是我的代码:
<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>
答案 0 :(得分:12)
这实际上是一个非平凡的数学问题,通常被称为“缩放点”
看看here,其他画布用户想要做同样的事情并找到方法。
<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>