Skip to content

Commit 79496e3

Browse files
fix: wire humanization sliders to canvas and mock backend
1 parent 7fffec1 commit 79496e3

3 files changed

Lines changed: 34 additions & 24 deletions

File tree

backend/app/ml/llm_engine.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -491,9 +491,9 @@ async def _stream_mock(
491491
cursor_y += line_height + random.uniform(-1.5, 1.5)
492492
line_num += 1
493493

494-
# Baseline drift
495-
global_drift = baseline_drift * 3.0 * math.sin(
496-
2 * math.pi * line_num / 10.0 + random.uniform(0, 0.5)
494+
# Baseline drift (Exaggerated for visual awareness in mock mode)
495+
global_drift = baseline_drift * 8.0 * math.sin(
496+
2 * math.pi * line_num / max(total_words / 5.0, 3.0) + random.uniform(0, 0.5)
497497
)
498498

499499
char_x = cursor_x

frontend/src/App.jsx

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ function App() {
5454
const [error, setError] = useState(null);
5555
const [charCount, setCharCount] = useState(0);
5656
const [inkColor, setInkColor] = useState("black");
57+
const [strokeWidth, setStrokeWidth] = useState(0.5);
5758

5859
const canvasRef = useRef(null);
5960
const abortRef = useRef(null);
@@ -116,7 +117,7 @@ function App() {
116117
character_inconsistency: f.character_inconsistency,
117118
slant_angle: f.slant_angle,
118119
baseline_drift: f.baseline_drift,
119-
ink_bleed: f.ink_bleed,
120+
fatigue_simulation: f.ink_bleed, // map the UI slider
120121
ligature_enabled: f.ligature_enabled,
121122
},
122123
paper_texture: f.paper_texture,
@@ -165,9 +166,11 @@ function App() {
165166
const setField = (key) => (e) => {
166167
const val = e.target.type === "checkbox" ? e.target.checked : e.target.value;
167168
formRef.current[key] = e.target.type === "range" ? parseFloat(val) : val;
168-
// Sync ink color to state so CanvasBoard gets the updated value
169+
// Sync visual styles to state so CanvasBoard gets the updated value
169170
if (key === "ink_color") {
170171
setInkColor(val);
172+
} else if (key === "stroke_width_variation") {
173+
setStrokeWidth(parseFloat(val));
171174
}
172175
};
173176

@@ -338,20 +341,20 @@ function App() {
338341
</div>
339342
)}
340343

341-
{/* Canvas Area */}
342-
<div
343-
className="flex-1 flex items-start justify-center rounded-xl p-6"
344-
style={{
345-
background: "var(--bg-secondary)",
346-
border: "1px solid var(--border-subtle)",
347-
}}
348-
>
349-
<CanvasBoard
350-
ref={canvasRef}
351-
width={800}
352-
height={600}
353-
inkColor={inkColor}
354-
/>
344+
{/* ─── Canvas Area ─── */}
345+
<div className="flex-1 p-6 flex flex-col items-center justify-center relative overflow-hidden">
346+
<div
347+
className="w-full max-w-[900px] h-[600px] shadow-2xl transition-all duration-300 relative flex items-center justify-center"
348+
style={{ background: formRef.current?.paper_texture === "blank" ? "#fefefe" : "#f4f4f4" }}
349+
>
350+
<CanvasBoard
351+
ref={canvasRef}
352+
width={900}
353+
height={600}
354+
inkColor={inkColor}
355+
strokeWidthVariation={strokeWidth}
356+
/>
357+
</div>
355358
</div>
356359
</main>
357360
</div>

frontend/src/components/CanvasBoard.jsx

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const DEFAULT_WIDTH = 800;
2323
const DEFAULT_HEIGHT = 600;
2424

2525
const CanvasBoard = forwardRef(function CanvasBoard(
26-
{ width = DEFAULT_WIDTH, height = DEFAULT_HEIGHT, inkColor = "black" },
26+
{ width = DEFAULT_WIDTH, height = DEFAULT_HEIGHT, inkColor = "black", strokeWidthVariation = 0.5 },
2727
ref
2828
) {
2929
const canvasRef = useRef(null);
@@ -32,6 +32,12 @@ const CanvasBoard = forwardRef(function CanvasBoard(
3232
// Mutable cursor position — never triggers a render
3333
const cursorRef = useRef({ x: 40, y: 40 });
3434

35+
// Helper to calculate line width
36+
const getLineWidth = (variation) => {
37+
// Map 0-1 variation to 1.0 - 2.8 context line width
38+
return 1.0 + (variation * 1.8);
39+
};
40+
3541
// Initialize canvas context once on mount or when dimensions change
3642
useEffect(() => {
3743
const canvas = canvasRef.current;
@@ -40,23 +46,24 @@ const CanvasBoard = forwardRef(function CanvasBoard(
4046
const ctx = canvas.getContext("2d");
4147
ctx.lineCap = "round";
4248
ctx.lineJoin = "round";
43-
ctx.lineWidth = 1.8;
49+
ctx.lineWidth = getLineWidth(strokeWidthVariation);
4450
ctx.strokeStyle = INK_COLORS[inkColor] || INK_COLORS.black;
4551
ctxRef.current = ctx;
4652

4753
// Start with a clean slate
4854
ctx.clearRect(0, 0, width, height);
4955
ctx.beginPath();
5056
ctx.moveTo(cursorRef.current.x, cursorRef.current.y);
51-
}, [width, height]); // Note: inkColor excluded - handled separately
57+
}, [width, height]); // Exclude style paints so we don't clear midway
5258

53-
// Update ink color without clearing canvas
59+
// Update styling properties dynamically without clearing canvas
5460
useEffect(() => {
5561
const ctx = ctxRef.current;
5662
if (ctx) {
5763
ctx.strokeStyle = INK_COLORS[inkColor] || INK_COLORS.black;
64+
ctx.lineWidth = getLineWidth(strokeWidthVariation);
5865
}
59-
}, [inkColor]);
66+
}, [inkColor, strokeWidthVariation]);
6067

6168
// Expose imperative methods to parent via ref
6269
useImperativeHandle(

0 commit comments

Comments
 (0)