Html 用画布缩放
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6775168/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Zooming with canvas
提问by Chris
In a test application i have a canvas with a simple rectangle on it. The method drawis called every 100ms.
在测试应用程序中,我有一个画布,上面有一个简单的矩形。draw方法每 100 毫秒调用一次。
as you can see from the code i'm using the Mousewheel to scale everything. What happens now is, that everything is scaled, but i.e. when the rectangle is at 10px,10px and i have the mouse right over it the rectangle is not under the mouse anymore after scaling. (Which is of course right because all units are scaled up to.
正如您从代码中看到的,我正在使用鼠标滚轮来缩放所有内容。现在发生的事情是,一切都被缩放了,但是当矩形在 10px,10px 并且我把鼠标放在它上面时,矩形在缩放后不再在鼠标下面。(这当然是正确的,因为所有单位都按比例放大。
But what i want to is, that the mouseposition is the "center of the zooming action" like in google maps so the content which is under the mouse before scaling, is under the mouse afterwards as well. I made a few attemps with translating, but i can't figure out, how to do that.
但我想要的是,鼠标位置是“缩放动作的中心”,就像在谷歌地图中一样,所以缩放前鼠标下方的内容,之后也位于鼠标下方。我做了一些翻译尝试,但我不知道如何做到这一点。
Thanks in advance.
提前致谢。
Here's my code:
这是我的代码:
<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>
采纳答案by Simon Sarris
It's actually a non-trivial math question, usually known as a "zoom point"
它实际上是一个不平凡的数学问题,通常被称为“缩放点”
Take a look at herewhere another canvas user wanted to do the same thing and found a way.
看看这里另一个画布用户想要做同样的事情并找到了一种方法。
<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>