wip
This commit is contained in:
102
connections.js
102
connections.js
@@ -60,12 +60,39 @@ export const connections = function(superClass) {
|
||||
firstUpdated() {
|
||||
this.addEventListener('port-click', this._handlePortClick);
|
||||
document.addEventListener('mousemove', this._updatePreviewConnection.bind(this));
|
||||
this.canvas.addEventListener('click', (e) => {
|
||||
|
||||
document.addEventListener('click', (e) => {
|
||||
// Check if clicking on an output port
|
||||
const path = e.composedPath();
|
||||
const isOutputPort = path.some(el =>
|
||||
el instanceof HTMLElement &&
|
||||
el.classList &&
|
||||
el.classList.contains('output-ports')
|
||||
);
|
||||
|
||||
// Only cancel connection if we're dragging AND it's not an output port
|
||||
if (this.draggingConnection && !isOutputPort) {
|
||||
// Check if we clicked on an input port
|
||||
const isInputPort = path.some(el =>
|
||||
el instanceof HTMLElement &&
|
||||
el.classList &&
|
||||
el.classList.contains('input-ports')
|
||||
);
|
||||
|
||||
// If not an input port, cancel the connection
|
||||
if (!isInputPort) {
|
||||
this.draggingConnection = null;
|
||||
this.requestUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
// Handle existing connection deselection
|
||||
if (e.target === this.canvas) {
|
||||
this.selectedConnection = null;
|
||||
this.requestUpdate();
|
||||
}
|
||||
});
|
||||
|
||||
super.firstUpdated();
|
||||
}
|
||||
|
||||
@@ -80,8 +107,31 @@ export const connections = function(superClass) {
|
||||
}
|
||||
|
||||
_renderConnections() {
|
||||
const bounds = this._calculateSVGBounds();
|
||||
|
||||
// Handle initial render when canvas is not ready
|
||||
const style = this.canvas ? `
|
||||
position: absolute;
|
||||
top: ${bounds.minY}px;
|
||||
left: ${bounds.minX}px;
|
||||
width: ${bounds.width}px;
|
||||
height: ${bounds.height}px;
|
||||
pointer-events: none;
|
||||
` : `
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
`;
|
||||
|
||||
return html`
|
||||
<svg class="connections" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none;">
|
||||
<svg
|
||||
class="connections"
|
||||
style="${style}"
|
||||
viewBox="${this.canvas ? `${bounds.minX} ${bounds.minY} ${bounds.width} ${bounds.height}` : '0 0 100 100'}"
|
||||
>
|
||||
${this.connections.map(conn => this._renderConnection(conn))}
|
||||
${this.draggingConnection ? this._renderPreviewConnection() : null}
|
||||
</svg>
|
||||
@@ -138,7 +188,7 @@ export const connections = function(superClass) {
|
||||
const sourceNode = this.nodes.find(node => node.id === conn.sourceNodeId);
|
||||
const targetNode = this.nodes.find(node => node.id === conn.targetNodeId);
|
||||
|
||||
if (!sourceNode || !targetNode) return '';
|
||||
if (!sourceNode?.shadowRoot || !targetNode?.shadowRoot) return '';
|
||||
|
||||
const sourcePort = sourceNode.shadowRoot.querySelector(`.output-ports [data-port-id="${conn.sourcePortId}"]`);
|
||||
const targetPort = targetNode.shadowRoot.querySelector(`.input-ports [data-port-id="${conn.targetPortId}"]`);
|
||||
@@ -247,8 +297,17 @@ export const connections = function(superClass) {
|
||||
}
|
||||
|
||||
_deleteConnection(connectionId) {
|
||||
const connection = this.connections.find(conn => conn.id === connectionId);
|
||||
this.connections = this.connections.filter(conn => conn.id !== connectionId);
|
||||
this.selectedConnection = null;
|
||||
|
||||
if (connection) {
|
||||
this._dispatchChangeEvent({
|
||||
type: 'connection-removed',
|
||||
data: { connectionId }
|
||||
});
|
||||
}
|
||||
|
||||
this.requestUpdate();
|
||||
}
|
||||
|
||||
@@ -282,11 +341,48 @@ export const connections = function(superClass) {
|
||||
};
|
||||
|
||||
this.connections = [...this.connections, connection];
|
||||
|
||||
this._dispatchChangeEvent({
|
||||
type: 'connection-added',
|
||||
data: connection
|
||||
});
|
||||
}
|
||||
}
|
||||
this.draggingConnection = null;
|
||||
this.requestUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
_calculateSVGBounds() {
|
||||
// If canvas is not ready yet, return default bounds
|
||||
if (!this.canvas) {
|
||||
return {
|
||||
minX: 0,
|
||||
minY: 0,
|
||||
width: '100%',
|
||||
height: '100%'
|
||||
};
|
||||
}
|
||||
|
||||
let minX = 0, minY = 0, maxX = 0, maxY = 0;
|
||||
const canvasRect = this.canvas.getBoundingClientRect();
|
||||
|
||||
// Include all node positions
|
||||
this.nodes.forEach(node => {
|
||||
const rect = node.getBoundingClientRect();
|
||||
minX = Math.min(minX, (rect.left - canvasRect.left) / this.scale);
|
||||
minY = Math.min(minY, (rect.top - canvasRect.top) / this.scale);
|
||||
maxX = Math.max(maxX, (rect.right - canvasRect.left) / this.scale);
|
||||
maxY = Math.max(maxY, (rect.bottom - canvasRect.top) / this.scale);
|
||||
});
|
||||
|
||||
const padding = 1000;
|
||||
return {
|
||||
minX: minX - padding,
|
||||
minY: minY - padding,
|
||||
width: maxX - minX + (padding * 2),
|
||||
height: maxY - minY + (padding * 2)
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user