From e060d218453d58dfd2c35c6888ecacd4808dd226 Mon Sep 17 00:00:00 2001 From: Yasutake Yohei <61961825+yasutakeyohei@users.noreply.github.com> Date: Tue, 6 Oct 2026 14:32:22 +0900 Subject: bluebey-studio: 思考の雲の半円に、決まったゆらぎを入れて大きさを揃えすぎないように MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 半円の大きさを0.72〜1.28倍の範囲でインデックス由来の決まった値でゆらがせる(プレビュー・書き出しで同じ絵になる)。 --- public/bluebey-studio/src/caption.js | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'public/bluebey-studio') diff --git a/public/bluebey-studio/src/caption.js b/public/bluebey-studio/src/caption.js index 08b962f..821ccb5 100644 --- a/public/bluebey-studio/src/caption.js +++ b/public/bluebey-studio/src/caption.js @@ -827,6 +827,7 @@ function thinkEdges(box, scale) { const amp = Math.min((perimeter / count) * 0.55, Math.min(w, h) * 0.26); const edges = []; + let outer = amp; for (let i = 0; i < points.length; i++) { const a = points[i]; const b = points[(i + 1) % points.length]; @@ -844,9 +845,13 @@ function thinkEdges(box, scale) { nx = -nx; ny = -ny; } - edges.push(scallopEdge(a, b, { x: nx, y: ny }, amp)); + // A small, *deterministic* wobble so the scallops are not all identical - the + // even size read as too regular. Same index, same bubble, every render. + const scallopAmp = amp * (0.72 + 0.56 * scallopJitter(i)); + if (scallopAmp > outer) outer = scallopAmp; + edges.push(scallopEdge(a, b, { x: nx, y: ny }, scallopAmp)); } - return { edges, amp }; + return { edges, amp: outer }; } /** A closed cloud, followed by the tail: two or three shrinking puffs. */ @@ -905,6 +910,17 @@ function scallopEdge(from, to, normal, amp) { ); } +/** + * A small deterministic wobble in 0..1 for the i-th scallop of a cloud. + * + * It is derived from the index alone, so a bubble draws its scallops exactly + * the same in the live preview, a screenshot, and the SVG export. + */ +function scallopJitter(i) { + const x = Math.sin((i + 1) * 12.9898) * 43758.5453; + return x - Math.floor(x); +} + /** A circle as `M`/`C`/`Z` commands, so it can join the bubble's one path. */ function circleCommands(cx, cy, r) { const k = r * KAPPA; -- cgit v1.3.1