diff --git a/apps/web/src/components/editor/panels/properties/text-properties.tsx b/apps/web/src/components/editor/panels/properties/text-properties.tsx
index f8c9bf87..8f40910b 100644
--- a/apps/web/src/components/editor/panels/properties/text-properties.tsx
+++ b/apps/web/src/components/editor/panels/properties/text-properties.tsx
@@ -30,6 +30,7 @@ import {
} from "@/components/ui/tooltip";
import { useEditor } from "@/hooks/use-editor";
import { DEFAULT_COLOR } from "@/constants/project-constants";
+import { MIN_FONT_SIZE, MAX_FONT_SIZE } from "@/constants/text-constants";
export function TextProperties({
element,
@@ -57,7 +58,7 @@ export function TextProperties({
const parsed = parseInt(value, 10);
const fontSize = Number.isNaN(parsed)
? element.fontSize
- : clamp({ value: parsed, min: 8, max: 300 });
+ : clamp({ value: parsed, min: MIN_FONT_SIZE, max: MAX_FONT_SIZE });
editor.timeline.updateTextElement({
trackId,
elementId: element.id,
@@ -70,7 +71,7 @@ export function TextProperties({
const parsed = parseInt(fontSizeInput, 10);
const fontSize = Number.isNaN(parsed)
? element.fontSize
- : clamp({ value: parsed, min: 8, max: 300 });
+ : clamp({ value: parsed, min: MIN_FONT_SIZE, max: MAX_FONT_SIZE });
setFontSizeInput(fontSize.toString());
editor.timeline.updateTextElement({
trackId,
@@ -274,8 +275,8 @@ export function TextProperties({
{
editor.timeline.updateTextElement({
@@ -290,8 +291,8 @@ export function TextProperties({
handleFontSizeChange({ value: e.target.value })
}
diff --git a/apps/web/src/constants/text-constants.ts b/apps/web/src/constants/text-constants.ts
index c8a23655..932d494b 100644
--- a/apps/web/src/constants/text-constants.ts
+++ b/apps/web/src/constants/text-constants.ts
@@ -1,11 +1,20 @@
import type { TextElement } from "@/types/timeline";
import { TIMELINE_CONSTANTS } from "./timeline-constants";
+export const MIN_FONT_SIZE = 5;
+export const MAX_FONT_SIZE = 300;
+
+/**
+ * higher value: smaller font size
+ * lower value: larger font size
+ */
+export const FONT_SIZE_SCALE_REFERENCE = 90;
+
export const DEFAULT_TEXT_ELEMENT: Omit = {
type: "text",
name: "Text",
content: "Default Text",
- fontSize: 48,
+ fontSize: 15,
fontFamily: "Arial",
color: "#ffffff",
backgroundColor: "transparent",
diff --git a/apps/web/src/services/renderer/nodes/text-node.ts b/apps/web/src/services/renderer/nodes/text-node.ts
index 2cbf3d2a..bb79e086 100644
--- a/apps/web/src/services/renderer/nodes/text-node.ts
+++ b/apps/web/src/services/renderer/nodes/text-node.ts
@@ -1,9 +1,21 @@
import type { CanvasRenderer } from "../canvas-renderer";
import { BaseNode } from "./base-node";
import type { TextElement } from "@/types/timeline";
+import { FONT_SIZE_SCALE_REFERENCE } from "@/constants/text-constants";
+
+function scaleFontSize({
+ fontSize,
+ canvasHeight,
+}: {
+ fontSize: number;
+ canvasHeight: number;
+}): number {
+ return fontSize * (canvasHeight / FONT_SIZE_SCALE_REFERENCE);
+}
export type TextNodeParams = TextElement & {
canvasCenter: { x: number; y: number };
+ canvasHeight: number;
textBaseline?: CanvasTextBaseline;
};
@@ -32,7 +44,11 @@ export class TextNode extends BaseNode {
const fontWeight = this.params.fontWeight === "bold" ? "bold" : "normal";
const fontStyle = this.params.fontStyle === "italic" ? "italic" : "normal";
- renderer.context.font = `${fontStyle} ${fontWeight} ${this.params.fontSize}px ${this.params.fontFamily}`;
+ const scaledFontSize = scaleFontSize({
+ fontSize: this.params.fontSize,
+ canvasHeight: this.params.canvasHeight,
+ });
+ renderer.context.font = `${fontStyle} ${fontWeight} ${scaledFontSize}px ${this.params.fontFamily}`;
renderer.context.textAlign = this.params.textAlign;
renderer.context.textBaseline = this.params.textBaseline || "middle";
renderer.context.fillStyle = this.params.color;
@@ -43,9 +59,9 @@ export class TextNode extends BaseNode {
if (this.params.backgroundColor) {
const metrics = renderer.context.measureText(this.params.content);
const ascent =
- metrics.actualBoundingBoxAscent ?? this.params.fontSize * 0.8;
+ metrics.actualBoundingBoxAscent ?? scaledFontSize * 0.8;
const descent =
- metrics.actualBoundingBoxDescent ?? this.params.fontSize * 0.2;
+ metrics.actualBoundingBoxDescent ?? scaledFontSize * 0.2;
const textW = metrics.width;
const textH = ascent + descent;
const padX = 8;
diff --git a/apps/web/src/services/renderer/scene-builder.ts b/apps/web/src/services/renderer/scene-builder.ts
index d5b189cd..5d33524e 100644
--- a/apps/web/src/services/renderer/scene-builder.ts
+++ b/apps/web/src/services/renderer/scene-builder.ts
@@ -85,6 +85,7 @@ export function buildScene(params: BuildSceneParams) {
new TextNode({
...element,
canvasCenter: { x: canvasSize.width / 2, y: canvasSize.height / 2 },
+ canvasHeight: canvasSize.height,
textBaseline: "middle",
}),
);