본문으로 건너뛰기

Animated Diagram Skill

Create dynamic animated diagrams using SVG with SMIL animations. Produces self-contained HTML files with traffic flow visualizations, pulsing effects, interactive legends, and responsive scaling.

Trigger Keywords

Activated by the following keywords:

  • "animated diagram", "traffic flow"
  • "animated architecture", "dynamic diagram"
  • "SMIL animation"

Use Cases

  • Traffic flow visualization through AWS services
  • Service interaction diagrams with animated connections
  • Deployment pipelines with step-by-step animation
  • Real-time monitoring dashboards with animated status indicators
  • Interactive scenarios — Scaling (EKS, ASG), Blue/Green deployment, failover simulation (button-driven state transitions)

Provided Resources

references/

Reference DocDescription
smil-animation-guide.mdSMIL animation syntax and patterns
aws-diagram-patterns.mdAWS architecture color coding and layout conventions

templates/

TemplateDescription
traffic-flow.htmlSMIL traffic flow template (with legend toggle)
interactive-scaling.htmlInteractive EKS hybrid node bursting (Scale Out/In buttons, JavaScript + CSS transitions)

Architecture

Each animated diagram is a self-contained HTML file with three layers:

┌─────────────────────────────────────────────┐
│ HTML Wrapper │
│ ┌───────────────────────────────────────┐ │
│ │ Background Layer │ │
│ │ (Draw.io PNG or inline SVG) │ │
│ ├───────────────────────────────────────┤ │
│ │ Animation Layer │ │
│ │ (SVG with SMIL animations) │ │
│ ├───────────────────────────────────────┤ │
│ │ Interactive Legend │ │
│ │ (JS toggle for animation groups) │ │
│ └───────────────────────────────────────┘ │
└─────────────────────────────────────────────┘

Color Standards

Traffic TypeColorHex
OutboundRed#DD344C
InboundBlue#147EBA
AWS InternalOrange#FF9900
Success/ActiveGreen#1B660F
WarningYellow#F2C94C
BackgroundSquid Ink#232F3E

SMIL Animation Patterns

Traffic Dots (animateMotion)

<svg viewBox="0 0 1600 900">
<!-- Path definition -->
<path id="path-user-to-alb" d="M 100,450 L 300,450 L 300,300 L 500,300"
fill="none" stroke="none" />

<!-- Dot moving along path -->
<circle r="5" fill="#147EBA">
<animateMotion dur="3s" repeatCount="indefinite">
<mpath href="#path-user-to-alb" />
</animateMotion>
</circle>
</svg>

Pulsing Glow Effect

<circle cx="500" cy="300" r="30" fill="none" stroke="#FF9900">
<animate attributeName="r" values="28;35;28" dur="2s" repeatCount="indefinite" />
<animate attributeName="opacity" values="0.8;0.3;0.8" dur="2s" repeatCount="indefinite" />
</circle>

Sequential Stagger

<!-- Dot 1: Start immediately -->
<circle r="4" fill="#DD344C">
<animateMotion dur="4s" begin="0s" repeatCount="indefinite">
<mpath href="#outbound-path" />
</animateMotion>
</circle>

<!-- Dot 2: Start after 1.3s -->
<circle r="4" fill="#DD344C">
<animateMotion dur="4s" begin="1.3s" repeatCount="indefinite">
<mpath href="#outbound-path" />
</animateMotion>
</circle>

<!-- Dot 3: Start after 2.6s -->
<circle r="4" fill="#DD344C">
<animateMotion dur="4s" begin="2.6s" repeatCount="indefinite">
<mpath href="#outbound-path" />
</animateMotion>
</circle>

Formula: begin_offset = (dur / dot_count) * index

Dashed Line Flow Animation

<line x1="200" y1="300" x2="600" y2="300"
stroke="#147EBA" stroke-width="2" stroke-dasharray="8 4">
<animate attributeName="stroke-dashoffset"
values="0;-24" dur="1s" repeatCount="indefinite" />
</line>

Sequential Highlight (Step-by-Step)

<!-- Step 1: ALB highlight at 0s -->
<rect x="200" y="280" width="100" height="40"
fill="none" stroke="#FF9900" stroke-width="3" opacity="0">
<animate attributeName="opacity"
values="0;1;1;0" keyTimes="0;0.1;0.4;0.5"
dur="6s" repeatCount="indefinite" />
</rect>

<!-- Step 2: Lambda highlight at 2s -->
<rect x="400" y="280" width="100" height="40"
fill="none" stroke="#FF9900" stroke-width="3" opacity="0">
<animate attributeName="opacity"
values="0;0;1;1;0;0" keyTimes="0;0.33;0.36;0.6;0.66;1"
dur="6s" repeatCount="indefinite" />
</rect>

Interactive Scenario Patterns

For user-driven state changes, use JavaScript + CSS instead of SMIL.

Scaling Scenario (EKS/ASG)

<div class="controls">
<button id="scaleOut" onclick="handleScaleOut()">Scale Out</button>
<button id="scaleIn" onclick="handleScaleIn()" disabled>Scale In</button>
</div>

<div class="status">
Pods: <span id="podCount">3</span> |
Nodes: <span id="nodeCount">2</span>
</div>

<svg id="diagram" viewBox="0 0 800 400">
<g id="nodes"></g>
<g id="pods"></g>
</svg>

