基于 Raphael.js 实现对 Raphael 画布进行缩放和移动

本贴最后更新于 3066 天前,其中的信息可能已经渤澥桑田

最近项目里有个基于 raphael.js 的功能要进行迭代,要求要可以对画布进行缩放和移动,类似于地图那种放大缩小移动,研究了一番,发现 raphael 并没有直接实现这些功能,看了手册,我发现了 paper 的 setViewBox 方法:
a375341fa9d941d7a4a9c492cc46b4ae-WX201707302346332x.png
经过测试,这个方法类似于一个放大镜的功能,它在不改变画布 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>

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • 区块链

    区块链是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。所谓共识机制是区块链系统中实现不同节点之间建立信任、获取权益的数学算法 。

    92 引用 • 752 回帖
  • PWA

    PWA(Progressive Web App)是 Google 在 2015 年提出、2016 年 6 月开始推广的项目。它结合了一系列现代 Web 技术,在网页应用中实现和原生应用相近的用户体验。

    14 引用 • 69 回帖 • 186 关注
  • 浅吟主题

    Jeffrey Chen 制作的思源笔记主题,项目仓库:https://github.com/TCOTC/Whisper

    2 引用 • 34 回帖 • 2 关注
  • TensorFlow

    TensorFlow 是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。节点(Nodes)在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数组,即张量(tensor)。

    20 引用 • 19 回帖
  • 生活

    生活是指人类生存过程中的各项活动的总和,范畴较广,一般指为幸福的意义而存在。生活实际上是对人生的一种诠释。生活包括人类在社会中与自己息息相关的日常活动和心理影射。

    230 引用 • 1432 回帖
  • Webswing

    Webswing 是一个能将任何 Swing 应用通过纯 HTML5 运行在浏览器中的 Web 服务器,详细介绍请看 将 Java Swing 应用变成 Web 应用

    1 引用 • 15 回帖 • 669 关注
  • 音乐

    你听到信仰的声音了么?

    63 引用 • 513 回帖
  • Angular

    AngularAngularJS 的新版本。

    26 引用 • 66 回帖 • 578 关注
  • danl
    217 关注
  • 运维

    互联网运维工作,以服务为中心,以稳定、安全、高效为三个基本点,确保公司的互联网业务能够 7×24 小时为用户提供高质量的服务。

    151 引用 • 257 回帖
  • Quicker

    Quicker 您的指尖工具箱!操作更少,收获更多!

    39 引用 • 170 回帖
  • 创业

    你比 99% 的人都优秀么?

    81 引用 • 1396 回帖
  • Redis

    Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。从 2010 年 3 月 15 日起,Redis 的开发工作由 VMware 主持。从 2013 年 5 月开始,Redis 的开发由 Pivotal 赞助。

    285 引用 • 248 回帖 • 2 关注
  • webpack

    webpack 是一个用于前端开发的模块加载器和打包工具,它能把各种资源,例如 JS、CSS(less/sass)、图片等都作为模块来使用和处理。

    43 引用 • 130 回帖 • 259 关注
  • 印象笔记
    3 引用 • 21 回帖 • 3 关注
  • 强迫症

    强迫症(OCD)属于焦虑障碍的一种类型,是一组以强迫思维和强迫行为为主要临床表现的神经精神疾病,其特点为有意识的强迫和反强迫并存,一些毫无意义、甚至违背自己意愿的想法或冲动反反复复侵入患者的日常生活。

    15 引用 • 161 回帖 • 1 关注
  • Dubbo

    Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,是 [阿里巴巴] SOA 服务化治理方案的核心框架,每天为 2,000+ 个服务提供 3,000,000,000+ 次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。

    60 引用 • 82 回帖 • 636 关注
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3206 引用 • 8217 回帖
  • Kafka

    Kafka 是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是现代系统中许多功能的基础。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。

    36 引用 • 35 回帖
  • abitmean

    有点意思就行了

    44 关注
  • Hibernate

    Hibernate 是一个开放源代码的对象关系映射框架,它对 JDBC 进行了非常轻量级的对象封装,使得 Java 程序员可以随心所欲的使用对象编程思维来操纵数据库。

    39 引用 • 103 回帖 • 740 关注
  • GAE

    Google App Engine(GAE)是 Google 管理的数据中心中用于 WEB 应用程序的开发和托管的平台。2008 年 4 月 发布第一个测试版本。目前支持 Python、Java 和 Go 开发部署。全球已有数十万的开发者在其上开发了众多的应用。

    14 引用 • 42 回帖 • 851 关注
  • 996
    13 引用 • 200 回帖 • 7 关注
  • 链书

    链书(Chainbook)是 B3log 开源社区提供的区块链纸质书交易平台,通过 B3T 实现共享激励与价值链。可将你的闲置书籍上架到链书,我们共同构建这个全新的交易平台,让闲置书籍继续发挥它的价值。

    链书社

    链书目前已经下线,也许以后还有机会重制。

    14 引用 • 258 回帖
  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    561 引用 • 677 回帖 • 2 关注
  • 脑图

    脑图又叫思维导图,是表达发散性思维的有效图形思维工具 ,它简单却又很有效,是一种实用性的思维工具。

    40 引用 • 157 回帖
  • 前端

    前端技术一般分为前端设计和前端开发,前端设计可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括 HTML、CSS 以及 JavaScript 等。

    248 引用 • 1342 回帖