mcpField
C
canvas-design

canvas-design

github.com/pixel-process-ugDesign & UI393 installsUpdated 33w ago
Repository

About canvas-design

A design skill for creating graphics and data visualizations with HTML Canvas 2D, SVG, WebGL, and visualization libraries such as D3.js. It helps developers choose a rendering approach and address interaction, accessibility, responsiveness, and performance during implementation.

Key features

  1. 01Select Canvas, SVG, or WebGL by requirements
  2. 02Create charts with D3.js patterns
  3. 03Add interaction and responsive resizing
  4. 04Plan accessibility and fallback content
  5. 05Optimize rendering and animation performance

Use cases

  1. 01Choosing a rendering method for a visualization
  2. 02Building interactive charts and maps
  3. 03Creating generative art or animated graphics
  4. 04Improving accessibility and rendering performance

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/pixel-process-ug/superkit-agents --skill canvas-design

After installing, type/canvas-designin Claude Code to confirm it loaded.

Details

From the project README

Canvas Design

Overview

Create performant, accessible, and visually compelling graphics using HTML Canvas 2D, SVG, and data visualization libraries. This skill covers everything from low-level pixel manipulation to high-level chart composition with D3.js, including generative art, interactive graphics, and animation.

Phase 1: Requirements Analysis

  1. Determine output type (static, animated, interactive, data-driven)
  2. Choose rendering technology (Canvas 2D, SVG, WebGL, hybrid)
  3. Identify data sources and update frequency
  4. Define accessibility requirements for the visualization
  5. Set performance budget (frame rate, element count)

STOP — Present technology recommendation with rationale before implementation.

Technology Selection Decision Table
RequirementCanvas 2DSVGWebGL
< 1000 elementsMaybeYesNo
> 10,000 elementsYesNoYes
DOM event handling neededNoYesNo
Pixel manipulationYesNoYes
Text-heavy visualizationNoYesNo
3D renderingNoNoYes
Print qualityNoYesNo
Animation-heavyYesMaybeYes
Accessibility criticalNoYesNo
SEO-relevant contentNoYesNo
When to Use Each Technology
Use CaseRecommendedWhy
Dashboard charts (< 500 data points)SVG + D3.jsDOM events, accessibility, print
Real-time data stream (1000+ points)Canvas 2DPerformance at scale
Interactive map with tooltipsSVGHover events, accessible
Particle system / generative artCanvas 2DPixel-level control, performance
3D data visualizationWebGL (Three.js)GPU acceleration
Infographic for blog postSVGScalable, accessible, printable
Game or simulationCanvas 2D or WebGLFrame rate, pixel control

Phase 2: Implementation

  1. Set up responsive canvas/SVG container
  2. Implement rendering pipeline (clear, update, draw)
  3. Add interaction handlers (hover, click, drag, zoom)
  4. Optimize render loop (requestAnimationFrame, dirty rectangles)
  5. Add accessibility layer (ARIA, screen reader descriptions)

STOP — Verify rendering works correctly at target frame rate before adding polish.

Canvas 2D API Patterns
Responsive Canvas Setup
function createResponsiveCanvas(container) {
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  const dpr = window.devicePixelRatio || 1;

  function resize() {
    const rect = container.getBoundingClientRect();
    canvas.width = rect.width * dpr;
    canvas.height = rect.height * dpr;
    canvas.style.width = `${rect.width}px`;
    canvas.style.height = `${rect.height}px`;
    ctx.scale(dpr, dpr);
  }

  const observer = new ResizeObserver(resize);
  observer.observe(container);
  container.appendChild(canvas);
  resize();

  return { canvas, ctx, destroy: () => observer.disconnect() };
}
Animation Loop Pattern
function createAnimationLoop(drawFn) {
  let rafId = null;
  let lastTime = 0;

  function loop(timestamp) {
    const deltaTime = timestamp - lastTime;
    lastTime = timestamp;
    drawFn(deltaTime, timestamp);
    rafId = requestAnimationFrame(loop);
  }

  return {
    start: () => { rafId = requestAnimationFrame(loop); },
    stop: () => { cancelAnimationFrame(rafId); rafId = null; },
    isRunning: () => rafId !== null,
  };
}
Dirty Rectangle Optimization
class DirtyRectRenderer {
  constructor(ctx, width, height) {
    this.ctx = ctx;
    this.dirtyRects = [];
    this.objects = [];
  }

  markDirty(x, y, w, h) {
    this.dirtyRects.push({ x, y, w, h });
  }

  render() {
    for (const rect of this.dirtyRects) {
      this.ctx.clearRect(rect.x, rect.y, rect.w, rect.h);
      for (const obj of this.objects) {
        if (this.intersects(obj.bounds, rect)) {
          obj.draw(this.ctx);
        }
      }
    }
    this.dirtyRects = [];
  }
}
SVG Patterns
Programmatic SVG Creation
function createSVG(width, height, viewBox) {
  const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
  svg.setAttribute('width', '100%');
  svg.setAttribute('height', '100%');
  svg.setAttribute('viewBox', viewBox || `0 0 ${width} ${height}`);
  svg.setAttribute('role', 'img');
  return svg;
}
SVG Accessibility
<svg role="img" aria-labelledby="chart-title chart-desc">
  <title id="chart-title">Monthly Revenue Chart</title>
  <desc id="chart-desc">Bar chart showing revenue from Jan to Dec 2025</desc>
  <!-- chart content -->
</svg>
D3.js Integration Patterns
Data Join Pattern (D3 v7)
function updateBars(svg, data) {
  const bars = svg.selectAll('.bar')
    .data(data, d => d.id);

  bars.exit()
    .transition().duration(300)
    .attr('opacity', 0)
    .remove();

  bars.enter()
    .append('rect')
    .attr('class', 'bar')
    .attr('opacity', 0)
    .merge(bars)
    .transition().duration(500)
    .attr('x', d => xScale(d.label))
    .attr('y', d => yScale(d.value))
    .attr('width', xScale.bandwidth())
    .attr('height', d => height - yScale(d.value))
    .attr('opacity', 1);
}
Scales and Axes
// Linear scale for continuous data
const yScale = d3.scaleLinear()
  .domain([0, d3.max(data, d => d.value)])
  .range([height, 0])
  .nice();

// Band scale for categorical data
const xScale = d3.scaleBand()
  .domain(data.map(d => d.label))
  .range([0, width])
  .padding(0.2);

// Color scale
const colorScale = d3.scaleOrdinal(d3.schemeTableau10);
Responsive D3 Chart
function responsiveChart(container, renderFn) {
  const observer = new ResizeObserver(entries => {
    const { width, height } = entries[0].contentRect;
    const margin = { top: 20, right: 20, bottom: 40, left: 50 };
    renderFn(container, {
      width: width - margin.left - margin.right,
      height: height - margin.top - margin.bottom,
      margin,
    });
  });
  observer.observe(container);
  return () => observer.disconnect();
}

Phase 3: Polish

  1. Add transitions and easing
  2. Implement responsive resizing
  3. Test across devices and browsers
  4. Add fallback content for unsupported environments

STOP — Verify accessibility and performance targets are met.

Generative Art Techniques
TechniqueCategoryUse Case
Perlin/Simplex noiseNoise-basedOrganic shapes, terrain
Fractal Brownian MotionNoise-basedTerrain-like textures
Domain warpingNoise-basedFluid-like effects
Particle systemsSimulationFire, water, swarms
L-systemsAlgorithmicPlant-like structures
Voronoi diagramsAlgorithmicCell-like partitions
Delaunay triangulationAlgorithmicMesh generation
Flow fieldsAlgorithmicDirectional patterns
Accessibility for Visualizations
RequirementImplementation
Text alternatives<title> and <desc> in SVG, ARIA labels on Canvas
Data table fallbackHidden table with same data for screen readers
Keyboard interactionTab to elements, arrow keys for navigation
Color-blind safeUse shape/pattern in addition to color
High contrast modeDetect and adjust colors
Reduced motionSimplify or disable animations with prefers-reduced-motion
Performance Guidelines
TechnologyOptimization
CanvasBatch draw calls, minimize state changes (fill/stroke/font)
SVGLimit to < 1000 DOM nodes, use <use> for repeated elements
WorkerOffscreenCanvas for web worker rendering
EventsThrottle mousemove handlers to 16ms (60fps)
CSSUse will-change: transform for CSS-animated SVG elements
CleanupDispose of observers, animation frames on unmount

Anti-Patterns / Common Mistakes

Anti-PatternWhy It Is WrongWhat to Do Instead
Canvas for text-heavy contentPoor text rendering, no accessibilityUse SVG for text-heavy visualizations
Full canvas redraw every frameWastes CPU when nothing changedUse dirty rectangle optimization
Creating new SVG elements instead of updatingMemory leaks, poor performanceUse D3 data join pattern
Forgetting devicePixelRatioBlurry on Retina/HiDPI displaysScale canvas by window.devicePixelRatio
No fallback content for CanvasScreen readers get nothingAdd aria-label and hidden data table
Inline event handlers on 1000+ SVG elementsMemory and performance overheadUse event delegation on parent
Not cleaning up animation framesMemory leaks on unmountcancelAnimationFrame in cleanup
Using D3 for simple static chartsOver-engineeringUse SVG directly or Chart.js

Integration Points

SkillIntegration
ui-ux-pro-maxChart type selection and color palettes
ui-design-systemDesign tokens for chart theming
artifacts-builderSelf-contained visualization artifacts
senior-frontendComponent integration in React/Vue/Svelte
performance-optimizationFrame rate and rendering optimization
mobile-designTouch interaction for mobile charts

Skill Type

FLEXIBLE — Choose the rendering technology and library that best fits the use case. SVG for accessibility-critical and interactive charts, Canvas for performance-critical and animation-heavy visuals, WebGL for 3D and massive datasets.

Comments

Markdown supported