Skip to content

feat: add screenshot export to Ruby tab #322

@takaokouji

Description

@takaokouji

Goal

Ruby タブの Monaco エディタの内容(行番号・ふりがな含む)を PNG 画像として保存する機能を追加する。長いプログラムも全行キャプチャする。

Affected Files

ファイル 変更内容
packages/scratch-gui/package.json html-to-image 依存追加
packages/scratch-gui/src/lib/ruby-screenshot.js NEW: キャプチャロジック
packages/scratch-gui/src/containers/ruby-tab.jsx ボタン追加・ハンドラ接続
packages/scratch-gui/src/containers/ruby-tab/ruby-tab.css ボタンスタイル(既存 zoomButton 再利用)
packages/scratch-gui/test/unit/lib/ruby-screenshot.test.js NEW: ユニットテスト

キャプチャ方式

Polacode(https://github.com/octref/polacode)と同じ dom-to-image 系アプローチ。ライブラリは html-to-image(モダンな TypeScript 製の後継、軽量)を使用。

キャプチャフロー:

  1. エディタの現在のスクロール位置・サイズを保存
  2. editor.getContentHeight() で全コンテンツ高さを取得
  3. エディタコンテナの高さを全コンテンツ高さに一時拡張 → editor.layout() で再レイアウト
  4. Monaco が全行を DOM に描画するのを待つ(requestAnimationFrame
  5. htmlToImage.toBlob(editorDomNode) でキャプチャ
  6. 元のサイズ・スクロール位置を復元
  7. 既存の download-blob.js で PNG ダウンロード

ファイル名: {projectTitle}_{spriteName}_ruby.png

ボタン配置

  • zoomControlsWrapper 内の最初の子要素として追加(zoom ボタンの上に自然にスタック)
  • 既存の zoomButton CSS クラスを再利用(36x36, transparent background)
  • アイコン: blocks-screenshot-button の icon--camera.svg を共有
  • ツールチップ: 「Rubyコードを画像として保存」

ふりがな対応

  • ViewZones は DOM 要素なので、dom-to-image が自然にキャプチャする
  • furiganaEnabled の状態に依存 — ON なら表示あり、OFF なら表示なし(見たまま)
  • 特別な処理は不要

Implementation Steps

  • Phase 1: スクリーンショットボタン UI

    • ruby-tab.jsx にカメラボタン追加(zoom ボタンの上)
    • CSS スタイル設定(既存 zoomButton 再利用)
    • feat: add screenshot button to ruby tab
  • Phase 2: キャプチャロジック実装

    • ruby-screenshot.js 作成(TDD: テスト先行)
    • html-to-image 依存追加
    • feat: implement ruby tab screenshot capture
  • Phase 3: ハンドラ接続 & 統合

    • ruby-tab.jsx でハンドラ接続(editor ref → capture → download)
    • feat: connect screenshot handler in ruby tab
  • Phase Final: Integration Tests

    • ブラウザ動作の回帰テスト作成
    • test: add integration tests for ruby screenshot
  • Phase DoD: CI + ブラウザ確認

Definition of Done

  • ユニットテスト pass
  • Integration テスト pass
  • lint pass
  • CI green
  • ブラウザ確認(Playwright MCP):
    • Ruby タブにカメラボタンが zoom ボタンの上に表示される
    • 短いプログラム(5行程度)でスクリーンショットが保存できる
    • 長いプログラム(50行以上)で全行がキャプチャされている
    • ふりがな ON の状態でふりがなが画像に含まれる
    • ふりがな OFF の状態でふりがなが画像に含まれない
    • 行番号が画像に含まれる

Test Plan

Type Timing Target
Unit tests (TDD) Before implementation ruby-screenshot.js のロジック
Integration tests After implementation ボタンクリック → ダウンロード
Browser verification After CI green Playwright MCP で DoD 確認

Risks & Open Questions

  1. Monaco の仮想スクロール: 一時拡張で全行が DOM に描画されるか実装時に検証。editor.layout() + requestAnimationFrame で描画を待つ。描画されない場合は scroll-and-stitch 方式にフォールバック
  2. html-to-image の cross-origin 制約: CSS インライン化で回避できる見込み。問題があれば filter オプションで除外
  3. 非常に長いプログラムのパフォーマンス: まず制限なしで実装し、問題が出たら対処

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions