最近项目里有个基于 raphael.js 的功能要进行迭代,要求要可以对画布进行缩放和移动,类似于地图那种放大缩小移动,研究了一番,发现 raphael 并没有直接实现这些功能,看了手册,我发现了 paper 的 setViewBox 方法:
经过测试,这个方法类似于一个放大镜的功能,它在不改变画布 paper 的情况下,截取某一个区域,用这个区域来铺满 paper,于是我们可以使用它来实现放大、移动的效果,代码如下:
<html> <head> <title>raphael缩放移动画布/</title> <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js" type="text/javascript"></script> <script src="https://cdn.bootcss.com/raphael/2.2.7/raphael.min.js" type="text/javascript"></script> </head> <body> <div id="paper"></div> </body> </html> <script> $(function () { //一些全局参数 const paperWidth = 500; //画布宽度 const paperHeight = 500; //画布高度 const maxSize = 3; //允许放大的最大倍数 const minSize = 0.5; //允许缩小的最大倍数 var mouseOnBackGround = false; //鼠标是否悬浮在画布上 var mouseOnObject = false; //鼠标是否悬浮在画布的某个对象上 var mouseDown = false; //鼠标是否得按住状态 var lastMouseLocation = {}; //记录鼠标移动之前的坐标 //缩放相关参数 //coef:每次放大、缩小的增量; //zoom:目前的大小与原来大小的比例; //(x,y):目前缩放图的左上角坐标; //w,h:以(x,y)为原点取得宽度和高度; const scale = {coef: 0.05, zoom: 1, x: 0, y: 0, w: paperWidth, h: paperHeight}; //创建一个画布 var paper = new Raphael("paper", paperWidth, paperHeight); //创建一个跟paper一样尺寸的rect模拟背景图 paper.rect(0, 0, paperWidth, paperHeight) .attr({ "stroke": "blue", "stroke-width": 4, "fill": "#e1e1e1" } ) .hover( function () { //鼠标进入背景 mouseOnBackGround = true; }, function () { //鼠标移出背景 mouseOnBackGround = false; } ); //创建一个圆 paper.circle(150, 150, 40) .attr({ "stroke": "red", "stroke-width": 4, "fill": "blue", "opacity": 0.5 }) .hover( function () { //鼠标进入 mouseOnObject = true; }, function () { //鼠标移出 mouseOnObject = false; } ); //创建一个圆角方形 paper.rect(250, 250, 50, 50, 10) .attr({ "stroke": "blue", "stroke-width": 4, "fill": "green" } ) .hover( function () { //鼠标进入 mouseOnObject = true; }, function () { //鼠标移出 mouseOnObject = false; } ); //更新Scale function updateScale(x, y, w, h) { scale.w = w; scale.h = h; scale.x = x; scale.y = y; } //获取操作前的viewbox中心点 function getLastCenterPoint() { var centerPoint = {}; centerPoint.x = scale.x + scale.w / 2; centerPoint.y = scale.y + scale.h / 2; return centerPoint; } /** *鼠标滚轮缩放 * */ function onMouseWheeling(e) { var dtl; if (!mouseOnBackGround && !mouseOnObject) { return; } if (e.wheelDelta) { //chrome dtl = e.wheelDelta; } else if (e.detail) {//firefox or others dtl = -e.detail; } if (dtl < 0) { //缩小, if (scale.zoom < minSize) { return; } scale.zoom -= scale.coef; } else { //放大 if (scale.zoom > maxSize) { return; } scale.zoom += scale.coef; } //计算新的视图参数 var w = paperWidth / scale.zoom; var h = paperHeight / scale.zoom; var lastCenterPoint = getLastCenterPoint(); var x = lastCenterPoint.x - w / 2; var y = lastCenterPoint.y - h / 2; updateScale(x, y, w, h); paper.setViewBox(x, y, w, h, false); } if (document.addEventListener) { document.addEventListener('DOMMouseScroll', onMouseWheeling, false); window.onmousewheel = document.onmousewheel = onMouseWheeling;//IE/Opera/Chrome/Safari } else { alert("鼠标滚轮监听事件绑定失败"); } //监听鼠标移动 $(document).bind('mousedown', function (e) { lastMouseLocation.x = e.clientX; lastMouseLocation.y = e.clientY; mouseDown = true; }).bind('mouseup', function (e) { lastMouseLocation = {}; mouseDown = false; }).bind('mousemove', function (e) { if (!mouseDown) { return; } if (!mouseOnBackGround && !mouseOnObject) { return; } var dx = e.clientX - lastMouseLocation.x; var dy = e.clientY - lastMouseLocation.y; var x = scale.x - dx; var y = scale.y - dy; updateScale(x, y, scale.w, scale.h); lastMouseLocation.x = e.clientX; lastMouseLocation.y = e.clientY; paper.setViewBox(x, y, scale.w, scale.h, false); }) }); </script>
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于