Code
SVG
Basic Shapes
rect, circle, ellipse, line, polygon, polyline — the foundational SVG elements.
Text
text, tspan, textPath — text layout, anchoring, and curved text.
Stroke & Fill
stroke-dasharray, linecap, linejoin, fill-opacity, and fill-rule.
Transforms
translate, rotate, scale, and skewX applied to group elements.
Paths
Path d commands: M L H V C Q A Z — lines, Béziers, and arcs.
Gradients
linearGradient and radialGradient with stop elements.
Patterns
pattern element as a tileable fill: checkerboard, dots, hatching.
Filters
Filter primitives: feGaussianBlur, feDropShadow, feTurbulence, feColorMatrix.
Clip & Mask
clipPath and mask elements for compositing and spotlight effects.
Animation (SMIL)
Declarative animation with animate, animateTransform, and animateMotion.
Symbols & Use
symbol + use for a reusable SVG icon system.
Generative Art
Animated Lissajous figures and phyllotaxis spiral — generative art via raw SVG DOM.
Generative Art
Expert Real-time animated generative art using raw SVG DOM — Lissajous orbital figures and golden-angle phyllotaxis spiral rendered with requestAnimationFrame and document.createElementNS. MDN createElementNS
// Angular component (AfterViewInit + NgZone)
private ns = 'http://www.w3.org/2000/svg';
private raf = 0;
private frame = 0;
ngAfterViewInit() {
if (!isPlatformBrowser(this.platformId)) return;
this.init();
}
private init() {
const svg = document.createElementNS(this.ns, 'svg');
svg.setAttribute('viewBox', '0 0 480 300');
svg.style.background = '#0f172a';
this.rootG = document.createElementNS(this.ns, 'g');
svg.appendChild(this.rootG);
this.containerRef.nativeElement.appendChild(svg);
this.zone.runOutsideAngular(() => this.animate());
}
private animate() {
const t = this.frame++;
const cx = 240, cy = 150;
for (let i = 0; i < 5; i++) {
// Lissajous orbital trail
const freqA = 2 + (i % 3);
const freqB = 3 + (i % 2);
const r = 40 + i * 18;
const tNorm = t * 0.012 + i * 1.3;
const x = cx + Math.cos(freqA * tNorm) * r;
const y = cy + Math.sin(freqB * tNorm) * r;
// Phyllotaxis golden-angle dot
// 137.508° = golden angle
const phi = (t * 0.03 + i * 137.508
* (Math.PI / 180)) % (Math.PI * 2);
const pr = Math.sqrt(t * 0.04 + i * 5) * 4;
this.addDot(x, y, this.palette[i % 5]);
}
// DOM pruning — prevent memory growth
if (this.rootG.childNodes.length > 20000) {
for (let k = 0; k < 3000; k++)
this.rootG.removeChild(this.rootG.firstChild!);
}
this.raf = requestAnimationFrame(() => this.animate());
}
private addDot(x: number, y: number, fill: string) {
const c = document.createElementNS(this.ns, 'circle');
c.setAttribute('cx', String(x));
c.setAttribute('cy', String(y));
c.setAttribute('r', '1.4');
c.setAttribute('fill', fill);
this.rootG.appendChild(c);
}Key Concepts
document.createElementNS('http://www.w3.org/2000/svg', 'circle')— creates SVG elements in the SVG namespace- Lissajous figures — parametric curves
x = A·cos(aθ), y = B·sin(bθ); different frequency ratios produce different orbit shapes - Phyllotaxis golden angle — 137.508° between successive elements produces the sunflower spiral pattern found in nature
NgZone.runOutsideAngular()— keeps the rAF loop outside Angular's change-detection zone for performance- DOM pruning — when child count exceeds a threshold (20 000), remove the oldest nodes to bound memory use
requestAnimationFrame— synchronises drawing with the browser's repaint cycle (~60 fps)cancelAnimationFrame(this.raf)inngOnDestroy()— essential to stop the loop when the component is destroyed