Raphael绘制流程图(二),添加带箭头的直线
上一篇文章中,我们添加了元素(矩形框),接下来给矩形框加上带箭头的直线,代码如下:
var wf_r = null; //画板对象
var wf_steps = []; //步骤数组
var wf_width = 108; //步骤宽度
var wf_height = 50; //步骤高度
var wf_rect = 8;
var wf_stepDefaultName = "新步骤";//默认步骤名称
var addToJSON = false;
var wf_nodeBorderColor = "#587aa9"; //节点边框颜色
var wf_noteColor = "#efeff0"; //节点填充颜色
var wf_focusObj=null;
var mouseX=0;
var mouseY=0;
var wf_option="";
var wf_conns = []; //连线数组
//添加连线
function addConn() {
if (!wf_focusObj || !isStepObj(wf_focusObj)) {
alert("请选择要连接的步骤!"); return false;
}
wf_option = "line";
document.body.onmousemove = mouseMove;
document.body.onmousedown = function () {
for (var i = 0; i < tempArrPath.length; i++) {
tempArrPath[i].arrPath.remove();
}
tempArrPath = [];
document.body.onmousemove = null;
};
}
//判断一个对象是否是步骤对象
function isStepObj(obj) {
return obj && obj.type1 && (obj.type1.toString() == "normal");
}
function mouseMove(ev) {
ev = ev || window.event;
var mousePos = mouseCoords(ev);
mouseX = mousePos.x;
mouseY = mousePos.y;
var obj = { obj1: wf_focusObj, obj2: null };
wf_r.drawArr(obj);
}
//判断一个节点与另一个节点之间是否可以连线
function isLine(obj) {
if (!obj || !obj.obj1 || !obj.obj2) {
return false;
}
if (obj.obj1 === obj.obj2) {
return false;
}
if (!isStepObj(obj.obj1) || !isStepObj(obj.obj2)) {
return false;
}
for (var i = 0; i < wf_conns.length; i++) {
if (obj.obj1 === obj.obj2 || (wf_conns[i].obj1 === obj.obj1 && wf_conns[i].obj2 === obj.obj2)) {
return false;
}
}
return true;
}
function mouseCoords(ev) {
if (ev.pageX || ev.pageY) {
return { x: ev.pageX, y: ev.pageY };
}
return {
x: ev.clientX + document.body.scrollLeft - document.body.clientLeft,
y: ev.clientY + document.body.scrollTop - document.body.clientTop
};
}
//随着节点位置的改变动态改变箭头
Raphael.fn.drawArr = function (obj) {
if (!obj || !obj.obj1) {
return;
}
if (!obj.obj2) {
var point1 = getStartEnd(obj.obj1, obj.obj2);
var path2 = getArr(point1.start.x, point1.start.y, mouseX, mouseY, 7);
for (var i = 0; i < tempArrPath.length; i++) {
tempArrPath[i].arrPath.remove();
}
tempArrPath = [];
obj.arrPath = this.path(path2);
obj.arrPath.attr({ "stroke-width": 1.7, "stroke": wf_connColor, "fill": wf_connColor });
tempArrPath.push(obj);
return;
}
var point = getStartEnd(obj.obj1, obj.obj2);
var path1 = getArr(point.start.x, point.start.y, point.end.x, point.end.y, 7);
try {
if (obj.arrPath) {
obj.arrPath.attr({ path: path1 });
}
else {
obj.arrPath = this.path(path1);
obj.arrPath.attr({ "stroke-width": 1.7, "stroke": wf_connColor, "fill": wf_connColor, "x": point.start.x, "y": point.start.y, "x1": point.end.x, "y1": point.end.y });
if (wf_designer) {
obj.arrPath.click(connClick);
obj.arrPath.dblclick(connSetting);
obj.arrPath.id = obj.id;
obj.arrPath.fromid = obj.obj1.id;
obj.arrPath.toid = obj.obj2.id;
}
}
} catch (e) { }
return obj;
};
//得到直线的在矩形上的起点和终点坐标
function getStartEnd(obj1, obj2) {
var bb1 = obj1 ? obj1.getBBox() : null;
var bb2 = obj2 ? obj2.getBBox() : null;
var p = [
{ x: bb1.x + bb1.width / 2, y: bb1.y - 1 },
{ x: bb1.x + bb1.width / 2, y: bb1.y + bb1.height + 1 },
{ x: bb1.x - 1, y: bb1.y + bb1.height / 2 },
{ x: bb1.x + bb1.width + 1, y: bb1.y + bb1.height / 2 },
bb2 ? { x: bb2.x + bb2.width / 2, y: bb2.y - 1 } : {},
bb2 ? { x: bb2.x + bb2.width / 2, y: bb2.y + bb2.height + 1 } : {},
bb2 ? { x: bb2.x - 1, y: bb2.y + bb2.height / 2 } : {},
bb2 ? { x: bb2.x + bb2.width + 1, y: bb2.y + bb2.height / 2 } : {}
];
var d = {}, dis = [];
for (var i = 0; i < 4; i++) {
for (var j = 4; j < 8; j++) {
var dx = Math.abs(p[i].x - p[j].x),
dy = Math.abs(p[i].y - p[j].y);
if (
(i == j - 4) ||
(((i != 3 && j != 6) || p[i].x < p[j].x) &&
((i != 2 && j != 7) || p[i].x > p[j].x) &&
((i != 0 && j != 5) || p[i].y > p[j].y) &&
((i != 1 && j != 4) || p[i].y < p[j].y))
) {
dis.push(dx + dy);
d[dis[dis.length - 1]] = [i, j];
}
}
}
if (dis.length == 0) {
var res = [0, 4];
} else {
// alert(Math.min.apply(Math, dis))
res = d[Math.min.apply(Math, dis)];
}
var result = {};
result.start = {};
result.end = {};
result.start.x = p[res[0]].x;
result.start.y = p[res[0]].y;
result.end.x = p[res[1]].x;
result.end.y = p[res[1]].y;
return result;
}
function getArr(x1, y1, x2, y2, size) {
var angle = Raphael.angle(x1, y1, x2, y2);
var a45 = Raphael.rad(angle - 28);
var a45m = Raphael.rad(angle + 28);
var x2a = x2 + Math.cos(a45) * size;
var y2a = y2 + Math.sin(a45) * size;
var x2b = x2 + Math.cos(a45m) * size;
var y2b = y2 + Math.sin(a45m) * size;
return ["M", x1, y1, "L", x2, y2, "M", x2, y2, "L", x2b, y2b, "L", x2a, y2a, "z"].join(",");
}
//得到带箭头的起点和终点坐标
function getArr(x1, y1, x2, y2, size) {
var angle = Raphael.angle(x1, y1, x2, y2);
var a45 = Raphael.rad(angle - 28);
var a45m = Raphael.rad(angle + 28);
var x2a = x2 + Math.cos(a45) * size;
var y2a = y2 + Math.sin(a45) * size;
var x2b = x2 + Math.cos(a45m) * size;
var y2b = y2 + Math.sin(a45m) * size;
return ["M", x1, y1, "L", x2, y2, "M", x2, y2, "L", x2b, y2b, "L", x2a, y2a, "z"].join(",");
}
//单击事件执行相关操作
function click()
{
var o = this;
switch (wf_option)
{
case "line":
var obj = { id: getGuid(), obj1: wf_focusObj, obj2: o };
connObj(obj);
break;
default:
changeStyle(o);
break;
}
wf_option = "";
wf_focusObj = this;
}
//连接对象
function connObj(obj, addToJSON, title) {
if (addToJSON == undefined || addToJSON == null) addToJSON = true;
if (isLine(obj))
{
var newline = wf_r.drawArr(obj);
wf_conns.push(newline);
}
}
//添加步骤
function addStep(x, y, text, id, addToJSON, type1, bordercolor, bgcolor) {
var guid = getGuid();
var xy = getNewXY();
x = x || xy.x;
y = y || xy.y;
text = text || wf_stepDefaultName;
id = id || guid;
var rect = wf_r.rect(x, y, wf_width, wf_height, wf_rect);
rect.attr({ "fill": bgcolor || wf_noteColor, "stroke": bordercolor || wf_nodeBorderColor, "stroke-width": 1.4, "cursor": "default" });
rect.id = id;
rect.type1 = type1 ? type1 : "normal";
rect.drag(move, dragger, up);
rect.click(click);
wf_steps.push(rect);
var text2 = text.length > 8 ? text.substr(0, 7) + "..." : text;
var text1 = wf_r.text(x + 52, y + 25, text2);
text1.attr({ "font-size": "12px" });
if (text.length > 8) text1.attr({ "title": text });
text1.id = "text_" + id;
text1.type1 = "text";
}
//拖动节点开始时的事件
function dragger() {
this.ox = this.attr("x");
this.oy = this.attr("y");
//changeStyle(this);
}
//拖动事件
function move(dx, dy) {
var x = this.ox + dx;
var y = this.oy + dy;
if (x < 0) {
x = 0;
}
else if (x > wf_r.width - wf_width) {
x = wf_r.width - wf_width;
}
if (y < 0) {
y = 0;
}
else if (y > wf_r.height - wf_height) {
y = wf_r.height - wf_height;
}
var att = { x: x, y: y };
this.attr(att);
if (this.id) {
var text = wf_r.getById('text_' + this.id);
if (text) {
text.attr("x", x + 52);
text.attr("y", y + 25);
}
}
};
//拖动后的事件
function up()
{
}
//得到新步骤的XY
function getNewXY() {
var x = 10, y = 50;
if (wf_steps.length > 0) {
var step = wf_steps[wf_steps.length - 1];
x = parseInt(step.attr("x")) + 170;
y = parseInt(step.attr("y"));
if (x > wf_r.width - wf_width) {
x = 10;
y = y + 100;
}
if (y > wf_r.height - wf_height) {
y = wf_r.height - wf_height;
}
}
return { x: x, y: y };
}
//得到GUID
function getGuid() {
return Raphael.createUUID().toLowerCase();
}
Raphael绘制流程图(二),添加带箭头的直线相关推荐
- Raphael绘制流程图箭头的方法
原项目使用的Raphael绘制流程图,要求能自定义箭头的样式和颜色,结合从网上找到的一些资料进行修改. 1.使用Raphael自带的箭头样式,代码与箭头的样式对应如下: var c = r.path( ...
- Raphael绘制流程图(一),添加可拖动的图形
原项目使用的Raphael绘制流程图,要求能自定义箭头的样式和颜色,结合从网上找到的一些资料进行修改. 1.jquery或javascript代码 var wf_r = null; //画板对象 va ...
- Android Canvas绘制带箭头的直线
先看下效果图: 下面我们直接看代码 我自定义了一个View,代码如下: package com.davis.drawtrangle;import android.content.Context; im ...
- Matlab任意两点之间绘制带箭头的直线
Matlab任意两点之间绘制带箭头的直线 简单绘制任意两点之间.本来不想自己写的,可是网上的代码用起来不舒服,所以简单看看原理,原来就是个坐标变换而已.索性自己写了一份,分享如下: function ...
- CAD里面怎么画带箭头的直线
转自:http://jingyan.baidu.com/article/9113f81b0192e72b3214c709.html?st=2&os=0&bd_page_type=1&a ...
- 【MFC】如何画带箭头的直线
[MFC]如何画带箭头的直线 前言 代码 获得箭头坐标 前言 如何绘制带箭头的直线,说来也简单,只需要算出箭头左右两边的坐标,再使用LineTo()函数即可.话不多说上代码. 代码 获得箭头坐标 已知 ...
- MFC画带箭头的直线
构造一个函数,是在startPoint,endPoint间画一条带箭头的线段: void CTry1View::DrawLine(POINT startPoint, POINT endPoint) { ...
- 关于google地图api3的离线和在线开发(画带箭头的直线,指定范围,搜索,计算距离)
最近因为开发的需要,要做一个离线的google地图.并且能够加载google地图的一些特效.例如:地图的标记,计算距离,获取标记的经纬度,画带有箭头的直线,获取指定范围的数据等等.在这里我总结了很多开 ...
- 关于利用canvas画带箭头的直线旋转
利用canvas在Vue项目中使用: <imgid="range_right"src=""style="position: absolute;l ...
最新文章
- 文件系统写入100G文件需要多久
- JDBC(二)——使用IDEA连接数据库、数据库连接池
- 史上最全PHP正则表达式实例汇总
- monogdb操作system.*权限
- python pdf转txt保留全部信息_Python 将pdf转换成txt(不处理图片)
- 软考网络工程师笔记-综合知识2
- instagram架构_通过创建Instagram副本学习Laravel
- word中添加mathtype
- 怎么做数据可视化大屏?从设计到上线,一般用这3类工具
- 如何操作反射中构造方法、属性和普通方法?
- circNet:人类环状RNA数据库
- 网管员常用工具(二)
- Alphapose_pytorch版本环境配置Win10
- 激光传感器构建栅格地图
- 爬虫之-bilibili视频下载-下载链接获取
- 美国人日常生活中常用的五星级句子
- 生病还要被压榨,外包太惨了!
- 网易企业邮箱技术剖析
- 使用阿里云消息服务mns发送短信
- 国富论(英语:The Wealth of Nations)
热门文章
- 多部电梯具有联动性的测试用例
- Windows磁盘管理工具Diskpart之一 管理基本磁盘
- 翻译——奇偶校验矩阵和低密度奇偶校验码的构造方法
- Layui前端判断,Date()函数时间戳转换
- linux搭建交换机日志,搭建属于自己的syslog日志服务器
- 俄罗斯盗版软件将被合法化:最大破解资源网站宣布解封,数十万盗版资源解禁...
- WordCount操作步骤
- IDC运维如何转linux运维,智简魔方DCIM系统助力IDC运维人员解决难题
- [IT 男人帮 -10/31] 雨林木风CEO赖霖枫: 互联网冬天前的思考
- 道路车辆 盲区监测(bsd)系统性能要求及试验方法_让你的爱车“多一双眼睛”——BSD盲点监测系统...