修复多次点击脉冲特效出现错误的问题

This commit is contained in:
锦恢 2024-12-31 14:19:57 +08:00
parent c403c8434c
commit a21b302922
3 changed files with 66 additions and 8 deletions

View File

@ -47,12 +47,26 @@ export class RangeTreeMap {
let degree = 0; let degree = 0;
const horizontalSegments = this.horizontal.get(y) || []; const horizontalSegments = this.horizontal.get(y) || [];
const verticalSegments = this.vertical.get(x) || []; const verticalSegments = this.vertical.get(x) || [];
let horizontalStartLocation = 0;
let horizontalEndLocation = 0;
let verticalStartLocation = 0;
let verticalEndLocation = 0;
for (const segment of horizontalSegments) { for (const segment of horizontalSegments) {
const x1 = Math.min(segment.x1, segment.x2); const x1 = Math.min(segment.x1, segment.x2);
const x2 = Math.max(segment.x1, segment.x2); const x2 = Math.max(segment.x1, segment.x2);
if (x1 <= x && x <= x2) { if (x1 <= x && x <= x2) {
degree ++; degree ++;
} }
if (x1 === x) {
horizontalStartLocation ++;
}
if (x2 === x) {
horizontalEndLocation ++;
}
} }
for (const segment of verticalSegments) { for (const segment of verticalSegments) {
@ -61,6 +75,30 @@ export class RangeTreeMap {
if (y1 <= y && y <= y2) { if (y1 <= y && y <= y2) {
degree ++; 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; return degree;

View File

@ -131,13 +131,21 @@ export class WireRender {
const pulse = new PulseLine(); const pulse = new PulseLine();
id2PluseLine.set(data.id, pulse); id2PluseLine.set(data.id, pulse);
// 开启脉冲动画
pulse.loadToSelection(_this.selection, data); pulse.loadToSelection(_this.selection, data);
pulse.startAnimation(); pulse.startAnimation();
} else { } else {
if (id2PluseLine.has(data.id)) { if (id2PluseLine.has(data.id)) {
const pulse = id2PluseLine.get(data.id); const pulse = id2PluseLine.get(data.id);
pulse.destory(); pulse.destory();
id2PluseLine.delete(data.id); 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) { lineSelections.on('mouseleave', function(_, data) {
const selection = d3.select(this); if (!id2PluseLine.has(data.id)) {
selection.attr('stroke', 'var(--wire-color)'); const selection = d3.select(this);
selection.attr('stroke', 'var(--wire-color)');
const arrowSelection = arrows.get(data.id); const arrowSelection = arrows.get(data.id);
arrowSelection.selectAll('path').attr('fill', 'var(--wire-color)'); arrowSelection.selectAll('path').attr('fill', 'var(--wire-color)');
}
}); });

View File

@ -29,6 +29,8 @@ export class PulseLine {
const mask = parentSelection.append("mask") const mask = parentSelection.append("mask")
.attr('id', mId); .attr('id', mId);
this.mask = mask;
const maskPathSelection = mask.append("use") const maskPathSelection = mask.append("use")
.attr("id", uId) .attr("id", uId)
.attr("href", "#" + pId) .attr("href", "#" + pId)
@ -91,6 +93,10 @@ export class PulseLine {
const pathLength = pathElement.getTotalLength(); const pathLength = pathElement.getTotalLength();
// 600 配合 3000 比较合适
const v = 0.5;
const duration = pathLength / v;
const keyframes = new KeyframeEffect( const keyframes = new KeyframeEffect(
pluseElement, [{ pluseElement, [{
strokeDasharray: `200 ${pathLength - 200}`, strokeDasharray: `200 ${pathLength - 200}`,
@ -101,7 +107,7 @@ export class PulseLine {
strokeDashoffset: `-${pathLength - 200}` strokeDashoffset: `-${pathLength - 200}`
} }
], { ], {
duration: 3000, duration: duration,
iterations: Infinity iterations: Infinity
} }
); );
@ -112,8 +118,9 @@ export class PulseLine {
requestAnimationFrame(() => { requestAnimationFrame(() => {
const motionElement = this.g.selectAll('animateMotion').node(); const motionElement = this.g.selectAll('animateMotion').node();
motionElement.setAttribute('begin', '0s'); motionElement.setAttribute('begin', '0s');
motionElement.setAttribute('dur', duration + 'ms');
motionElement.beginElement(); motionElement.beginElement();
pulsationAnimation.currentTime = 0;
pulsationAnimation.play(); pulsationAnimation.play();
}); });
} }
@ -128,7 +135,10 @@ export class PulseLine {
destory() { destory() {
if (this.g) { if (this.g) {
this.g.selectAll('*').remove(); this.g.remove();
}
if (this.mask) {
this.mask.remove();
} }
} }
} }