Compare commits
10 Commits
5338a4c021
...
2d3a4631c8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d3a4631c8 | ||
|
|
ae173f5b92 | ||
|
|
20523ce0aa | ||
|
|
56c2052f40 | ||
|
|
6408d3377b | ||
|
|
bcb76e197e | ||
|
|
6ffdb79001 | ||
|
|
fc16a1840f | ||
|
|
4b107e772c | ||
|
|
85a03f7c1d |
11
buildoz.css
11
buildoz.css
@@ -206,7 +206,9 @@ bz-graflow .bzgf-main-container{
|
||||
}
|
||||
|
||||
/* BZGRAFLOW_CORE_START */
|
||||
/* bz-graflow internal layout rules (used in light DOM, and injected into shadow DOM when isolated) */
|
||||
/* Keep this commented section !
|
||||
bz-graflow internal layout rules (used in light DOM, and injected into shadow DOM when isolated)
|
||||
*/
|
||||
bz-graflow .bzgf-wires-container,
|
||||
bz-graflow .bzgf-nodes-container{
|
||||
position: absolute;
|
||||
@@ -214,6 +216,13 @@ bz-graflow .bzgf-nodes-container{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
bz-graflow .bzgf-nodes-container{ /* used to keep the nodes container pointer-events: none, but allow the nodes to be moved ! */
|
||||
pointer-events: none;
|
||||
}
|
||||
bz-graflow .bzgf-nodes-container > * { /* allow the nodes to be moved ! */
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
bz-graflow .bzgf-nodes-container .bzgf-node{ position:absolute; }
|
||||
bz-graflow .bzgf-nodes-container .bzgf-fake-node{
|
||||
position: absolute;
|
||||
|
||||
319
bzGraflow.js
319
bzGraflow.js
@@ -85,9 +85,21 @@ class BZgraflow extends Buildoz{
|
||||
this.mainContainer.append(this.nodesContainer)
|
||||
this.append(this.hostContainer)
|
||||
this.loadFlow(flowUrl).then(() => {
|
||||
if((this.getBZAttribute('edit')=='move') || (this.getBZAttribute('edit')=='full')){
|
||||
this.dnd = new MovingNodes(this)
|
||||
this.dnd.enableMovingNodes('.bzgf-node')
|
||||
if(this.getBZAttribute('edit')){
|
||||
const edit = this.getBZAttribute('edit').split(',')
|
||||
if(edit.includes('nodesmove')){
|
||||
this.nodesMover = new MovingNodes(this)
|
||||
this.nodesMover.enableMovingNodes('.bzgf-node')
|
||||
}
|
||||
if(edit.includes('wires')){
|
||||
this.WiresEditor = new EditWires(this)
|
||||
this.WiresEditor.enableEditWires()
|
||||
//this.WiresEditor.enableMovingNodes('.bzgf-wire')
|
||||
}
|
||||
if(edit.includes('dropnodes')){
|
||||
this.NodesReceiver = new DroppingNodes(this)
|
||||
//this.NodesReceiver.enableDroppingNodes('.bzgf-node')
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -225,7 +237,7 @@ class BZgraflow extends Buildoz{
|
||||
btnExitSubflow.addEventListener('click', () => {
|
||||
this.exitSubflow(childEl)
|
||||
})
|
||||
// Put the child in the exact same viewport rect as the parent (fixed overlay)
|
||||
// Put the child in the exact same viewport rect as the parent
|
||||
this.invade(this, childEl)
|
||||
childEl.hostContainer.appendChild(btnExitSubflow)
|
||||
|
||||
@@ -266,9 +278,9 @@ class BZgraflow extends Buildoz{
|
||||
const ty0 = (nodeBB.top - parentBB.top) + (this.scrollTop || 0)
|
||||
|
||||
// Inline "scaler" (shadow styles don't apply to the child element)
|
||||
childEl.style.border = 'none'
|
||||
childEl.style.transformOrigin = 'top left'
|
||||
childEl.style.willChange = 'transform'
|
||||
childEl.style.transition = 'transform 1000ms ease-in-out'
|
||||
childEl.style.transform = 'translate(var(--tx, 0px), var(--ty, 0px)) scale(var(--sx, 1), var(--sy, 1))'
|
||||
childEl.style.setProperty('--tx', tx0 + 'px')
|
||||
childEl.style.setProperty('--ty', ty0 + 'px')
|
||||
@@ -277,7 +289,10 @@ class BZgraflow extends Buildoz{
|
||||
|
||||
// Force style flush, then animate back to identity (full parent size)
|
||||
childEl.getBoundingClientRect()
|
||||
childEl.style.transition = 'transform 1000ms ease-in-out'
|
||||
requestAnimationFrame(() => {
|
||||
childEl.style.top = 0;
|
||||
childEl.style.left = 0;
|
||||
childEl.style.setProperty('--tx', '0px')
|
||||
childEl.style.setProperty('--ty', '0px')
|
||||
childEl.style.setProperty('--sx', 1)
|
||||
@@ -290,6 +305,7 @@ class BZgraflow extends Buildoz{
|
||||
this.hostContainer.style.visibility = 'hidden'
|
||||
childEl.style.transform = 'none' // Important for nested subflows to position correctly
|
||||
childEl.style.willChange = ''
|
||||
newEl.style.overflow = 'auto'
|
||||
this.dispatchEvent(new CustomEvent('subflowLoaded', {
|
||||
detail: { subflow: childEl },
|
||||
bubbles: true,
|
||||
@@ -299,16 +315,14 @@ class BZgraflow extends Buildoz{
|
||||
}
|
||||
|
||||
invade(oldEl, newEl){
|
||||
// Scroll-proof overlay: position inside oldEl so it follows oldEl scrolling.
|
||||
// Ensure oldEl is a positioning context.
|
||||
const pos = getComputedStyle(oldEl).position
|
||||
if(pos === 'static') oldEl.style.position = 'relative'
|
||||
newEl.style.position = 'absolute'
|
||||
newEl.style.inset = '0'
|
||||
// Override bz-graflow's default width/height (100vw/50vh) when used as an embedded overlay
|
||||
newEl.style.width = '100%'
|
||||
newEl.style.height = '100%'
|
||||
const bbox = oldEl.getBoundingClientRect()
|
||||
newEl.style.left = `${bbox.left+bbox.width/2}px`
|
||||
newEl.style.top = `${bbox.top+bbox.height/2}px`
|
||||
newEl.style.width = `${bbox.width}px`
|
||||
newEl.style.height = `${bbox.height}px`
|
||||
newEl.style.display = 'block'
|
||||
newEl.style.overflow = 'hidden'
|
||||
oldEl.appendChild(newEl)
|
||||
}
|
||||
|
||||
@@ -459,6 +473,60 @@ class BZgraflow extends Buildoz{
|
||||
return({ x: x - r.left, y: y - r.top })
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
const startAxis = ['n', 's'].includes(dir1) ? 'v' : 'h'
|
||||
if(wireType == 'bezier'){
|
||||
return(`C ${c1x} ${c1y}, ${c2x} ${c2y}, ${x2} ${y2}`)
|
||||
}
|
||||
if(wireType == 'straight'){
|
||||
return(`L ${c1x} ${c1y} L ${c2x} ${c2y} L ${x2} ${y2}`)
|
||||
}
|
||||
if(wireType == 'ortho'){
|
||||
const medianx = (x1 + x2) / 2
|
||||
const mediany = (y1 + y2) / 2
|
||||
if(startAxis == 'v') {
|
||||
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}`)
|
||||
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 ${c1y} H ${medianx} V ${c2y} H ${x2} V ${y2}`)
|
||||
}
|
||||
}
|
||||
else {
|
||||
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}`)
|
||||
else if((dir2=='n') || (dir2=='s')) return(`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 {
|
||||
return(`H ${c1x} V ${mediany} H ${c2x} V ${y2} H ${x2}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
return('')
|
||||
}
|
||||
|
||||
linkNodes(idNode1, idPort1, idNode2, idPort2) {
|
||||
const tension = parseInt(this.getBZAttribute('tension')) || 60
|
||||
const wireType = this.getBZAttribute('wiretype') || 'bezier'
|
||||
@@ -494,24 +562,11 @@ class BZgraflow extends Buildoz{
|
||||
c2y -= 1*tension
|
||||
}
|
||||
}
|
||||
|
||||
if(wireType === 'bezier') {
|
||||
return(`M ${x1} ${y1} C ${c1x} ${c1y}, ${c2x} ${c2y}, ${x2} ${y2}`)
|
||||
}
|
||||
if(wireType === 'straight') {
|
||||
return(`M ${x1} ${y1} L ${c1x} ${c1y} L ${c2x} ${c2y} L ${x2} ${y2}`)
|
||||
}
|
||||
if(wireType === 'ortho') {
|
||||
let path = `M ${x1} ${y1} `
|
||||
if(['n', 's'].includes(port1.direction)) {
|
||||
path += `V ${(c1y+c2y)/2} H ${c2x} V ${y2}`
|
||||
} else {
|
||||
path += `H ${(c1x+c2x)/2} V ${c2y} H ${x2}`
|
||||
}
|
||||
return(path)
|
||||
}
|
||||
return('')
|
||||
const seg = this.buildSegment(x1, y1, c1x, c1y, c2x, c2y, x2, y2, wireType, node1, node2, port1.direction, port2.direction, tension, loop)
|
||||
if(!seg) return('')
|
||||
return(`M ${x1} ${y1} ${seg}`)
|
||||
}
|
||||
|
||||
linkInterNodes(idNode1, idPort1, idNode2, idPort2, interNodes, orientation='horizontal') {
|
||||
const tension = parseInt(this.getBZAttribute('tension')) || 60
|
||||
const wireType = this.getBZAttribute('wiretype') || 'bezier'
|
||||
@@ -524,38 +579,12 @@ class BZgraflow extends Buildoz{
|
||||
return('')
|
||||
}
|
||||
|
||||
const makeSegment = (x1, y1, x2, y2, orientation1, orientation2) => {
|
||||
let c1x, c1y, c2x, c2y
|
||||
if(orientation1=='horizontal') {
|
||||
c1x = Math.floor(x1 + tension)
|
||||
c1y = y1
|
||||
} else {
|
||||
c1x = x1
|
||||
c1y = Math.floor(y1 + tension)
|
||||
}
|
||||
if(orientation2=='horizontal') {
|
||||
c2x = Math.floor(x2 - tension)
|
||||
c2y = y2
|
||||
} else {
|
||||
c2x = x2
|
||||
c2y = Math.floor(y2 - tension)
|
||||
}
|
||||
if(wireType === 'bezier') {
|
||||
return(`C ${c1x} ${c1y}, ${c2x} ${c2y}, ${x2} ${y2}`)
|
||||
}
|
||||
if(wireType === 'straight') {
|
||||
return(`L ${c1x} ${c1y} L ${c2x} ${c2y} L ${x2} ${y2}`)
|
||||
}
|
||||
if(wireType === 'ortho') {
|
||||
let path = `M ${x1} ${y1} `
|
||||
if(['n', 's'].includes(port1.direction)) {
|
||||
path += `V ${(c1y+c2y)/2} H ${c2x} V ${y2}`
|
||||
} else {
|
||||
path += `H ${(c1x+c2x)/2} V ${c2y} H ${x2}`
|
||||
}
|
||||
return(path)
|
||||
}
|
||||
return(``)
|
||||
const makeSegment = (x1, y1, x2, y2, node1, node2, dir1, dir2, tension) => {
|
||||
const c1x = Math.floor(x1 + (this.dirVect[dir1].x * tension))
|
||||
const c1y = Math.floor(y1 + (this.dirVect[dir1].y * tension))
|
||||
const c2x = Math.floor(x2 + (this.dirVect[dir2].x * tension))
|
||||
const c2y = Math.floor(y2 + (this.dirVect[dir2].y * tension))
|
||||
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)
|
||||
@@ -569,6 +598,8 @@ class BZgraflow extends Buildoz{
|
||||
const yEnd = Math.floor(ep.y)
|
||||
let path = `M ${x1} ${y1} `
|
||||
|
||||
const entryDir = (orientation == 'horizontal') ? 'w' : 'n'
|
||||
const exitDir = (orientation == 'horizontal') ? 'e' : 's'
|
||||
let firstPort = port1
|
||||
for(const interNode of interNodes){
|
||||
const bb = this.stagedNodes[interNode].getBoundingClientRect()
|
||||
@@ -587,10 +618,10 @@ class BZgraflow extends Buildoz{
|
||||
let y2 = Math.floor(entry.y)
|
||||
|
||||
if(firstPort){
|
||||
path += makeSegment(x1, y1, x2, y2, ['w','e'].includes(firstPort.direction) ? 'horizontal' : 'vertical', orientation)
|
||||
path += makeSegment(x1, y1, x2, y2, node1, node2, firstPort.direction, entryDir, tension)
|
||||
firstPort = null
|
||||
} else {
|
||||
path += makeSegment(x1, y1, x2, y2, orientation, orientation)
|
||||
path += makeSegment(x1, y1, x2, y2, node1, node2, exitDir, entryDir, tension)
|
||||
}
|
||||
|
||||
const x3 = Math.floor(exit.x)
|
||||
@@ -600,7 +631,7 @@ class BZgraflow extends Buildoz{
|
||||
x1 = x3
|
||||
y1 = y3
|
||||
}
|
||||
path += ' ' + makeSegment(x1, y1, xEnd, yEnd, orientation, orientation)
|
||||
path += ' ' + makeSegment(x1, y1, xEnd, yEnd, node1, node2, exitDir, port2.direction, tension)
|
||||
return(path)
|
||||
}
|
||||
|
||||
@@ -610,8 +641,6 @@ class BZgraflow extends Buildoz{
|
||||
if(tween == null) tween = parseInt(this.getBZAttribute('tween')) || 500
|
||||
if(align == null) align = this.getBZAttribute('align') || 'center'
|
||||
|
||||
console.log('autoPlace', orientation, gapx, gapy, tween, align)
|
||||
|
||||
this.currentOrientation = orientation
|
||||
// Cancel any previous autoPlace() animations by bumping a token.
|
||||
// moveNode() checks this token each frame and will no-op if superseded.
|
||||
@@ -711,44 +740,97 @@ class BZgraflow extends Buildoz{
|
||||
// Finally place everything
|
||||
if(orientation=='horizontal'){
|
||||
const fakeNodeHeight = 10
|
||||
const parentsY = {}
|
||||
const nodeY = {}
|
||||
const nodeX = {}
|
||||
let x = gapx
|
||||
for(const [idx, layer] of layers.entries()){
|
||||
let wMax = this.getMaxWidth(layer)
|
||||
let y = 0
|
||||
switch(align){
|
||||
case'center':
|
||||
case 'center':
|
||||
y = ((maxHeight - layerHeights[idx]) / 2) + gapy
|
||||
break
|
||||
case'first':
|
||||
case 'first':
|
||||
y = gapy
|
||||
break
|
||||
case'last':
|
||||
case 'last':
|
||||
y = maxHeight - layerHeights[idx] + gapy
|
||||
break
|
||||
case 'auto':
|
||||
//TODO
|
||||
case 'parent': // y will be absolutely positioned by the parent(s) but have fallback for 1st layer
|
||||
y = ((maxHeight - layerHeights[idx]) / 2) + gapy
|
||||
break
|
||||
}
|
||||
for(const nid of layer){
|
||||
let placedY
|
||||
if(!nid.startsWith('longLinkPlaceHolder_')) {
|
||||
const bb = this.stagedNodes[nid].getBoundingClientRect()
|
||||
this.moveNode(nid, x, y, orientation, tween, null, token)
|
||||
y += gapy + (this.stagedNodes[nid].offsetHeight || bb.height)
|
||||
const nodeHeight = this.stagedNodes[nid].offsetHeight || bb.height
|
||||
if((align == 'parent') && (nid in parents) && (parents[nid][0] in parentsY)) {
|
||||
y = Math.max(parentsY[parents[nid][0]], y) //TODO handle multiple parents with avg
|
||||
console.log('parent', nid, parents[nid], parentsY[parents[nid][0]])
|
||||
}
|
||||
placedY = y
|
||||
this.moveNode(nid, x, y, orientation, tween, null, token)
|
||||
if((align == 'parent') && (nid in parents) && (parents[nid][0] in parentsY)) {
|
||||
parentsY[parents[nid][0]] += gapy + nodeHeight
|
||||
} else {
|
||||
y += gapy + nodeHeight
|
||||
}
|
||||
y = Math.max(y, placedY + gapy + nodeHeight)
|
||||
} else {
|
||||
if((align == 'parent') && (nid in parents) && (parents[nid][0] in parentsY)) {
|
||||
y = Math.max(parentsY[parents[nid][0]], y)
|
||||
}
|
||||
placedY = y
|
||||
this.addFakeNode(nid, x, y, wMax*0.75, fakeNodeHeight)
|
||||
this.moveNode(nid, x, y, orientation, tween, null, token)
|
||||
y += gapy + fakeNodeHeight
|
||||
// Never increment parentsY for fake nodes: they're placeholders and must not disalign real children
|
||||
y = Math.max(y, placedY + gapy + fakeNodeHeight)
|
||||
}
|
||||
parentsY[nid] = placedY
|
||||
nodeY[nid] = placedY
|
||||
nodeX[nid] = x
|
||||
}
|
||||
x += wMax + gapx
|
||||
}
|
||||
// Correct parent positions: when fake nodes pushed children down, align parents with their first real child
|
||||
if(align == 'parent'){
|
||||
for(let idx = 1; idx < layers.length; idx++){
|
||||
const layer = layers[idx]
|
||||
const prevLayer = layers[idx - 1]
|
||||
for(const pid of prevLayer){
|
||||
if(pid.startsWith('longLinkPlaceHolder_')) continue
|
||||
const firstRealChild = layer.find(nid =>
|
||||
!nid.startsWith('longLinkPlaceHolder_') && nid in parents && parents[nid][0] === pid
|
||||
)
|
||||
if(firstRealChild && nodeY[pid] !== nodeY[firstRealChild]){
|
||||
this.moveNode(pid, nodeX[pid], nodeY[firstRealChild], orientation, tween, null, token)
|
||||
nodeY[pid] = nodeY[firstRealChild]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(orientation=='vertical'){
|
||||
const fakeNodeWidth = 10
|
||||
let y = gapy
|
||||
for(const [idx, layer] of layers.entries()){
|
||||
let hMax = this.getMaxHeight(layer)
|
||||
let x = ((maxWidth - layerWidths[idx]) / 2) + gapx
|
||||
let x = 0
|
||||
switch(align){
|
||||
case 'center':
|
||||
x = ((maxWidth - layerWidths[idx]) / 2) + gapx
|
||||
break
|
||||
case 'first':
|
||||
x = gapx
|
||||
break
|
||||
case 'last':
|
||||
x = maxWidth - layerWidths[idx] + gapx
|
||||
break
|
||||
case 'parent': // x will be absolutely positioned by the parent(s)
|
||||
//TODO
|
||||
break
|
||||
}
|
||||
for(const nid of layer){
|
||||
if(!nid.startsWith('longLinkPlaceHolder_')){
|
||||
const bb = this.stagedNodes[nid].getBoundingClientRect()
|
||||
@@ -1075,6 +1157,17 @@ class BZgraflow extends Buildoz{
|
||||
return(crossLayerLinks)
|
||||
}
|
||||
|
||||
autofit(){
|
||||
const parentBB = this.parentElement.getBoundingClientRect()
|
||||
// Use scroll dimensions for actual content extent (nodes can extend beyond element bounds)
|
||||
const contentW = Math.max(this.scrollWidth || this.offsetWidth || 1, 1)
|
||||
const contentH = Math.max(this.scrollHeight || this.offsetHeight || 1, 1)
|
||||
const sx = parentBB.width / contentW
|
||||
const sy = parentBB.height / contentH
|
||||
const scale = Math.min(sx, sy) // uniform scale to fit inside parent
|
||||
this.style.transformOrigin = 'top left'
|
||||
this.style.transform = `scale(${scale})`
|
||||
}
|
||||
}
|
||||
Buildoz.define('graflow', BZgraflow)
|
||||
|
||||
@@ -1083,6 +1176,14 @@ class MovingNodes{
|
||||
this.graflow = graflow
|
||||
this.nodesContainer = this.graflow.mainContainer.querySelector('.bzgf-nodes-container')
|
||||
this.state = null
|
||||
|
||||
this.interactiveElementsSelector = `
|
||||
input,
|
||||
textarea,
|
||||
select,
|
||||
button,
|
||||
a[href]
|
||||
`
|
||||
}
|
||||
|
||||
enableMovingNodes(itemSelector, handleSelector = itemSelector) {
|
||||
@@ -1095,16 +1196,44 @@ class MovingNodes{
|
||||
this._handleCursorStyle = style
|
||||
}
|
||||
|
||||
this.nodesContainer.addEventListener('pointerdown', this.pointerDown.bind(this))
|
||||
this.nodesContainer.querySelectorAll(this.handleSelector).forEach(item =>
|
||||
item.addEventListener('pointerdown', this.pointerDown.bind(this))
|
||||
)
|
||||
this.nodesContainer.addEventListener('pointermove', this.pointerMove.bind(this))
|
||||
this.nodesContainer.addEventListener('pointerup', this.pointerUp.bind(this))
|
||||
this.nodesContainer.querySelectorAll(this.handleSelector).forEach(item =>
|
||||
item.addEventListener('pointerup', this.pointerUp.bind(this))
|
||||
)
|
||||
}
|
||||
|
||||
disableMovingNodes(){
|
||||
this.nodesContainer.querySelectorAll(this.handleSelector).forEach(item =>
|
||||
item.removeEventListener('pointerdown', this.pointerDown.bind(this))
|
||||
)
|
||||
this.nodesContainer.removeEventListener('pointermove', this.pointerMove.bind(this))
|
||||
this.nodesContainer.querySelectorAll(this.handleSelector).forEach(item =>
|
||||
item.removeEventListener('pointerup', this.pointerUp.bind(this))
|
||||
)
|
||||
}
|
||||
|
||||
pointerDown(e){
|
||||
this.graflow.clearFakeNodes()
|
||||
const node = (e.target.classList.contains(this.itemSelector)) ? e.target : e.target.closest(this.itemSelector)
|
||||
const handle = (node.classList.contains(this.handleSelector)) ? node : node.querySelector(this.handleSelector)
|
||||
console.log('=====> interactive element', e.target)
|
||||
|
||||
const node = e.target.closest(this.itemSelector)
|
||||
if(!node) return
|
||||
|
||||
let handle
|
||||
if(this.handleSelector == this.itemSelector) {
|
||||
handle = node
|
||||
if(e.target.closest(this.interactiveElementsSelector)) return
|
||||
e.preventDefault()
|
||||
} else { // If defined handle, then no need to care about interactive elements
|
||||
handle = node.querySelector(this.handleSelector)
|
||||
if(e.target != handle) return
|
||||
}
|
||||
|
||||
|
||||
|
||||
const rect = node.getBoundingClientRect()
|
||||
|
||||
this.state = {
|
||||
@@ -1123,6 +1252,7 @@ class MovingNodes{
|
||||
node.style.top = `${y}px`
|
||||
node.style.margin = '0'
|
||||
node.style.zIndex = '9999'
|
||||
node.style.pointerEvents = 'none'
|
||||
}
|
||||
|
||||
pointerMove(e){
|
||||
@@ -1138,6 +1268,33 @@ class MovingNodes{
|
||||
pointerUp(e){
|
||||
if(!this.state) return
|
||||
this.state.node.releasePointerCapture(e.pointerId)
|
||||
this.state.node.style.pointerEvents = ''
|
||||
this.state = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class EditWires{
|
||||
constructor(graflow){
|
||||
this.graflow = graflow
|
||||
this.nodesContainer = this.graflow.mainContainer.querySelector('.bzgf-nodes-container')
|
||||
this.state = null
|
||||
}
|
||||
enableEditWires(){
|
||||
for(const ref in this.graflow.stagedWires ){
|
||||
this.graflow.stagedWires[ref].addEventListener('click', this.onSelectWire.bind(this))
|
||||
}
|
||||
}
|
||||
onSelectWire(e){
|
||||
const wire = e.target
|
||||
console.log('wire', wire)
|
||||
}
|
||||
}
|
||||
|
||||
class DroppingNodes{
|
||||
constructor(graflow){
|
||||
this.graflow = graflow
|
||||
this.nodesContainer = this.graflow.mainContainer.querySelector('.bzgf-nodes-container')
|
||||
this.state = null
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user