diff --git a/client/src/components/Studio/TextEffectsView.tsx b/client/src/components/Studio/TextEffectsView.tsx index d1b3a78b7..16110c3e5 100644 --- a/client/src/components/Studio/TextEffectsView.tsx +++ b/client/src/components/Studio/TextEffectsView.tsx @@ -152,6 +152,12 @@ function lettersPaint(el: BookTextElement, id: string): PaintParts | null { return paint ? paintParts(paint, { x: 0, y: 0, w: el.frame.w, h: el.frame.h }, id) : null; } +/** What the letters are filled with: the paint's fill, else their own colour. */ +function lettersFill(el: BookTextElement, paint: PaintParts | null): string { + if (paint) return paint.fill; + return letterFill(el) ?? el.color; +} + /** A pattern's ground and its marks, clipped to the letters. */ function PatternLetters({ parts, w, h, clipId }: { parts: PaintParts; w: number; h: number; clipId: string }) { const pattern = parts.pattern; @@ -240,7 +246,7 @@ function DrawnText({ el, frameStyle, big }: { el: BookTextElement; frameStyle: C } else if (pattern && letterPaint) { layers.push(); } else { - layers.push(glyphs({ fill: letterPaint ? letterPaint.fill : (letterFill(el) ?? el.color) }, 'fill')); + layers.push(glyphs({ fill: lettersFill(el, letterPaint) }, 'fill')); } return ( diff --git a/client/src/components/Studio/paint/paintParts.tsx b/client/src/components/Studio/paint/paintParts.tsx index 8727ec7e7..199d73103 100644 --- a/client/src/components/Studio/paint/paintParts.tsx +++ b/client/src/components/Studio/paint/paintParts.tsx @@ -9,20 +9,12 @@ import { patternGeometry, type PatternBox } from './patterns'; * the letters of a text share it without the component file exporting a helper. */ -function Stops({ stops }: { stops: readonly BookPaintStop[] }) { - return ( - <> - {sortedStops(stops).map((s, i) => ( - - ))} - - ); +/** A gradient's stops as SVG elements, in order. */ +function stopElements(stops: readonly BookPaintStop[]): ReactNode { + // Two stops may share an offset (a hard edge), so the index keys them. + return sortedStops(stops).map((s, i) => ( + + )); } /** What a painted outline needs: the defs to put in the SVG, and how to fill the outline. */ @@ -53,7 +45,7 @@ export function paintParts(paint: BookPaint, box: PatternBox, id: string): Paint return { defs: ( - + {stopElements(paint.stops)} ), fill: `url(#${id})`, @@ -70,7 +62,7 @@ export function paintParts(paint: BookPaint, box: PatternBox, id: string): Paint cy={r2(box.y + paint.cy * box.h)} r={r2((paint.r * Math.hypot(box.w, box.h)) / 2)} > - + {stopElements(paint.stops)} ), fill: `url(#${id})`,