Update reveal node styling

pull/5562/head
Nick O'Leary 2026-03-11 17:21:23 +00:00
parent 5232ec0373
commit 5d4c7b9749
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
4 changed files with 152 additions and 55 deletions

View File

@ -421,24 +421,16 @@ RED.sidebar.config = (function() {
//cancel current flashing node before flashing new node
clearInterval(flashingConfigNodeTimer);
flashingConfigNodeTimer = null;
flashingConfigNode.children("div").removeClass('highlighted');
flashingConfigNode.children("div").removeClass('red-ui-flow-node-highlighted');
flashingConfigNode = null;
}
if(!el || !el.children("div").length) { return; }
flashingConfigNodeTimer = setInterval(function(flashEndTime) {
if (flashEndTime >= Date.now()) {
const highlighted = el.children("div").hasClass("highlighted");
el.children("div").toggleClass('highlighted', !highlighted)
} else {
clearInterval(flashingConfigNodeTimer);
flashingConfigNodeTimer = null;
flashingConfigNode = null;
el.children("div").removeClass('highlighted');
}
}, 100, Date.now() + 2200);
flashingConfigNodeTimer = setTimeout(function() {
flashingConfigNode.children("div").removeClass('red-ui-flow-node-highlighted');
}, 8100)
flashingConfigNode = el;
el.children("div").addClass('highlighted');
flashingConfigNode.children("div").addClass('red-ui-flow-node-highlighted');
}
function show(id) {

View File

@ -3446,6 +3446,9 @@ RED.view = (function() {
movingSet.clear();
selectedLinks.clear();
selectedGroups.clear();
$(".red-ui-flow-node-highlighted").removeClass("red-ui-flow-node-highlighted");
$(".red-ui-flow-group-highlighted").removeClass("red-ui-flow-group-highlighted");
cancelFlash();
}
var lastSelection = null;
@ -5220,6 +5223,7 @@ RED.view = (function() {
// - node is disabled
if (!showStatus || !d.status || d.d === true) {
nodeEl.__statusGroup__.style.display = "none";
d.statusHeight = 0;
} else {
nodeEl.__statusGroup__.style.display = "inline";
let backgroundWidth = 15
@ -5246,6 +5250,7 @@ RED.view = (function() {
if (backgroundWidth > 0 && textSize.width > 0) {
backgroundWidth += 6
}
d.statusHeight = nodeEl.__statusGroup__.getBBox().height
nodeEl.__statusBackground__.setAttribute('width', backgroundWidth)
}
delete d.dirtyStatus;
@ -5290,7 +5295,7 @@ RED.view = (function() {
.on("touchstart",nodeTouchStart)
.on("touchend",nodeTouchEnd)
nodeContents.appendChild(mainRect);
const port_label_group = document.createElementNS("http://www.w3.org/2000/svg","g");
port_label_group.setAttribute("x",0);
port_label_group.setAttribute("y",0);
@ -5704,6 +5709,15 @@ RED.view = (function() {
nodeContents.appendChild(statusEl);
const nodeHalo = document.createElementNS("http://www.w3.org/2000/svg","rect");
nodeHalo.setAttribute("class", "red-ui-flow-node-highlight");
nodeHalo.setAttribute("rx", 5);
nodeHalo.setAttribute("ry", 5);
nodeHalo.setAttribute("x", -10)
nodeHalo.setAttribute("y", -10)
node[0][0].__halo__ = nodeHalo;
nodeContents.appendChild(nodeHalo);
node[0][0].appendChild(nodeContents);
if (!d.__ghost) {
@ -5771,11 +5785,15 @@ RED.view = (function() {
// This might be the first redraw after a node has been click-dragged to start a move.
// So its selected state might have changed since the last redraw.
this.classList.toggle("red-ui-flow-node-selected", !!d.selected )
this.classList.toggle("red-ui-flow-node-highlighted",!!d.highlighted );
if (mouse_mode != RED.state.MOVING_ACTIVE) {
this.classList.toggle("red-ui-flow-node-disabled", d.d === true);
this.__mainRect__.setAttribute("width", d.w)
this.__mainRect__.setAttribute("height", d.h)
this.__mainRect__.classList.toggle("red-ui-flow-node-highlighted",!!d.highlighted );
this.__halo__.setAttribute("width", d.w + 20)
this.__halo__.setAttribute("height", d.h + 20 + (d.statusHeight || 0))
if (labelParts) {
// The label has changed
@ -5996,6 +6014,7 @@ RED.view = (function() {
});
if (d._def.button) {
let buttonVisible = true
var buttonEnabled = isButtonEnabled(d);
this.__buttonGroup__.classList.toggle("red-ui-flow-node-button-disabled", !buttonEnabled);
if (RED.runtime && RED.runtime.started !== undefined) {
@ -6016,11 +6035,18 @@ RED.view = (function() {
if (typeof d._def.button.visible === "function") { // is defined and a function...
if (d._def.button.visible.call(d) === false) {
this.__buttonGroup__.style.display = "none";
}
else {
buttonVisible = false
} else {
this.__buttonGroup__.style.display = "inherit";
}
}
// Need to adjust the halo to encompass the button
if (buttonVisible) {
this.__halo__.setAttribute("width", d.w + 40)
if (d._def.align !== 'right') {
this.__halo__.setAttribute("x", -30)
}
}
}
// thisNode.selectAll(".node_badge_group").attr("transform",function(d){return "translate("+(d.w-40)+","+(d.h+3)+")";});
// thisNode.selectAll("text.node_badge_label").text(function(d,i) {
@ -6571,6 +6597,11 @@ RED.view = (function() {
} else {
selectGroup.classList.remove("red-ui-flow-group-selected")
}
if (d.highlighted) {
selectGroup.classList.add("red-ui-flow-group-highlighted")
} else {
selectGroup.classList.remove("red-ui-flow-group-highlighted")
}
var selectGroupRect = selectGroup.children[0];
// Background
selectGroupRect.setAttribute("width",d.w+6)
@ -6579,19 +6610,12 @@ RED.view = (function() {
selectGroupRect = selectGroup.children[1];
selectGroupRect.setAttribute("width",d.w+6)
selectGroupRect.setAttribute("height",d.h+6)
selectGroupRect.style.strokeOpacity = (d.selected || d.highlighted)?0.8:0;
// selectGroupRect.style.strokeOpacity = (d.selected || d.highlighted)?0.8:0;
// Line
selectGroupRect = selectGroup.children[2];
selectGroupRect.setAttribute("width",d.w+6)
selectGroupRect.setAttribute("height",d.h+6)
selectGroupRect.style.strokeOpacity = (d.selected || d.highlighted)?0.8:0;
if (d.highlighted) {
selectGroup.classList.add("red-ui-flow-node-highlighted");
} else {
selectGroup.classList.remove("red-ui-flow-node-highlighted");
}
// selectGroupRect.style.strokeOpacity = (d.selected || d.highlighted)?0.8:0;
g.selectAll(".red-ui-flow-group-body")
.attr("width",d.w)
@ -7304,33 +7328,28 @@ RED.view = (function() {
return result;
}
function flashNode(n) {
let node = n;
if(typeof node === "string") { node = RED.nodes.node(n); }
if(!node) { return; }
const flashingNode = flashingNodeId && RED.nodes.node(flashingNodeId);
if(flashingNode) {
//cancel current flashing node before flashing new node
clearInterval(flashingNode.__flashTimer);
function cancelFlash() {
const flashingNode = flashingNodeId && (RED.nodes.node(flashingNodeId) || RED.nodes.group(flashingNodeId));
if (flashingNode) {
clearTimeout(flashingNode.__flashTimer);
delete flashingNode.__flashTimer;
flashingNode.dirty = true;
flashingNode.highlighted = false;
_redraw()
}
node.__flashTimer = setInterval(function(flashEndTime, n) {
}
function flashNode(n) {
let node = n;
if (typeof node === "string") { node = RED.nodes.node(n); }
if (!node) { return; }
cancelFlash()
node.__flashTimer = setTimeout(function(n) {
n.dirty = true;
if (flashEndTime >= Date.now()) {
n.highlighted = !n.highlighted;
} else {
clearInterval(n.__flashTimer);
delete n.__flashTimer;
flashingNodeId = null;
n.highlighted = false;
}
n.highlighted = false;
RED.view.redraw();
}, 100, Date.now() + 2200, node)
}, 8100, node)
flashingNodeId = node.id;
node.dirty = true;
node.highlighted = true;
RED.view.redraw();
}

View File

@ -135,6 +135,25 @@
}
}
.red-ui-flow-group.red-ui-flow-group-selected {
.red-ui-flow-group-outline-select-outline,
.red-ui-flow-group-outline-select-line {
stroke-opacity: 0.8;// !important;
}
}
.red-ui-flow-group.red-ui-flow-group-highlighted {
.red-ui-flow-group-outline-select-line {
stroke-width: 4;
stroke-opacity: 1;
stroke-dasharray: 8, 4;
animation-duration: 8s;
animation-name: node-reveal-highlight;
animation-timing-function: ease-out;
animation-iteration-count: 1;
}
}
svg:not(.red-ui-workspace-lasso-active) {
.red-ui-flow-group:not(.red-ui-flow-group-selected) {
.red-ui-flow-group-outline-select.red-ui-flow-group-outline-select-background:hover {
@ -273,17 +292,83 @@ g.red-ui-flow-node-selected {
stroke: var(--red-ui-node-selected-color) !important;
}
}
.red-ui-flow-node-highlighted {
.red-ui-flow-node-highlight {
border-color: var(--red-ui-node-selected-color) !important;
border-style: dashed !important;
stroke: var(--red-ui-node-selected-color);
stroke-width: 3;
stroke-width: 4;
stroke-opacity: 0;
stroke-dasharray: 8, 4;
fill: none;
pointer-events: none;
.red-ui-flow-node-highlighted & {
animation-duration: 8s;
animation-name: node-reveal-highlight;
animation-timing-function: ease-out;
animation-iteration-count: 1;
}
}
.red-ui-flow-subflow .red-ui-flow-node {
@keyframes node-reveal-highlight {
from {
stroke-opacity: 1;
}
2% { stroke-opacity: 1;}
3% { stroke-opacity: 0 ;}
4% { stroke-opacity: 1 ;}
5% { stroke-opacity: 0 ;}
6% { stroke-opacity: 1 ;}
7% { stroke-opacity: 0 ;}
8% { stroke-opacity: 1 ;}
9% { stroke-opacity: 0 ;}
10% { stroke-opacity: 1 ;}
11% { stroke-opacity: 0 ;}
12% { stroke-opacity: 1;}
13% { stroke-opacity: 0 ;}
14% { stroke-opacity: 1 ;}
15% { stroke-opacity: 0 ;}
16% { stroke-opacity: 1 ;}
80% {
stroke-opacity: 1;
}
to {
stroke-opacity: 0;
}
}
.red-ui-palette-node.red-ui-flow-node-highlighted {
border-color: transparent;
outline: dashed var(--red-ui-node-selected-color) 4px;
animation-duration: 8s;
animation-name: config-node-reveal-highlight;
animation-timing-function: ease-out;
animation-iteration-count: 1;
}
@keyframes config-node-reveal-highlight {
from {
outline-color: var(--red-ui-node-selected-color);
}
2% { outline-color: var(--red-ui-node-selected-color);}
3% { outline-color: transparent ;}
4% { outline-color: var(--red-ui-node-selected-color) ;}
5% { outline-color: transparent ;}
6% { outline-color: var(--red-ui-node-selected-color) ;}
7% { outline-color: transparent ;}
8% { outline-color: var(--red-ui-node-selected-color) ;}
9% { outline-color: transparent ;}
10% { outline-color: var(--red-ui-node-selected-color) ;}
11% { outline-color: transparent ;}
12% { outline-color: var(--red-ui-node-selected-color) ;}
13% { outline-color: transparent ;}
14% { outline-color: var(--red-ui-node-selected-color) ;}
15% { outline-color: transparent ;}
16% { outline-color: var(--red-ui-node-selected-color) ;}
80% {
outline-color: var(--red-ui-node-selected-color) ;
}
to {
outline-color: transparent ;
}
}
.red-ui-workspace-disabled {
.red-ui-flow-node {
stroke-dasharray: 8, 3;

View File

@ -62,10 +62,11 @@ ul.red-ui-sidebar-node-config-list {
border-color: transparent;
box-shadow: 0 0 0 2px var(--red-ui-node-selected-color);
}
&.highlighted {
border-color: transparent;
outline: dashed var(--red-ui-node-selected-color) 4px;
}
// Highlighted state handled in flow.scss
// &.red-ui-flow-node-highlighted {
// border-color: transparent;
// outline: dashed var(--red-ui-node-selected-color) 4px;
// }
}
.red-ui-palette-label {
margin-left: 8px;