javascript
262 lines · 1 tab
Alex Chang
Feb 2026
1 tab
// 1. Create SVG elements
const svgNS = 'http://www.w3.org/2000/svg';
function createSVGElement(type, attributes = {}) {
const element = document.createElementNS(svgNS, type);
Object.entries(attributes).forEach(([key, value]) => {
element.setAttribute(key, value);
});
return element;
}
// Create SVG container
const svg = createSVGElement('svg', {
width: '600',
height: '400',
viewBox: '0 0 600 400'
});
document.body.appendChild(svg);
// 2. Create shapes
// Circle
const circle = createSVGElement('circle', {
cx: '100',
cy: '100',
r: '50',
fill: '#4285f4',
stroke: '#1a73e8',
'stroke-width': '2'
});
svg.appendChild(circle);
// Rectangle
const rect = createSVGElement('rect', {
x: '200',
y: '50',
width: '100',
height: '80',
fill: '#34a853',
rx: '10' // rounded corners
});
svg.appendChild(rect);
// Line
const line = createSVGElement('line', {
x1: '50',
y1: '200',
x2: '200',
y2: '200',
stroke: '#ea4335',
'stroke-width': '3'
});
svg.appendChild(line);
// Polyline
const polyline = createSVGElement('polyline', {
points: '250,200 300,220 350,180 400,210',
fill: 'none',
stroke: '#fbbc04',
'stroke-width': '2'
});
svg.appendChild(polyline);
// Polygon
const polygon = createSVGElement('polygon', {
points: '450,200 500,250 400,250',
fill: '#ea4335'
});
svg.appendChild(polygon);
// 3. Path element (complex shapes)
const path = createSVGElement('path', {
d: 'M 50 300 Q 150 250 250 300 T 450 300',
fill: 'none',
stroke: '#4285f4',
'stroke-width': '2'
});
svg.appendChild(path);
// Path commands:
// M = moveto
// L = lineto
// H = horizontal lineto
// V = vertical lineto
// C = curveto (cubic Bezier)
// S = smooth curveto
// Q = quadratic Bezier curve
// T = smooth quadratic Bezier
// A = elliptical arc
// Z = closepath
// 4. Text
const text = createSVGElement('text', {
x: '300',
y: '350',
'text-anchor': 'middle',
'font-size': '24',
fill: '#000'
});
text.textContent = 'SVG Text';
svg.appendChild(text);
// 5. Groups
const group = createSVGElement('g', {
transform: 'translate(500, 300)'
});
const groupCircle = createSVGElement('circle', {
cx: '0',
cy: '0',
r: '20',
fill: '#4285f4'
});
const groupRect = createSVGElement('rect', {
x: '-10',
y: '-40',
width: '20',
height: '30',
fill: '#34a853'
});
group.appendChild(groupCircle);
group.appendChild(groupRect);
svg.appendChild(group);
// 6. Animations with JavaScript
let angle = 0;
function rotateSVG() {
angle += 1;
group.setAttribute('transform', `translate(500, 300) rotate(${angle})`);
requestAnimationFrame(rotateSVG);
}
rotateSVG();
// 7. Interactive SVG
circle.addEventListener('click', function() {
const currentFill = this.getAttribute('fill');
const newFill = currentFill === '#4285f4' ? '#ea4335' : '#4285f4';
this.setAttribute('fill', newFill);
});
circle.addEventListener('mouseenter', function() {
this.setAttribute('r', '60');
});
circle.addEventListener('mouseleave', function() {
this.setAttribute('r', '50');
});
// 8. Drag and drop SVG elements
let selectedElement = null;
let offset = null;
svg.addEventListener('mousedown', (e) => {
if (e.target.tagName === 'circle' || e.target.tagName === 'rect') {
selectedElement = e.target;
const transform = selectedElement.transform.baseVal;
if (transform.length === 0) {
const translate = svg.createSVGTransform();
selectedElement.transform.baseVal.appendItem(translate);
}
const pt = svg.createSVGPoint();
pt.x = e.clientX;
pt.y = e.clientY;
offset = pt.matrixTransform(svg.getScreenCTM().inverse());
}
});
svg.addEventListener('mousemove', (e) => {
if (selectedElement) {
e.preventDefault();
const pt = svg.createSVGPoint();
pt.x = e.clientX;
pt.y = e.clientY;
const cursorPt = pt.matrixTransform(svg.getScreenCTM().inverse());
const dx = cursorPt.x - offset.x;
const dy = cursorPt.y - offset.y;
const transform = selectedElement.transform.baseVal.getItem(0);
transform.setTranslate(dx, dy);
}
});
svg.addEventListener('mouseup', () => {
selectedElement = null;
});
// 9. Charts with SVG
function createBarChart(data, width, height) {
const chartSvg = createSVGElement('svg', {
width: width,
height: height,
viewBox: `0 0 ${width} ${height}`
});
const maxValue = Math.max(...data.map(d => d.value));
const barWidth = width / data.length;
data.forEach((item, index) => {
const barHeight = (item.value / maxValue) * (height - 40);
const x = index * barWidth;
const y = height - barHeight - 20;
const bar = createSVGElement('rect', {
x: x + 5,
y: y,
width: barWidth - 10,
height: barHeight,
fill: '#4285f4'
});
const label = createSVGElement('text', {
x: x + barWidth / 2,
y: height - 5,
'text-anchor': 'middle',
'font-size': '12'
});
label.textContent = item.label;
chartSvg.appendChild(bar);
chartSvg.appendChild(label);
});
return chartSvg;
}
const chartData = [
{ label: 'A', value: 30 },
{ label: 'B', value: 50 },
{ label: 'C', value: 40 },
{ label: 'D', value: 70 },
{ label: 'E', value: 20 }
];
const chart = createBarChart(chartData, 400, 200);
document.body.appendChild(chart);
// 10. SVG filters
const defs = createSVGElement('defs');
svg.appendChild(defs);
const filter = createSVGElement('filter', {
id: 'blur'
});
const blur = createSVGElement('feGaussianBlur', {
in: 'SourceGraphic',
stdDeviation: '5'
});
filter.appendChild(blur);
defs.appendChild(filter);
// Apply filter
circle.setAttribute('filter', 'url(#blur)');
1 file · javascript
Explain with highlit
SVG (Scalable Vector Graphics) creates resolution-independent graphics. I manipulate SVG elements with DOM methods like createElementNS(). Attributes control SVG properties: setAttribute(), getAttribute(). Animations use CSS or SMIL for declarative effects. The getBBox() method gets element dimensions. Path data with d attribute defines complex shapes. The viewBox attribute controls coordinate system and scaling. SVG filters create visual effects. Inline SVG allows CSS styling and JavaScript interaction. SVG excels at icons, logos, charts, and responsive graphics.
Related snips
javascript
// Creating a Promise
const myPromise = new Promise((resolve, reject) => {
const success = true;
setTimeout(() => {
if (success) {
Promises and async/await patterns for asynchronous JavaScript
javascript
promises
async-await
by Alex Chang
1 tab
javascript
import { Controller } from "@hotwired/stimulus"
import Mousetrap from "mousetrap"
export default class extends Controller {
connect() {
// Global shortcuts
Keyboard shortcuts with Stimulus and Mousetrap
stimulus
javascript
ux
by Jordan Lee
2 tabs
javascript
// Get canvas and context
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// 1. Basic shapes
// Rectangle (filled)
Canvas API for graphics and animations
canvas
javascript
graphics
by Alex Chang
1 tab
javascript
// Basic event listener
const button = document.getElementById('myButton');
button.addEventListener('click', function(event) {
console.log('Button clicked!');
console.log('Event type:', event.type);
Event handling and event delegation patterns in JavaScript
javascript
events
event-delegation
by Alex Chang
1 tab
javascript
// Basic GET request
fetch('https://api.example.com/users')
.then(response => {
console.log('Status:', response.status);
console.log('OK:', response.ok);
return response.json();
Fetch API for HTTP requests and AJAX communication
javascript
fetch
api
by Alex Chang
1 tab
erb
<turbo-stream action="set_title">
<template><%= "Inbox (#{@unread_count})" %></template>
</turbo-stream>
Turbo Streams: update document title with a custom action
rails
hotwire
turbo
by Henry Kim
2 tabs
Share this code
Here's the card — post it anywhere.