采用d3开发流程设计器(六)通过拖拽选中多个节点,然后拖动调整位置

11 篇文章 14 订阅
7 篇文章 2 订阅

需求:
1、通过拖拽选中多个节点,然后进行位置调整。
2、选中多个节点,点击删除来进行多个节点删除。

效果图:
在这里插入图片描述
选中多个节点进行拖拽移动。

关键代码:
第一步拖拽的时候创建一个临时的rect,并且设置透明度为0.7


/**
 * 初始化一个用于拖拽都rect区块
 * @param containerId
 */
FlowDragSelArea.prototype.init=function (containerId) {
    this.flowDesCtl.svgObj.append("rect")
        .attr("rx", '4')
        .attr("ry", '4')
        .attr("x", '-100')
        .attr("y", '0')
        .attr("width", 90)
        .attr("height", 50)
        .attr("opacity", 0.7)
        .attr("stroke-dasharray",'2')
        .attr("cursor", "normal")
        .attr("nodeType", "nodeTextDrag")
        .attr("fill", "#F6F6F6")
        .attr("stroke", "#999")
        .style("cursor", `move`)
        .attr("stroke-width", "1")
        .attr("id", () => {
            return "selAreaDrag" + containerId + "";
        })
    ;
};

第二步:拖拽结束去判断坐标,如果在这范围之内的节点进行选中操作

/**
 * 选中区域
 */
FlowDragSelArea.prototype.selAreaNode=function () {
    let selRreaNode=window.d3.select("#selAreaDrag"+this.flowDesCtl.containerId);
    if(selRreaNode==null){
        return void(0);
    }
    let startX=selRreaNode.attr("x");
    let startY=selRreaNode.attr("y");
    let endX=parseFloat(selRreaNode.attr("x"))+parseFloat(selRreaNode.attr("width"));
    let endY=parseFloat(selRreaNode.attr("y"))+parseFloat(selRreaNode.attr("height"));
    //对普通节点进行选中
    for(let nodeId in this.flowDesCtl.flowRectNode.nodes){
        let oldTransform=window.d3.select("#"+nodeId).attr("transform");
        let nodePos=flowDesUtils.prseTransform(oldTransform);
        if(parseFloat(nodePos.x)>startX&&nodePos.x<parseFloat(endX)){
            if(parseFloat(nodePos.y)>startY&&nodePos.y<parseFloat(endY)){
                //显示当前节点的拖拽边框
                this._activeBorder(nodeId);
                this.selNodes[nodeId]=this.flowDesCtl.flowRectNode.nodes[nodeId];
            }
        }
    }
    //对图像节点也进行选中
    for(let nodeId in this.flowDesCtl.flowCircleNode.nodes){
        let oldTransform=window.d3.select("#"+nodeId).attr("transform");
        let nodePos=flowDesUtils.prseTransform(oldTransform);
        if(parseFloat(nodePos.x)>startX&&nodePos.x<parseFloat(endX)){
            if(parseFloat(nodePos.y)>startY&&nodePos.y<parseFloat(endY)){
                //显示当前节点的拖拽边框
                this._activeBorder(nodeId);
                this.selNodes[nodeId]=this.flowDesCtl.flowCircleNode.nodes[nodeId];
            }
        }
    }
};

_activeBorder 将选中的节点进行选中状态创建

/**
 * 对节点进行选中操作
 * @private
 */
FlowDragSelArea.prototype._activeBorder=function (nodeId) {
    this.padding=10;
    let nodeG=window.d3.select(`#${nodeId}`);
    if(nodeG!=null){
        let nodePos=flowDesUtils.prseTransform(nodeG.attr("transform"));

        //设置拖拽边框节点的位置以及相应大小
        let showNodeDom=window.d3.select(`#${nodeId}_show_real`);
        let rectWidth=parseFloat(showNodeDom.attr("width"));
        let rectHeight=parseFloat(showNodeDom.attr("height"));
        let showNodePos=flowDesUtils.prseTransform(showNodeDom.attr("transform"));
        //创建选中对容器
        let borderNode=this.initSelSvgDom({nodeId,nodePos,rectWidth,rectHeight});

        let showRelNode=window.d3.select("#drage_size_rect_"+nodeId);
        showRelNode.attr("width", rectWidth+parseFloat(this.padding))
            .attr("height", rectHeight+parseFloat(this.padding))
            .attr("fill-opacity", 1)
            .attr("stroke-opacity", 1)
            .attr("transform", `translate(${parseFloat(showNodePos.x)-this.padding/2},${parseFloat(showNodePos.y)-this.padding/2})`)
        ;
        //绘制top 第一个 top-left拖拽节点
        this._setDragNodePos({
            borderNode,
            nodeId,
            x:showNodePos.x-this.padding,
            y:showNodePos.y-this.padding,
            dragType: "nw"
        });
        //绘制top 第二个 top-center拖拽节点
        this._setDragNodePos({
            borderNode,
            nodeId,
            x: showNodePos.x+rectWidth / 2,
            y: showNodePos.y-this.padding,
            dragType: "n"
        });
        //绘制top 第三个 top-right拖拽节点
        this._setDragNodePos({
            borderNode,
            nodeId,
            x: showNodePos.x+rectWidth+this.padding/2,
            y: showNodePos.y-this.padding,
            dragType: "ne"
        });


        //绘制center 第一个拖拽节点 center-left
        this._setDragNodePos({
            borderNode,
            nodeId,
            x:showNodePos.x-this.padding,
            y: showNodePos.y+rectHeight/2,
            dragType: "w"
        });
        //绘制center 第二个拖拽节点 center-right
        this._setDragNodePos({
            borderNode,
            nodeId,
            x: showNodePos.x+rectWidth+this.padding/2,
            y: showNodePos.y+rectHeight/2,
            dragType: "e"
        });


        //绘制bottom 第一个 bottom-left拖拽节点
        this._setDragNodePos({
            borderNode,
            nodeId,
            x:showNodePos.x-this.padding,
            y:showNodePos.y+rectHeight+this.padding/2,
            dragType: "sw"
        });
        //绘制bottom 第二个 bottom-center拖拽节点
        this._setDragNodePos({
            borderNode,
            nodeId,
            x: showNodePos.x+rectWidth/2,
            y: showNodePos.y+rectHeight+this.padding/2,
            dragType: "s"
        });
        //绘制bottom 第三个 bottom-right拖拽节点
        this._setDragNodePos({
            borderNode,
            nodeId,
            x: showNodePos.x+rectWidth+this.padding/2,
            y: showNodePos.y+rectHeight+this.padding/2,
            dragType: "se"
        });
    }
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值