设计器快捷调整间距

This commit is contained in:
mrs_12345@163.com 2022-07-22 11:04:16 +08:00
parent 9b2914639a
commit 54784c9e46
4 changed files with 494 additions and 98 deletions

View File

@ -919,12 +919,12 @@
<li ac="selectall">全选
<div class="extend">Ctrl+A</div>
</li>
<!-- <li ac="selectVertical">调整垂直间距-->
<!-- <div class="extend"></div>-->
<!-- </li>-->
<!-- <li ac="selectHorizontal">调整水平间距-->
<!-- <div class="extend"></div>-->
<!-- </li>-->
<li ac="selectVertical">调整垂直间距
<div class="extend"></div>
</li>
<li ac="selectHorizontal">调整水平间距
<div class="extend"></div>
</li>
<li class="devider devi_selectall"></li>
<li ac="drawline">
<div class="ico linkertype_normal"></div>创建连线
@ -935,8 +935,8 @@
<div class="extend"></div>
</li>
</ul>
<!-- <div id="designer_subline1" style="position:absolute;"></div>-->
<!-- <div id="designer_subline2" style="position:absolute;"></div>-->
<div id="designer_subline1" style="position:absolute;"></div>
<div id="designer_subline2" style="position:absolute;"></div>
</div>
</div>
<div id="shape_img_container"></div>

View File

