TortoiseUI: 亀を任意の画像で描けるようにする - #42
Merged
Merged
Conversation
Add `TortoiseSprite` and the `.tortoiseSprite(_:)` environment modifier, so
the tortoise can be drawn as the user's own image instead of the built-in
green triangle:
TortoiseCanvas(🐢)
.tortoiseSprite(.image(Image("Turtle"), size: CGSize(width: 40, height: 40)))
The sprite is a view-side setting, not a `TortoiseCommand`, so it never
enters the serialized stream and TortoiseSVG is unaffected.
The image is centered on the tortoise's position and rotated so its top edge
faces the heading, with transparency preserved. `size` is a bounding box in
points at viewport scale 1: the image is scaled to fit inside it with its
aspect ratio preserved, then scales with the viewport exactly like the
triangle (clamped to 0.5x-2x).
`ViewportMode.autoFit`'s edge inset now derives from the sprite's
half-diagonal instead of a triangle-sized constant, so a large sprite never
clips at the view edge. Both canvas layers read the environment value —
only `AnimationLayer` draws the sprite, but the two layers must derive the
identical transform.
The default is `.triangle` and its rendering is unchanged, which the
existing canvas goldens confirm.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
TortoiseUIにTortoiseSpriteと.tortoiseSprite(_:)environment modifier を追加し、亀を組み込みの緑の三角形ではなく任意の画像で描けるようにします。デフォルトは従来どおり
.triangleで、その描画結果は一切変わりません(既存の canvas ゴールデン画像が無変更で通ることで確認済み)。設計上の判断
\.tortoiseViewportと同様に environment 経由の表示側の設定であり、TortoiseCommandではありません。したがってシリアライズされるコマンドストリームには入らず、TortoiseSVGにも影響しません(SVG 出力はもともと亀を描いていません)。sizeはバウンディングボックス(ビューポート倍率1でのポイント数)として扱い、アスペクト比を保って内側にフィットさせます(SwiftUI のscaledToFitと同じ考え方)。その上で三角形と同様にビューポート倍率で拡縮し、0.5×〜2× にクランプされます。ViewportMode.autoFitの端の inset を、三角形固定のサイズではなくスプライトの半対角長(TortoiseSprite.halfExtent)基準に変更しました。これにより大きなスプライトでもビュー端で切れず、どの heading でも成立します。スプライトを描くのはAnimationLayerだけですが、2つのレイヤーは同一の transform を導出する必要があるため、両方が environment 値を読んでいます。UIImage/NSImageはImage(uiImage:)/Image(nsImage:)で渡してもらう形にし、プラットフォーム分岐を API に持ち込んでいません。sizeはポイント指定なので、Asset Catalog の@2x/@3xは自動的に効きます。関連 issue
なし(直接の機能要望)
チェックリスト
swift testがローカルで通る(120件)xcrun swift-format lint --recursive --strict Sources Testsが通る新しい挙動に対するテストを追加
TortoiseSpriteTestsを新規追加:halfExtent、autoFitの inset、Equatableの単体テストに加え、macOS のスナップショット2件(画像が三角形を置き換えて heading 方向に回転すること/非正方形の画像が引き伸ばされずフィットすること)。スプライト画像はImageRendererでコード内生成しているため、テストリソースは増えていません。CHANGELOG.mdを更新ゴールデン画像: デフォルトの三角形の描画結果は変わらないため、既存ゴールデンの再録は不要でした。新規追加した2件は目視で確認済みです。
README、
TortoiseUIの DocC 記事、CLAUDE.mdも更新し、TortoiseCanvas.swiftに#Preview("Custom Sprite")を追加しています。