Загрузка...

Анимированная SVG-диаграмма потока сигналов. Визуализирует процессы, схемы принятия решений, AI-пайплайны. Интерактивная, стилизуется CSS.
<svg class="w-[462px] h-[346px]" viewBox="0 0 400 300" stroke-width="2"
style="width: 462px; height: 346px; color: rgb(17, 17, 17);">
<style>
/* ============ Señal en movimiento (reutilizable) ============ */
.signal-path {
stroke-dasharray: 60 400;
stroke-dashoffset: 60;
animation: signal-flow 6s linear infinite;
stroke-linecap: round;
}
/* Variante para la línea de abajo (mismo efecto, distinto timing) */
.signal-path-bottom {
stroke-dasharray: 60 400;
stroke-dashoffset: 60;
animation: signal-flow 6s linear infinite;
animation-delay: 0.7s;
/* quítalo si quieres que vaya sincronizada */
stroke-linecap: round;
}
@keyframes signal-flow {
0% {
stroke-dashoffset: 60;
opacity: 0;
}
5% {
opacity: 1;
}
90% {
stroke-dashoffset: -360;
opacity: 1;
}
95% {
opacity: 0;
}
100% {
stroke-dashoffset: -360;
opacity: 0;
}
}
/* ============ Pulsos de nodos (tu código original) ============ */
.node-context {
animation: pulse-context 6s infinite ease-out;
transform-origin: 50px 150px;
}
@keyframes pulse-context {
0% {
transform: scale(1);
fill: #111;
}
5% {
transform: scale(1.4);
fill: #000;
}
15% {
transform: scale(1);
fill: #111;
}
}
.node-assumptions {
animation: pulse-assumptions 6s infinite ease-out;
transform-origin: 190px 80px;
}
@keyframes pulse-assumptions {
25% {
stroke-width: 1.5;
transform: scale(1);
}
30% {
stroke-width: 2.5;
transform: scale(1.05);
stroke: #000;
}
40% {
stroke-width: 1.5;
transform: scale(1);
stroke: #111;
}
}
.node-evidence {
animation: pulse-evidence 6s infinite ease-out;
transform-origin: 280px 120px;
}
@keyframes pulse-evidence {
55% {
stroke-width: 1.5;
transform: scale(1);
}
60% {
stroke-width: 2.5;
transform: scale(1.05);
stroke: #000;
}
70% {
stroke-width: 1.5;
transform: scale(1);
stroke: #111;
}
}
.node-outcome {
animation: pulse-outcome 6s infinite ease-out;
transform-origin: 320px 150px;
}
@keyframes pulse-outcome {
85% {
transform: scale(1);
fill: #111;
}
90% {
transform: scale(1.25);
fill: #000;
}
100% {
transform: scale(1);
fill: #111;
}
}
.outcome-check {
stroke-dasharray: 12;
stroke-dashoffset: 12;
animation: check-draw 6s linear infinite;
}
@keyframes check-draw {
0%,
88% {
stroke-dashoffset: 12;
opacity: 0;
}
92% {
stroke-dashoffset: 0;
opacity: 1;
}
100% {
stroke-dashoffset: 0;
opacity: 0;
}
}
</style>
<!-- ============ Static Base Paths (gris) ============ -->
<!-- Rama superior -->
<path d="M50,150 C100,150 100,80 150,80" fill="none" stroke="#E5E5E5" stroke-width="2"></path>
<path d="M150,80 C200,80 200,120 250,120" fill="none" stroke="#E5E5E5" stroke-width="2"></path>
<path d="M250,120 L320,150" fill="none" stroke="#E5E5E5" stroke-width="2"></path>
<!-- Rama inferior -->
<path d="M50,150 C100,150 100,220 150,220" fill="none" stroke="#E5E5E5" stroke-width="2"></path>
<path d="M150,220 C200,220 200,180 250,180" fill="none" stroke="#E5E5E5" stroke-width="2"></path>
<path d="M250,180 L320,150" fill="none" stroke="#E5E5E5" stroke-width="2"></path>
<!-- ============ Active Signal Paths (negro animado) ============ -->
<!-- Señal arriba (igual que tu original) -->
<path d="M50,150 C100,150 100,80 150,80 C200,80 200,120 250,120 L320,150" fill="none" stroke="#111" stroke-width="2.5"
class="signal-path"></path>
<!-- Señal abajo (nuevo) -->
<path d="M50,150 C100,150 100,220 150,220 C200,220 200,180 250,180 L320,150" fill="none" stroke="#111"
stroke-width="2.5" class="signal-path-bottom"></path>
<!-- ============ Nodes & Text ============ -->
<circle cx="50" cy="150" r="6" fill="#111" class="node-context"></circle>
<text x="50" y="175" text-anchor="middle" font-family='"Plus Jakarta Sans", sans-serif' font-size="10"
font-weight="600" fill="#111">Consulta</text>
<rect x="150" y="70" width="80" height="20" rx="4" fill="white" stroke="#111" stroke-width="1.5"
class="node-assumptions"></rect>
<text x="190" y="83" text-anchor="middle" font-family='"Plus Jakarta Sans", sans-serif' font-size="9"
font-weight="600" fill="#111" dy="1">IA Propietaria</text>
<rect x="150" y="210" width="80" height="20" rx="4" fill="white" stroke="#E5E5E5"></rect>
<text x="190" y="222" text-anchor="middle" font-family='"Plus Jakarta Sans", sans-serif' font-size="9"
font-weight="600" fill="#111" dy="1">BBDD Cliente</text>
<rect x="230" y="170" width="60" height="20" rx="4" fill="white" stroke="#E5E5E5"></rect>
<text x="260" y="180" text-anchor="middle" font-family='"Plus Jakarta Sans", sans-serif' font-size="9"
font-weight="600" fill="#111" dy="1">Memoria</text>
<rect x="250" y="110" width="60" height="20" rx="4" fill="white" stroke="#111" stroke-width="1.5"
class="node-evidence"></rect>
<text x="280" y="123" text-anchor="middle" font-family='"Plus Jakarta Sans", sans-serif' font-size="9"
font-weight="600" fill="#111" dy="1">Abogados</text>
<circle cx="320" cy="150" r="12" fill="#111" class="node-outcome"></circle>
<path d="M316 150l3 3 5-5" stroke="white" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"
class="outcome-check"></path>
<text x="320" y="178" text-anchor="middle" font-family='"Plus Jakarta Sans", sans-serif' font-size="10"
font-weight="600" fill="#111">Solución</text>
</svg>