Raphael path 拖动实现
让 Raphael 的 Path 动起来
Raphaël 是一个很实用的线上矢量图操作 Javascript 库。使用简单,一个值得一提的卖点是通过抽象出共同的接口屏蔽了 SVG 和 VML 之间的差异,做到了对主流浏览器的支持,包括很不给力的 IE6。(很可惜,并不支持手机 UC 浏览器)
Raphael 对于交互事件也有一定的支持,比如常用的鼠标的拖放操作(Drag and Drop)。在官方网站上也有拖放操作的例子。可惜的是,官方的这个例子的写法只对 Circle,Rect 等有效,但对于 Path 却不起作用。经过一番实践,终于了解了 Raphaël 对于拖放支持的原理,想出了一个通用的拖放操作的写法,支持所有的 Raphael 矢量对象,包括 path。
官方例子之所以不能让 Path 动起来是因为:Path 没有象 Circle 里面的 cx 和 cy 属性,要移动 Path,只能使用 Path.translate() 方法。还有一点要注意的是,Path 必须要先 fill 才能移动。
仿照官方的例子,下面是一个 Path 移动的代码示例:
var R = Raphael("paper", 400, 300);
var p = R.path('M0 0L100 0L50 80Z');
p.attr({"fill":"green", 'opacity':0.8});
var start = function (x, y) {
this.attr({opacity: 1});
this.lastX = x;
this.lastY = y;
},
move = function (dx, dy, x, y) {
var deltaX = x - this.lastX;
var deltaY = y - this.lastY;
this.translate(deltaX, deltaY);
this.lastX = x;
this.lastY = y;
},
up = function () {
this.attr({opacity: 0.8});
};
p.drag(move, start, up);
运行效果如下
上面的例子有几点要说明一下
- 回调函数 move 的第一个和第二个参数永远是鼠标所在的点距移动初始时的鼠标位置的相对位移值。而不是距离上次 move 回调时鼠标位置的相对位移值
- 我们在 start 和 move 中记录并不断更新相对上次鼠标位置的相对位移值,并保存在 this.lastX 和 this.lastY 中
- 我们通过 this.translate() 进行实际的移动操作
- 在一开始,要设置 fill 属性,否则就不能进行移动操作
这个例子不但能工作,更好的是,因为所有的 Raphael 矢量对象都有 translate 方法。所以,它不仅对 path 有效,也对所有的 Raphael 矢量对象有效。那么,是不是能做出来类似 jQuery.ui 里面的 draggble 的函数呢。下面就是一个简单的扩展,为 Raphael 对象加入了 draggable 方法。
(function(R) {
R.el.draggable = function(move, start, up) {
this._ui = this._ui || {};
var that = this;
this._ui.onMove = R.is(move, 'function') ?
move : function(distanceX, distanceY, x, y, deltaX, deltaY) {
that.translate(deltaX, deltaY);
};
this._ui.onStart = R.is(start, 'function') ? start : function(x, y) {
};
function onMove(distanceX, distanceY, x, y) {
var deltaX = x - that._ui.lastX;
var deltaY = y - that._ui.lastY;
that._ui.lastX = x;
that._ui.lastY = y;
that._ui.onMove(distanceX, distanceY, x, y, deltaX, deltaY);
that.paper.safari();
};
function onStart(x, y) {
that._ui.lastX = x;
that._ui.lastY = y;
that._ui.onStart(x, y);
};
return this.drag(onMove, onStart, up);
};
})(Raphael);
上面的一段代码,扩展了 Raphael 对象的方法,让它们拥有了类似 jquery.ui 里 draggable 的能力。下面是用利用这个扩展重新写的拖放 Path 的例子。
var R = Raphael("paper", 400, 300);
R.rect(0, 0, 400, 300);
var p = R.path('M0 0L100 0L50 80Z');
p.attr({"fill":"green", 'opacity':0.5});
p.draggable();
可以看到,像 jquery.ui 提供的功能一样,只需要简单的调用 .draggable() 就可以让对象被鼠标拖拽
Raphael path 拖动实现的更多相关文章
- Raphael的拖动处理
Raphael的拖动处理: <%@ page language="java" contentType="text/html; charset=UTF-8" ...
- Raphael初始化,path,circle,rect,ellipse,image
path jsp: <%@ page language="java" contentType="text/html; charset=UTF-8" pag ...
- 学习RaphaelJS矢量图形包--Learning Raphael JS Vector Graphics中文翻译(一)
(原文地址:http://www.cnblogs.com/idealer3d/p/LearningRaphaelJSVectorGraphics.html) 前面3篇博文里面,我们讲解了一本叫做< ...
- 对Raphael画图标的一个jquery简单封装
公司要做一个项目的demo,要求地图上可以插红旗,所以就用到了Raphael. 因为是个demo,所以地图就用了一张图片,效果如下: 所以为了更好的封装一下这个功能,就写了一个简单的插件:jquery ...
- MAC 设置环境变量path的几种方法
mac 一般使用bash作为默认shell Mac系统的环境变量,加载顺序为:/etc/profile /etc/paths ~/.bash_profile ~/.bash_login ~/.prof ...
- CentOS6下基于Nginx搭建mp4/flv流媒体服务器(可随意拖动)并支持RTMP/HLS协议(含转码工具)
1.先添加几个RPM下载源 1.1)安装RPMforge的CentOS6源 [root@AY130611215205Z ~]# wget -c http://pkgs.repoforge.or ...
- IOS第七天(6:UiTableView编辑模式, 拖动位置 ,滑动删除)
**********UiTableView编辑模式, 拖动位置 ,滑动删除 #import "HMViewController.h" @interface HMViewContro ...
- svg―Raphael.js Library(一)
Raphael是一个用于在网页中绘制矢量图形的Javascript库,它使用SVG W3C推荐标准和VML作为创建图形的基础,可以通过JavaScript操作DOM来轻松创建出各种复杂的柱状图.饼图. ...
- vbs实现的支持拖动的txt文本切割器
vbs实现的支持拖动的txt文本切割器 作者: 字体:[增加 减小] 类型:转载 时间:2008-06-20我要评论 用vbs实现的txt文本文件切割器,默认为8000个字符切为一个文件.支持拖动. ...
随机推荐
- Linux驱动之PCI
<背景> PCI设备有许多地址配置的寄存器,初始化时这寄存器来配置设备的总线地址,配置好后CPU就可以访问该设备的各项资源了.(提炼:配置总线地址) <配置寄存器> ( ...
- [PE484]Arithmetic Derivative
题意:对整数定义求导因子$'$:$p'=1,(ab)'=a'b+ab'$,求$\sum\limits_{i=2}^n(i,i')$ 这个求导定义得比较妙:$(p^e)'=ep^{e-1}$ 推一下就可 ...
- 【枚举】【贪心】Codeforces Round #482 (Div. 2) B. Treasure Hunt
题意:给你3个字符串,3个人各对自己的字符串执行n轮操作,每一次选择一个字符变为任意一个和原来不同的字符.最后问你谁能使自己的串中的任意重复子串出现的次数最大化. 显然只需关注字符而非子串. 枚举每个 ...
- js的继承实现方式
1. 使用call或者apply来实现js对象继承 function Animal(age){ this.age = age; this.say = function(){ console.log(' ...
- Codeforces Round #297 (Div. 2)D. Arthur and Walls 暴力搜索
Codeforces Round #297 (Div. 2)D. Arthur and Walls Time Limit: 2 Sec Memory Limit: 512 MBSubmit: xxx ...
- opencv 利用Haar 人脸识别
#include <opencv2/opencv.hpp> #include <cstdio> #include <cstdlib> #include <io ...
- Codeforces Round #281 (Div. 2) C. Vasya and Basketball 暴力水题
C. Vasya and Basketball time limit per test 2 seconds memory limit per test 256 megabytes input stan ...
- 【转】Spring中事务与aop的先后顺序问题
[原文链接] http://my.oschina.net/HuifengWang/blog/304188 [正文] Spring中的事务是通过aop来实现的,当我们自己写aop拦截的时候,会遇到跟sp ...
- SVN服务端的版本对比及创建仓库时的注意事项
SVN是一个开放源代码的版本控制系统,分为客户端和服务端.就windows系统而言,客户端通常使用 TortoiseSVN,下载地址:https://tortoisesvn.net/ ,而服务端通常 ...
- Oracle中NVARCHAR2与VARCHAR2的相互转换
将NVARCHAR2转换为VARCHAR2: declare v_username varchar2(12) ; v_nm_login nvarchar2(12); begin selec ...