JS组件系列——JsPlumb制作流程图及相关效果详解

上    篇

前言:之前项目里面用到了Web里面的拖拽流程图的技术JsPlumb,其实真不算难,不过项目里面用HTML做的一些类似flash的效果,感觉还不错,在此分享下。

Jsplumb官网:https://jsplumbtoolkit.com

GitHub:https://github.com/sporritt/jsplumb/

一、效果图展示

1、从左边拖动元素到中间区域,然后连线

JS组件系列——JsPlumb制作流程图及相关效果详解

2、连线类型可以自定义:这里定义为直线、折线、曲线。实际项目中根据业务我们定义为分装线、分装支线、总装线等

JS组件系列——JsPlumb制作流程图及相关效果详解

3、鼠标拖动区域选中元素,并且选中元素统一拖动位置。

JS组件系列——JsPlumb制作流程图及相关效果详解

JS组件系列——JsPlumb制作流程图及相关效果详解

JS组件系列——JsPlumb制作流程图及相关效果详解

4、对选中的元素左对齐。

JS组件系列——JsPlumb制作流程图及相关效果详解

5、对选中元素居中对齐

JS组件系列——JsPlumb制作流程图及相关效果详解

6、右对齐

JS组件系列——JsPlumb制作流程图及相关效果详解

7、上对齐

JS组件系列——JsPlumb制作流程图及相关效果详解

8、垂直居中对齐

JS组件系列——JsPlumb制作流程图及相关效果详解

9、下对齐

JS组件系列——JsPlumb制作流程图及相关效果详解

10、根据第一个选中的元素上下靠拢

JS组件系列——JsPlumb制作流程图及相关效果详解

11、根据第一个选中的元素左右靠拢

JS组件系列——JsPlumb制作流程图及相关效果详解

12、根据第一个选中的元素同高

JS组件系列——JsPlumb制作流程图及相关效果详解

13、根据第一个选中的元素同宽

JS组件系列——JsPlumb制作流程图及相关效果详解

14、选中元素顺时针旋转,点击一次旋转45度

JS组件系列——JsPlumb制作流程图及相关效果详解

JS组件系列——JsPlumb制作流程图及相关效果详解

15、选中元素逆时针旋转。

JS组件系列——JsPlumb制作流程图及相关效果详解

16、选中统一删除元素以及元素上面的连线

JS组件系列——JsPlumb制作流程图及相关效果详解

这里很多效果其实在项目中作用并不太大,很多单纯就是为了展示用的。没办法,领导要求,我们就只有做喽。

二、代码详解

这里涉及的效果比较多,可能要分多篇来介绍。这篇还是来看看构造流程图的核心技术:JsPlumb。

1、概述

关于JsPlumb的内容,园子里也有很多朋友做过分享,也有写得不错的博文。在此就简单说明下吧。jsPlumb是一个强大的JavaScript连线库,它可以将html中的元素用箭头、曲线、直线等连接起来,适用于开发Web上的图表、建模工具等。它同时支持jQuery+jQuery UI、MooTools和YUI3这三个JavaScript框架,十分强大。本项目中还是结合大家最熟悉的JQuery来讲解。并且还要注意的一点就是JsPlumb的浏览器兼容性,JsPlumb支持IE 6以上、火狐、谷歌等各种浏览器

2、使用

(1)引入JS文件

可以直接去官网上面下载最新的js库,由于JsPlumb需要JQuery的支持,按照网上的说法,它只兼容jQuery1.3.x及以上版本,并在jQuery UI 1.7.x、1.8.x及1.9.x上测试通过。所以我们需要下载较高一点版本的JQuery和JQuery UI。关于JsPlumb的内容只需要引用一个Js即可。类似

<script src="~/Content/jquery-1.9.1.min.js"></script>
<script src="~/Content/jquery-ui-1.11.4.custom/jquery-ui.js"></script>
<link href="~/Content/jquery-ui-1.11.4.custom/jquery-ui.min.css" rel="stylesheet" />
<script src="~/Content/jsPlumb-master/dist/js/jquery.jsPlumb-1.7.5.js"></script>

