Skip to content

Commit abbd317

Browse files
committed
feat: enhance flow example diagram glow
1 parent 464fb05 commit abbd317

1 file changed

Lines changed: 90 additions & 63 deletions

File tree

src/components/sections/client/FlowExampleDiagram.tsx

Lines changed: 90 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ export function FlowExampleDiagram({ trigger, items }: { trigger: FlowDiagramNod
2525
const cycleDuration = Math.max((items.length - 1) * stepDuration + travelDuration + 1.5, travelDuration + 1.5)
2626
const resetStart = cycleDuration - resetDuration
2727
const resetEnd = resetStart + 0.01
28+
const resetStartTime = resetStart / cycleDuration
29+
const resetEndTime = resetEnd / cycleDuration
2830

2931
return (
3032
<motion.div
@@ -33,82 +35,107 @@ export function FlowExampleDiagram({ trigger, items }: { trigger: FlowDiagramNod
3335
whileInView="show"
3436
viewport={{ once: true, amount: 0.35 }}
3537
>
36-
{nodes.map((node, index) => (
37-
<div className="flex flex-col items-center" key={node.id}>
38-
{index > 0 && (
39-
<div className="relative h-12 w-px overflow-hidden bg-white/10 md:h-16" aria-hidden="true">
40-
<motion.div
41-
className="absolute inset-0 origin-top bg-brand"
42-
animate={
43-
reducedMotion
44-
? { scaleY: 1, opacity: 0.45 }
45-
: {
46-
scaleY: [0, 0, 1, 1, 1, 1],
47-
opacity: [0, 0, 1, 1, 0, 0],
48-
}
49-
}
50-
transition={{
51-
duration: reducedMotion ? 0 : cycleDuration,
52-
repeat: reducedMotion ? 0 : Infinity,
53-
ease: "linear",
54-
times: [
55-
0,
56-
((index - 1) * stepDuration) / cycleDuration,
57-
((index - 1) * stepDuration + travelDuration) / cycleDuration,
58-
resetStart / cycleDuration,
59-
resetEnd / cycleDuration,
60-
1,
61-
],
62-
}}
63-
/>
64-
</div>
65-
)}
66-
<motion.div
67-
variants={{
68-
hidden: { opacity: reducedMotion ? 1 : 0, y: reducedMotion ? 0 : 12 },
69-
show: { opacity: 1, y: 0 },
70-
}}
71-
transition={{ duration: 0.38, delay: index * 0.2, ease: [0.22, 1, 0.36, 1] }}
72-
>
73-
{"trigger" in node ? (
74-
<TriggerDisplay icon={node.trigger.icon} text={node.trigger.text} />
75-
) : (
76-
<motion.div
77-
className="relative isolate rounded-2xl"
78-
>
38+
{nodes.map((node, index) => {
39+
const arrivalTime = index > 0 ? ((index - 1) * stepDuration + travelDuration) / cycleDuration : 0
40+
const arrivalPeakTime = Math.min(arrivalTime + 0.04, resetStartTime)
41+
const arrivalSettleTime = Math.min(arrivalTime + 0.1, resetStartTime)
42+
43+
return (
44+
<div className="flex flex-col items-center" key={node.id}>
45+
{index > 0 && (
46+
<div className="relative h-12 w-px overflow-hidden bg-white/10 md:h-16" aria-hidden="true">
7947
<motion.div
80-
className="pointer-events-none absolute -inset-1 z-0 rounded-2xl blur-sm"
81-
style={{ backgroundColor: getNodeAccentColor(node.node.color) }}
48+
className="absolute inset-0 origin-top bg-linear-to-b from-brand/50 via-brand to-brand/70"
8249
animate={
8350
reducedMotion
84-
? { opacity: 0.16, scale: 1 }
51+
? { scaleY: 1, opacity: 0.45 }
8552
: {
86-
opacity: [0, 0, 0.16, 0.16, 0, 0],
87-
scale: [0.98, 0.98, 1, 1, 1, 1],
53+
scaleY: [0, 0, 1, 1, 1, 1],
54+
opacity: [0, 0, 1, 1, 0, 0],
8855
}
8956
}
9057
transition={{
9158
duration: reducedMotion ? 0 : cycleDuration,
9259
repeat: reducedMotion ? 0 : Infinity,
9360
ease: "linear",
94-
times: [
95-
0,
96-
((index - 1) * stepDuration + travelDuration) / cycleDuration,
97-
((index - 1) * stepDuration + travelDuration + 0.45) / cycleDuration,
98-
resetStart / cycleDuration,
99-
resetEnd / cycleDuration,
100-
1,
101-
],
61+
times: [0, ((index - 1) * stepDuration) / cycleDuration, arrivalTime, resetStartTime, resetEndTime, 1],
10262
}}
10363
/>
104-
<div className="relative z-10">
105-
<NodeDisplay node={node.node} />
106-
</div>
107-
</motion.div>
64+
</div>
10865
)}
109-
</motion.div>
110-
</div>
111-
))}
66+
<motion.div
67+
variants={{
68+
hidden: { opacity: reducedMotion ? 1 : 0, y: reducedMotion ? 0 : 12 },
69+
show: { opacity: 1, y: 0 },
70+
}}
71+
transition={{ duration: 0.38, delay: index * 0.2, ease: [0.22, 1, 0.36, 1] }}
72+
>
73+
{"trigger" in node ? (
74+
<TriggerDisplay icon={node.trigger.icon} text={node.trigger.text} />
75+
) : (
76+
<motion.div
77+
className="relative isolate rounded-2xl"
78+
animate={
79+
reducedMotion
80+
? { scale: 1 }
81+
: {
82+
scale: [1, 1, 1.012, 1, 1, 1, 1],
83+
}
84+
}
85+
transition={{
86+
duration: reducedMotion ? 0 : cycleDuration,
87+
repeat: reducedMotion ? 0 : Infinity,
88+
ease: "linear",
89+
times: [0, arrivalTime, arrivalPeakTime, arrivalSettleTime, resetStartTime, resetEndTime, 1],
90+
}}
91+
>
92+
<motion.div
93+
aria-hidden="true"
94+
className="pointer-events-none absolute inset-0 z-0 rounded-[inherit]"
95+
style={{
96+
boxShadow: `0 0 0 1px color-mix(in srgb, ${getNodeAccentColor(node.node.color)} 24%, transparent), 0 0 14px color-mix(in srgb, ${getNodeAccentColor(node.node.color)} 22%, transparent)`,
97+
}}
98+
animate={
99+
reducedMotion
100+
? { opacity: 0.45 }
101+
: {
102+
opacity: [0, 0, 0.75, 0.45, 0.45, 0, 0],
103+
}
104+
}
105+
transition={{
106+
duration: reducedMotion ? 0 : cycleDuration,
107+
repeat: reducedMotion ? 0 : Infinity,
108+
ease: "linear",
109+
times: [0, arrivalTime, arrivalPeakTime, arrivalSettleTime, resetStartTime, resetEndTime, 1],
110+
}}
111+
/>
112+
<motion.div
113+
aria-hidden="true"
114+
className="pointer-events-none absolute -inset-2 z-0 rounded-3xl blur-xl"
115+
style={{ backgroundColor: getNodeAccentColor(node.node.color) }}
116+
animate={
117+
reducedMotion
118+
? { opacity: 0.08 }
119+
: {
120+
opacity: [0, 0, 0.14, 0.08, 0.08, 0, 0],
121+
}
122+
}
123+
transition={{
124+
duration: reducedMotion ? 0 : cycleDuration,
125+
repeat: reducedMotion ? 0 : Infinity,
126+
ease: "linear",
127+
times: [0, arrivalTime, arrivalPeakTime, arrivalSettleTime, resetStartTime, resetEndTime, 1],
128+
}}
129+
/>
130+
<div className="relative z-10">
131+
<NodeDisplay node={node.node} />
132+
</div>
133+
</motion.div>
134+
)}
135+
</motion.div>
136+
</div>
137+
)
138+
})}
112139
</motion.div>
113140
)
114141
}

0 commit comments

Comments
 (0)