This commit is contained in:
trading_peter 2024-12-18 22:11:06 +01:00
parent 80f69bf09c
commit 6af27de3dd
2 changed files with 117 additions and 8 deletions

View File

@ -7,12 +7,45 @@ export const connectionStyles = css`
.connections path {
transition: stroke 0.3s ease, stroke-width 0.3s ease;
pointer-events: all;
cursor: pointer;
}
.connections path:hover {
stroke: #999;
stroke-width: 3;
}
.connections path.selected {
stroke: #3498db;
stroke-width: 3;
}
.delete-button-group {
pointer-events: all;
cursor: pointer;
}
.delete-button-group:hover .delete-button-circle {
fill: #c0392b;
}
.delete-button-circle {
fill: #e74c3c;
transition: fill 0.2s ease;
}
.delete-button-x {
stroke: white;
stroke-width: 2;
}
.delete-button-group {
pointer-events: all;
cursor: pointer;
/* Ensure buttons are always on top of nodes */
z-index: 1000;
}
`;
export const connections = function(superClass) {
@ -27,6 +60,12 @@ export const connections = function(superClass) {
firstUpdated() {
this.addEventListener('port-click', this._handlePortClick);
document.addEventListener('mousemove', this._updatePreviewConnection.bind(this));
this.canvas.addEventListener('click', (e) => {
if (e.target === this.canvas) {
this.selectedConnection = null;
this.requestUpdate();
}
});
super.firstUpdated();
}
@ -130,19 +169,89 @@ export const connections = function(superClass) {
y: end.y
};
// Helper function to get point on cubic bezier curve at t (0-1)
const getPointOnCurve = (t) => {
const t1 = 1 - t;
return {
x: Math.pow(t1, 3) * start.x +
3 * Math.pow(t1, 2) * t * controlPoint1.x +
3 * t1 * Math.pow(t, 2) * controlPoint2.x +
Math.pow(t, 3) * end.x,
y: Math.pow(t1, 3) * start.y +
3 * Math.pow(t1, 2) * t * controlPoint1.y +
3 * t1 * Math.pow(t, 2) * controlPoint2.y +
Math.pow(t, 3) * end.y
};
};
// Get points at 15% and 85% along the curve
const startButton = getPointOnCurve(0.15);
const endButton = getPointOnCurve(0.85);
const path = `M${start.x},${start.y} C${controlPoint1.x},${controlPoint1.y} ${controlPoint2.x},${controlPoint2.y} ${end.x},${end.y}`;
const isSelected = this.selectedConnection === conn.id;
return svg`
<g>
<path
d="${path}"
fill="none"
stroke="#666"
stroke-width="2"
id="${conn.id}"
class="${isSelected ? 'selected' : ''}"
@click="${() => this._handleConnectionClick(conn.id)}"
/>
${isSelected ? svg`
<g>
<!-- Source delete button -->
<g class="delete-button-group" @click="${() => this._deleteConnection(conn.id)}">
<circle
class="delete-button-circle"
cx="${startButton.x}"
cy="${startButton.y}"
r="8"
/>
<path
class="delete-button-x"
d="M ${startButton.x-4},${startButton.y-4} L ${startButton.x+4},${startButton.y+4} M ${startButton.x-4},${startButton.y+4} L ${startButton.x+4},${startButton.y-4}"
/>
</g>
<!-- Target delete button -->
<g class="delete-button-group" @click="${() => this._deleteConnection(conn.id)}">
<circle
class="delete-button-circle"
cx="${endButton.x}"
cy="${endButton.y}"
r="8"
/>
<path
class="delete-button-x"
d="M ${endButton.x-4},${endButton.y-4} L ${endButton.x+4},${endButton.y+4} M ${endButton.x-4},${endButton.y+4} L ${endButton.x+4},${endButton.y-4}"
/>
</g>
</g>
` : ''}
</g>
`;
}
_handleConnectionClick(connectionId) {
// Deselect if clicking the same connection
if (this.selectedConnection === connectionId) {
this.selectedConnection = null;
} else {
this.selectedConnection = connectionId;
}
this.requestUpdate();
}
_deleteConnection(connectionId) {
this.connections = this.connections.filter(conn => conn.id !== connectionId);
this.selectedConnection = null;
this.requestUpdate();
}
_handlePortClick(e) {
const { nodeId, portType, portId, portName } = e.detail;

View File

@ -29,11 +29,11 @@ export const panning = function(superClass) {
}
firstUpdated() {
super.firstUpdated();
this.canvas = this.shadowRoot.querySelector('.canvas');
this.addEventListener('mousedown', this._startDrag.bind(this));
document.addEventListener('mousemove', this._drag.bind(this));
document.addEventListener('mouseup', this._endDrag.bind(this));
super.firstUpdated();
}
_getTopNodeAtPoint(x, y) {