Zooming with canvas(用画布缩放)
问题描述
在一个测试应用程序中,我有一个带有简单矩形的画布.draw 方法每 100 毫秒调用一次.
In a test application i have a canvas with a simple rectangle on it. The method draw is called every 100ms.
从代码中可以看出,我使用鼠标滚轮来缩放所有内容.现在发生的事情是,一切都被缩放了,但即当矩形位于 10px,10px 并且我将鼠标放在它上面时,矩形在缩放后不再位于鼠标下方.(这当然是正确的,因为所有单位都按比例放大.
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.
但我想要的是,鼠标位置是缩放动作的中心",就像在谷歌地图中一样,所以缩放前位于鼠标下的内容,之后也位于鼠标下.我尝试了一些翻译,但我不知道该怎么做.
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.
提前致谢.
这是我的代码:
<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>
推荐答案
其实是一道不平凡的数学题,通常被称为缩放点"
It's actually a non-trivial math question, usually known as a "zoom point"
看看这里画布用户想做同样的事情并找到了方法.
Take a look at here where 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>
这篇关于用画布缩放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:用画布缩放
基础教程推荐
- 直接将值设置为滑块 2022-01-01
- 如何使用JIT在顺风css中使用布局变体? 2022-01-01
- 如何使用TypeScrip将固定承诺数组中的项设置为可选 2022-01-01
- 我可以在浏览器中与Babel一起使用ES模块,而不捆绑我的代码吗? 2022-01-01
- Vue 3 – <过渡>渲染不能动画的非元素根节点 2022-01-01
- Electron 将 Node.js 和 Chromium 上下文结合起来意味着 2022-01-01
- html表格如何通过更改悬停边框来突出显示列? 2022-01-01
- 自定义 XMLHttpRequest.prototype.open 2022-01-01
- 用于 Twitter 小部件宽度的 HTML/CSS 2022-01-01
- Chart.js 在线性图表上拖动点 2022-01-01