@ -1,5 +1,7 @@
// 右键菜单添加"属性"和"流程属性" 功能
Designer.contextMenu.show = function(x, y) {
$('#designer_subline1').hide()
$('#designer_subline2').hide() // 隐藏快捷调整间距辅助线
this.menuPos.x = x;
this.menuPos.y = y;
var menu = $("#designer_contextmenu");

View File

@ -71,15 +71,9 @@ Designer.addFunction("selectAll", function(){
/**
* 设计器方法调节垂直间距
*/
Designer.addFunction("selectVertical", function(menuPos){
var selectedIds = [];
var lineArr = []
var shapeArr = []
var menuY = menuPos.y
var shapes = Model.define.elements;
console.log(shapes)
var subline1 = $('#designer_subline1')
Designer.addFunction("selectVertical", function(menuPos) {
var sublinePos = menuPos.y
var subline1 = $('#designer_subline1') // 初始位置
var subline2 = $('#designer_subline2')
subline1.css({
display : "block",
@ -89,7 +83,7 @@ Designer.addFunction("selectVertical", function(menuPos){
borderStyle:'dotted',
borderWidth: '1px',
left: 0,
top : menuY
top : sublinePos
});
subline2.css({
display : "block",
@ -99,134 +93,534 @@ Designer.addFunction("selectVertical", function(menuPos){
borderStyle:'dotted',
borderWidth: '1px',
left: 0,
top : menuY,
top : sublinePos,
cursor: 'move'
});
var obj = filterShapeAndLine('y',sublinePos)
var container = $("#canvas_container");
var canvas = $("#designer_canvas");
subline2.bind('mousedown.drag',function (b) {
container.bind('mousemove.drag',function (e) {
var newPos = Utils.getRelativePos(e.pageX, e.pageY, canvas);
if (newPos.y >= menuY) {
if (newPos.y >= sublinePos) { // 增加
subline1.css({
borderColor: 'rgb(114,253,107)',
backgroundColor: 'rgba(114,253,107,0.5)',
height: newPos.y - menuY
height: newPos.y - sublinePos
})
subline2.css({
backgroundColor: 'translate',
borderColor: 'rgb(114,253,107)',
backgroundColor: 'transparent',
height: 0
})
} else {
subline2.css({
top : newPos.y,
});
} else { // 减少
let maxY = obj.passedShapesEdge - obj.sublineSideEdge > 0 ? obj.passedShapesEdge : obj.sublineSideEdge
if (newPos.y < maxY) {
newPos.y = maxY
}
subline1.css({
backgroundColor: 'translate',
borderColor: 'rgb(246,163,163)',
backgroundColor: 'transparent',
height: 0
})
subline2.css({
borderColor: 'rgb(246,163,163)',
backgroundColor: 'rgba(246,163,163,0.5)',
height: menuY - newPos.y
height: sublinePos - newPos.y
})
subline2.css({
top : newPos.y,
});
}
subline2.css({
top : newPos.y,
});
$(document).unbind("mouseup.drop").bind("mouseup.drop",
function() {
function(e) {
var height1 = subline1.height()
var height2 = subline2.height()
if (height1 != 0 && height2 == 0) { // 增加
moveShapeAndFile('y',sublinePos,height1)
} else if (height1 == 0 && height2 != 0) { // 减少
moveShapeAndFile('y',sublinePos,0-height2)
}
subline1.css({
backgroundColor: 'translate',
borderColor: '#333',
backgroundColor: 'transparent',
height: 0
})
subline2.css({
backgroundColor: 'translate',
borderColor: '#333',
backgroundColor: 'transparent',
height: 0
})
subline1.hide()
subline2.hide()
$(document).unbind("mouseup.drop")
})
})
$(document).bind('mouseup.drag',function () {
container.unbind("mousemove.drag");
// subline2.unbind("mousedown.drag");
subline2.unbind("mousedown.drag");
$(document).unbind("mouseup.drag");
})
})
for(var shapeId in shapes){
if (shapes[shapeId].points == undefined) {
shapeArr.push(shapes[shapeId])
} else {
lineArr.push(shapes[shapeId])
}
}
for (var i = 0; i < shapeArr.length; i++) {
if (shapeArr[i].props.y + shapeArr[i].props.h >= menuY) {
selectedIds.push(shapeArr[i].id)
}
}
for (var i = 0; i < lineArr.length; i++) {
if (lineArr[i].from.y >= menuY || lineArr[i].to.y >= menuY) {
selectedIds.push(lineArr[i].id)
}
}
// Utils.selectShape(selectedIds);
// for (var i = 0; i < selectedIds.length; i++) {
// N(selectedIds[i])
// $(".shape_contour[forshape=" + selectedIds[i].id + "]").css({
// left: selectedIds[i].props.x.toScale(),
// top: selectedIds[i].props.y.toScale()
// })
// }
// var K = Utils.getSelectedLinkerIds();
// if (selectedIds.length == 1 && K.length == 1) {
// return
// }
// if (K.length > 0) {
// var I = Utils.getSelectedIds();
// Designer.painter.drawControls(I)
// } else {
// var E = $("#shape_controls");
// E.css({
// left: parseFloat(E.css("left")),
// top: parseFloat(E.css("top")) + 100
// })
// }
// var F = $("#shape_controls").position();
// if (F && Utils.getSelected().length > 0) {
// Designer.op.showTip("X: " + Math.round(F.left.restoreScale()) + "&nbsp;&nbsp;Y: " + Math.round(F.top.restoreScale()));
// }
// function N(a) {
// a.props.x += 0;
// a.props.y += 100;
// var b = $("#" + a.id);
// b.css({
// left: parseFloat(b.css("left")),
// top: parseFloat(b.css("top")) + 100
// })
// }
});
/*
整体思路(以上下移动举例)
根据辅助线的位置分为三种:
1. 没有穿过图形, 这种直接移动图形和线就行
2. 穿过辅助线上半部分, 这种情况该图形需要移动, 并且该图形上的起点(终点)也要移动, 和起点(终点)在同一水平线的拐点也要移动
3. 穿过辅助线下半部分,这种情况图形不需要移动,该图形上的起点(终点)不需要移动, 和起点(终点)在同一水平线的拐点不需要移动
含有泳池泳道时要改变泳池泳道的高()
*/
function isLineBelowOrRight(line,type,pos) {
let flag = false
if(line.from[type] > pos) {
flag = true
}
if(line.to[type] > pos) {
flag = true
}
for (let i = 0; i < line.points.length; i++) {
if (line.points[i][type] > pos) {
flag = true
}
}
return flag
}
function filterShapeAndLine(type,sublinePos) {
var elements = Model.define.elements;
var shapeArr = []
var lineArr = []
var laneArr = [] // 泳池泳道
var passedShapes = [] // 穿过辅助线上(左)半部分的图形 要移动
var passedMoreShapes = [] // 穿过辅助线下(右)半部分的图形 不要移动
var passedShapesEdge = 0
var sublineSideShape = [] // 辅助线上(左)的图形
var sublineSideEdge = 0
var movingShapes = []; // 移动的图形
var movingLines = []
for(let shapeId in elements) {
if (elements[shapeId].points == undefined) {
shapeArr.push(elements[shapeId])
} else {
lineArr.push(elements[shapeId])
}
if(elements[shapeId].category == 'lane') {
laneArr.push(elements[shapeId])
}
}
for (let i = 0; i < shapeArr.length; i++) {
if(type == 'x') {
if (shapeArr[i].props[type] >= sublinePos) {
movingShapes.push(shapeArr[i])
} else if(shapeArr[i].props.x + shapeArr[i].props.w/2>= sublinePos) {
passedShapes.push(shapeArr[i])
movingShapes.push(shapeArr[i])
} else if(shapeArr[i].props.x + shapeArr[i].props.w/2 < sublinePos && shapeArr[i].props.x + shapeArr[i].props.w > sublinePos) {
passedMoreShapes.push(shapeArr[i])
}
else {
sublineSideShape.push(shapeArr[i])
}
} else if(type == 'y') {
if (shapeArr[i].props[type] >= sublinePos) { // 辅助线以下
movingShapes.push(shapeArr[i])
} else if(shapeArr[i].props.y + shapeArr[i].props.h/2>= sublinePos) { // 辅助线穿过图形上半
passedShapes.push(shapeArr[i])
movingShapes.push(shapeArr[i])
} else if(shapeArr[i].props.y + shapeArr[i].props.h/2 < sublinePos && shapeArr[i].props.y + shapeArr[i].props.h > sublinePos) {
passedMoreShapes.push(shapeArr[i])
}
else {
sublineSideShape.push(shapeArr[i])
}
}
}
for (let i = 0; i < lineArr.length; i++) {
let index = movingLines.findIndex(item => item.id == lineArr[i].id)
if(isLineBelowOrRight(lineArr[i],type,sublinePos) && index == -1) {
movingLines.push(lineArr[i])
}
}
if (sublineSideShape.length > 0 && type == 'y') {
sublineSideEdge = Math.max.apply(Math,sublineSideShape.map(item => { return (item.props.y + item.props.h) }))
} else if (sublineSideShape.length > 0 && type == 'x') {
sublineSideEdge = Math.max.apply(Math,sublineSideShape.map(item => { return (item.props.x + item.props.w) }))
}
if (passedShapes.concat(passedMoreShapes).length > 0) {
passedShapesEdge = Math.max.apply(Math,passedShapes.concat(passedMoreShapes).map(item => { return item.props[type] }))
}
if (passedShapes.length > 0) {
// 获取选中形状上的连接线
let linkers = Utils.getOutlinkers(passedShapes);
for (let i = 0; i < linkers.length; i++) {
if (movingLines.findIndex(item => item.id == linkers[i].id) == -1) { // 形状关联的线不存在
movingLines.push(linkers[i])
}
}
}
return {
passedShapes,
passedMoreShapes,
passedShapesEdge,
sublineSideEdge,
movingShapes,
movingLines,
laneArr
}
}
function moveShapeAndFile(type,sublinePos,movedDistance) {
var obj = filterShapeAndLine(type,sublinePos)
var movingLines = obj.movingLines
var movingShapes = obj.movingShapes
var passedShapes = obj.passedShapes
var passedMoreShapes = obj.passedMoreShapes
var laneArr = obj.laneArr
for (let i = 0; i < movingLines.length; i++) {
let fromIndex = passedShapes.findIndex(item => item.id == movingLines[i].from.id)
let toIndex = passedShapes.findIndex(item => item.id == movingLines[i].to.id)
let moreFromIndex = passedMoreShapes.findIndex(item => item.id == movingLines[i].from.id)
let moreToIndex = passedMoreShapes.findIndex(item => item.id == movingLines[i].to.id)
for (let j = 0; j < movingLines[i].points.length; j++) {
if(movingLines[i].points[j][type] > sublinePos ) {
movingLines[i].points[j][type] += movedDistance
}
}
if (movingLines[i].from[type] > sublinePos && moreFromIndex == -1) {
movingLines[i].from[type] += movedDistance
} else if(movingLines[i].from[type] <= sublinePos && fromIndex !== -1) {
for (let j = 0; j < movingLines[i].points.length; j++) {
if(movingLines[i].points[j][type] == movingLines[i].from[type]) {
movingLines[i].points[j][type] += movedDistance
}
}
movingLines[i].from[type] += movedDistance
}
if (movingLines[i].to[type] > sublinePos && moreToIndex == -1) {
movingLines[i].to[type] += movedDistance
} else if(passedShapes.length > 0 && movingLines[i].to[type] <= sublinePos && toIndex !== -1) {
for (let j = 0; j < movingLines[i].points.length; j++) {
if(movingLines[i].points[j][type] == movingLines[i].to[type]) {
movingLines[i].points[j][type] += movedDistance
}
}
movingLines[i].to[type] += movedDistance
}
Designer.painter.renderLinker(movingLines[i])
}
if(laneArr.length == 0) {
if(type == 'y') {
Designer.op.moveShape(movingShapes,{
x: 0,
y: movedDistance
})
} else if(type == 'x') {
Designer.op.moveShape(movingShapes,{
x: movedDistance,
y: 0
})
}
Designer.op.hideTip();
Utils.unselect();
var movedArr = movingShapes.concat(movingLines)
if (movedArr.length > 0) {
Model.updateMulti(movedArr);
}
} else {
moveLanes(type,sublinePos,movedDistance)
}
}
function moveLanes(type,sublinePos,movedDistance) {
var obj = filterShapeAndLine(type,sublinePos)
var movingLines = obj.movingLines
var movingShapes = obj.movingShapes
var laneArr = obj.laneArr
var laneGroupArr = []
var changedLanes = []
for (let i = 0; i < laneArr.length; i++) {
if(laneArr[i].parent == '') {
laneGroupArr.push({
id: laneArr[i].id,
name: laneArr[i].name,
isPassed: false,
lanes: [laneArr[i]],
changed: []
})
}
}
for (let i = 0; i < laneGroupArr.length; i++) {
for (let j = 0; j < laneArr.length; j++) {
if (laneGroupArr[i].id == laneArr[j].parent) {
laneGroupArr[i].lanes.push(laneArr[j])
}
}
}
laneGroupArr.forEach(group => {
let index1 = group.lanes.findIndex(item => item.parent == '')
let index2 = group.lanes.findIndex(item => item.name == 'verticalSeparatorBar')
let index3 = group.lanes.findIndex(item => item.name == 'horizontalSeparatorBar')
let parent = group.lanes[index1]
let verticalSeparatorBar = group.lanes[index2];
let horizontalSeparatorBar = group.lanes[index3];
if(type == 'x') {
let flag = parent.props.x < sublinePos && parent.props.x + parent.props.w > sublinePos
let flag1 = verticalSeparatorBar !== undefined && verticalSeparatorBar.props.x < sublinePos && verticalSeparatorBar.props.x + verticalSeparatorBar.props.w > sublinePos
let flag2 = parent.props.x < sublinePos && parent.props.x + parent.textBlock.w > sublinePos
if(group.name == 'verticalPool') { // 垂直泳池含有'阶段' 辅助线在'阶段' 泳池不需要移动
group.isPassed = flag && !flag1
} else if(group.name == 'horizontalPool') { // 水平泳池 辅助线位置在泳池title处 泳池不需要移动
group.isPassed = flag && !flag2
}
group.lanes.forEach(item => {
if(item.props.x + item.props.w > sublinePos) {
group.changed.push(item)
}
})
} else if(type == 'y') {
let flag = parent.props.y < sublinePos && parent.props.y + parent.props.h > sublinePos
let flag1 = horizontalSeparatorBar !== undefined && horizontalSeparatorBar.props.y < sublinePos && horizontalSeparatorBar.props.y + horizontalSeparatorBar.props.h > sublinePos
let flag2 = parent.props.y < sublinePos && parent.props.y + parent.textBlock.h > sublinePos
if(group.name == 'verticalPool') { // 垂直泳池 辅助线位置在泳池title处 泳池不需要移动
group.isPassed = flag && !flag2
} else if(group.name == 'horizontalPool') { // 水平泳池 含有'阶段' 辅助线在'阶段' 泳池不需要移动
group.isPassed = flag && !flag1
}
group.lanes.forEach(item => {
if(item.props.y + item.props.h > sublinePos) {
group.changed.push(item)
}
})
}
})
if(type == 'x') {
Designer.op.moveShape(movingShapes.filter(item => item.category !== 'lane'),{
x: movedDistance,
y: 0
})
laneGroupArr.forEach(group => {
group.changed.forEach(item => {
if (!group.isPassed) {
item.props.x += movedDistance
} else if(group.isPassed) {
if(group.name == 'verticalPool') {
switch (item.name) {
case 'verticalPool':
item.props.w += movedDistance
break
case 'verticalLane':
item.props.w += (item.props.x < sublinePos && item.props.x + item.props.w > sublinePos) ? movedDistance : 0
item.props.x += item.props.x > sublinePos ? movedDistance : 0
break
case 'horizontalSeparator' :
item.props.w += movedDistance
break
}
}
if(group.name == 'horizontalPool') {
switch (item.name) {
case 'horizontalPool' :
item.props.w += movedDistance
break
case 'horizontalLane' :
item.props.w += movedDistance
break
case 'verticalSeparator' :
item.props.w += (item.props.x < sublinePos && item.props.x + item.props.w > sublinePos) ? movedDistance : 0
item.props.x += item.props.x > sublinePos ? movedDistance : 0
break
case 'horizontalSeparatorBar':
item.props.w += movedDistance
}
}
}
changedLanes.push(item)
Designer.painter.renderShape(item);
})
})
} else if(type == 'y') {
Designer.op.moveShape(movingShapes.filter(item => item.category !== 'lane'),{
x: 0,
y: movedDistance
})
laneGroupArr.forEach(group => {
group.changed.forEach(item => {
if(!group.isPassed) {
item.props.y += movedDistance
} else if(group.isPassed) {
if(group.name == 'verticalPool') {
switch (item.name) {
case 'verticalPool' :
item.props.h += movedDistance
break
case 'verticalLane' :
item.props.h += movedDistance
break
case 'horizontalSeparator':
item.props.h += (item.props.y < sublinePos && item.props.y + item.props.h > sublinePos) ? movedDistance : 0
item.props.y += item.props.y > sublinePos ? movedDistance : 0
break
case 'verticalSeparatorBar' :
item.props.h += movedDistance
break
}
}
if(group.name == 'horizontalPool') {
switch (item.name) {
case 'horizontalPool' :
item.props.h += movedDistance
break
case 'horizontalLane':
item.props.h += (item.props.y < sublinePos && item.props.y + item.props.h > sublinePos) ? movedDistance : 0
item.props.y += item.props.y > sublinePos ? movedDistance : 0
break
case 'verticalSeparator' :
item.props.h += movedDistance
break
}
}
}
changedLanes.push(item)
Designer.painter.renderShape(item);
})
})
}
Designer.op.hideTip();
Utils.unselect();
var movedArr = movingShapes.filter(item => item.category !== 'lane').concat(changedLanes).concat(movingLines)
if (movedArr.length > 0) {
Model.updateMulti(movedArr);
}
}
/**
* 设计器方法调节水平间距
*/
Designer.addFunction("selectHorizontal", function(menuPos){
var menuX = menuPos.x
let subline = $('#designer_subline')
console.log(subline)
subline.css({
Designer.addFunction("selectHorizontal", function(menuPos) {
var sublinePos = menuPos.x
var subline1 = $('#designer_subline1') // 初始位置
var subline2 = $('#designer_subline2')
subline1.css({
display : "block",
"z-index" : Model.orderList.length + 4,
width: 0,
height: Model.define.page.height,
height: Model.define.page.width,
borderStyle:'dotted',
borderWidth: '1px',
left: menuX,
top :0,
left: sublinePos,
top : 0
});
subline2.css({
display : "block",
"z-index" : Model.orderList.length + 5,
width: 0,
height: Model.define.page.width,
borderStyle:'dotted',
borderWidth: '1px',
left: sublinePos,
top : 0,
cursor: 'move'
});
var obj = filterShapeAndLine('x',sublinePos)
var container = $("#canvas_container");
var canvas = $("#designer_canvas");
subline2.bind('mousedown.drag',function (b) {
container.bind('mousemove.drag',function (e) {
var newPos = Utils.getRelativePos(e.pageX, e.pageY, canvas);
if (newPos.x >= sublinePos) { // 增加
subline1.css({
borderColor: 'rgb(114,253,107)',
backgroundColor: 'rgba(114,253,107,0.5)',
width: newPos.x - sublinePos
})
subline2.css({
borderColor: 'rgb(114,253,107)',
backgroundColor: 'transparent',
width: 0
})
subline2.css({
left : newPos.x,
});
} else { // 减少
let max = obj.passedShapesEdge - obj.sublineSideEdge > 0 ? obj.passedShapesEdge : obj.sublineSideEdge
if (newPos.x < max) {
newPos.x = max
}
subline1.css({
borderColor: 'rgb(246,163,163)',
backgroundColor: 'transparent',
width: 0
})
subline2.css({
borderColor: 'rgb(246,163,163)',
backgroundColor: 'rgba(246,163,163,0.5)',
width: sublinePos - newPos.x
})
subline2.css({
left : newPos.x,
});
}
$(document).unbind("mouseup.drop").bind("mouseup.drop",
function(e) {
var width1 = subline1.width()
var width2 = subline2.width()
if(width1 != 0 && width2 == 0) { // 增加
moveShapeAndFile('x',sublinePos,width1)
} else if(width1 == 0 && width2 != 0) { // 减少
moveShapeAndFile('x',sublinePos,0-width2)
}
subline1.css({
borderColor: '#333',
backgroundColor: 'transparent',
width: 0
})
subline2.css({
borderColor: '#333',
backgroundColor: 'transparent',
width: 0
})
subline1.hide()
subline2.hide()
$(document).unbind("mouseup.drop")
})
})
$(document).bind('mouseup.drag',function () {
container.unbind("mousemove.drag");
subline2.unbind("mousedown.drag");
$(document).unbind("mouseup.drag");
})
})
});
/**