Skip to content

feat(layers): add star, triangle, diamond, hexagon and speech bubble masks - #901

Merged
hm21 merged 2 commits into
stablefrom
feat/more-mask-shapes
Oct 23, 2026
Merged

hm21 merged 2 commits into
stablefrom
feat/more-mask-shapes

Conversation

@hm21

@hm21 hm21 commented Oct 23, 2026 •

Copy link
Copy Markdown
Owner

Description

Problem. A layer mask offers an ellipse, a rounded rectangle, a heart and a linear edge. Hosts want more frames for picture-in-picture clips and stickers: a star for a celebration, a speech bubble for a reaction, hexagons for a grid of clips.

Approach. LayerMaskShape gains star, triangle, diamond, hexagon and speechBubble.

  • Every new shape fills the mask's box, as the heart does, so the box a host stretches is the box the shape fills, and size, rotation, feather, invert, area, outline, toImage and applyTo work unchanged.
  • The star, triangle, diamond and hexagon are polygons in a unit box, stretched to the mask's box. The star has the proportions of the Material Design star (inner corners a little under half the radius of its points), plumper than a pentagram so more of the layer shows. The triangle is equilateral and the hexagon regular when the box has the proportions their docs give (about 1.15 and 0.87 times as wide as high).
  • The speech bubble is a rounded body over the top four fifths of the box with a tail down to its bottom left. It is built in the box's own coordinates, so its corners stay round when the box is not square. A box with a negative width or height mirrors it, as it mirrors the other shapes.
  • Serialisation is by name, as before; an older version reading a new shape falls back to an ellipse.

Not changed. Existing shapes paint, capture and serialise exactly as before. A switch over LayerMaskShape has to handle the new values; the CHANGELOG says so.

CHANGELOG 14.18.0.

Related Issue: Closes #none; requested in divinevideo/divine-mobile#10396.

Verification

  • New tests: every unturned shape's outline fills its box exactly; for each new shape, pixels that must show and pixels that must stay hidden in a rendered mask.
  • New tests: a speech bubble in a box with a negative width or height is mirrored, not turned inside out.
  • flutter test: 1107 passed on Flutter 3.47.2; flutter analyze clean; dart format clean.
  • Rendered every new shape plain, inverted, feathered, turned and stretched both ways, and checked the result by eye.
  • Used in the Divine video editor on a Samsung Galaxy S26 (debug): every new shape on a video clip, with softness, invert, stretching against the edges and an export whose frame matches the preview.

Type of Change

  • ✨ New feature (non-breaking change which adds functionality)
  • 🛠️ Bug fix (non-breaking change which fixes an issue)
  • ❌ Breaking change (fix or feature that would cause existing functionality to change)
  • 🧹 Code refactor
  • ✅ Build configuration change
  • 📝 Documentation
  • 🗑️ Chore

…masks

A layer mask offered an ellipse, a rounded rectangle, a heart and a linear
edge. Hosts want more frames for picture-in-picture clips and stickers, such
as a star for a celebration or a speech bubble for a reaction.

Every new shape fills the mask's box like the heart does, so stretching,
softness, inversion and `toImage` work unchanged. The speech bubble is built
in the box's own coordinates so its corners stay round when the box is not
square.
@hm21 hm21 self-assigned this Oct 23, 2026
Every other mask shape mirrors when its box has a negative width or
height. The speech bubble turned its corners inside out instead, and with
a negative height its tail reached outside the box. It is now built at
the box's absolute size and mirrored onto it.
@hm21
hm21 merged commit 50db8bf into stable Oct 23, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant