From a21b302922b3f8c7a6c8e2b37c520acd20f97bd3 Mon Sep 17 00:00:00 2001 From: Kirigaya <1193466151@qq.com> Date: Tue, 31 Dec 2024 14:19:57 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=A4=9A=E6=AC=A1=E7=82=B9?= =?UTF-8?q?=E5=87=BB=E8=84=89=E5=86=B2=E7=89=B9=E6=95=88=E5=87=BA=E7=8E=B0?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hook/algorithm/range-tree.js | 38 ++++++++++++++++++++++++++++++++ src/hook/render/wire.js | 20 ++++++++++++----- src/hook/skin/plusation.js | 16 +++++++++++--- 3 files changed, 66 insertions(+), 8 deletions(-) diff --git a/src/hook/algorithm/range-tree.js b/src/hook/algorithm/range-tree.js index 908e3ab..9f967ca 100644 --- a/src/hook/algorithm/range-tree.js +++ b/src/hook/algorithm/range-tree.js @@ -47,12 +47,26 @@ export class RangeTreeMap { let degree = 0; const horizontalSegments = this.horizontal.get(y) || []; const verticalSegments = this.vertical.get(x) || []; + + let horizontalStartLocation = 0; + let horizontalEndLocation = 0; + let verticalStartLocation = 0; + let verticalEndLocation = 0; + for (const segment of horizontalSegments) { const x1 = Math.min(segment.x1, segment.x2); const x2 = Math.max(segment.x1, segment.x2); if (x1 <= x && x <= x2) { degree ++; } + + if (x1 === x) { + horizontalStartLocation ++; + } + + if (x2 === x) { + horizontalEndLocation ++; + } } for (const segment of verticalSegments) { @@ -61,6 +75,30 @@ export class RangeTreeMap { if (y1 <= y && y <= y2) { degree ++; } + + if (y1 === y) { + verticalStartLocation ++; + } + + if (y2 === y) { + verticalEndLocation ++; + } + } + + if (horizontalStartLocation > 1) { + degree -= horizontalStartLocation - 1; + } + + if (horizontalEndLocation > 1) { + degree -= horizontalEndLocation - 1; + } + + if (verticalStartLocation > 1) { + degree -= verticalStartLocation - 1; + } + + if (verticalEndLocation > 1) { + degree -= verticalEndLocation - 1; } return degree; diff --git a/src/hook/render/wire.js b/src/hook/render/wire.js index c56cf62..afb8625 100644 --- a/src/hook/render/wire.js +++ b/src/hook/render/wire.js @@ -131,13 +131,21 @@ export class WireRender { const pulse = new PulseLine(); id2PluseLine.set(data.id, pulse); + // 开启脉冲动画 pulse.loadToSelection(_this.selection, data); pulse.startAnimation(); + } else { if (id2PluseLine.has(data.id)) { const pulse = id2PluseLine.get(data.id); pulse.destory(); id2PluseLine.delete(data.id); + + // 关闭高亮 + const selection = d3.select(this); + selection.attr('stroke', 'var(--wire-color)'); + const arrowSelection = arrows.get(data.id); + arrowSelection.selectAll('path').attr('fill', 'var(--wire-color)'); } } }); @@ -153,11 +161,13 @@ export class WireRender { }); lineSelections.on('mouseleave', function(_, data) { - const selection = d3.select(this); - selection.attr('stroke', 'var(--wire-color)'); - - const arrowSelection = arrows.get(data.id); - arrowSelection.selectAll('path').attr('fill', 'var(--wire-color)'); + if (!id2PluseLine.has(data.id)) { + const selection = d3.select(this); + selection.attr('stroke', 'var(--wire-color)'); + + const arrowSelection = arrows.get(data.id); + arrowSelection.selectAll('path').attr('fill', 'var(--wire-color)'); + } }); diff --git a/src/hook/skin/plusation.js b/src/hook/skin/plusation.js index 61c7259..cddc227 100644 --- a/src/hook/skin/plusation.js +++ b/src/hook/skin/plusation.js @@ -29,6 +29,8 @@ export class PulseLine { const mask = parentSelection.append("mask") .attr('id', mId); + this.mask = mask; + const maskPathSelection = mask.append("use") .attr("id", uId) .attr("href", "#" + pId) @@ -90,6 +92,10 @@ export class PulseLine { const pluseElement = this.maskPathSelection.node(); const pathLength = pathElement.getTotalLength(); + + // 600 配合 3000 比较合适 + const v = 0.5; + const duration = pathLength / v; const keyframes = new KeyframeEffect( pluseElement, [{ @@ -101,7 +107,7 @@ export class PulseLine { strokeDashoffset: `-${pathLength - 200}` } ], { - duration: 3000, + duration: duration, iterations: Infinity } ); @@ -112,8 +118,9 @@ export class PulseLine { requestAnimationFrame(() => { const motionElement = this.g.selectAll('animateMotion').node(); motionElement.setAttribute('begin', '0s'); + motionElement.setAttribute('dur', duration + 'ms'); motionElement.beginElement(); - + pulsationAnimation.currentTime = 0; pulsationAnimation.play(); }); } @@ -128,7 +135,10 @@ export class PulseLine { destory() { if (this.g) { - this.g.selectAll('*').remove(); + this.g.remove(); + } + if (this.mask) { + this.mask.remove(); } } }