热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用Raphael绘制流程图,自绘动态箭头,可拖动,有双击事件,纯前端,兼容各种浏览器...

关于RaphalRaphal是一个在网页上绘图的js类库,非常小压缩版只有89k左右官方宣称兼容各种主流浏览器,据笔者测试在IE6下尚有一些问题

关于Raphaël

Raphaël是一个在网页上绘图的js类库,非常小压缩版只有89k左右

官方宣称兼容各种主流浏览器,据笔者测试在IE6下尚有一些问题(不过这些与本文无关)

他是使用js来创建vml或svg来绘图的

缘起

项目中不能使用Silverlight或者flash来解决绘图和拖动的问题

而且为了项目效果较好,要求拖动的时候箭头能动态改变起点和重点,别且箭头要改变方向

所以只能考虑JS了

效果

image

演示

http://www.mrlh.net/flowchart/demo.htm[已经不能访问了]

源码

引用

这两个东西是不相干的,引用先后顺序也无所谓

页面加载完成后的代码

$(function () {//用来存储节点的顺序var connections = [];//拖动节点开始时的事件var dragger = function () {this.ox = this.attr("x");this.oy = this.attr("y");this.animate({ "fill-opacity": .2 }, 500);};//拖动事件var move = function (dx, dy) {var att = { x: this.ox + dx, y: this.oy + dy };this.attr(att);$("#test" + this.id).offset({ top: this.oy + dy + 10, left: this.ox + dx + 10 });for (var i = connections.length; i--; ) {r.drawArr(connections[i]);}};//拖动结束后的事件var up = function () {this.animate({ "fill-opacity": 0 }, 500);};//创建绘图对象var r = Raphael("holder", $(window).width(), $(window).height());//绘制节点var shapes = [r.rect(190, 100, 60, 40, 4),r.rect(290, 80, 60, 40, 4),r.rect(290, 180, 60, 40, 4),r.rect(450, 100, 60, 40, 4)];//定位节点上的文字$("#test1").offset({ top: 100 + 10, left: 190 + 10 });$("#test2").offset({ top: 80 + 10, left: 290 + 10 });$("#test3").offset({ top: 180 + 10, left: 290 + 10 });$("#test4").offset({ top: 100 + 10, left: 450 + 10 });//为节点添加样式和事件,并且绘制节点之间的箭头for (var i = 0, ii = shapes.length; i

这些代码注释比较详细,就不多说了

在这些代码中涉及到操作的界面元素HTML代码如下

测试1
测试2
测试3
测试4

其中关键元素的样式如下

#holder{top: 0px;left: 0px;right: 0px;bottom: 0px;position: absolute;z-index: 999;}test{position: absolute;width: 80px;height: 30px;top: 0px;z-index: 0;}

在拖动事件中,动态改变了节点文本元素的位置

并且重绘了节点和箭头

drawArr是一个自定义方法,负责修改箭头的方向,代码如下

//随着节点位置的改变动态改变箭头Raphael.fn.drawArr = function (obj) {var point = getStartEnd(obj.obj1, obj.obj2);var path1 = getArr(point.start.x, point.start.y, point.end.x, point.end.y, 8);if (obj.arrPath) {obj.arrPath.attr({ path: path1 });} else {obj.arrPath = this.path(path1);}return obj;};

首先需要确定箭头的起始位置,

point包含两个点,

point.start为起点,

point.end为终点,

然后需要确定箭头的绘图路径

一个箭头包含三个线段,四个点

1:起点,2:终点,3:箭头终点1,4:箭头终点2

image

在此函数中,判断如果箭头已经被绘制过,

只要修改属性即可

如果没有被绘制过,则需要重新绘制

 

下面来看一下动态确定起点和终点的代码

function getStartEnd(obj1, obj2) {var bb1 &#61; obj1.getBBox(),bb2 &#61; obj2.getBBox();var p &#61; [{ x: bb1.x &#43; bb1.width / 2, y: bb1.y - 1 },{ x: bb1.x &#43; bb1.width / 2, y: bb1.y &#43; bb1.height &#43; 1 },{ x: bb1.x - 1, y: bb1.y &#43; bb1.height / 2 },{ x: bb1.x &#43; bb1.width &#43; 1, y: bb1.y &#43; bb1.height / 2 },{ x: bb2.x &#43; bb2.width / 2, y: bb2.y - 1 },{ x: bb2.x &#43; bb2.width / 2, y: bb2.y &#43; bb2.height &#43; 1 },{ x: bb2.x - 1, y: bb2.y &#43; bb2.height / 2 },{ x: bb2.x &#43; bb2.width &#43; 1, y: bb2.y &#43; bb2.height / 2 }];var d &#61; {}, dis &#61; [];for (var i &#61; 0; i <4; i&#43;&#43;) {for (var j &#61; 4; j <8; j&#43;&#43;) {var dx &#61; Math.abs(p[i].x - p[j].x),dy &#61; Math.abs(p[i].y - p[j].y);if ((i &#61;&#61; j - 4) ||(((i !&#61; 3 && j !&#61; 6) || p[i].x p[j].x) &&((i !&#61; 0 && j !&#61; 5) || p[i].y > p[j].y) &&((i !&#61; 1 && j !&#61; 4) || p[i].y

这段代码来自Raphael官方demo

不是我写的

也一时半会说不清楚&#xff0c;

大家还是自己去研究吧

 

确定箭头路径的代码如下

//获取组成箭头的三条线段的路径function getArr(x1, y1, x2, y2, size) {var angle &#61; Raphael.angle(x1, y1, x2, y2);//得到两点之间的角度var a45 &#61; Raphael.rad(angle - 45);//角度转换成弧度var a45m &#61; Raphael.rad(angle &#43; 45);var x2a &#61; x2 &#43; Math.cos(a45) * size;var y2a &#61; y2 &#43; Math.sin(a45) * size;var x2b &#61; x2 &#43; Math.cos(a45m) * size;var y2b &#61; y2 &#43; Math.sin(a45m) * size;var result &#61; ["M", x1, y1, "L", x2, y2, "L", x2a, y2a, "M", x2, y2, "L", x2b, y2b];return result;}

此函数把箭头路径作为数组反馈给调用函数

数组中

M表示画笔起点移动到此点

L表示从某点绘制到某点&#xff0c;绘制直线

以上函数反馈结果的意思是&#xff1a;

画笔从&#xff08;x1,y1&#xff09;开始绘制直线到(x2,y2),然后从(x2,y2)绘制直线到(x2a,y2a)然后画笔移动到(x2,y2)然后从(x2,y2)绘制直线到(x2b,y2b)

在确定这几个点的过程中

用到了一些数学知识&#xff0c;具体原理也不多说了

 

 

喜欢的朋友请点支持&#xff01;谢谢大家&#xff01;

转:https://www.cnblogs.com/liulun/archive/2012/05/18/2507472.html



推荐阅读
  • 本文介绍了Java后台Jsonp处理方法及其应用场景。首先解释了Jsonp是一个非官方的协议,它允许在服务器端通过Script tags返回至客户端,并通过javascript callback的形式实现跨域访问。然后介绍了JSON系统开发方法,它是一种面向数据结构的分析和设计方法,以活动为中心,将一连串的活动顺序组合成一个完整的工作进程。接着给出了一个客户端示例代码,使用了jQuery的ajax方法请求一个Jsonp数据。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 如何压缩网站页面以减少页面加载时间
    本文介绍了影响网站打开时间的两个因素,即网页加载速度和网站页面大小。重点讲解了如何通过压缩网站页面来减少页面加载时间。具体包括图片压缩、Javascript压缩、CSS压缩和HTML压缩等方法,并推荐了相应的压缩工具。此外,还提到了一款Google Chrome插件——网页加载速度分析工具Speed Tracer。 ... [详细]
  • 今天周六,原则上要休息,但想到下周还有一堆任务,还是先做一部分工作吧,就把之前做的票面设计器改了改,增加了上传图片和更换背景底图的功能。现在打算整理下这个设计器,也算对齐一个总结。不过这属于我们部门的 ... [详细]
  • webui之常用js操作(webui界面是什么)
    本文目录一览:1、web前端开发需要掌握的几个必备技术 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Android实战——jsoup实现网络爬虫,糗事百科项目的起步
    本文介绍了Android实战中使用jsoup实现网络爬虫的方法,以糗事百科项目为例。对于初学者来说,数据源的缺乏是做项目的最大烦恼之一。本文讲述了如何使用网络爬虫获取数据,并以糗事百科作为练手项目。同时,提到了使用jsoup需要结合前端基础知识,以及如果学过JS的话可以更轻松地使用该框架。 ... [详细]
  • 本文介绍了OkHttp3的基本使用和特性,包括支持HTTP/2、连接池、GZIP压缩、缓存等功能。同时还提到了OkHttp3的适用平台和源码阅读计划。文章还介绍了OkHttp3的请求/响应API的设计和使用方式,包括阻塞式的同步请求和带回调的异步请求。 ... [详细]
  • Node.js学习笔记(一)package.json及cnpm
    本文介绍了Node.js中包的概念,以及如何使用包来统一管理具有相互依赖关系的模块。同时还介绍了NPM(Node Package Manager)的基本介绍和使用方法,以及如何通过NPM下载第三方模块。 ... [详细]
  • angular.element使用方法及总结
    2019独角兽企业重金招聘Python工程师标准在线查询:http:each.sinaapp.comangularapielement.html使用方法 ... [详细]
  • 025_JavaScript数组方法
    1.把数组转换为字符串1.1.toString()方法1.1.1.toString()方法把数组转换为数组值(逗号分隔)的字符串,并返回结果。1.1.2.语法arrayOb ... [详细]
  • 前端提高篇(七十):SVG基本使用、基本样式、路径path
    SVG是使用XML来描述二维图形和绘图程序的语言。SVG遵循的是xml的规范,与html5的使用有所区别SVG绘制出来的是矢量图,放大之后不会失真官方文 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
author-avatar
mobiledu2502878383
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有