Repository navigation
fix(scratch-gui): ブロックのスクリーンショットを高解像度で書き出す (#1176) - #1178
Conversation
書き出し倍率を導入し、レイアウトを workspace.scale(既定 0.675 のユーザーズーム)から 切り離した。ブロックは SVG なので倍率を上げるとベクタとして再描画され、そのまま高解像度に なる。ダウンロードは 4 倍(教材・印刷用途)、提出/不具合報告はサイズを抑えて 2 倍 (ruby-screenshot.js の PIXEL_RATIO=2 と同等)。巨大なプログラムでは clampExportScale が キャンバス上限に収まるよう倍率を自動的に下げる。 Closes #1176 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
🤖 autopilot status
Linked issue #1176. Maintained by autopilot (single writer); do not edit. |
|
🚀 Preview deployed: https://smalruby.jp/smalruby3-editor/topic/autopilot-1176/ |
- MAX_EXPORT_PIXELS を 32M から iOS/iPadOS Safari のキャンバス面積上限 16,777,216 px に下げる。授業で使う iPad で書き出しが失敗しないようにする - クランプの対象をスプライトヘッダーを含めた合成後サイズにする。ブロック部分 だけで判定すると最終キャンバスがヘッダー分だけ上限を超えていた - toBlob() が null を返したときに downloadBlob() へ渡さず警告のみにする。 従来は blob.type 参照で TypeError になっていた - 上記 3 点の単体テストを追加
|
[Must]
実測(この PR の実装で計算):
倍率 4 で面積クランプが効き始めるのは論理面積 2 Mpx(≒ 1600×1250)あたりで、これは 対応: |
|
[Must]
canvas.toBlob((blob) => {
downloadBlob(buildFilename(projectTitle, spriteName), blob); // blob が null になりうる
}, 'image/png');
いずれも unhandled rejection になり、ユーザーには「ボタンを押しても何も起きない」ように見える。 なお同じ 対応: null のときはダウンロードせず |
|
[Question] クランプがスプライトヘッダーを勘定に入れておらず、自分で決めた上限自体を超えていた(修正済み: 0bef21e)
結果、クランプ後でも合成キャンバスは 対応: クランプ対象を合成後サイズ(ブロック+スプライトヘッダー)にした。加えて |
|
[Question] 提出 / 不具合報告のアップロード量が 1 枚あたり約 8.8 倍になる(コメントのみ・人間の判断に委ねます) Issue #1176 の「影響範囲」でも挙げられていた点の確認です。既定経路
つまり「壊れない」ことは確認済みで、残るのは どこまで許容するか という判断です。 |
|
[FYI] テストのモック周りの小さな気になり点(対応不要と判断)
|
|
[FYI] 中間キャンバスの分だけピーク時メモリが 2 倍
|
|
🤖 敵対的レビュー完了。指摘 6 件(Must 2 / Question 2 / FYI 2)。Must は修正済み(0bef21ee43)。Question 1 件(スプライトヘッダーを含めたクランプ)も併せて修正済み、残り 1 件(提出経路のアップロード量が約 8.8 倍になる件)はコメントのみで人間の判断に委ねます。lint / 単体テスト 40 件はローカルで green。 |
…lot-1176 fix(scratch-gui): ブロックのスクリーンショットを高解像度で書き出す (#1176)
Summary
ブロックのスクリーンショット(コードタブのカメラボタン / クラス機能の提出 / 不具合報告)が
低解像度で書き出される問題を修正した。
blocks-screenshot.jsに書き出し倍率を導入し、レイアウト倍率を
workspace.scale(ユーザーの現在ズーム。既定 0.675)から切り離した。ブロックは SVG なので、倍率を上げるとベクタとして再描画され、ぼやけずに高解像度になる。
Changes Made
packages/scratch-gui/src/lib/blocks-screenshot.jsLOGICAL_SCALE = 1— レイアウトは常にブロックの自然サイズ。出力サイズがユーザーのズーム状態に依存しなくなる(同じプログラムなら誰が撮っても同じサイズ)
DEFAULT_EXPORT_SCALE = 2—renderBlocksToCanvasの既定。提出 / 不具合報告経路が使う。Ruby タブの
ruby-screenshot.js(PIXEL_RATIO = 2) と同等でアップロード / S3 サイズを抑えるDOWNLOAD_EXPORT_SCALE = 4—downloadBlocksAsImage(カメラボタン)の既定。教材・ワークシート・印刷での判読性を優先
{exportScale}で上書きできる(renderBlocksToCanvas(ws, uri, {exportScale})/downloadBlocksAsImage(ws, title, name, uri, {exportScale}))。既存の呼び出し元 3 箇所は変更不要(既定で妥当な倍率になる)
EXPORT_PADDING/SPRITE_IMAGE_SIZE/SPRITE_IMAGE_GAP/ スプライト描画オフセットにも一律で掛けている(掛け忘れると余白やスプライトだけ小さくなる)
clampExportScale()を追加 — 巨大なプログラムでブラウザのキャンバス上限(
MAX_EXPORT_DIMENSION = 8192/MAX_EXPORT_PIXELS = 32Mpx) を超えないよう倍率を自動的に下げる(下限は等倍。
toBlob()が null を返して画像が出ない事態を避ける)docs/screenshot/README.md— 「出力形式」に書き出し倍率の節を追加。Test Coverage
packages/scratch-gui/test/unit/lib/blocks-screenshot.test.js(37 tests, all pass)clampExportScaleの 4 ケース(通常 / 辺の上限 / 面積の上限 / 下限 1)calculateCanvasDimensionsの padding も倍率が掛かることdownloadBlocksAsImageのキャンバスが(論理サイズ) × DOWNLOAD_EXPORT_SCALEであることrenderBlocksToCanvasの既定倍率 = 2、明示exportScaleの反映、空ワークスペースで nulllint / prettier ともにクリーン。ブラウザでの実描画確認(クリッピング / スプライトヘッダの
見た目)は headless では判断しづらいため、DoD フェーズでの目視確認に回している。
Related Issues
Closes #1176