From c46d28891fee62ca2d3132da876af6411a41d9da Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Wed, 15 Apr 2026 15:45:50 +0200 Subject: feat: text / custom masks, fix preview pan, refactor selection --- apps/web/src/services/renderer/nodes/text-node.ts | 89 +++-------------------- 1 file changed, 10 insertions(+), 79 deletions(-) (limited to 'apps/web/src/services/renderer/nodes/text-node.ts') diff --git a/apps/web/src/services/renderer/nodes/text-node.ts b/apps/web/src/services/renderer/nodes/text-node.ts index c9e13261..86384328 100644 --- a/apps/web/src/services/renderer/nodes/text-node.ts +++ b/apps/web/src/services/renderer/nodes/text-node.ts @@ -3,16 +3,9 @@ import type { TextElement } from "@/lib/timeline"; import type { EffectPass } from "@/lib/effects/types"; import type { Transform } from "@/lib/rendering"; import { - CORNER_RADIUS_MAX, - CORNER_RADIUS_MIN, -} from "@/lib/text/background"; -import { - drawTextDecoration, - getTextBackgroundRect, - setCanvasLetterSpacing, -} from "@/lib/text/layout"; + drawMeasuredTextLayout, +} from "@/lib/text/primitives"; import type { MeasuredTextElement } from "@/lib/text/measure-element"; -import { clamp } from "@/utils/math"; export type TextNodeParams = TextElement & { canvasCenter: { x: number; y: number }; @@ -46,22 +39,6 @@ export function renderTextToContext({ const x = resolved.transform.position.x + node.params.canvasCenter.x; const y = resolved.transform.position.y + node.params.canvasCenter.y; const baseline = node.params.textBaseline ?? "middle"; - const { - scaledFontSize, - fontString, - letterSpacing, - lineHeightPx, - lines, - lineMetrics, - block, - fontSizeRatio, - resolvedBackground, - } = resolved.measuredText; - const lineCount = lines.length; - const resolvedBackgroundWithColor = { - ...resolvedBackground, - color: resolved.backgroundColor, - }; ctx.save(); ctx.translate(x, y); @@ -70,60 +47,14 @@ export function renderTextToContext({ ctx.rotate((resolved.transform.rotate * Math.PI) / 180); } - ctx.font = fontString; - ctx.textAlign = node.params.textAlign; - ctx.textBaseline = baseline; - ctx.fillStyle = resolved.textColor; - setCanvasLetterSpacing({ ctx, letterSpacingPx: letterSpacing }); - - if ( - node.params.background.enabled && - node.params.background.color && - node.params.background.color !== "transparent" && - lineCount > 0 - ) { - const backgroundRect = getTextBackgroundRect({ - textAlign: node.params.textAlign, - block, - background: resolvedBackgroundWithColor, - fontSizeRatio, - }); - if (backgroundRect) { - const p = - clamp({ - value: resolvedBackgroundWithColor.cornerRadius, - min: CORNER_RADIUS_MIN, - max: CORNER_RADIUS_MAX, - }) / 100; - const radius = - (Math.min(backgroundRect.width, backgroundRect.height) / 2) * p; - ctx.fillStyle = resolvedBackgroundWithColor.color; - ctx.beginPath(); - ctx.roundRect( - backgroundRect.left, - backgroundRect.top, - backgroundRect.width, - backgroundRect.height, - radius, - ); - ctx.fill(); - ctx.fillStyle = resolved.textColor; - } - } - - for (let index = 0; index < lineCount; index++) { - const lineY = index * lineHeightPx - block.visualCenterOffset; - ctx.fillText(lines[index], 0, lineY); - drawTextDecoration({ - ctx, - textDecoration: node.params.textDecoration ?? "none", - lineWidth: lineMetrics[index].width, - lineY, - metrics: lineMetrics[index], - scaledFontSize, - textAlign: node.params.textAlign, - }); - } + drawMeasuredTextLayout({ + ctx, + layout: resolved.measuredText, + textColor: resolved.textColor, + background: resolved.measuredText.resolvedBackground, + backgroundColor: resolved.backgroundColor, + textBaseline: baseline, + }); ctx.restore(); } -- cgit v1.3.1