
Mermaid To Gif
Turn Mermaid diagrams in docs or markdown into animated GIFs for tweets, landing pages, and README storytelling without manual screen recording.
Install
npx skills add https://github.com/zc277584121/marketing-skills --skill mermaid-to-gifWhat is this skill?
- Full pipeline: Mermaid code → HTML animation → Playwright frames → FFmpeg GIF
- CLI supports .mmd files and markdown extractions with -o output directory
- Four animation styles: progressive, highlight-walk, pulse-flow, wave
- Tunable fps, duration, hold, padding, scale, theme, and background color
Adoption & trust: 797 installs on skills.sh; 2/3 security scanners passed (skills.sh audits).
Recommended Skills
Seo Auditcoreyhaines31/marketingskills
Copywritingcoreyhaines31/marketingskills
Twitter Automationqu-skills/skills
Marketing Psychologycoreyhaines31/marketingskills
Content Strategycoreyhaines31/marketingskills
Programmatic Seocoreyhaines31/marketingskills
Journey fit
Primary fit
Grow → content is where animated explainers ship; the tool produces marketing and education assets from existing diagram source. Content subphase covers repurposing technical diagrams into shareable visuals that solo builders use for distribution.
Common Questions / FAQ
Is Mermaid To Gif safe to install?
skills.sh reports 2 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.
SKILL.md
READMESKILL.md - Mermaid To Gif
#!/usr/bin/env python3 """ mermaid_to_gif.py - Convert Mermaid diagrams to animated GIFs. Pipeline: Mermaid code -> HTML with animation -> Playwright frame capture -> FFmpeg GIF Usage: python mermaid_to_gif.py diagram.mmd python mermaid_to_gif.py document.md --style progressive python mermaid_to_gif.py document.md -o ./gifs/ --fps 12 --duration 5 """ from __future__ import annotations import argparse import html as html_lib import os import re import shutil import subprocess import sys import tempfile from pathlib import Path # ============================================================ # Constants # ============================================================ MERMAID_CDN = "https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js" STYLES = ["progressive", "highlight-walk", "pulse-flow", "wave"] DEFAULT_STYLE = "progressive" DEFAULT_FPS = 10 DEFAULT_DURATION = 4.0 DEFAULT_HOLD = 1.0 DEFAULT_BG = "#ffffff" DEFAULT_THEME = "default" DEFAULT_PADDING = 40 DEFAULT_SCALE = 2 # ============================================================ # Dependency checks # ============================================================ def check_dependencies(): """Verify required external tools are available.""" errors = [] if not shutil.which("ffmpeg"): errors.append( "FFmpeg is not installed.\n" " macOS: brew install ffmpeg\n" " Ubuntu: sudo apt install ffmpeg" ) try: import playwright # noqa: F401 except ImportError: errors.append( "Playwright is not installed.\n" " pip install playwright\n" " playwright install chromium" ) if errors: for e in errors: print(f"Error: {e}", file=sys.stderr) sys.exit(1) # ============================================================ # Input parsing # ============================================================ def extract_mermaid_blocks(text: str) -> list[str]: """Extract ```mermaid code blocks from markdown text.""" pattern = r"```mermaid\s*\n(.*?)```" return [m.strip() for m in re.findall(pattern, text, re.DOTALL)] def read_input(path: str) -> list[tuple[str, str]]: """Read input file and return list of (name, mermaid_code) tuples.""" p = Path(path) if not p.exists(): print(f"Error: {path} does not exist", file=sys.stderr) sys.exit(1) text = p.read_text(encoding="utf-8") if p.suffix == ".mmd": return [(p.stem, text.strip())] # Markdown or other text file - extract mermaid blocks blocks = extract_mermaid_blocks(text) if not blocks: print(f"No mermaid code blocks found in {path}", file=sys.stderr) return [] if len(blocks) == 1: return [(p.stem, blocks[0])] return [(f"{p.stem}-{i + 1}", block) for i, block in enumerate(blocks)] def detect_direction(mermaid_code: str) -> str: """Detect diagram flow direction from mermaid source code.""" first_line = mermaid_code.strip().split("\n")[0].lower() if any(d in first_line for d in ["lr", "rl"]): return "horizontal" return "vertical" # ============================================================ # Animation JS - shared element collection logic # ============================================================ ELEMENT_COLLECTION_JS = """ // Collect elements by type separately for better animation control var clusters = []; var nodes = []; var edges = []; var edgeLabels = []; var direction = '{direction}'; var sortFn = direction === 'horizontal' ? function(a, b) { return (a.x - b.x) || (a.y - b.y); } : function(a, b) { return (a.y - b.y) || (a.x - b.x); }; svg.querySelectorAll('.cluster').forEach(function(el) { var rect = el.getBoundingClientRect(); clusters.push({ el: el, x: rect.x, y: rect.y }); }); svg.querySelectorAll('.node, .actor, [class*="note"]').forEach(function(el) {