blob: 79ed02729b4a53a5d2370930bb225dba598b78ad (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
import { BaseNode } from "./base-node";
import type { TextElement } from "@/timeline";
import type { EffectPass } from "@/effects/types";
import type { BlendMode, Transform } from "@/rendering";
import type { VisualTransition } from "@/rendering/transition";
import { drawMeasuredTextLayout } from "@/text/primitives";
import type { MeasuredTextElement } from "@/text/measure-element";
export type TextNodeParams = TextElement & {
transform: Transform;
opacity: number;
blendMode?: BlendMode;
transition?: VisualTransition;
canvasCenter: { x: number; y: number };
canvasHeight: number;
textBaseline?: CanvasTextBaseline;
};
export interface ResolvedTextNodeState {
transform: Transform;
opacity: number;
textColor: string;
backgroundColor: string;
effectPasses: EffectPass[][];
measuredText: MeasuredTextElement;
}
export class TextNode extends BaseNode<TextNodeParams, ResolvedTextNodeState> {}
export function renderTextToContext({
node,
ctx,
}: {
node: TextNode;
ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;
}): void {
const resolved = node.resolved;
if (!resolved) {
return;
}
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";
ctx.save();
ctx.translate(x, y);
ctx.scale(resolved.transform.scaleX, resolved.transform.scaleY);
if (resolved.transform.rotate) {
ctx.rotate((resolved.transform.rotate * Math.PI) / 180);
}
drawMeasuredTextLayout({
ctx,
layout: resolved.measuredText,
textColor: resolved.textColor,
background: resolved.measuredText.resolvedBackground,
backgroundColor: resolved.backgroundColor,
textBaseline: baseline,
});
ctx.restore();
}
|