Transition map beads: connector-colored elongated pulses
Beads now take their connector's color — accent for internal links, plain text color for external ones (matching the tconn-exit styling) — and render as an elongated pulse along the direction of travel instead of a plain dot: a rounded capsule with a gradient-faded tail, rotated to the edge's angle (cached per flow). Flow objects carry an 'external' tag from buildFlows; the gradients live in the svg defs with stop colors resolved from CSS so theme variables apply.
This commit is contained in:
1 parent
fb2914d853
commit
3c9ef04ffd
3 files changed
+52
-12
No files matched your search
@@ -13,6 +13,7 @@ import {
|
||||
TNODE_W,
|
||||
TNODE_H,
|
||||
BEAD_R,
|
||||
BEAD_LEN,
|
||||
buildTransitionGraph,
|
||||
} from './analytics/transitions.js'
|
||||
|
||||
@@ -145,7 +146,17 @@ const tick = (t) => {
|
||||
continue
|
||||
}
|
||||
const f = b.e.flow
|
||||
out.push({ x: f.x1 + (f.x2 - f.x1) * b.p, y: f.y1 + (f.y2 - f.y1) * b.p })
|
||||
// The pulse is elongated along the direction of travel (constant per
|
||||
// flow) and colored like its connector (external edges use --text).
|
||||
if (f.deg === undefined) {
|
||||
f.deg = (Math.atan2(f.y2 - f.y1, f.x2 - f.x1) * 180) / Math.PI
|
||||
}
|
||||
out.push({
|
||||
x: f.x1 + (f.x2 - f.x1) * b.p,
|
||||
y: f.y1 + (f.y2 - f.y1) * b.p,
|
||||
deg: f.deg,
|
||||
ext: f.external,
|
||||
})
|
||||
}
|
||||
beads.value = out
|
||||
rafId = requestAnimationFrame(tick)
|
||||
@@ -184,6 +195,21 @@ const countLabel = (n) =>
|
||||
<section v-if="graph">
|
||||
<svg class="tmap" :style="{ maxWidth: `${graph.bounds.x1 - graph.bounds.x0}px` }" :viewBox="`${graph.bounds.x0} ${graph.bounds.y0} ${graph.bounds.x1 - graph.bounds.x0} ${graph.bounds.y1 - graph.bounds.y0}`"
|
||||
role="img" aria-label="map of transitions between pages">
|
||||
<defs>
|
||||
<!-- Pulse gradient: opaque head at the bead position (local origin),
|
||||
fading tail trailing behind it (stop-color comes from CSS so
|
||||
theme vars resolve). -->
|
||||
<linearGradient id="tbead-grad">
|
||||
<stop offset="0" class="tbead-stop" stop-opacity="0" />
|
||||
<stop offset="0.55" class="tbead-stop" stop-opacity="0.5" />
|
||||
<stop offset="1" class="tbead-stop" stop-opacity="1" />
|
||||
</linearGradient>
|
||||
<linearGradient id="tbead-grad-exit">
|
||||
<stop offset="0" class="tbead-stop-exit" stop-opacity="0" />
|
||||
<stop offset="0.55" class="tbead-stop-exit" stop-opacity="0.5" />
|
||||
<stop offset="1" class="tbead-stop-exit" stop-opacity="1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path v-for="(a, i) in graph.arcs" :key="'a' + i"
|
||||
:id="`tarc${i}`" :d="a.d" :class="['tarc', a.top && 'tarc-top']" />
|
||||
<template v-for="(a, i) in graph.arcs" :key="'t' + i">
|
||||
@@ -194,8 +220,11 @@ const countLabel = (n) =>
|
||||
:d="e.d" :class="['tconn', e.external && 'tconn-exit']">
|
||||
<title>{{ e.title }}</title>
|
||||
</path>
|
||||
<circle v-for="(b, i) in beads" :key="'b' + i"
|
||||
:cx="b.x" :cy="b.y" :r="BEAD_R" class="tbead" />
|
||||
<rect v-for="(b, i) in beads" :key="'b' + i"
|
||||
:x="-BEAD_LEN" :y="-BEAD_R" :width="BEAD_LEN" :height="2 * BEAD_R" :rx="BEAD_R"
|
||||
:fill="b.ext ? 'url(#tbead-grad-exit)' : 'url(#tbead-grad)'"
|
||||
:class="['tbead', b.ext && 'tbead-exit']"
|
||||
:transform="`translate(${b.x} ${b.y}) rotate(${b.deg})`" />
|
||||
<g v-for="(x, i) in graph.extNodes" :key="'x' + i">
|
||||
<clipPath :id="`xclip${i}`">
|
||||
<rect :x="x.x - TNODE_W/2 + 6" :y="x.y - TNODE_H/2" :width="TNODE_W - 12"
|
||||
@@ -259,10 +288,13 @@ const countLabel = (n) =>
|
||||
fill: var(--text);
|
||||
}
|
||||
.tmap .tbead {
|
||||
fill: var(--accent);
|
||||
opacity: 0.85;
|
||||
filter: drop-shadow(0 0 2.5px var(--accent));
|
||||
}
|
||||
.tmap .tbead-exit {
|
||||
filter: drop-shadow(0 0 2.5px var(--text));
|
||||
}
|
||||
.tmap .tbead-stop { stop-color: var(--accent); }
|
||||
.tmap .tbead-stop-exit { stop-color: var(--text); }
|
||||
.tmap .txnode {
|
||||
/* External source/exit pills: plain white on every theme, with a hairline
|
||||
so the pill stays visible on a white page. */
|
||||
|
||||
Reference in new issue
Block a user