(2)初始化

使用JsPlumb需要注意一点,JsPlumb的连线的样式是由点确定的,也就是说点的样式里面包含了相关的属性来说明当使用此点来连线的时候,连线的样式应该是什么样的。

在我们项目里面,左边的模型区域,中间才是设计区域。那么要将一个元素从模型区域创建出来,就要用到我们JQuery UI里面的draggable和droppable事件。首先我们注册左边模型的draggable和中间区域的droppable事件。

cshtml页面代码,<div id="divContentLeftMenu">这个是左边模型的容器,<div id="divCenter"></div>表示中间区域容器。

JS组件系列——JsPlumb制作流程图及相关效果详解
      <div id="divContentLeftMenu">
<div class="sidebar-menu" id="divSidebar">
<a href="#plantmodel" onclick="Resize()" class="nav-header menu-first collapsed" data-toggle="collapse">工厂模型</a>
<ul id="plantmodel" class="nav nav-list collapse menu-second">
</ul>
<a href="#artlinemodel" onclick="Resize()" class="nav-header menu-first collapsed" data-toggle="collapse">工艺段模型</a>
<ul id="artlinemodel" class="nav nav-list collapse menu-second">
<li>
<a href="#">
<div class="node radius" id="node4" dbtype="DTO_TM_ART_LINE">
<label>工段</label>
</div>
</a>
</li>
<li>
<a href="#">
<div class="node" id="node5" dbtype="DTO_TM_ULOC">
<label>工位</label>
</div>
</a>
</li>
</ul>
</div>
</div>
<div id="divCenter"></div>
JS组件系列——JsPlumb制作流程图及相关效果详解

Js代码:

首先我们定义几个点的样式的全局变量

JS组件系列——JsPlumb制作流程图及相关效果详解
//基本连接线样式
var connectorPaintStyle = {
strokeStyle: "#1e8151",
fillStyle: "transparent",
radius: 5,
lineWidth: 2
};
// 鼠标悬浮在连接线上的样式
var connectorHoverStyle = {
lineWidth: 3,
strokeStyle: "#216477",
outlineWidth: 2,
outlineColor: "white"
};
var endpointHoverStyle = {
fillStyle: "#216477",
strokeStyle: "#216477"
};
//空心圆端点样式设置
var hollowCircle = {
DragOptions: { cursor: 'pointer', zIndex: 2000 },
endpoint: ["Dot", { radius: 7 }], //端点的形状
connectorStyle: connectorPaintStyle,//连接线的颜色,大小样式
connectorHoverStyle: connectorHoverStyle,
paintStyle: {
strokeStyle: "#1e8151",
fillStyle: "transparent",
radius: 5,
lineWidth: 2
}, //端点的颜色样式
//anchor: "AutoDefault",
isSource: true, //是否可以拖动(作为连线起点)
connector: ["Straight", { stub: [0, 0], gap: 10, cornerRadius: 5, alwaysRespectStubs: true }], //连接线的样式种类有[Bezier],[Flowchart],[StateMachine ],[Straight ]
isTarget: true, //是否可以放置(连线终点)
maxConnections: -1, // 设置连接点最多可以连接几条线
connectorOverlays: [["Arrow", { width: 10, length: 10, location: 1 }]]
};
JS组件系列——JsPlumb制作流程图及相关效果详解

然后再页面初始化完成之后注册事件

JS组件系列——JsPlumb制作流程图及相关效果详解
        $(function(){
//左边区域的draggable事件
$("#divContentLeftMenu .node").draggable({
helper: "clone",
scope: "plant"
}); //中间拖拽区的drop事件
$("#divCenter").droppable({
scope: "plant",
drop: function (event, ui) {
// 创建工厂模型到拖拽区
CreateModel(ui, $(this));
}
});
        });
