JS組件系列——JsPlumb制作流程圖及相關效果詳解


上    篇

前言:之前項目里面用到了Web里面的拖拽流程圖的技術JsPlumb,其實真不算難,不過項目里面用HTML做的一些類似flash的效果,感覺還不錯,在此分享下。

Jsplumb官網:https://jsplumbtoolkit.com

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

一、效果圖展示

 1、從左邊拖動元素到中間區域,然后連線

 2、連線類型可以自定義:這里定義為直線、折線、曲線。實際項目中根據業務我們定義為分裝線、分裝支線、總裝線等

 3、鼠標拖動區域選中元素,並且選中元素統一拖動位置。

 4、對選中的元素左對齊。

5、對選中元素居中對齊

6、右對齊

7、上對齊

8、垂直居中對齊

9、下對齊

10、根據第一個選中的元素上下靠攏

11、根據第一個選中的元素左右靠攏

12、根據第一個選中的元素同高

13、根據第一個選中的元素同寬

14、選中元素順時針旋轉,點擊一次旋轉45度

15、選中元素逆時針旋轉。

16、選中統一刪除元素以及元素上面的連線

這里很多效果其實在項目中作用並不太大,很多單純就是為了展示用的。沒辦法,領導要求,我們就只有做嘍。

二、代碼詳解

 這里涉及的效果比較多,可能要分多篇來介紹。這篇還是來看看構造流程圖的核心技術: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>表示中間區域容器。

復制代碼
      <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代碼:

首先我們定義幾個點的樣式的全局變量

復制代碼
//基本連接線樣式
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 }]]
};
復制代碼

然后再頁面初始化完成之后注冊事件

復制代碼
        $(function(){
                //左邊區域的draggable事件
                $("#divContentLeftMenu .node").draggable({
                    helper: "clone",
                    scope: "plant"
                });

                //中間拖拽區的drop事件
                $("#divCenter").droppable({
                    scope: "plant",
                    drop: function (event, ui) {
                        // 創建工廠模型到拖拽區
                        CreateModel(ui, $(this));
                    }
                });
        });    
復制代碼
復制代碼
//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; };
復制代碼

重點來看看這一句:

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

調用了JsPlumb里面的addEndpoint方法,第一個參數表示頁面標簽的id,第一個表示連線點的位置(RightMiddle、LeftMiddle、TopCenter、BottomCenter四個選項);第三參數表示點的樣式以及連線的樣式。沒調用依次addEndpoint方法,元素上面就會多一個連線的節點。關於hollowCircle里面各個參數的意義,可以查看api。

還有一句多個地方都看到了:

jsPlumb.repaintEverything();

看字面意思大概能知道這句是干什么的,修復所有。當在中間區域拖動元素的時候,如果不帶這一句,節點不會跟着元素一起移動。加上之后節點才會跟隨標簽移動。至此,最基礎的JsPlumb連線就完成了。源碼在下篇。

 


下    篇

前言:在上篇介紹了下JsPlumb在瀏覽器里面畫流程圖的效果展示,以及簡單的JsPlumb代碼示例。這篇還是接着來看看各個效果的代碼說明。

一、設置連線的樣式和顏色效果代碼示例

大概的效果如圖:

這些效果看着很簡單,那么,我們如何用代碼去實現它呢。上章我們說過,JsPlumb的連線樣式是由點的某些屬性決定的,既然如此,我們就通過設置點的樣式來動態改變連線的樣式即可。來看代碼:

首先來看看連線類型的那個select

復制代碼
 <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>
復制代碼

在頁面初始化的時候注冊select的change事件

復制代碼
//全局的空心圓端點樣式設置
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 }]]
};
復制代碼
復制代碼
//頁面初始化完成之后
$(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;
        }
    });
});
復制代碼

其實也就幾行代碼,設置已經存在和將要拖動到界面上面的端點的連線樣式。

二、全選、全選拖動效果代碼示例

 可以選中元素,批量拖動元素和連線,大概效果:

看看實現代碼:

1、初始化的時候注冊可選中

復制代碼
$(function () {
    var oRegionSelect = new RegionSelect({
        region: '#divCenter div.node',
        selectedClass: 'seled',
        parentId: "divCenter"
    });
    oRegionSelect.select();
});
復制代碼

 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM