mcpField
C
canvas-design

canvas-design

github.com/pixel-process-ugデザイン・UI393 回インストール33 週間前に更新
リポジトリ

canvas-design について

HTML Canvas 2D、SVG、WebGLやD3.jsなどの可視化ライブラリで、グラフィックやデータ可視化を作成するためのデザインスキルです。開発者が描画方式を選び、実装時の操作性、アクセシビリティ、レスポンシブ対応、性能を検討できるよう支援します。

主な機能

  1. 01要件に応じたCanvas、SVG、WebGLの選択
  2. 02D3.jsのパターンによるチャート作成
  3. 03操作性とレスポンシブなサイズ調整
  4. 04アクセシビリティと代替コンテンツの設計
  5. 05描画とアニメーション性能の最適化

活用シーン

  1. 01可視化に適した描画方式の選定
  2. 02操作可能なチャートやマップの作成
  3. 03ジェネレーティブアートやアニメーションの制作
  4. 04アクセシビリティと描画性能の改善

インストール

コマンドをコピーしてターミナルで実行します。

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

インストール後、Claude Code で/canvas-designを入力して読み込まれたか確認します。

詳細

Canvas デザイン

概要

HTML Canvas 2D、SVG、データ可視化ライブラリを使用して、高性能でアクセシブル、かつ視覚的に魅力的なグラフィックを作成します。このスキルでは、低レベルのピクセル操作から、D3.js を使った高度なチャート構成までを網羅し、ジェネレーティブアート、インタラクティブなグラフィック、アニメーションも扱います。

フェーズ 1:要件分析

  1. 出力の種類(静的、アニメーション、インタラクティブ、データ駆動型)を決定します
  2. レンダリング技術(Canvas 2D、SVG、WebGL、ハイブリッド)を選択します
  3. データソースと更新頻度を特定します
  4. 可視化に必要なアクセシビリティ要件を定義します
  5. パフォーマンス予算(フレームレート、要素数)を設定します

STOP — 実装の前に、根拠を添えて技術の推奨を提示してください。

技術選択の判断表
要件Canvas 2DSVGWebGL
< 1000 要素場合によるはいいいえ
> 10,000 要素はいいいえはい
DOM イベント処理が必要いいえはいいいえ
ピクセル操作はいいいえはい
テキスト中心の可視化いいえはいいいえ
3D レンダリングいいえいいえはい
印刷品質いいえはいいいえ
アニメーションが多いはい場合によるはい
アクセシビリティが重要いいえはいいいえ
SEO に関連するコンテンツいいえはいいいえ
各技術の使いどころ
使用例推奨理由
ダッシュボードのチャート(データポイント < 500)SVG + D3.jsDOM イベント、アクセシビリティ、印刷
リアルタイムのデータストリーム(データポイント 1000 以上)Canvas 2D大規模でも高いパフォーマンス
ツールチップ付きのインタラクティブな地図SVGホバーイベント、アクセシビリティ
パーティクルシステム/ジェネレーティブアートCanvas 2Dピクセルレベルの制御、パフォーマンス
3D データ可視化WebGL (Three.js)GPU アクセラレーション
ブログ記事用のインフォグラフィックSVG拡大縮小可能、アクセシブル、印刷可能
ゲームまたはシミュレーションCanvas 2D または WebGLフレームレート、ピクセル制御

フェーズ 2:実装

  1. レスポンシブな Canvas/SVG コンテナーを設定します
  2. レンダリングパイプライン(クリア、更新、描画)を実装します
  3. インタラクションハンドラー(ホバー、クリック、ドラッグ、ズーム)を追加します
  4. レンダリングループ(requestAnimationFrame、ダーティレクタングル)を最適化します
  5. アクセシビリティレイヤー(ARIA、スクリーンリーダー向けの説明)を追加します

STOP — 装飾を加える前に、目標フレームレートで正しくレンダリングされることを確認してください。

Canvas 2D API パターン
レスポンシブな Canvas のセットアップ
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() };
}
アニメーションループのパターン
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,
  };
}
ダーティレクタングルによる最適化
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 パターン
プログラムによる SVG の作成
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 のアクセシビリティ
<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>
  
</svg>
D3.js 統合パターン
データ結合パターン(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);
}
スケールと軸
// 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);
レスポンシブな D3 チャート
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();
}

フェーズ 3:仕上げ

  1. トランジションとイージングを追加します
  2. レスポンシブなサイズ変更を実装します
  3. デバイスやブラウザーをまたいでテストします
  4. 非対応の環境向けに代替コンテンツを追加します

STOP — アクセシビリティとパフォーマンスの目標を満たしていることを確認してください。

ジェネレーティブアートの手法
手法カテゴリ使用例
Perlin/Simplex ノイズノイズベース有機的な形状、地形
フラクタルブラウン運動ノイズベース地形のようなテクスチャ
ドメインワーピングノイズベース流体のような効果
パーティクルシステムシミュレーション火、水、群れ
L システムアルゴリズム植物のような構造
ボロノイ図アルゴリズム細胞のような分割
ドロネー三角形分割アルゴリズムメッシュ生成
フローフィールドアルゴリズム方向性のあるパターン
可視化のアクセシビリティ
要件実装
テキストによる代替SVG の <title> と <desc>、Canvas の ARIA ラベル
データテーブルによる代替スクリーンリーダー用に同じデータを含む非表示テーブル
キーボード操作要素への Tab 移動、ナビゲーション用の矢印キー
色覚多様性への配慮色に加えて形状/パターンを使用
ハイコントラストモード検出して色を調整
動きの低減prefers-reduced-motion を使ってアニメーションを簡略化または無効化
パフォーマンスのガイドライン
技術最適化
Canvas描画呼び出しをまとめ、状態の変更(塗りつぶし/線/フォント)を最小限に抑えます
SVGDOM ノードを 1000 未満に抑え、繰り返し要素には <use> を使用します
WorkerWeb ワーカーでの描画には OffscreenCanvas を使用します
イベントmousemove ハンドラーを 16ms(60fps)間隔でスロットリングします
CSSCSS でアニメーションする SVG 要素には will-change: transform を使用します
クリーンアップアンマウント時にオブザーバーとアニメーションフレームを破棄します

アンチパターン/よくある間違い

アンチパターン誤りである理由代わりにすること
テキスト中心のコンテンツに Canvas を使うテキストの描画品質が低く、アクセシビリティにも対応できませんテキスト中心の可視化には SVG を使用します
毎フレーム、Canvas 全体を再描画する何も変わっていないときにも CPU を浪費しますダーティー矩形による最適化を使用します
更新する代わりに、新しい SVG 要素を作成するメモリーリークやパフォーマンス低下の原因になりますD3 のデータ結合パターンを使用します
devicePixelRatio を考慮しないRetina/HiDPI ディスプレイでぼやけますwindow.devicePixelRatio に合わせて Canvas を拡大縮小します
Canvas にフォールバックコンテンツがないスクリーンリーダーに何も伝わりませんaria-label と非表示のデータテーブルを追加します
1000 個以上の SVG 要素にインラインイベントハンドラーを設定するメモリーとパフォーマンスに負荷がかかります親要素でイベント委譲を使用します
アニメーションフレームをクリーンアップしないアンマウント時にメモリーリークが発生しますクリーンアップで cancelAnimationFrame を呼び出します
シンプルな静的グラフに D3 を使う過剰な設計になりますSVG を直接使うか、Chart.js を使用します

統合ポイント

スキル統合
ui-ux-pro-maxグラフの種類の選定とカラーパレット
ui-design-systemグラフのテーマ設定に使うデザイントークン
artifacts-builder自己完結型の可視化アーティファクト
senior-frontendReact/Vue/Svelte でのコンポーネント統合
performance-optimizationフレームレートと描画の最適化
mobile-designモバイルグラフのタッチ操作

スキルの種類

FLEXIBLE — 用途に最適な描画技術とライブラリを選択します。アクセシビリティが重要なグラフやインタラクティブなグラフには SVG、パフォーマンスが重要なビジュアルやアニメーションを多用するビジュアルには Canvas、3D や大規模なデータセットには WebGL を使用します。

コメント