JS组件系列——JsPlumb制作流程图及相关效果详解
JS组件系列——JsPlumb制作流程图及相关效果详解
//1.创建模型(参数依次为:drop事件的ui、当前容器、id、当前样式)
function CreateModel(ui, selector) {
//1.1 添加html模型
var modelid = $(ui.draggable).attr("id");
i++;
var id = modelid + i;
var cur_css = modelid;
var type = $(ui.helper).attr("dbtype");
$(selector).append('<div class="node ' + cur_css + '" id="' + id + '" dbtype="' + type + '" parentid="' + $(selector).attr("id") + '" onclick="oInitElement.GetPropertiesByType(\'' + type + '\',this)" ondblclick="InitStation().DbClick(\'' + type + '\',this)" >' + $(ui.helper).html() + '</div>');
var left = parseInt(ui.offset.left - $(selector).offset().left);
var top = parseInt(ui.offset.top - $(selector).offset().top);
$("#" + id).css("left", left).css("top", top);
//jsPlumb.setContainer($("#divCenter"));
//1.2 添加连接点
jsPlumb.addEndpoint(id, { anchors: "RightMiddle" }, hollowCircle);
jsPlumb.addEndpoint(id, { anchors: "LeftMiddle" }, hollowCircle);
jsPlumb.addEndpoint(id, { anchors: "TopCenter" }, hollowCircle);
jsPlumb.addEndpoint(id, { anchors: "BottomCenter" }, hollowCircle);
jsPlumb.draggable(id); //1.3 注册实体可draggable和resizable
$("#" + id).draggable({
containment: "parent",
start: function () {
startMove();
},
drag: function (event, ui) {
MoveSelectDiv(event, ui, id);
jsPlumb.repaintEverything();
},
stop: function () {
jsPlumb.repaintEverything();
}
}); $("#" + id).resizable({
resize: function () {
jsPlumb.repaintEverything();
},
stop: function () {
jsPlumb.repaintEverything();
//oInitElement.SendPropRequest("DTO_TM_PLANT", $(this));
}
});
return id;
};
JS组件系列——JsPlumb制作流程图及相关效果详解

重点来看看这一句:

jsPlumb.addEndpoint(id, { anchors: "RightMiddle" }, hollowCircle);

调用了JsPlumb里面的addEndpoint方法,第一个参数表示页面标签的id,第一个表示连线点的位置(RightMiddle、LeftMiddle、TopCenter、BottomCenter四个选项);第三参数表示点的样式以及连线的样式。没调用依次addEndpoint方法,元素上面就会多一个连线的节点。关于hollowCircle里面各个参数的意义,可以查看api。

还有一句多个地方都看到了:

jsPlumb.repaintEverything();

看字面意思大概能知道这句是干什么的,修复所有。当在中间区域拖动元素的时候,如果不带这一句,节点不会跟着元素一起移动。加上之后节点才会跟随标签移动。至此,最基础的JsPlumb连线就完成了。源码在下篇。


下    篇

前言:在上篇介绍了下JsPlumb在浏览器里面画流程图的效果展示,以及简单的JsPlumb代码示例。这篇还是接着来看看各个效果的代码说明。

一、设置连线的样式和颜色效果代码示例

大概的效果如图:

JS组件系列——JsPlumb制作流程图及相关效果详解

这些效果看着很简单,那么,我们如何用代码去实现它呢。上章我们说过,JsPlumb的连线样式是由点的某些属性决定的,既然如此,我们就通过设置点的样式来动态改变连线的样式即可。来看代码:

首先来看看连线类型的那个select

JS组件系列——JsPlumb制作流程图及相关效果详解
 <div id="btn_linetype" class="divMenuBtn btn-default btn">
连线类型:
  <select id="sel_linetype" style="width:80px;height:20px">
    <option value="2">直线</option>
    <option value="1">折线</option>
    <option value="3">曲线</option>
  </select>
</div>
JS组件系列——JsPlumb制作流程图及相关效果详解

在页面初始化的时候注册select的change事件

JS组件系列——JsPlumb制作流程图及相关效果详解
//全局的空心圆端点样式设置
var hollowCircle = {
DragOptions: { cursor: 'pointer', zIndex: 2000 },
endpoint: ["Dot", { radius: 7 }], //端点的形状
connectorStyle: connectorPaintStyle,//连接线的颜色,大小样式
connectorHoverStyle: connectorHoverStyle,
paintStyle: {
strokeStyle: "#1e8151",
fillStyle: "transparent",
radius: 5,
lineWidth: 2
}, //端点的颜色样式
//anchor: "AutoDefault",
isSource: true, //是否可以拖动(作为连线起点)
connector: ["Straight", { stub: [0, 0], gap: 10, cornerRadius: 5, alwaysRespectStubs: true }], //连接线的样式种类有[Bezier],[Flowchart],[StateMachine ],[Straight ]
isTarget: true, //是否可以放置(连线终点)
maxConnections: -1, // 设置连接点最多可以连接几条线
connectorOverlays: [["Arrow", { width: 10, length: 10, location: 1 }]]
};
JS组件系列——JsPlumb制作流程图及相关效果详解
JS组件系列——JsPlumb制作流程图及相关效果详解
//页面初始化完成之后
$(function () {
//连线样式下拉框的change事件
$("#sel_linetype").change(function () {
var strlinetype = "";
var strlinecolor = "";
//设置新添加元素的节点的连线样式
//直线的样式和样色
if ($(this).val() == "1") {
strlinetype = "Flowchart";
strlinecolor = "red";
hollowCircle.connector = ["Flowchart", { stub: [0, 0], gap: 10, cornerRadius: 5, alwaysRespectStubs: true }];
}
//折线的样式和颜色
else if ($(this).val() == "2") {
strlinetype = "Straight";
strlinecolor = "green";
hollowCircle.connector = ["Straight", { stub: [0, 0], gap: 10, cornerRadius: 5, alwaysRespectStubs: true }];
}
//曲线的样式和颜色
else if ($(this).val() == "3") {
strlinetype = "Bezier";
strlinecolor = "orange";
hollowCircle.connector = ["Bezier", { stub: [0, 0], gap: 10, cornerRadius: 5, alwaysRespectStubs: true }];
}
//设置已经存在的所有的连接点的连线样式
var arrnode = $("#divCenter").find(".node");
for (var i = 0; i < arrnode.length; i++) {
var arrendpoints = jsPlumb.getEndpoints($(arrnode[i]).attr("id"));
if (arrendpoints == undefined || arrendpoints == null) {
return;
}
var oconnector = arrendpoints[0].connector;
if (oconnector == null || oconnector == undefined) {
return;
}
oconnector[0] = strlinetype;
var oconnectstyle = arrendpoints[0].connectorStyle;
if (oconnectstyle == null || oconnectstyle == undefined) {
return;
}
oconnectstyle.strokeStyle = strlinecolor;
}
});
});
JS组件系列——JsPlumb制作流程图及相关效果详解

其实也就几行代码,设置已经存在和将要拖动到界面上面的端点的连线样式。

二、全选、全选拖动效果代码示例

可以选中元素,批量拖动元素和连线,大概效果:

JS组件系列——JsPlumb制作流程图及相关效果详解

JS组件系列——JsPlumb制作流程图及相关效果详解

看看实现代码:

1、初始化的时候注册可选中

JS组件系列——JsPlumb制作流程图及相关效果详解
$(function () {
var oRegionSelect = new RegionSelect({
region: '#divCenter div.node',
selectedClass: 'seled',
parentId: "divCenter"
});
oRegionSelect.select();
});
JS组件系列——JsPlumb制作流程图及相关效果详解

2、选中相关方法

