SVG manipulation with JavaScript

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.