docs: capture subtitle preview scaling

This commit is contained in:
Song367 2026-03-21 14:51:01 +08:00
parent eac9f65925
commit 3324012338
2 changed files with 218 additions and 0 deletions

View File

@ -0,0 +1,55 @@
# Subtitle Preview Scale Design
**Goal:** Make the subtitle sample inside the small preview screen visually proportional by scaling the rendered preview text down, while keeping the real subtitle size values unchanged for export and editing.
## Context
The current subtitle defaults card renders the preview text using the raw subtitle font size value. In a compact sample screen, that makes the text appear nearly as tall as the preview display itself, which breaks visual proportion and makes the mock preview feel unrealistic.
The user approved the "preview scale mapping" direction instead of enlarging the screen or rebuilding the preview as a strict video-canvas simulator.
## Approved Direction
- keep the stored subtitle size value unchanged
- keep the slider values unchanged
- keep exported subtitle defaults unchanged
- only scale the preview rendering inside the small sample screen
- make the preview text visually smaller relative to the sample screen
## Recommended Behavior
Use a lightweight preview-only mapping:
- compute a preview font size from the real subtitle size
- apply a clamp so small values do not become unreadable
- keep the label beside the slider showing the real value such as `24px`
- keep upload/export using the real value such as `24`
This preserves the product meaning of the controls while making the small preview believable.
## Rendering Rules
- real subtitle size remains the source of truth in state
- preview font size is a derived value for UI only
- preview outline strength should scale down with the preview text so the stroke does not overpower the sample
- subtitle bottom offset behavior remains unchanged
## Testing Strategy
Update upload-screen tests to verify:
- the preview text no longer renders at the raw `24px` size
- the slider can still change the real font size value
- the preview updates to the mapped display size
- upload confirmation still sends the unmodified real subtitle size
## Out of Scope
- changing the export subtitle engine
- changing slider ranges
- redesigning the subtitle defaults card
- introducing full video-canvas simulation
## Success Criteria
Success means the sample subtitle looks appropriately smaller than the preview screen, while the UI still communicates and submits the real subtitle size values unchanged.

View File

@ -0,0 +1,163 @@
# Subtitle Preview Scale Implementation Plan
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
**Goal:** Scale subtitle text inside the compact preview screen so it looks proportional, without changing the real subtitle size values used elsewhere in the flow.
**Architecture:** Keep `subtitleDefaults.fontSize` as the source of truth and derive a preview-only font size in `src/components/UploadScreen.tsx`. Lock the behavior with upload-screen tests that prove the preview is scaled down while upload/export still use the real font size.
**Tech Stack:** React 19, TypeScript, Tailwind CSS v4 utilities, Vitest, React Testing Library
---
### Task 1: Lock preview-only scaling with a failing test
**Files:**
- Modify: `src/components/UploadScreen.test.tsx`
- Reference: `src/components/UploadScreen.tsx`
**Step 1: Write the failing test**
Update the existing preview test so it expects scaled preview rendering rather than raw font size rendering:
```tsx
it('scales the subtitle preview while preserving the real subtitle size value', () => {
renderUploadScreen();
const sizeSlider = screen.getByLabelText(/subtitle initial size/i);
const positionSlider = screen.getByLabelText(/subtitle initial position/i);
const preview = screen.getByTestId('upload-subtitle-preview');
expect(sizeSlider).toHaveValue('24');
expect(positionSlider).toHaveValue('10');
expect(preview).toHaveStyle({ fontSize: '12px', bottom: '10%' });
fireEvent.change(sizeSlider, { target: { value: '32' } });
fireEvent.change(positionSlider, { target: { value: '18' } });
expect(preview).toHaveStyle({ fontSize: '16px', bottom: '18%' });
});
```
**Step 2: Run test to verify it fails**
Run:
```bash
node ./node_modules/vitest/vitest.mjs run src/components/UploadScreen.test.tsx
```
Expected: FAIL because the preview currently renders the raw font size values.
**Step 3: Write minimal implementation**
Add a preview-only derived font size and use it for the preview text.
**Step 4: Run test to verify it passes**
Run:
```bash
node ./node_modules/vitest/vitest.mjs run src/components/UploadScreen.test.tsx
```
Expected: PASS for the new preview-scaling expectation.
**Step 5: Commit**
```bash
git add src/components/UploadScreen.tsx src/components/UploadScreen.test.tsx
git commit -m "test: lock subtitle preview scaling"
```
### Task 2: Keep export behavior unchanged
**Files:**
- Modify: `src/components/UploadScreen.tsx`
- Reference: `src/components/UploadScreen.test.tsx`
**Step 1: Write the failing test**
Use the existing upload-confirmation test as the regression check for preserving the real font size value.
**Step 2: Run test to verify it fails**
Run:
```bash
node ./node_modules/vitest/vitest.mjs run src/components/UploadScreen.test.tsx
```
Expected: FAIL only if the implementation accidentally changes uploaded subtitle defaults instead of preview-only rendering.
**Step 3: Write minimal implementation**
Ensure only the preview rendering uses the derived font size. Keep:
- slider state values unchanged
- upload callback values unchanged
- bottom offset behavior unchanged
**Step 4: Run test to verify it passes**
Run:
```bash
node ./node_modules/vitest/vitest.mjs run src/components/UploadScreen.test.tsx
```
Expected: PASS for both the preview mapping test and the upload-confirmation regression test.
**Step 5: Commit**
```bash
git add src/components/UploadScreen.tsx src/components/UploadScreen.test.tsx
git commit -m "fix: scale subtitle preview text"
```
### Task 3: Full verification
**Files:**
- Modify: `src/components/UploadScreen.tsx`
- Modify: `src/components/UploadScreen.test.tsx`
**Step 1: Write the failing test**
If any final regression appears, add the smallest targeted test first.
**Step 2: Run test to verify it fails**
Run:
```bash
node ./node_modules/vitest/vitest.mjs run src/components/UploadScreen.test.tsx src/App.test.tsx
```
Expected: FAIL only if a real regression remains.
**Step 3: Write minimal implementation**
Apply only the smallest visual or logic adjustment needed to restore parity.
**Step 4: Run test to verify it passes**
Run:
```bash
npm.cmd test
npm.cmd run lint
npm.cmd run build
```
Expected:
- all tests PASS
- lint PASS
- build PASS
**Step 5: Commit**
```bash
git add src/components/UploadScreen.tsx src/components/UploadScreen.test.tsx docs/plans/2026-03-21-subtitle-preview-scale-design.md docs/plans/2026-03-21-subtitle-preview-scale.md
git commit -m "test: verify subtitle preview scaling"
```