var _selectedRegions = [];
//var selProp; function RegionSelect(selRegionProp) {
//selProp = selRegionProp;
this.regions = [];
this.selProp = selRegionProp;
this.InitRegions(selRegionProp);
this.selectedClass = selRegionProp["selectedClass"];
this.selectedRegion = [];
this.selectDiv = null;
this.startX = null;
this.startY = null;
this.parentId = selRegionProp["parentId"];
} RegionSelect.prototype.InitRegions = function () {
var _self = this;
_self.regions = [];
var _regions = document.getElementsBySelector(_self.selProp["region"]);//$("#divCenter > .node");// var bSelect = true;
if (_regions && _regions.length > 0) {
for (var i = 0; i < _regions.length; i++) {
_regions[i].onmousedown = function () {
bSelect = false;
var evt = window.event || arguments[0];
if (!evt.shiftKey && !evt.ctrlKey) {
if ($.inArray(this, _selectedRegions) === -1) {
// 清空所有select样式
_self.clearSelections(_regions);
this.className += " " + _self.selectedClass;
// 清空selected数组,并加入当前select中的元素
_selectedRegions = [];
_selectedRegions.push(this);
}
} else {
if (this.className.indexOf(_self.selectedClass) == -1) {
this.className += " " + _self.selectedClass;
_selectedRegions.push(this);
} else {
this.className = this.className.replaceAll(_self.selectedClass, "");
_selectedRegions.remove(this);
}
}
clearEventBubble(evt);
}
this.regions.push(_regions[i]);
}
} if (bSelect) {
// 清空所有select样式
_self.clearSelections(_regions);
// 清空selected数组,并加入当前select中的元素
_selectedRegions = [];
}
} RegionSelect.prototype.select = function () {
var _self = this;
var sDivId = _self.parentId;
var intMousePosition = [0, 0];
var intOriginalPosition = [0, 0];
var parentWidth = parseInt(document.getElementById(sDivId).parentElement.offsetWidth);
var parentHeight = parseInt(document.getElementById(sDivId).parentElement.offsetHeight);
addEvent("mousedown", function () {
var evt = window.event || arguments[0];
var buttonType = evt.buttons || evt.button;
if (evt.target != undefined) {
if (evt.target.id !== sDivId) return;
}
if (evt.srcElement != undefined) {
if (evt.srcElement.id !== sDivId) return;
}
if (evt.buttons == undefined && buttonType == 0){
_self.onBeforeSelect(evt, sDivId);
}
if (buttonType === 1) {
_self.onBeforeSelect(evt, sDivId);
}
if (buttonType === 2) {
intMousePosition = [evt.clientX, evt.clientY];
var movX = parseInt(GetStyle(document.getElementById(sDivId), "left"));
var movY = parseInt(GetStyle(document.getElementById(sDivId), "top"));
intOriginalPosition = [movX, movY];
document.getElementById(sDivId).style.cursor = "move";
}
clearEventBubble(evt);
}, document); addEvent("mousemove", function () {
var evt = window.event || arguments[0];
//if (evt.target.id !== sDivId) return;
var buttonType = evt.buttons || evt.button;
if (evt.buttons == undefined && buttonType == 0) {
_self.onSelect(evt, sDivId);
}
if (buttonType === 1) {
_self.onSelect(evt, sDivId);
}
if (buttonType === 2) {
var newX = intOriginalPosition[0] + evt.clientX - intMousePosition[0];
var newY = intOriginalPosition[1] + evt.clientY - intMousePosition[1];
if (newX >= 0) {
newX = 0;
}
if (newY >= 0) {
newY = 0;
}
$("#" + sDivId).css("left", newX + "px");
$("#" + sDivId).css("top", newY + "px");
$("#" + sDivId).css("width", (parentWidth-newX) + "px");
$("#" + sDivId).css("height", (parentHeight-newY) + "px"); }
clearEventBubble(evt);
}, document); addEvent("mouseup", function () {
var evt = window.event || arguments[0];
var buttonType = evt.buttons || evt.button;
if (evt.buttons == undefined && buttonType == 0) {
}
if (buttonType === 1) {
}
document.getElementById(sDivId).style.cursor = "default";
_self.onEnd();
}, document);
} RegionSelect.prototype.onBeforeSelect = function (evt, sDivId) {
// 创建模拟 选择框
var _self = this;
_self.InitRegions(_self.selProp);
if (!document.getElementById("selContainer")) {
this.selectDiv = document.createElement("div");
this.selectDiv.style.cssText = "position:absolute;width:0px;height:0px;font-size:0px;margin:0px;padding:0px;border:1px dashed #0099FF;background-color:#C3D5ED;z-index:1000;filter:alpha(opacity:60);opacity:0.6;display:none;";
this.selectDiv.id = "selContainer";
document.getElementById(sDivId).appendChild(this.selectDiv);
} else {
this.selectDiv = document.getElementById("selContainer");
} this.startX = posXY(evt, sDivId).x;
this.startY = posXY(evt, sDivId).y;
this.isSelect = true; } RegionSelect.prototype.onSelect = function (evt, sDivId) {
var self = this;
if (self.isSelect) {
if (self.selectDiv.style.display == "none") self.selectDiv.style.display = ""; var posX = posXY(evt, sDivId).x;
var poxY = posXY(evt, sDivId).y;
self.selectDiv.style.left = Math.min(posX, this.startX) + "px";
self.selectDiv.style.top = Math.min(poxY, this.startY) + "px";
self.selectDiv.style.width = Math.abs(posX - this.startX) + "px";
self.selectDiv.style.height = Math.abs(poxY - this.startY) + "px"; var regionList = self.regions;
for (var i = 0; i < regionList.length; i++) {
if (self.selectDiv.parentNode.id !== regionList[i].parentNode.id) continue;
var r = regionList[i], sr = self.innerRegion(self.selectDiv, r);
if (sr && r.className.indexOf(self.selectedClass) == -1) {
r.className = r.className + " " + self.selectedClass;
_selectedRegions.push(r);
} else if (!sr && r.className.indexOf(self.selectedClass) != -1) {
r.className = r.className.replaceAll(self.selectedClass, "");
_selectedRegions.remove(r);
} }
}
} RegionSelect.prototype.onEnd = function () {
var self = this;
if (self.selectDiv) {
self.selectDiv.style.display = "none";
}
this.isSelect = false;
//_selectedRegions = this.selectedRegion;
} // 判断一个区域是否在选择区内
RegionSelect.prototype.innerRegion = function (selDiv, region) {
var s_top = parseInt(selDiv.style.top);
var s_left = parseInt(selDiv.style.left);
var s_right = s_left + parseInt(selDiv.offsetWidth);
var s_bottom = s_top + parseInt(selDiv.offsetHeight); var r_top = parseInt(region.offsetTop);
var r_left = parseInt(region.offsetLeft);
var r_right = r_left + parseInt(region.offsetWidth);
var r_bottom = r_top + parseInt(region.offsetHeight); var t = Math.max(s_top, r_top);
var r = Math.min(s_right, r_right);
var b = Math.min(s_bottom, r_bottom);
var l = Math.max(s_left, r_left); if (b > t + 5 && r > l + 5) {
return region;
} else {
return null;
} } RegionSelect.prototype.clearSelections = function (regions) {
for (var i = 0; i < regions.length; i++) {
regions[i].className = regions[i].className.replaceAll(this.selectedClass, "");
}
} function getSelectedRegions() {
return _selectedRegions;
} /*-------------------------------------- 区域选择方法结束 --------------------------------------------*/ function showSelDiv() {
var selInfo = "";
var arr = getSelectedRegions();
for (var i = 0; i < arr.length; i++) {
selInfo += arr[i].innerHTML + "\n";
} alert("共选择 " + arr.length + " 个文件,分别是:\n" + selInfo); } function MoveSelectDiv(event, ui,id) {
var arr = getSelectedRegions();
var iMoveLeft = ui.position.left - ui.originalPosition.left;
var iMoveTop = ui.position.top - ui.originalPosition.top; for (var i = 0; i < arr.length; i++) {
//if (arr[i].id === id) continue; if (arr[i].parentNode.id !== document.getElementById(id).parentNode.id) continue;
var iLeft = parseInt($(arr[i]).attr("bLeft"));
var iTop = parseInt($(arr[i]).attr("bTop"));
$(arr[i]).css("left", (iLeft + iMoveLeft) + "px");
$(arr[i]).css("top", (iTop + iMoveTop) + "px");
}
} function startMove() {
var arr = getSelectedRegions();
for (var i = 0; i < arr.length; i++) {
$(arr[i]).attr("bLeft", $(arr[i]).position().left);
$(arr[i]).attr("bTop", $(arr[i]).position().top);
}
}

