Dav*_*lsh 4 zoom panning html5-canvas
我有一张地图.我希望用户能够缩放和平移地图.想象一下谷歌地图,但不是无限地平移,地图是一个正方形(如果你超越它的边缘,它不会再次环绕).
我使用scale()和实现了缩放和平移translate().这些都很好用.
我被困在最后一部分 - 当用户放大时,我想围绕该点居中放大.很难用文字解释,所以想象一下当你在谷歌地图中鼠标轮时会发生什么 - 这就是我想要的.
我已经在标题中查看了关于SO的每个答案.大多数是这个的变体,基本上说这是我需要做的:
ctx.translate(/* to the point where the mouse is */);
ctx.scale(/* to zoom level I want */)
ctx.translate(/* back to the point where the mouse was, taking zoom into account */);
Run Code Online (Sandbox Code Playgroud)
然而,无论我做什么,我似乎无法让它工作.我可以让它在缩放后缩放到特定点,但无论我做什么,我都无法使该点等于鼠标指针所在的位置.
看看这个小提琴.想象一下,广场是一张地图,圆圈是国家或其他什么.
我找到的最佳实现是这个SO答案和链接的例子.但是,代码使用了SVG和.createSVGMatrix()各种各样的东西,坦率地说,我无法理解.如果可能的话,我更喜欢全画布解决方案.
显然我对使用库这样做不感兴趣.我想明白为什么我所做的不起作用.
这是一种缩放点的技巧:
绘制地图
通过不使用变换来绘制地图来简化事物(不需要翻译,缩放!).
所需要的只是缩放版本context.drawImage.
您所做的是将原始地图缩放到所需大小,然后从用户选择的缩放点向上和向左拉动它.
context.drawImage(
map,
0,0,map.width,map.height, // start with the map at original (unscaled) size
offsetX,offsetY, // pull the map leftward & upward from the scaling point
scaledWidth,scaledHeight // resize the map to the currently scaled size
Run Code Online (Sandbox Code Playgroud)
选择缩放点(焦点):
缩放焦点实际上是2分!
第一个焦点是mouseX,mouseY,用户在其中单击以设置所需的缩放点.重要的是要记住鼠标坐标位于缩放空间中.用户正在查看/单击的地图被缩放,因此他们的mouseX,mouseY也被缩放.
通过不缩放鼠标坐标来计算第二个焦点.第二个点是原始未缩放地图上的等效鼠标位置.
第二个未缩放的焦点用于计算从第一个焦点向左和向上拉刻度图的程度.
function setFocus(mx,my){
// mouseX,mouseY is the scaling point in scaled coordinates
focusX=mx;
focusY=my;
// convert the scaled focal point
// to an unscaled focal point
focusX1=parseInt((mx-mapLeft)/scale);
focusY1=parseInt((my-mapTop)/scale);
}
Run Code Online (Sandbox Code Playgroud)
缩放地图
当用户表明他们想要将地图缩放或更大时:
码:
function setScale(newScale){
scale=newScale;
// calc the width & height of the newly scaled map
mapWidth=parseInt(iw*scale);
mapHeight=parseInt(ih*scale);
// calc how much to offset the map on the canvas
mapLeft=parseInt(focusX-focusX1*scale);
mapTop =parseInt(focusY-focusY1*scale);
// draw the map
drawMap();
}
Run Code Online (Sandbox Code Playgroud)
这是示例代码和演示:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var $canvas=$("#canvas");
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
//
var counter=1;
var PI2=Math.PI*2;
var iw,ih;
var mapLeft,mapTop,mapWidth,mapHeight;
var focusX,focusY,focusX1,focusY1;
var scale;
var map=new Image();
map.onload=start;
map.src="https://dl.dropboxusercontent.com/u/139992952/multple/mapSmall.png";
function start(){
iw=map.width;
ih=map.height;
// initial
mapLeft=0;
mapTop=0;
scale=1.00;
setFocus(iw/2*scale,ih/2*scale);
setScale(scale); // also sets mapWidth,mapHeight
drawMap();
//
$("#canvas").mousedown(function(e){handleMouseDown(e);});
//
canvas.addEventListener('DOMMouseScroll',handleScroll,false);
canvas.addEventListener('mousewheel',handleScroll,false);
}
//
function setScale(newScale){
scale=newScale;
mapWidth=parseInt(iw*scale);
mapHeight=parseInt(ih*scale);
mapLeft=parseInt(focusX-focusX1*scale);
mapTop =parseInt(focusY-focusY1*scale);
drawMap();
}
//
function setFocus(mx,my){
// mouseX,mouseY is the scaling point in scaled coordinates
focusX=mx;
focusY=my;
// convert the scaled focal point
// to an unscaled focal point
focusX1=parseInt((mx-mapLeft)/scale);
focusY1=parseInt((my-mapTop)/scale);
//
drawMap();
}
//
function drawMap(){
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.save();
ctx.drawImage(map,0,0,iw,ih,mapLeft,mapTop,mapWidth,mapHeight);
dot(ctx,focusX,focusY,"red");
ctx.restore();
}
function dot(ctx,x,y,fill){
ctx.beginPath();
ctx.arc(x,y,4,0,PI2);
ctx.closePath();
ctx.fillStyle=fill;
ctx.fill();
ctx.lineWidth=2;
ctx.stroke();
}
//
function handleScroll(e){
e.preventDefault();
e.stopPropagation();
var delta=e.wheelDelta?e.wheelDelta/30:e.detail?-e.detail:0;
if (delta){
counter+=delta;
setScale(1+counter/100);
}
};
//
function handleMouseDown(e){
e.preventDefault();
e.stopPropagation();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
setFocus(mouseX,mouseY);
drawMap();
}Run Code Online (Sandbox Code Playgroud)
body{ background-color: ivory; }
canvas{border:1px solid red;}Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Click to set zoom point<br>Use mousewheel to zoom</h4>
<canvas id="canvas" width=600 height=400></canvas><br>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2982 次 |
| 最近记录: |