<script>
const state = { pods: 3, nodes: 2, animating: false };

function handleScaleOut() {
if (state.animating) return;
state.animating = true;

// Animate new pods appearing
for (let i = 0; i < 3; i++) {
setTimeout(() => {
state.pods++;
renderPod(state.pods);
updateDisplay();
}, i * 300);
}

// Add new node after pods
setTimeout(() => {
state.nodes++;
renderNode(state.nodes);
state.animating = false;
updateButtons();
}, 1000);
}

function handleScaleIn() {
if (state.animating || state.pods <= 3) return;
state.animating = true;

// Animate pods disappearing
removePods(3);

setTimeout(() => {
state.nodes--;
removeNode(state.nodes + 1);
state.animating = false;
updateButtons();
}, 1000);
}
</script>

<style>
.pod {
transition: opacity 0.3s ease, transform 0.3s ease;
}
.pod.removing {
opacity: 0;
transform: scale(0);
}
.node {
transition: all 0.5s ease;
}
</style>

Blue/Green Deployment Scenario

const deploymentState = {
current: 'blue', // 'blue' | 'green' | 'switching'
blueTraffic: 100,
greenTraffic: 0
};

function startDeployment() {
deploymentState.current = 'switching';

// Gradual traffic shift
const interval = setInterval(() => {
if (deploymentState.blueTraffic > 0) {
deploymentState.blueTraffic -= 10;
deploymentState.greenTraffic += 10;
updateTrafficDisplay();
updateArrowWeights();
} else {
clearInterval(interval);
deploymentState.current = 'green';
updateStatus('Deployment Complete');
}
}, 500);
}

Failover Simulation Scenario

const failoverState = {
primaryActive: true,
failoverInProgress: false
};

function triggerFailover() {
failoverState.failoverInProgress = true;

// Step 1: Primary shows error
showError('primary-db');

// Step 2: Health check fails
setTimeout(() => {
updateHealthIndicator('primary', 'unhealthy');
}, 1000);

// Step 3: Traffic redirects
setTimeout(() => {
redirectTraffic('primary', 'standby');
updateHealthIndicator('standby', 'active');
}, 2000);

// Step 4: Complete
setTimeout(() => {
failoverState.primaryActive = false;
failoverState.failoverInProgress = false;
updateStatus('Failover Complete');
}, 3000);
}

SMIL vs CSS Animation Comparison

When to Use SMIL

ScenarioRecommended
Continuous traffic flow loopsSMIL
Pulsing/glow status indicatorsSMIL
Path-based motion (dots along lines)SMIL
No user interaction neededSMIL
Legend toggle is the only interactionSMIL

When to Use JavaScript + CSS

ScenarioRecommended
Button-triggered state changesJavaScript
Dynamic element creation/deletionJavaScript
Multi-step storytelling with user controlJavaScript
Before/after state comparisonJavaScript
Counters that update in real-timeJavaScript
Complex state machinesJavaScript

Decision Guide

Does the animation need user-triggered state changes?
├─ No → Use SMIL
│ ├─ Continuous loop? → animateMotion
│ └─ Pulsing effect? → animate
└─ Yes → Use JavaScript + CSS
├─ Simple toggle? → CSS classes
└─ Complex state? → State machine

Animation Timing Guidelines

Animation TypeDurationRepeat
Traffic dot (short path)2-3sindefinite
Traffic dot (long path)4-6sindefinite
Pulsing glow2sindefinite
Highlight flash1s3 times
State transition0.3-0.5sonce

Interactive Legend

<div class="legend">
<label>
<input type="checkbox" checked onchange="toggleGroup('inbound')">
<span style="color:#147EBA">● Inbound Traffic</span>
</label>
<label>
<input type="checkbox" checked onchange="toggleGroup('outbound')">
<span style="color:#DD344C">● Outbound Traffic</span>
</label>
</div>

<script>
function toggleGroup(group) {
document.querySelectorAll(`[data-group="${group}"]`).forEach(el => {
el.style.display = el.style.display === 'none' ? '' : 'none';
});
}
</script>

Usage Example

User: "Create VPC traffic flow animation"

1. animated-diagram-agent called
2. Static background created (Draw.io or inline SVG)
3. SMIL animations added
4. Interactive legend added
5. content-review-agent review

Output Usage

Generated HTML files can be embedded in various places:

  • Presentations: Insert as <iframe> in HTML slides
  • GitBook: Embed <iframe> in document pages
  • Standalone: Open directly in browser

Quality Review (Required)

After content completion:

  1. Call content-review-agent
  2. Achieve PASS (85+ score) before completion

Validation Checklist

SMIL Animation

  • All <animateMotion> paths are valid and visible
  • Color coding matches standard (Red/Blue/Orange)
  • Legend toggle works for each animation group
  • Responsive scaling works at various viewport sizes
  • Background image/SVG aligns with animation overlay
  • Animation elements don't exceed viewBox
  • data-group attributes match legend toggle functions

Interactive Animation

  • All buttons trigger correct state transitions
  • Dynamic elements appear/disappear with smooth transitions
  • State machine prevents invalid transitions (buttons disabled during animation)
  • No orphaned SVG elements after repeated Scale Out/In cycles
  • Works correctly in both standalone and iframe-embedded contexts