选中相关方法

三、对齐、旋转代码示例

//左对齐
function SelectAlignLeft() {
var arr = getSelectedRegions();
var iLeft = 0;
var id = ""; for (var i = 0; i < arr.length; i++) {
if (id === "") id = arr[i].parentNode.id;
if (id !== arr[i].parentNode.id) continue;
if ($(arr[i]).position().left<iLeft||iLeft===0) {
iLeft = $(arr[i]).position().left;
}
} for (var j = 0; j < arr.length; j++) {
if (id !== arr[j].parentNode.id) continue;
$(arr[j]).css("left", iLeft + "px");
} jsPlumb.repaintEverything();
} //居中对齐
function SelectAlignCenter() {
var arr = getSelectedRegions();
var iLeft = 0;
var id = ""; for (var i = 0; i < arr.length; i++) {
if (id === "") id = arr[i].parentNode.id;
if (id !== arr[i].parentNode.id) continue;
if ($(arr[i]).position().left < iLeft || iLeft === 0) {
iLeft = $(arr[i]).position().left + parseInt(GetStyle(arr[i],"width")) / 2;
}
} for (var j = 0; j < arr.length; j++) {
if (id !== arr[j].parentNode.id) continue;
$(arr[j]).css("left", (iLeft - parseInt(GetStyle(arr[j],"width")) / 2) + "px");
} jsPlumb.repaintEverything();
}
//右对齐
function SelectAlignRight() {
var arr = getSelectedRegions();
var iLeft = 0;
var id = ""; for (var i = 0; i < arr.length; i++) {
if (id === "") id = arr[i].parentNode.id;
if (id !== arr[i].parentNode.id) continue;
if ($(arr[i]).position().left + parseInt(GetStyle(arr[i], "width")) > iLeft || iLeft === 0) {
iLeft = $(arr[i]).position().left + parseInt(GetStyle(arr[i], "width"));
}
} for (var j = 0; j < arr.length; j++) {
if (id !== arr[j].parentNode.id) continue;
$(arr[j]).css("left", (iLeft - parseInt(GetStyle(arr[j], "width"))) + "px");
} jsPlumb.repaintEverything();
} //上对齐
function SelectAlignTop() {
var arr = getSelectedRegions();
var iTop = 0;
var id = ""; for (var i = 0; i < arr.length; i++) {
if (id === "") id = arr[i].parentNode.id;
if (id !== arr[i].parentNode.id) continue;
if ($(arr[i]).position().top < iTop || iTop === 0) {
iTop = $(arr[i]).position().top;
}
} for (var j = 0; j < arr.length; j++) {
if (id !== arr[j].parentNode.id) continue;
$(arr[j]).css("top", iTop + "px");
} jsPlumb.repaintEverything();
} //垂直居中
function SelectAlignMiddle() {
var arr = getSelectedRegions();
var iTop = 0;
var id = ""; for (var i = 0; i < arr.length; i++) {
if (id === "") id = arr[i].parentNode.id;
if (id !== arr[i].parentNode.id) continue;
if ($(arr[i]).position().top + parseInt(GetStyle(arr[i], "height")) / 2 < iTop || iTop === 0) {
iTop = $(arr[i]).position().top + parseInt(GetStyle(arr[i], "height")) / 2;
}
} for (var j = 0; j < arr.length; j++) {
if (id !== arr[j].parentNode.id) continue;
$(arr[j]).css("top", (iTop - parseInt(GetStyle(arr[j], "height")) / 2) + "px");
} jsPlumb.repaintEverything();
} //下对齐
function SelectAlignBottom() {
var arr = getSelectedRegions();
var iTop = 0;
var id = ""; for (var i = 0; i < arr.length; i++) {
if (id === "") id = arr[i].parentNode.id;
if (id !== arr[i].parentNode.id) continue;
if ($(arr[i]).position().top + parseInt(GetStyle(arr[i], "height")) > iTop || iTop === 0) {
iTop = $(arr[i]).position().top + parseInt(GetStyle(arr[i], "height"));
}
} for (var j = 0; j < arr.length; j++) {
if (id !== arr[j].parentNode.id) continue;
$(arr[j]).css("top", (iTop - parseInt(GetStyle(arr[j], "height"))) + "px");
} jsPlumb.repaintEverything();
} //上下靠拢
function SelectUpColse() {
var arr = getSelectedRegions();
var iTop = 0;
var id = "";
for (var i = 0; i < arr.length; i++) {
if (id === "") id = arr[i].parentNode.id;
if (id !== arr[i].parentNode.id) continue;
if (iTop === 0) iTop = $(arr[i]).position().top;
$(arr[i]).css("top", iTop + "px");
iTop += parseInt(GetStyle(arr[i], "height"));
} jsPlumb.repaintEverything();
} //左右靠拢
function SelectLeftColse() {
var arr = getSelectedRegions();
var iLeft = 0;
var id = "";
for (var i = 0; i < arr.length; i++) {
if (id === "") id = arr[i].parentNode.id;
if (id !== arr[i].parentNode.id) continue;
if (iLeft === 0) iLeft = $(arr[i]).position().left;
$(arr[i]).css("left", iLeft + "px");
iLeft += parseInt(GetStyle(arr[i], "width"));
} jsPlumb.repaintEverything(); } //同高
function SelectSameHeight() {
var arr = getSelectedRegions();
var iHeigth = 0;
var id = "";
for (var i = 0; i < arr.length; i++) {
if (id === "") id = arr[i].parentNode.id;
if (id !== arr[i].parentNode.id) continue;
if (iHeigth === 0) iHeigth = parseInt(GetStyle(arr[i], "height"));
$(arr[i]).css("height", iHeigth+"px");
} jsPlumb.repaintEverything();
} //同宽
function SelectSameWidth() {
var arr = getSelectedRegions();
var iWidth = 0;
var id = "";
for (var i = 0; i < arr.length; i++) {
if (id === "") id = arr[i].parentNode.id;
if (id !== arr[i].parentNode.id) continue;
if (iWidth === 0) iWidth = parseInt(GetStyle(arr[i], "width"));
$(arr[i]).css("width", iWidth + "px");
} jsPlumb.repaintEverything(); } //旋转
function SelectClockwise(index) {
var arr = getSelectedRegions();
//var iWidth = 0;
//var id = "";
for (var i = 0; i < arr.length; i++) {
//if (id === "") id = arr[i].parentNode.id;
//if (id !== arr[i].parentNode.id) continue;
var sIndex= arr[i].style.transform.replace("rotate(", "").replace("deg)", "");
var iNum = 0;
if (sIndex) iNum = parseInt(sIndex);
$(arr[i]).css("transform", "rotate(" + (iNum + index)%360 + "deg)"); var points = jsPlumb.getEndpoints(arr[i]);
} jsPlumb.repaintEverything(); }
//删除选中
function DeleteSelect() {
var arr = getSelectedRegions();
for (var i = 0; i < arr.length; i++) {
jsPlumb.remove(arr[i],true);
//var points = jsPlumb.getEndpoints(arr[i]);
//for (var j = 0; j < points.length; j++) {
// jsPlumb.deleteEndpoint(points[j]);
//}
//arr[i].parentNode.removeChild(arr[i]);
} jsPlumb.repaintEverything(); } function GetStyle(obj, attr) {
if (obj.currentStyle) {
return obj.currentStyle[attr]; //只适用于IE
}
else {
return getComputedStyle(obj, false)[attr]; //只适用于FF,Chrome,Safa
}
return obj.style[attr]; //本人测试在IE和FF下没有用,chrome有用
}

对齐、旋转代码示例

代码可能有点乱,待整理。上章有博友就找我要过源码,这次出来一个初级的版本,还是把源码贴出来。有兴趣可以看看。源码下载

出处:

http://www.cnblogs.com/landeanfen/p/4959584.html

http://www.cnblogs.com/landeanfen/p/4971211.html

上一篇:[整理]LumiSoft.Net 开源组件


下一篇:Ajax实现异步刷新验证用户名是否已存在