graflow: improved ortho walkarounds
This commit is contained in:
@@ -48,7 +48,7 @@
|
|||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
border: 2px solid black;
|
border: 2px solid black;
|
||||||
}
|
}
|
||||||
bz-graflow.compunet{ grid-column: 1 / -1; width: 100vw; height: 60vh; background:black; }
|
bz-graflow.compunet{ grid-column: 1 / -1; width: 100vw; height: 100vh; background:black; }
|
||||||
</style>
|
</style>
|
||||||
<script>
|
<script>
|
||||||
window.addEventListener('load',()=>{
|
window.addEventListener('load',()=>{
|
||||||
|
|||||||
@@ -1,84 +1,245 @@
|
|||||||
{
|
{
|
||||||
"nodesFile": "/app/assets/html/bzGraflow/nodes16ports.html",
|
"nodesFile": "/app/assets/html/bzGraflow/nodes16ports.html",
|
||||||
"flow": {
|
"flow": {
|
||||||
"nodes":[
|
"nodes": [
|
||||||
{ "nodeType": "square",
|
{
|
||||||
|
"nodeType": "square",
|
||||||
"id": "p1center",
|
"id": "p1center",
|
||||||
"coords": { "x": 300, "y": 200},
|
"coords": {
|
||||||
|
"x": 300,
|
||||||
|
"y": 200
|
||||||
|
},
|
||||||
"markup": {
|
"markup": {
|
||||||
"title": "Center",
|
"title": "Center",
|
||||||
"subtitle": "."
|
"subtitle": "."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ "nodeType": "square",
|
{
|
||||||
|
"nodeType": "square",
|
||||||
"id": "p1west",
|
"id": "p1west",
|
||||||
"coords": { "x": 200, "y": 200},
|
"coords": {
|
||||||
|
"x": 200,
|
||||||
|
"y": 200
|
||||||
|
},
|
||||||
"markup": {
|
"markup": {
|
||||||
"title": "West",
|
"title": "West",
|
||||||
"subtitle": "."
|
"subtitle": "."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ "nodeType": "square",
|
{
|
||||||
|
"nodeType": "square",
|
||||||
"id": "p1north",
|
"id": "p1north",
|
||||||
"coords": { "x": 300, "y": 100},
|
"coords": {
|
||||||
|
"x": 300,
|
||||||
|
"y": 100
|
||||||
|
},
|
||||||
"markup": {
|
"markup": {
|
||||||
"title": "North",
|
"title": "North",
|
||||||
"subtitle": "."
|
"subtitle": "."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ "nodeType": "square",
|
{
|
||||||
|
"nodeType": "square",
|
||||||
"id": "p1east",
|
"id": "p1east",
|
||||||
"coords": { "x": 400, "y": 200},
|
"coords": {
|
||||||
|
"x": 400,
|
||||||
|
"y": 200
|
||||||
|
},
|
||||||
"markup": {
|
"markup": {
|
||||||
"title": "East",
|
"title": "East",
|
||||||
"subtitle": "."
|
"subtitle": "."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ "nodeType": "square",
|
{
|
||||||
|
"nodeType": "square",
|
||||||
"id": "p1south",
|
"id": "p1south",
|
||||||
"coords": { "x": 300, "y": 300},
|
"coords": {
|
||||||
|
"x": 300,
|
||||||
|
"y": 300
|
||||||
|
},
|
||||||
"markup": {
|
"markup": {
|
||||||
"title": "South",
|
"title": "South",
|
||||||
"subtitle": "."
|
"subtitle": "."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
{ "nodeType": "square",
|
"nodeType": "square",
|
||||||
"id": "p2center",
|
"id": "p2center",
|
||||||
"coords": { "x": 800, "y": 200},
|
"coords": {
|
||||||
|
"x": 800,
|
||||||
|
"y": 200
|
||||||
|
},
|
||||||
"markup": {
|
"markup": {
|
||||||
"title": "Center",
|
"title": "Center",
|
||||||
"subtitle": "."
|
"subtitle": "."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ "nodeType": "square",
|
{
|
||||||
|
"nodeType": "square",
|
||||||
"id": "p2west",
|
"id": "p2west",
|
||||||
"coords": { "x": 700, "y": 200},
|
"coords": {
|
||||||
|
"x": 700,
|
||||||
|
"y": 200
|
||||||
|
},
|
||||||
"markup": {
|
"markup": {
|
||||||
"title": "West",
|
"title": "West",
|
||||||
"subtitle": "."
|
"subtitle": "."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ "nodeType": "square",
|
{
|
||||||
|
"nodeType": "square",
|
||||||
"id": "p2north",
|
"id": "p2north",
|
||||||
"coords": { "x": 800, "y": 100},
|
"coords": {
|
||||||
|
"x": 800,
|
||||||
|
"y": 100
|
||||||
|
},
|
||||||
"markup": {
|
"markup": {
|
||||||
"title": "North",
|
"title": "North",
|
||||||
"subtitle": "."
|
"subtitle": "."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ "nodeType": "square",
|
{
|
||||||
|
"nodeType": "square",
|
||||||
"id": "p2east",
|
"id": "p2east",
|
||||||
"coords": { "x": 900, "y": 200},
|
"coords": {
|
||||||
|
"x": 900,
|
||||||
|
"y": 200
|
||||||
|
},
|
||||||
"markup": {
|
"markup": {
|
||||||
"title": "East",
|
"title": "East",
|
||||||
"subtitle": "."
|
"subtitle": "."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ "nodeType": "square",
|
{
|
||||||
|
"nodeType": "square",
|
||||||
"id": "p2south",
|
"id": "p2south",
|
||||||
"coords": { "x": 800, "y": 300},
|
"coords": {
|
||||||
|
"x": 800,
|
||||||
|
"y": 300
|
||||||
|
},
|
||||||
|
"markup": {
|
||||||
|
"title": "South",
|
||||||
|
"subtitle": "."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"nodeType": "square",
|
||||||
|
"id": "p3center",
|
||||||
|
"coords": {
|
||||||
|
"x": 300,
|
||||||
|
"y": 600
|
||||||
|
},
|
||||||
|
"markup": {
|
||||||
|
"title": "Center",
|
||||||
|
"subtitle": "."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"nodeType": "square",
|
||||||
|
"id": "p3west",
|
||||||
|
"coords": {
|
||||||
|
"x": 200,
|
||||||
|
"y": 600
|
||||||
|
},
|
||||||
|
"markup": {
|
||||||
|
"title": "West",
|
||||||
|
"subtitle": "."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"nodeType": "square",
|
||||||
|
"id": "p3north",
|
||||||
|
"coords": {
|
||||||
|
"x": 300,
|
||||||
|
"y": 500
|
||||||
|
},
|
||||||
|
"markup": {
|
||||||
|
"title": "North",
|
||||||
|
"subtitle": "."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"nodeType": "square",
|
||||||
|
"id": "p3east",
|
||||||
|
"coords": {
|
||||||
|
"x": 400,
|
||||||
|
"y": 600
|
||||||
|
},
|
||||||
|
"markup": {
|
||||||
|
"title": "East",
|
||||||
|
"subtitle": "."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"nodeType": "square",
|
||||||
|
"id": "p3south",
|
||||||
|
"coords": {
|
||||||
|
"x": 300,
|
||||||
|
"y": 700
|
||||||
|
},
|
||||||
|
"markup": {
|
||||||
|
"title": "South",
|
||||||
|
"subtitle": "."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"nodeType": "square",
|
||||||
|
"id": "p4center",
|
||||||
|
"coords": {
|
||||||
|
"x": 800,
|
||||||
|
"y": 600
|
||||||
|
},
|
||||||
|
"markup": {
|
||||||
|
"title": "Center",
|
||||||
|
"subtitle": "."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"nodeType": "square",
|
||||||
|
"id": "p4west",
|
||||||
|
"coords": {
|
||||||
|
"x": 700,
|
||||||
|
"y": 600
|
||||||
|
},
|
||||||
|
"markup": {
|
||||||
|
"title": "West",
|
||||||
|
"subtitle": "."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"nodeType": "square",
|
||||||
|
"id": "p4north",
|
||||||
|
"coords": {
|
||||||
|
"x": 800,
|
||||||
|
"y": 500
|
||||||
|
},
|
||||||
|
"markup": {
|
||||||
|
"title": "North",
|
||||||
|
"subtitle": "."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"nodeType": "square",
|
||||||
|
"id": "p4east",
|
||||||
|
"coords": {
|
||||||
|
"x": 900,
|
||||||
|
"y": 600
|
||||||
|
},
|
||||||
|
"markup": {
|
||||||
|
"title": "East",
|
||||||
|
"subtitle": "."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"nodeType": "square",
|
||||||
|
"id": "p4south",
|
||||||
|
"coords": {
|
||||||
|
"x": 800,
|
||||||
|
"y": 700
|
||||||
|
},
|
||||||
"markup": {
|
"markup": {
|
||||||
"title": "South",
|
"title": "South",
|
||||||
"subtitle": "."
|
"subtitle": "."
|
||||||
@@ -94,7 +255,17 @@
|
|||||||
{ "from": ["p2center", "s"], "to": ["p2south", "e"] },
|
{ "from": ["p2center", "s"], "to": ["p2south", "e"] },
|
||||||
{ "from": ["p2center", "e"], "to": ["p2east", "n"] },
|
{ "from": ["p2center", "e"], "to": ["p2east", "n"] },
|
||||||
{ "from": ["p2center", "n"], "to": ["p2north", "w"] },
|
{ "from": ["p2center", "n"], "to": ["p2north", "w"] },
|
||||||
{ "from": ["p2center", "w"], "to": ["p2west", "s"] }
|
{ "from": ["p2center", "w"], "to": ["p2west", "s"] },
|
||||||
|
|
||||||
|
{ "from": ["p3center", "s"], "to": ["p3south", "s"] },
|
||||||
|
{ "from": ["p3center", "e"], "to": ["p3east", "e"] },
|
||||||
|
{ "from": ["p3center", "n"], "to": ["p3north", "n"] },
|
||||||
|
{ "from": ["p3center", "w"], "to": ["p3west", "w"] },
|
||||||
|
|
||||||
|
{ "from": ["p4center", "s"], "to": ["p4south", "w"] },
|
||||||
|
{ "from": ["p4center", "e"], "to": ["p4east", "s"] },
|
||||||
|
{ "from": ["p4center", "n"], "to": ["p4north", "e"] },
|
||||||
|
{ "from": ["p4center", "w"], "to": ["p4west", "n"] }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Vendored
+28
-8
@@ -459,7 +459,7 @@ class BZgraflow extends Buildoz{
|
|||||||
return({ x: x - r.left, y: y - r.top })
|
return({ x: x - r.left, y: y - r.top })
|
||||||
}
|
}
|
||||||
|
|
||||||
buildSegment(x1, y1, c1x, c1y, c2x, c2y, x2, y2, wireType, dir1, dir2, loop=false){
|
buildSegment(x1, y1, c1x, c1y, c2x, c2y, x2, y2, wireType, node1, node2, dir1, dir2, tension, loop=false){
|
||||||
if(loop) wireType = 'bezier' // loops only use bezier to look good
|
if(loop) wireType = 'bezier' // loops only use bezier to look good
|
||||||
|
|
||||||
const startAxis = ['n', 's'].includes(dir1) ? 'v' : 'h'
|
const startAxis = ['n', 's'].includes(dir1) ? 'v' : 'h'
|
||||||
@@ -476,6 +476,16 @@ class BZgraflow extends Buildoz{
|
|||||||
if( ((dir1 == 's') && (c1y < mediany)) || ((dir1 == 'n') && (c1y > mediany)) ){
|
if( ((dir1 == 's') && (c1y < mediany)) || ((dir1 == 'n') && (c1y > mediany)) ){
|
||||||
if( (dir2=='e') && (c2x > x1) || (dir2=='w') && (c2x < x1)) return(`V ${mediany} H ${c2x} V ${y2} H ${x2}`)
|
if( (dir2=='e') && (c2x > x1) || (dir2=='w') && (c2x < x1)) return(`V ${mediany} H ${c2x} V ${y2} H ${x2}`)
|
||||||
else if((dir2=='e') || (dir2=='w')) return(`V ${y2} H ${x2}`)
|
else if((dir2=='e') || (dir2=='w')) return(`V ${y2} H ${x2}`)
|
||||||
|
else if(dir2 == dir1) { // walk-around node
|
||||||
|
const deviation = node2.offsetWidth / 2
|
||||||
|
if(x1>x2) {
|
||||||
|
if(x1>x2+deviation+tension) return(`V ${c2y} H ${x2} V ${y2}`)
|
||||||
|
else return(`V ${c1y} H ${x1+deviation+tension} V ${c2y} H ${x2} V ${y2}`)
|
||||||
|
} else {
|
||||||
|
if(x1<x2-deviation-tension) return(`V ${c2y} H ${x2} V ${y2}`)
|
||||||
|
else return(`V ${c1y} H ${x1-deviation-tension} V ${c2y} H ${x2} V ${y2}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
else return(`V ${mediany} H ${c2x} V ${y2} H ${x2}`)
|
else return(`V ${mediany} H ${c2x} V ${y2} H ${x2}`)
|
||||||
} else {
|
} else {
|
||||||
return(`V ${c1y} H ${medianx} V ${c2y} H ${x2} V ${y2}`)
|
return(`V ${c1y} H ${medianx} V ${c2y} H ${x2} V ${y2}`)
|
||||||
@@ -485,7 +495,16 @@ class BZgraflow extends Buildoz{
|
|||||||
if( ((dir1 == 'e') && (c1x <medianx)) || ((dir1 == 'w') && (c1x > medianx)) ){
|
if( ((dir1 == 'e') && (c1x <medianx)) || ((dir1 == 'w') && (c1x > medianx)) ){
|
||||||
if( (dir2=='s') && (c2y > y1) || (dir2=='n') && (c2y < y1)) return(`H ${medianx} V ${c2y} H ${x2} V ${y2}`)
|
if( (dir2=='s') && (c2y > y1) || (dir2=='n') && (c2y < y1)) return(`H ${medianx} V ${c2y} H ${x2} V ${y2}`)
|
||||||
else if((dir2=='n') || (dir2=='s')) return(`H ${x2} V ${y2}`)
|
else if((dir2=='n') || (dir2=='s')) return(`H ${x2} V ${y2}`)
|
||||||
else return(`H ${medianx} V ${c2y} H ${x2} V ${y2}`)
|
else if(dir2 == dir1) { // walk-around node
|
||||||
|
const deviation = node2.offsetHeight / 2
|
||||||
|
if(y1>y2) {
|
||||||
|
if(y1>y2+deviation+tension) return(`H ${c2x} V ${y2} H ${x2}`)
|
||||||
|
else return(`H ${c1x} V ${y1+deviation+tension} H ${c2x} V ${y2} H ${x2}`)
|
||||||
|
} else {
|
||||||
|
if(y1<y2-deviation-tension) return(`H ${c2x} V ${y2} H ${x2}`)
|
||||||
|
else return(`H ${c1x} V ${y1-deviation-tension} H ${c2x} V ${y2} H ${x2}`)
|
||||||
|
}
|
||||||
|
} else return(`H ${medianx} V ${c2y} H ${x2} V ${y2}`)
|
||||||
} else {
|
} else {
|
||||||
return(`H ${c1x} V ${mediany} H ${c2x} V ${y2} H ${x2}`)
|
return(`H ${c1x} V ${mediany} H ${c2x} V ${y2} H ${x2}`)
|
||||||
}
|
}
|
||||||
@@ -529,7 +548,7 @@ class BZgraflow extends Buildoz{
|
|||||||
c2y -= 1*tension
|
c2y -= 1*tension
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const seg = this.buildSegment(x1, y1, c1x, c1y, c2x, c2y, x2, y2, wireType, port1.direction, port2.direction, loop)
|
const seg = this.buildSegment(x1, y1, c1x, c1y, c2x, c2y, x2, y2, wireType, node1, node2, port1.direction, port2.direction, tension, loop)
|
||||||
if(!seg) return('')
|
if(!seg) return('')
|
||||||
return(`M ${x1} ${y1} ${seg}`)
|
return(`M ${x1} ${y1} ${seg}`)
|
||||||
}
|
}
|
||||||
@@ -546,12 +565,12 @@ class BZgraflow extends Buildoz{
|
|||||||
return('')
|
return('')
|
||||||
}
|
}
|
||||||
|
|
||||||
const makeSegment = (x1, y1, x2, y2, dir1, dir2) => {
|
const makeSegment = (x1, y1, x2, y2, node1, node2, dir1, dir2, tension) => {
|
||||||
const c1x = Math.floor(x1 + (this.dirVect[dir1].x * tension))
|
const c1x = Math.floor(x1 + (this.dirVect[dir1].x * tension))
|
||||||
const c1y = Math.floor(y1 + (this.dirVect[dir1].y * tension))
|
const c1y = Math.floor(y1 + (this.dirVect[dir1].y * tension))
|
||||||
const c2x = Math.floor(x2 + (this.dirVect[dir2].x * tension))
|
const c2x = Math.floor(x2 + (this.dirVect[dir2].x * tension))
|
||||||
const c2y = Math.floor(y2 + (this.dirVect[dir2].y * tension))
|
const c2y = Math.floor(y2 + (this.dirVect[dir2].y * tension))
|
||||||
return(this.buildSegment(x1, y1, c1x, c1y, c2x, c2y, x2, y2, wireType, dir1, dir2, false))
|
return(this.buildSegment(x1, y1, c1x, c1y, c2x, c2y, x2, y2, wireType, node1, node2, dir1, dir2, tension, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start/end points in SVG coords (works for both bezier and line)
|
// Start/end points in SVG coords (works for both bezier and line)
|
||||||
@@ -585,10 +604,10 @@ class BZgraflow extends Buildoz{
|
|||||||
let y2 = Math.floor(entry.y)
|
let y2 = Math.floor(entry.y)
|
||||||
|
|
||||||
if(firstPort){
|
if(firstPort){
|
||||||
path += makeSegment(x1, y1, x2, y2, firstPort.direction, entryDir)
|
path += makeSegment(x1, y1, x2, y2, node1, node2, firstPort.direction, entryDir, tension)
|
||||||
firstPort = null
|
firstPort = null
|
||||||
} else {
|
} else {
|
||||||
path += makeSegment(x1, y1, x2, y2, exitDir, entryDir)
|
path += makeSegment(x1, y1, x2, y2, node1, node2, exitDir, entryDir, tension)
|
||||||
}
|
}
|
||||||
|
|
||||||
const x3 = Math.floor(exit.x)
|
const x3 = Math.floor(exit.x)
|
||||||
@@ -598,7 +617,7 @@ class BZgraflow extends Buildoz{
|
|||||||
x1 = x3
|
x1 = x3
|
||||||
y1 = y3
|
y1 = y3
|
||||||
}
|
}
|
||||||
path += ' ' + makeSegment(x1, y1, xEnd, yEnd, exitDir, port2.direction)
|
path += ' ' + makeSegment(x1, y1, xEnd, yEnd, node1, node2, exitDir, port2.direction, tension)
|
||||||
return(path)
|
return(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1101,6 +1120,7 @@ class MovingNodes{
|
|||||||
pointerDown(e){
|
pointerDown(e){
|
||||||
this.graflow.clearFakeNodes()
|
this.graflow.clearFakeNodes()
|
||||||
const node = (e.target.classList.contains(this.itemSelector)) ? e.target : e.target.closest(this.itemSelector)
|
const node = (e.target.classList.contains(this.itemSelector)) ? e.target : e.target.closest(this.itemSelector)
|
||||||
|
if(!node) return
|
||||||
const handle = (node.classList.contains(this.handleSelector)) ? node : node.querySelector(this.handleSelector)
|
const handle = (node.classList.contains(this.handleSelector)) ? node : node.querySelector(this.handleSelector)
|
||||||
|
|
||||||
const rect = node.getBoundingClientRect()
|
const rect = node.getBoundingClientRect()
|
||||||
|
|||||||
Reference in New Issue
Block a user