【整理】用html和javascript实现类似百度地图的画布
来源:互联网 发布:武汉理工大学网络平台 编辑:程序博客网 时间:2024/05/22 15:03
原文是stackoverflow上面的一个问题,链接地址是
http://stackoverflow.com/questions/5189968/zoom-canvas-to-mouse-cursor/5526721
分为三个步骤:
In short, you want to translate()
the canvas context by your offset, scale()
it to zoom in or out, and then translate()
back by the opposite of the mouse offset. Note that you need to transform the cursor position from screen space into the transformed canvas context.
ctx.translate(pt.x,pt.y);ctx.scale(factor,factor);ctx.translate(-pt.x,-pt.y);
translate函数先根据鼠标对画布的偏移量来调整新的画布,然后通过scale函数来完成大小调整,之后通过函数translate函数将其调整回来,最终完成一个鼠标滚轮缩放效果。顺便贴出了一个网页即完成这个功能的demo,地址是
http://phrogz.net/tmp/canvas_zoom_to_cursor.html
最后是这个网页的源代码
<!DOCTYPE HTML><html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>Zooming via HTML5 Canvas Context</title><style type="text/css" media="screen">body { background:#eee; margin:1em; text-align:center; }canvas { display:block; margin:1em auto; background:#fff; border:1px solid #ccc }</style></head><body><p>Showing how to use transform methods on the HTML5 Canvas Context to selectively zoom in and out. Drag to pan. Click to zoom at that location. Shift-click to zoom out. Mousewheel up/down over the canvas to zoom in to/out from that location.</p><p>By redrawing the canvas at different scales the strokes remain smooth during zooming. For example, zoom in on the earring or circle on the forehead to see fine detail.</p><canvas></canvas><p id="footer">Copyright © 2011 <a href="mailto:!@phrogz.net">Gavin Kistner</a>. Written to support <a href="http://stackoverflow.com/questions/5189968/zoom-to-cursor-calculations/5526721#5526721">this Stack Overflow answer</a>.</p><script type="text/javascript" charset="utf-8">var canvas = document.getElementsByTagName('canvas')[0];canvas.width = 800; canvas.height = 600;var gkhead = new Image;var ball = new Image;window.onload = function(){var ctx = canvas.getContext('2d');trackTransforms(ctx);function redraw(){// Clear the entire canvasvar p1 = ctx.transformedPoint(0,0);var p2 = ctx.transformedPoint(canvas.width,canvas.height);ctx.clearRect(p1.x,p1.y,p2.x-p1.x,p2.y-p1.y);// Alternatively:// ctx.save();// ctx.setTransform(1,0,0,1,0,0);// ctx.clearRect(0,0,canvas.width,canvas.height);// ctx.restore();ctx.drawImage(gkhead,200,50);ctx.beginPath();ctx.lineWidth = 6;ctx.moveTo(399,250);ctx.lineTo(474,256);ctx.stroke();ctx.save();ctx.translate(4,2);ctx.beginPath();ctx.lineWidth = 1;ctx.moveTo(436,253);ctx.lineTo(437.5,233);ctx.stroke();ctx.save();ctx.translate(438.5,223);ctx.strokeStyle = '#06c';ctx.beginPath();ctx.lineWidth = 0.05;for (var i=0;i<60;++i){ctx.rotate(6*i*Math.PI/180);ctx.moveTo(9,0);ctx.lineTo(10,0);ctx.rotate(-6*i*Math.PI/180);}ctx.stroke();ctx.restore();ctx.beginPath();ctx.lineWidth = 0.2;ctx.arc(438.5,223,10,0,Math.PI*2);ctx.stroke();ctx.restore();ctx.drawImage(ball,379,233,40,40);ctx.drawImage(ball,454,239,40,40);ctx.drawImage(ball,310,295,20,20);ctx.drawImage(ball,314.5,296.5,5,5);ctx.drawImage(ball,319,297.2,5,5);}redraw();var lastX=canvas.width/2, lastY=canvas.height/2;var dragStart,dragged;canvas.addEventListener('mousedown',function(evt){document.body.style.mozUserSelect = document.body.style.webkitUserSelect = document.body.style.userSelect = 'none';lastX = evt.offsetX || (evt.pageX - canvas.offsetLeft);lastY = evt.offsetY || (evt.pageY - canvas.offsetTop);dragStart = ctx.transformedPoint(lastX,lastY);dragged = false;},false);canvas.addEventListener('mousemove',function(evt){lastX = evt.offsetX || (evt.pageX - canvas.offsetLeft);lastY = evt.offsetY || (evt.pageY - canvas.offsetTop);dragged = true;if (dragStart){var pt = ctx.transformedPoint(lastX,lastY);ctx.translate(pt.x-dragStart.x,pt.y-dragStart.y);redraw();}},false);canvas.addEventListener('mouseup',function(evt){dragStart = null;if (!dragged) zoom(evt.shiftKey ? -1 : 1 );},false);var scaleFactor = 1.1;var zoom = function(clicks){var pt = ctx.transformedPoint(lastX,lastY);ctx.translate(pt.x,pt.y);var factor = Math.pow(scaleFactor,clicks);ctx.scale(factor,factor);ctx.translate(-pt.x,-pt.y);redraw();}var handleScroll = function(evt){var delta = evt.wheelDelta ? evt.wheelDelta/40 : evt.detail ? -evt.detail : 0;if (delta) zoom(delta);return evt.preventDefault() && false;};canvas.addEventListener('DOMMouseScroll',handleScroll,false);canvas.addEventListener('mousewheel',handleScroll,false);};gkhead.src = 'http://phrogz.net/tmp/gkhead.jpg';ball.src = 'http://phrogz.net/tmp/alphaball.png';// Adds ctx.getTransform() - returns an SVGMatrix// Adds ctx.transformedPoint(x,y) - returns an SVGPointfunction trackTransforms(ctx){var svg = document.createElementNS("http://www.w3.org/2000/svg",'svg');var xform = svg.createSVGMatrix();ctx.getTransform = function(){ return xform; };var savedTransforms = [];var save = ctx.save;ctx.save = function(){savedTransforms.push(xform.translate(0,0));return save.call(ctx);};var restore = ctx.restore;ctx.restore = function(){xform = savedTransforms.pop();return restore.call(ctx);};var scale = ctx.scale;ctx.scale = function(sx,sy){xform = xform.scaleNonUniform(sx,sy);return scale.call(ctx,sx,sy);};var rotate = ctx.rotate;ctx.rotate = function(radians){xform = xform.rotate(radians*180/Math.PI);return rotate.call(ctx,radians);};var translate = ctx.translate;ctx.translate = function(dx,dy){xform = xform.translate(dx,dy);return translate.call(ctx,dx,dy);};var transform = ctx.transform;ctx.transform = function(a,b,c,d,e,f){var m2 = svg.createSVGMatrix();m2.a=a; m2.b=b; m2.c=c; m2.d=d; m2.e=e; m2.f=f;xform = xform.multiply(m2);return transform.call(ctx,a,b,c,d,e,f);};var setTransform = ctx.setTransform;ctx.setTransform = function(a,b,c,d,e,f){xform.a = a;xform.b = b;xform.c = c;xform.d = d;xform.e = e;xform.f = f;return setTransform.call(ctx,a,b,c,d,e,f);};var pt = svg.createSVGPoint();ctx.transformedPoint = function(x,y){pt.x=x; pt.y=y;return pt.matrixTransform(xform.inverse());}}</script></body></html>
0 0
- 【整理】用html和javascript实现类似百度地图的画布
- Flex中调用本地html实现百度地图API Javascript版的一些常用地图功能
- HTML实现百度地图的效果
- 实现类似百度地图-添加到主屏幕的功能
- HTML 5 画布的实现
- 用html+jquery实现类似flash的地图区域选择效果
- javascript 类似百度的搜索
- android 画笔和画布的使用,实现类似360清除内存的画面
- 关于百度地图的整理
- 百度地图API制作类似 百度地图的路线导航界面并实现简单的路线规划功能
- 百度地图的使用和编程实现
- 类似滴滴打车,多辆小车在地图上平滑移动的实现,基于百度地图实现(轨迹已画好)
- 类似滴滴打车,多辆小车在地图上平滑移动的实现,基于百度地图实现(无轨迹)
- Arcgis for javascript实现百度地图ABCD marker的效果
- Arcgis for javascript实现百度地图ABCD marker的效果
- 【百度地图JavaScript API】手机端浏览器定位的实现
- 【百度地图JavaScript API】手机端浏览器定位的实现
- 天易10----js实现的类似百度地图(带查询功能)
- Hibernate基础篇
- 系统去掉 Android 4.4.2 的StatusBar和NavigationBar
- [leetcode]Valid Parentheses
- CTS测试与GTS测试区别
- mongodb 常用API
- 【整理】用html和javascript实现类似百度地图的画布
- hadoop总结总结吧
- canvas
- 递归实现数字转换成字符串
- Android文件的读写
- IOS UIImage类方法总结
- java基础之对象与引用
- 码了5年代码,积累了些东西
- IMAGE_EXPORT_DIRECTORY