feat(image-editor): Warp Text — arc / bulge / flag / wave / rise / fish / inflate#79
Merged
Merged
Conversation
Photoshop Type > Warp Text as a non-destructive, re-editable property of a text layer (shape.warp). The renderer rasterizes the text and bends it via a vertical-envelope warp — each column is remapped between a per-column top/bottom edge curve with bilinear inverse sampling — which faithfully reproduces the classic PS warp shapes without a 2-D mesh solve. - 8 styles (none + arc/bulge/flag/wave/rise/fish/inflate) with Bend and Horizontal/Vertical distortion (-100..100). Distortion stays a vertical- envelope modulation, not 2-D perspective, so the inverse stays a 1-D solve. - Warp Text dialog (Layer menu, enabled for a plain text layer) with live canvas preview via a display-state overlay; Apply commits one undo step, Cancel drops the preview — history untouched during preview. - drawShape runs on every render, so warped bitmaps are cached keyed on text / font / align / warp params / scale; plain or zero-amount warps short-circuit to the existing drawText. Layout (multi-line / align / letterSpacing / underline) is shared with drawText so warp can't drift from plain text. - The warp is purely visual: the layer's logical bbox is unchanged, so hit-testing, move and handles keep working (verified select + pick on a warped layer in headless Chrome). 9 new unit tests (envelope identity, isWarpActive gating, zero-bend remap is a no-op, real bends move pixels in range); full suite 197 green. typecheck / lint / build clean. All 8 styles + distortion verified in headless Chrome via the real drawShape dispatch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
What
Warp Text (Photoshop Type ▸ Warp Text) as a non-destructive, re-editable property of a text layer (
shape.warp). Pick a style, dial Bend / Horizontal / Vertical distortion, see it live, Apply — the text stays editable vector text with a warp envelope.8 styles:
None·Arc·Bulge·Flag·Wave·Rise·Fish·Inflate, each with Bend and Horizontal/Vertical Distortion (−100…100).How
Vertical-envelope warp. Every classic PS warp shape (for horizontal text) is a deformation where each vertical column of the rendered text keeps its x but is bent/stretched vertically. So the renderer rasterizes the text to a padded offscreen and remaps it column-by-column between a per-column top/bottom edge curve via bilinear inverse sampling (the same technique as the Wave/Ripple filters). This reproduces all the shapes faithfully with a trivial 1-D inverse — no 2-D mesh solve.
That's also why Horizontal Distortion here is a left/right asymmetry of the envelope (still a function of
u), not PS's true horizontal perspective: real perspective makesxdepend on the row and would force a 2-D inversion. The vertical-envelope model covers the popular set cleanly.Integration care
drawShaperuns on every render (unlike a baked filter), so warped bitmaps are cached keyed on text / font / align / warp params / scale; plain or zero-amount warps short-circuit to the existingdrawText. The offscreen reusesdrawText's exact layout (multi-line / align / letterSpacing / underline) — one implementation, so warp can't silently drift from plain text.displayStatefed to the canvas; the real document state is untouched until Apply commits a single undo step. Cancel just drops the preview.getLayerBBox(warped) === getLayerBBox(plain)and thatpickLayerselects a warped layer at its centre.Verification
pnpm typecheck·pnpm lint·pnpm build— clean.none/zero params,isWarpActivegating, zero-bend remap is an exact no-op, real bends move pixels and stay in range). Full suite 197 green.drawShapedispatch (contact sheet), and confirmed the select/move integration (bbox unchanged, warped layer pickable at centre).EN + zh-CN strings included.
🤖 Generated with Claude Code