@juspay/svelte-ui-components 4.33.2 → 4.33.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* split keeps "the shape's own motion" and "the camera's fixed angle on it"
|
|
12
12
|
* from tangling together in the per-dot math.
|
|
13
13
|
*/
|
|
14
|
-
import { easeInOutCubic, hashUnit, modeSizing, project, rotateX, rotateY, rotateZ } from '../space';
|
|
14
|
+
import { easeInOutCubic, hashUnit, modeSizing, project, rotateX, rotateY, rotateZ, sampleSphere } from '../space';
|
|
15
15
|
const TWO_PI = Math.PI * 2;
|
|
16
16
|
/** The shared "reads as a form inside a square" contract: radius as a share of `size`. */
|
|
17
17
|
const FORM_RADIUS_RATIO = 0.4;
|
|
@@ -45,7 +45,11 @@ const EMPTY_STROKES = [];
|
|
|
45
45
|
// --- composing ---------------------------------------------------------
|
|
46
46
|
/** Dots along each thread at 64px; `countAlongPath` keeps their spacing as the canvas shrinks. */
|
|
47
47
|
const RIBBON_PER_THREAD_BASE = 36;
|
|
48
|
-
|
|
48
|
+
/** Reference parity (BZ-6466 follow-up): upstream thinking-orbs' `ribbon` mode resolves to a
|
|
49
|
+
* ~0.9-1.1px base dot radius at 64px (its BASE_PROFILES rBase 1.1, x0.85 for this preset's `size`
|
|
50
|
+
* multiplier). This used to carry 2.2px, exactly the radius that fused composing's dots into a
|
|
51
|
+
* solid corrugated band instead of the reference's fine, individually-visible beads. */
|
|
52
|
+
const RIBBON_BASE_DOT_RADIUS = 1.2;
|
|
49
53
|
/** Fewer, narrower threads than a full band: at 7 threads across 0.4 rad the 64px ribbon covered
|
|
50
54
|
* most of the sphere and read as a filled ball rather than a strip of cloth. */
|
|
51
55
|
const RIBBON_THREADS = { 64: 5, 32: 4, 20: 3 };
|
|
@@ -68,6 +72,16 @@ const RIBBON_CAMERA_TILT = 0.45;
|
|
|
68
72
|
* combined ink/alpha/radius fade would collapse an edge row to a speck. */
|
|
69
73
|
const RIBBON_EDGE_ALPHA_FLOOR = 0.5;
|
|
70
74
|
const RIBBON_EDGE_INK_LIFT = 0.22;
|
|
75
|
+
/** Reference parity (BZ-6466 follow-up): upstream's `ribbon` mode fills the sphere behind the band
|
|
76
|
+
* with a faint, fully static "ghost" texture (150 dots at 64px, this preset's `spin: 0` freezing
|
|
77
|
+
* even the shared camera precession that would otherwise turn it). Ours had no such backing layer,
|
|
78
|
+
* so the ribbon read as a thin strip floating in empty space rather than cloth wrapped on a solid
|
|
79
|
+
* form -- the ribbon's own turn was the only motion on screen, with nothing to anchor it against. */
|
|
80
|
+
const RIBBON_GHOST_BASE_COUNT = 110;
|
|
81
|
+
const RIBBON_GHOST_RADIUS_PX = 0.5;
|
|
82
|
+
const RIBBON_GHOST_INK = 0.3;
|
|
83
|
+
const RIBBON_GHOST_ALPHA_BASE = 0.16;
|
|
84
|
+
const RIBBON_GHOST_ALPHA_DEPTH = 0.22;
|
|
71
85
|
/**
|
|
72
86
|
* A ribbon of dots looped once around the sphere on its own tilted great
|
|
73
87
|
* circle -- distinct from the spin axis -- rippling along its length like a
|
|
@@ -80,7 +94,20 @@ export const composing = (t, ctx) => {
|
|
|
80
94
|
const threads = RIBBON_THREADS[ctx.size];
|
|
81
95
|
const perThread = sizing.countAlongPath(RIBBON_PER_THREAD_BASE);
|
|
82
96
|
const total = threads * perThread;
|
|
83
|
-
const
|
|
97
|
+
const ghostCount = Math.max(20, sizing.count(RIBBON_GHOST_BASE_COUNT));
|
|
98
|
+
const dots = Array.from({ length: ghostCount }, (_unused, i) => {
|
|
99
|
+
const point = sampleSphere(i, ghostCount, worldRadius);
|
|
100
|
+
const tilted = rotateX(point, RIBBON_CAMERA_TILT);
|
|
101
|
+
const projected = project(tilted, originPx, worldRadius);
|
|
102
|
+
return {
|
|
103
|
+
x: projected.x,
|
|
104
|
+
y: projected.y,
|
|
105
|
+
depth: projected.depth,
|
|
106
|
+
radius: sizing.radius(RIBBON_GHOST_RADIUS_PX),
|
|
107
|
+
ink: RIBBON_GHOST_INK,
|
|
108
|
+
alpha: clamp01(RIBBON_GHOST_ALPHA_BASE + RIBBON_GHOST_ALPHA_DEPTH * projected.depth)
|
|
109
|
+
};
|
|
110
|
+
});
|
|
84
111
|
for (let index = 0; index < total; index += 1) {
|
|
85
112
|
const thread = index % threads;
|
|
86
113
|
const step = Math.floor(index / threads);
|
|
@@ -6,7 +6,11 @@
|
|
|
6
6
|
* projection setup below.
|
|
7
7
|
*/
|
|
8
8
|
import type { ModeFn } from '../types';
|
|
9
|
+
import type { ModeSizing } from '../space';
|
|
9
10
|
/** A few nodes on a sphere; lines to near neighbours carry small travelling pulses. */
|
|
10
11
|
export declare const connecting: ModeFn;
|
|
12
|
+
/** Exported so tests that index `weaving`'s strand dots can reproduce and slice off this count,
|
|
13
|
+
* rather than duplicating the formula as a hardcoded literal. */
|
|
14
|
+
export declare const weavingGhostCount: (sizing: ModeSizing) => number;
|
|
11
15
|
/** Three closed strands wrapped around a sphere, crossing over and under each other as they turn. */
|
|
12
16
|
export declare const weaving: ModeFn;
|
|
@@ -144,6 +144,21 @@ const STRAND_DOT_SIZE_FACTOR = { 64: 1, 32: 0.85, 20: 0.7 };
|
|
|
144
144
|
const STRAND_DEPTH_INK = 0.45;
|
|
145
145
|
/** A slight per-strand shade; the paths and their over/under crossings are what separate them. */
|
|
146
146
|
const STRAND_SHADE_STEP = 0.1;
|
|
147
|
+
/** Reference parity (BZ-6466 follow-up): upstream's `braid` mode fills the sphere behind the
|
|
148
|
+
* strands with a faint, static-in-object-space "ghost" texture (150 dots at 64px) that shares the
|
|
149
|
+
* strands' own turn, so the strands read as plaiting round a solid ball rather than floating loops
|
|
150
|
+
* in empty space. Ours had no such backing layer. Always appended after every strand's dots, so
|
|
151
|
+
* code and tests that index `dots` by strand can slice it off by a known, reproducible count. */
|
|
152
|
+
const STRAND_GHOST_BASE_COUNT = 110;
|
|
153
|
+
const STRAND_GHOST_RADIUS_PX = 0.5;
|
|
154
|
+
const STRAND_GHOST_INK = 0.3;
|
|
155
|
+
/** With STRAND_GHOST_INK 0.3, `inkAlpha` = (1-ink)*alpha = 0.7*alpha, so this needs to clear
|
|
156
|
+
* 0.1/0.7 for the "nothing paints below 10% opacity" contract even on a ghost dot's far side. */
|
|
157
|
+
const STRAND_GHOST_ALPHA_BASE = 0.16;
|
|
158
|
+
const STRAND_GHOST_ALPHA_DEPTH = 0.22;
|
|
159
|
+
/** Exported so tests that index `weaving`'s strand dots can reproduce and slice off this count,
|
|
160
|
+
* rather than duplicating the formula as a hardcoded literal. */
|
|
161
|
+
export const weavingGhostCount = (sizing) => Math.max(20, sizing.count(STRAND_GHOST_BASE_COUNT));
|
|
147
162
|
const strandBaseAngle = (strand) => (strand / STRAND_COUNT) * Math.PI * 2;
|
|
148
163
|
/**
|
|
149
164
|
* The `pointIndex`-th of `pointsPerStrand` points around closed `strand`: a
|
|
@@ -192,5 +207,22 @@ export const weaving = (t, ctx) => {
|
|
|
192
207
|
alpha: 0.6 + depth * 0.35
|
|
193
208
|
};
|
|
194
209
|
}));
|
|
195
|
-
|
|
210
|
+
// Shares the strands' own spin+tilt (not their per-strand inclination/phase, which is strand
|
|
211
|
+
// geometry, not camera) so the backdrop turns together with what it is behind.
|
|
212
|
+
const ghostCount = weavingGhostCount(sizing);
|
|
213
|
+
const ghosts = Array.from({ length: ghostCount }, (_unused, i) => {
|
|
214
|
+
const point = sampleSphere(i, ghostCount, sphereRadius);
|
|
215
|
+
const spun = rotateY(point, t * STRAND_ROTATE_SPEED);
|
|
216
|
+
const tilted = rotateX(spun, STRAND_TILT);
|
|
217
|
+
const projected = project(tilted, originPx, sphereRadius);
|
|
218
|
+
return {
|
|
219
|
+
x: projected.x,
|
|
220
|
+
y: projected.y,
|
|
221
|
+
depth: projected.depth,
|
|
222
|
+
radius: sizing.radius(STRAND_GHOST_RADIUS_PX),
|
|
223
|
+
ink: STRAND_GHOST_INK,
|
|
224
|
+
alpha: clamp01(STRAND_GHOST_ALPHA_BASE + STRAND_GHOST_ALPHA_DEPTH * projected.depth)
|
|
225
|
+
};
|
|
226
|
+
});
|
|
227
|
+
return { dots: [...dots, ...ghosts], strokes };
|
|
196
228
|
};
|
|
@@ -44,19 +44,33 @@ const toStroke = (from, to, width, ink, alpha) => ({
|
|
|
44
44
|
/** Particles travel in short trailing arcs ("trains") rather than scattering
|
|
45
45
|
* independently around their orbit -- a lone random phase per particle reads
|
|
46
46
|
* as noise once density thins the count out at 32/20px, while a handful of
|
|
47
|
-
* particles held close together always reads as motion along a path.
|
|
48
|
-
|
|
47
|
+
* particles held close together always reads as motion along a path.
|
|
48
|
+
*
|
|
49
|
+
* Reference parity (BZ-6466 follow-up): the upstream thinking-orbs `orbits`
|
|
50
|
+
* mode this was ported from draws 12 orbits x 3 particles = 36 marks at
|
|
51
|
+
* 64px, radius ~1.2px, and reads as a sparse field of distinct particles.
|
|
52
|
+
* The previous tuning here (22 trains x 5-long, radius 2.2px = 110 marks)
|
|
53
|
+
* packed 3x the marks at ~1.7x the radius into the same arcs, so consecutive
|
|
54
|
+
* dots overlapped their own diameter and the whole thing fused into a
|
|
55
|
+
* blurred scribble instead of scattered points. */
|
|
56
|
+
const WORKING_TRAIN_BASE_COUNT = 12;
|
|
49
57
|
/** Keeps at least this many short arcs on screen at 64px (32/20px use WORKING_SMALL_LAYOUT). The
|
|
50
58
|
* area scaler alone already clears it at the default density; it only bites when density is low. */
|
|
51
59
|
const WORKING_MIN_TRAINS_64 = 3;
|
|
52
|
-
const WORKING_TRAIN_LENGTH =
|
|
60
|
+
const WORKING_TRAIN_LENGTH = 3;
|
|
53
61
|
/** How far apart, in radians, a train's particles trail behind its lead --
|
|
54
62
|
* wide enough to read as a short curved arc, short enough to stay a cluster
|
|
55
63
|
* rather than smearing back into the full-orbit scatter this replaces. */
|
|
56
64
|
const WORKING_TRAIN_ARC_SPAN = 0.5;
|
|
57
|
-
/**
|
|
58
|
-
*
|
|
59
|
-
|
|
65
|
+
/** Reference's `orbits` mode draws particles at ~1.2px on a 64px canvas but scales them back UP
|
|
66
|
+
* at smaller sizes (2.4x at 20px) rather than shrinking further, so they stay legible once there's
|
|
67
|
+
* less room for arc spacing to keep them apart. `sizing.radius`'s sub-linear shrink-with-a-floor
|
|
68
|
+
* goes the other way, so the two sizes need their own base rather than one shared constant. */
|
|
69
|
+
const WORKING_BASE_RADIUS_PX = 1.3;
|
|
70
|
+
/** 32/20px (WORKING_SMALL_LAYOUT): kept at this mode's original, pre-reference-parity radius --
|
|
71
|
+
* these sizes weren't the fused-blur regression 64px was, and shrinking to match 64px's new,
|
|
72
|
+
* smaller radius here would drop dots below a legible stroke width. */
|
|
73
|
+
const WORKING_SMALL_BASE_RADIUS_PX = 2.2;
|
|
60
74
|
const WORKING_ORBIT_COUNT = 6;
|
|
61
75
|
const WORKING_ANGULAR_SPEED = 1.1;
|
|
62
76
|
/** How far an orbit's `weight` can push its dots' ink away from the shared
|
|
@@ -68,6 +82,17 @@ const WORKING_ORBIT_ALPHA_FLOOR = 0.65;
|
|
|
68
82
|
/** A train's trailing-most particle never fades past this floor, so the arc's
|
|
69
83
|
* tail stays legible instead of thinning away to nothing. */
|
|
70
84
|
const WORKING_TRAIL_ALPHA_FLOOR = 0.35;
|
|
85
|
+
/** Reference parity (BZ-6466 follow-up): upstream's `orbits` mode traces each orbit's full circle
|
|
86
|
+
* as a faint, static "ghost" ring of many dots (40 per orbit at 64px) UNDER the few bright
|
|
87
|
+
* travelling particles -- about 13x as many ghost dots as particles, so the ring lattice anchors
|
|
88
|
+
* the silhouette and the particles read as a sparkle on top of it. Ours had no such layer: every
|
|
89
|
+
* visible dot was one of the sweeping particles, so with only 6-22 of them the whole silhouette
|
|
90
|
+
* reshaped every frame instead of holding a roughly stable shape -- the actual "fluidity" gap a
|
|
91
|
+
* static/moving frame comparison alone doesn't show. */
|
|
92
|
+
const WORKING_GHOST_DOTS_PER_ORBIT = 40;
|
|
93
|
+
const WORKING_GHOST_RADIUS_PX = 0.7;
|
|
94
|
+
const WORKING_GHOST_INK = 0.4;
|
|
95
|
+
const WORKING_GHOST_ALPHA = 0.5;
|
|
71
96
|
/** Every particle's own orbital plane, radius, pace and shading weight, keyed by its orbit. */
|
|
72
97
|
const workingOrbit = (orbit) => {
|
|
73
98
|
const seed = orbit * 31 + 7;
|
|
@@ -84,8 +109,10 @@ const workingOrbit = (orbit) => {
|
|
|
84
109
|
* the view axis (like an atom symbol) and give each train a long arc, so every train draws a
|
|
85
110
|
* visible curve and the separate orbits stay readable. */
|
|
86
111
|
const WORKING_SMALL_LAYOUT = {
|
|
87
|
-
|
|
88
|
-
|
|
112
|
+
// Shorter trains than before (was 6/7): at the smaller shared radius above, a longer train's
|
|
113
|
+
// dots sat closer together than their own diameter and fused the same way 64px did.
|
|
114
|
+
32: { orbits: 4, trainLength: 4, arcSpan: 0.75 },
|
|
115
|
+
20: { orbits: 3, trainLength: 4, arcSpan: 0.9 }
|
|
89
116
|
};
|
|
90
117
|
/** How far each small-size orbit tips out of edge-on. Its projection is an ellipse sin(tilt) as
|
|
91
118
|
* tall as it is wide; near 1 rad every orbit projects to nearly the same circle and rolling it
|
|
@@ -147,10 +174,32 @@ export const working = (t, ctx) => {
|
|
|
147
174
|
(orbit.weight - 0.5) * WORKING_ORBIT_INK_SPREAD;
|
|
148
175
|
const alpha = (WORKING_TRAIL_ALPHA_FLOOR + (1 - WORKING_TRAIL_ALPHA_FLOOR) * trail) *
|
|
149
176
|
(WORKING_ORBIT_ALPHA_FLOOR + (1 - WORKING_ORBIT_ALPHA_FLOOR) * orbit.weight);
|
|
150
|
-
const
|
|
177
|
+
const radiusBase = small ? WORKING_SMALL_BASE_RADIUS_PX : WORKING_BASE_RADIUS_PX;
|
|
178
|
+
const radius = sizing.radius(radiusBase) * (0.9 + 0.25 * hashUnit(seed + 3));
|
|
151
179
|
dots.push(toDot(projected, radius, ink, alpha));
|
|
152
180
|
}
|
|
153
181
|
}
|
|
182
|
+
// 64px only: 32/20px already anchor their orbits with the faint stroke path below, drawn for
|
|
183
|
+
// every size in WORKING_SMALL_LAYOUT.
|
|
184
|
+
if (!small) {
|
|
185
|
+
const ghostDotsPerOrbit = Math.max(8, sizing.countAlongPath(WORKING_GHOST_DOTS_PER_ORBIT));
|
|
186
|
+
for (let orbitIndex = 0; orbitIndex < WORKING_ORBIT_COUNT; orbitIndex += 1) {
|
|
187
|
+
const orbit = workingOrbit(orbitIndex);
|
|
188
|
+
const orbitRadius = worldRadius * orbit.orbitRadiusFactor;
|
|
189
|
+
for (let k = 0; k < ghostDotsPerOrbit; k += 1) {
|
|
190
|
+
const angle = (k / ghostDotsPerOrbit) * TWO_PI;
|
|
191
|
+
const planar = {
|
|
192
|
+
x: Math.cos(angle) * orbitRadius,
|
|
193
|
+
y: 0,
|
|
194
|
+
z: Math.sin(angle) * orbitRadius
|
|
195
|
+
};
|
|
196
|
+
const tilted = rotateX(planar, orbit.tilt);
|
|
197
|
+
const point = rotateZ(tilted, orbit.roll);
|
|
198
|
+
const projected = project(point, origin, worldRadius);
|
|
199
|
+
dots.push(toDot(projected, sizing.radius(WORKING_GHOST_RADIUS_PX), WORKING_GHOST_INK, WORKING_GHOST_ALPHA * (0.4 + 0.6 * projected.depth)));
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
154
203
|
const paths = small
|
|
155
204
|
? Array.from({ length: small.orbits }, (_unused, orbitIndex) => {
|
|
156
205
|
const orbit = workingSmallOrbit(orbitIndex, small.orbits);
|
|
@@ -236,10 +285,16 @@ export const searching = (t, ctx) => {
|
|
|
236
285
|
};
|
|
237
286
|
// ---------------------------------------------------------------------------
|
|
238
287
|
// solving -- tiers that snap a quarter turn out of alignment, hold scrambled,
|
|
239
|
-
// then resolve back, on a loop.
|
|
240
|
-
//
|
|
241
|
-
//
|
|
242
|
-
//
|
|
288
|
+
// then resolve back, on a loop. Each tier's own texture dots rotate with it
|
|
289
|
+
// (reference parity, BZ-6466 follow-up: matching upstream thinking-orbs'
|
|
290
|
+
// `rubik`, which reads solved-vs-scrambled off this same per-band rotation
|
|
291
|
+
// alone), so the misalignment shows as a visible discontinuity in the dot
|
|
292
|
+
// pattern itself; oversized landmark dots add a brighter set of accent
|
|
293
|
+
// points per tier. An earlier tuning also drew fixed seam rings and
|
|
294
|
+
// per-landmark meridian strokes to make the misalignment legible, but next
|
|
295
|
+
// to the reference that wireframe read as a busy skeleton the upstream
|
|
296
|
+
// version doesn't have, so it's gone -- the texture's own rotation already
|
|
297
|
+
// carries the same information.
|
|
243
298
|
// ---------------------------------------------------------------------------
|
|
244
299
|
const SOLVING_BASE_COUNT = 130;
|
|
245
300
|
const SOLVING_BASE_RADIUS_PX = 1.5;
|
|
@@ -260,23 +315,6 @@ const SOLVING_LANDMARK_PHASE = hashUnit(5) * TWO_PI;
|
|
|
260
315
|
const SOLVING_LANDMARK_RADIUS_PX = 3.1;
|
|
261
316
|
const SOLVING_LANDMARK_INK_BOOST = 0.45;
|
|
262
317
|
const SOLVING_LANDMARK_ALPHA = 0.9;
|
|
263
|
-
/** Each landmark also draws a short meridian stroke spanning its tier. Solved, the strokes of all
|
|
264
|
-
* tiers join into three unbroken vertical lines; a turned tier's strokes jump sideways and break
|
|
265
|
-
* the lines into a visible staircase. Held scrambled, loose landmark dots alone still formed tidy
|
|
266
|
-
* columns of their own and read as just another solved pose. */
|
|
267
|
-
const SOLVING_MERIDIAN_POINTS_PER_TIER = 3;
|
|
268
|
-
const SOLVING_MERIDIAN_WIDTH_PX = 1.6;
|
|
269
|
-
const SOLVING_MERIDIAN_INK_BOOST = 0.35;
|
|
270
|
-
const SOLVING_MERIDIAN_ALPHA = 0.85;
|
|
271
|
-
/** The meridians stop this far short of the poles, where all three would otherwise converge. */
|
|
272
|
-
const SOLVING_MERIDIAN_Y_LIMIT = 0.9;
|
|
273
|
-
/** A static ring of short strokes at each cut between tiers, unaffected by
|
|
274
|
-
* any turn, so the "cut into bands" structure reads even while the puzzle
|
|
275
|
-
* sits solved and nothing is moving. */
|
|
276
|
-
const SOLVING_SEAM_SEGMENTS = 12;
|
|
277
|
-
const SOLVING_SEAM_STROKE_RADIUS = 1.05;
|
|
278
|
-
const SOLVING_SEAM_INK = 0.15;
|
|
279
|
-
const SOLVING_SEAM_ALPHA = 0.5;
|
|
280
318
|
const solvingTurnStart = (tier) => tier * SOLVING_TURN_GAP;
|
|
281
319
|
const solvingTurnEnd = (tier) => solvingTurnStart(tier) + SOLVING_TURN_DURATION;
|
|
282
320
|
const SOLVING_HOLD_START = solvingTurnEnd(SOLVING_TIER_COUNT - 1) + SOLVING_HOLD_GAP;
|
|
@@ -310,8 +348,6 @@ const solvingTierOf = (yUnit) => clamp(Math.floor(((1 - yUnit) / 2) * SOLVING_TI
|
|
|
310
348
|
const solvingTierDirection = (tier) => (hashUnit(tier * 53 + 21) < 0.5 ? -1 : 1);
|
|
311
349
|
/** The y-unit (-1..1) at the centre of a tier's latitude band. */
|
|
312
350
|
const solvingTierCenterYUnit = (tier) => 1 - (2 * tier + 1) / SOLVING_TIER_COUNT;
|
|
313
|
-
/** The y-unit (-1..1) of the fixed cut between one tier and the next. */
|
|
314
|
-
const solvingSeamYUnit = (seam) => 1 - (2 * (seam + 1)) / SOLVING_TIER_COUNT;
|
|
315
351
|
const solvingTurnAngle = (tier, cyclePos) => solvingTierTurn(tier, cyclePos) * solvingTierDirection(tier) * (Math.PI / 2);
|
|
316
352
|
export const solving = (t, ctx) => {
|
|
317
353
|
const sizing = modeSizing(ctx.size, ctx.density, ctx.dotScale);
|
|
@@ -349,47 +385,7 @@ export const solving = (t, ctx) => {
|
|
|
349
385
|
const ink = shadeByDepth(projected.depth) - SOLVING_LANDMARK_INK_BOOST;
|
|
350
386
|
return toDot(projected, sizing.radius(SOLVING_LANDMARK_RADIUS_PX), ink, SOLVING_LANDMARK_ALPHA);
|
|
351
387
|
});
|
|
352
|
-
|
|
353
|
-
const seams = Array.from({ length: SOLVING_TIER_COUNT - 1 }, (_unused, seam) => {
|
|
354
|
-
const yUnit = solvingSeamYUnit(seam);
|
|
355
|
-
const y = yUnit * worldRadius;
|
|
356
|
-
const ringRadius = Math.sqrt(Math.max(0, 1 - yUnit * yUnit)) * worldRadius;
|
|
357
|
-
const ringPoints = Array.from({ length: SOLVING_SEAM_SEGMENTS + 1 }, (_unusedPoint, j) => {
|
|
358
|
-
const angle = (j / SOLVING_SEAM_SEGMENTS) * TWO_PI;
|
|
359
|
-
const point = {
|
|
360
|
-
x: Math.cos(angle) * ringRadius,
|
|
361
|
-
y,
|
|
362
|
-
z: Math.sin(angle) * ringRadius
|
|
363
|
-
};
|
|
364
|
-
return project(rotateX(point, SOLVING_TILT), origin, worldRadius);
|
|
365
|
-
});
|
|
366
|
-
return Array.from({ length: SOLVING_SEAM_SEGMENTS }, (_unusedSegment, j) => toStroke(ringPoints[j], ringPoints[j + 1], seamWidth, SOLVING_SEAM_INK, SOLVING_SEAM_ALPHA));
|
|
367
|
-
}).flat();
|
|
368
|
-
const meridianWidth = sizing.radius(SOLVING_MERIDIAN_WIDTH_PX);
|
|
369
|
-
const meridians = Array.from({ length: SOLVING_TIER_COUNT * SOLVING_LANDMARKS_PER_TIER }, (_unused, i) => {
|
|
370
|
-
const tier = Math.floor(i / SOLVING_LANDMARKS_PER_TIER);
|
|
371
|
-
const slot = i % SOLVING_LANDMARKS_PER_TIER;
|
|
372
|
-
const longitude = SOLVING_LANDMARK_PHASE + (slot / SOLVING_LANDMARKS_PER_TIER) * TWO_PI;
|
|
373
|
-
const topYUnit = Math.min(SOLVING_MERIDIAN_Y_LIMIT, 1 - (2 * tier) / SOLVING_TIER_COUNT);
|
|
374
|
-
const bottomYUnit = Math.max(-SOLVING_MERIDIAN_Y_LIMIT, 1 - (2 * (tier + 1)) / SOLVING_TIER_COUNT);
|
|
375
|
-
const points = Array.from({ length: SOLVING_MERIDIAN_POINTS_PER_TIER }, (_unusedPoint, j) => {
|
|
376
|
-
const yUnit = topYUnit + ((bottomYUnit - topYUnit) * j) / (SOLVING_MERIDIAN_POINTS_PER_TIER - 1);
|
|
377
|
-
const ringRadius = Math.sqrt(Math.max(0, 1 - yUnit * yUnit)) * worldRadius;
|
|
378
|
-
const base = {
|
|
379
|
-
x: Math.cos(longitude) * ringRadius,
|
|
380
|
-
y: yUnit * worldRadius,
|
|
381
|
-
z: Math.sin(longitude) * ringRadius
|
|
382
|
-
};
|
|
383
|
-
const turned = rotateY(base, solvingTurnAngle(tier, cyclePos));
|
|
384
|
-
return project(rotateX(turned, SOLVING_TILT), origin, worldRadius);
|
|
385
|
-
});
|
|
386
|
-
return points.slice(1).map((to, j) => {
|
|
387
|
-
const from = points[j];
|
|
388
|
-
const depth = (from.depth + to.depth) / 2;
|
|
389
|
-
return toStroke(from, to, meridianWidth, shadeByDepth(depth) - SOLVING_MERIDIAN_INK_BOOST, SOLVING_MERIDIAN_ALPHA);
|
|
390
|
-
});
|
|
391
|
-
}).flat();
|
|
392
|
-
return { dots: [...texture, ...landmarks], strokes: [...seams, ...meridians] };
|
|
388
|
+
return { dots: [...texture, ...landmarks], strokes: [] };
|
|
393
389
|
};
|
|
394
390
|
// ---------------------------------------------------------------------------
|
|
395
391
|
// listening -- stacked horizontal rings with a wave rolling through them
|
package/dist-wc/index.js
CHANGED
|
@@ -24079,7 +24079,7 @@ var clamp01$5 = (e) => Math.max(0, Math.min(1, e)), rotateX = (e, t) => {
|
|
|
24079
24079
|
width: n,
|
|
24080
24080
|
ink: clamp01$2(i),
|
|
24081
24081
|
alpha: clamp01$2(a)
|
|
24082
|
-
}), WORKING_TRAIN_BASE_COUNT =
|
|
24082
|
+
}), WORKING_TRAIN_BASE_COUNT = 12, WORKING_MIN_TRAINS_64 = 3, WORKING_TRAIN_LENGTH = 3, WORKING_TRAIN_ARC_SPAN = .5, WORKING_BASE_RADIUS_PX = 1.3, WORKING_SMALL_BASE_RADIUS_PX = 2.2, WORKING_ORBIT_COUNT = 6, WORKING_ANGULAR_SPEED = 1.1, WORKING_ORBIT_INK_SPREAD = .3, WORKING_ORBIT_ALPHA_FLOOR = .65, WORKING_TRAIL_ALPHA_FLOOR = .35, WORKING_GHOST_DOTS_PER_ORBIT = 40, WORKING_GHOST_RADIUS_PX = .7, WORKING_GHOST_INK = .4, WORKING_GHOST_ALPHA = .5, workingOrbit = (e) => {
|
|
24083
24083
|
let t = e * 31 + 7;
|
|
24084
24084
|
return {
|
|
24085
24085
|
tilt: (hashUnit(t) - .5) * Math.PI,
|
|
@@ -24091,13 +24091,13 @@ var clamp01$5 = (e) => Math.max(0, Math.min(1, e)), rotateX = (e, t) => {
|
|
|
24091
24091
|
}, WORKING_SMALL_LAYOUT = {
|
|
24092
24092
|
32: {
|
|
24093
24093
|
orbits: 4,
|
|
24094
|
-
trainLength:
|
|
24095
|
-
arcSpan:
|
|
24094
|
+
trainLength: 4,
|
|
24095
|
+
arcSpan: .75
|
|
24096
24096
|
},
|
|
24097
24097
|
20: {
|
|
24098
24098
|
orbits: 3,
|
|
24099
|
-
trainLength:
|
|
24100
|
-
arcSpan:
|
|
24099
|
+
trainLength: 4,
|
|
24100
|
+
arcSpan: .9
|
|
24101
24101
|
}
|
|
24102
24102
|
}, WORKING_SMALL_ORBIT_TILT = .5, WORKING_PATH_SEGMENTS = 24, WORKING_PATH_WIDTH_PX = .8, WORKING_PATH_INK = .5, WORKING_PATH_ALPHA = .45, WORKING_SMALL_ORBIT_RADIUS = .85, WORKING_SMALL_SPEEDS = [
|
|
24103
24103
|
.8,
|
|
@@ -24115,12 +24115,26 @@ var clamp01$5 = (e) => Math.max(0, Math.min(1, e)), rotateX = (e, t) => {
|
|
|
24115
24115
|
for (let t = 0; t < c; t += 1) {
|
|
24116
24116
|
let c = o ? workingSmallOrbit(t % o.orbits, o.orbits) : workingOrbit(t % WORKING_ORBIT_COUNT), p = (o ? Math.floor(t / o.orbits) / s * TWO_PI$1 + t % o.orbits * .9 : hashUnit(t * 5 + 1) * TWO_PI$1) + e * WORKING_ANGULAR_SPEED * c.speedFactor, h = a * c.orbitRadiusFactor;
|
|
24117
24117
|
for (let e = 0; e < l; e += 1) {
|
|
24118
|
-
let
|
|
24119
|
-
x: Math.cos(
|
|
24118
|
+
let s = p - e * u, S = project(rotateZ(rotateX({
|
|
24119
|
+
x: Math.cos(s) * h,
|
|
24120
24120
|
y: 0,
|
|
24121
|
-
z: Math.sin(
|
|
24122
|
-
}, c.tilt), c.roll), i, a),
|
|
24123
|
-
f.push(toDot(
|
|
24121
|
+
z: Math.sin(s) * h
|
|
24122
|
+
}, c.tilt), c.roll), i, a), C = t * 13 + e * 7 + 2, k = 1 - e / (l - 1), R = shadeByDepth(S.depth) + (hashUnit(C) - .5) * .08 - (c.weight - .5) * WORKING_ORBIT_INK_SPREAD, te = (WORKING_TRAIL_ALPHA_FLOOR + (1 - WORKING_TRAIL_ALPHA_FLOOR) * k) * (WORKING_ORBIT_ALPHA_FLOOR + (1 - WORKING_ORBIT_ALPHA_FLOOR) * c.weight), ne = o ? WORKING_SMALL_BASE_RADIUS_PX : WORKING_BASE_RADIUS_PX, re = n.radius(ne) * (.9 + .25 * hashUnit(C + 3));
|
|
24123
|
+
f.push(toDot(S, re, R, te));
|
|
24124
|
+
}
|
|
24125
|
+
}
|
|
24126
|
+
if (!o) {
|
|
24127
|
+
let e = Math.max(8, n.countAlongPath(WORKING_GHOST_DOTS_PER_ORBIT));
|
|
24128
|
+
for (let t = 0; t < WORKING_ORBIT_COUNT; t += 1) {
|
|
24129
|
+
let o = workingOrbit(t), s = a * o.orbitRadiusFactor;
|
|
24130
|
+
for (let t = 0; t < e; t += 1) {
|
|
24131
|
+
let c = t / e * TWO_PI$1, l = project(rotateZ(rotateX({
|
|
24132
|
+
x: Math.cos(c) * s,
|
|
24133
|
+
y: 0,
|
|
24134
|
+
z: Math.sin(c) * s
|
|
24135
|
+
}, o.tilt), o.roll), i, a);
|
|
24136
|
+
f.push(toDot(l, n.radius(WORKING_GHOST_RADIUS_PX), WORKING_GHOST_INK, WORKING_GHOST_ALPHA * (.4 + .6 * l.depth)));
|
|
24137
|
+
}
|
|
24124
24138
|
}
|
|
24125
24139
|
}
|
|
24126
24140
|
return {
|
|
@@ -24156,10 +24170,10 @@ var clamp01$5 = (e) => Math.max(0, Math.min(1, e)), rotateX = (e, t) => {
|
|
|
24156
24170
|
dots: c,
|
|
24157
24171
|
strokes: Array.from({ length: SEARCHING_ARC_SEGMENTS }, (e, t) => toStroke(l[t], l[t + 1], u, SEARCHING_ARC_INK, SEARCHING_ARC_ALPHA))
|
|
24158
24172
|
};
|
|
24159
|
-
}, SOLVING_BASE_COUNT = 130, SOLVING_BASE_RADIUS_PX = 1.5, SOLVING_TIER_COUNT = 4, SOLVING_TURN_DURATION = .16, SOLVING_TURN_GAP = .3, SOLVING_HOLD_GAP = .55, SOLVING_TILT = -.5, SOLVING_LANDMARKS_PER_TIER = 3, SOLVING_LANDMARK_PHASE = hashUnit(5) * TWO_PI$1, SOLVING_LANDMARK_RADIUS_PX = 3.1, SOLVING_LANDMARK_INK_BOOST = .45, SOLVING_LANDMARK_ALPHA = .9,
|
|
24173
|
+
}, SOLVING_BASE_COUNT = 130, SOLVING_BASE_RADIUS_PX = 1.5, SOLVING_TIER_COUNT = 4, SOLVING_TURN_DURATION = .16, SOLVING_TURN_GAP = .3, SOLVING_HOLD_GAP = .55, SOLVING_TILT = -.5, SOLVING_LANDMARKS_PER_TIER = 3, SOLVING_LANDMARK_PHASE = hashUnit(5) * TWO_PI$1, SOLVING_LANDMARK_RADIUS_PX = 3.1, SOLVING_LANDMARK_INK_BOOST = .45, SOLVING_LANDMARK_ALPHA = .9, solvingTurnStart = (e) => e * SOLVING_TURN_GAP, solvingTurnEnd = (e) => solvingTurnStart(e) + SOLVING_TURN_DURATION, SOLVING_HOLD_START = solvingTurnEnd(SOLVING_TIER_COUNT - 1) + SOLVING_HOLD_GAP, solvingReturnStart = (e) => SOLVING_HOLD_START + (SOLVING_TIER_COUNT - 1 - e) * SOLVING_TURN_GAP, solvingReturnEnd = (e) => solvingReturnStart(e) + SOLVING_TURN_DURATION, SOLVING_CYCLE = solvingReturnEnd(0) + SOLVING_HOLD_GAP, solvingTierTurn = (e, t) => {
|
|
24160
24174
|
let n = solvingTurnStart(e), i = solvingTurnEnd(e), a = solvingReturnStart(e), o = solvingReturnEnd(e);
|
|
24161
24175
|
return t <= n ? 0 : t < i ? easeOutCubic((t - n) / SOLVING_TURN_DURATION) : t < a ? 1 : t < o ? 1 - easeInOutCubic((t - a) / SOLVING_TURN_DURATION) : 0;
|
|
24162
|
-
}, solvingTierOf = (e) => clamp$1(Math.floor((1 - e) / 2 * SOLVING_TIER_COUNT), 0, SOLVING_TIER_COUNT - 1), solvingTierDirection = (e) => hashUnit(e * 53 + 21) < .5 ? -1 : 1, solvingTierCenterYUnit = (e) => 1 - (2 * e + 1) / SOLVING_TIER_COUNT,
|
|
24176
|
+
}, solvingTierOf = (e) => clamp$1(Math.floor((1 - e) / 2 * SOLVING_TIER_COUNT), 0, SOLVING_TIER_COUNT - 1), solvingTierDirection = (e) => hashUnit(e * 53 + 21) < .5 ? -1 : 1, solvingTierCenterYUnit = (e) => 1 - (2 * e + 1) / SOLVING_TIER_COUNT, solvingTurnAngle = (e, t) => solvingTierTurn(e, t) * solvingTierDirection(e) * (Math.PI / 2), solving = (e, t) => {
|
|
24163
24177
|
let n = modeSizing(t.size, t.density, t.dotScale), i = originOf(t), a = worldRadiusOf(t), o = n.count(SOLVING_BASE_COUNT), s = e - SOLVING_CYCLE * Math.floor(e / SOLVING_CYCLE), c = Array.from({ length: o }, (e, t) => {
|
|
24164
24178
|
let c = sampleSphere(t, o, a), l = project(rotateX(rotateY(c, solvingTurnAngle(solvingTierOf(a > 0 ? c.y / a : 0), s)), SOLVING_TILT), i, a), u = shadeByDepth(l.depth), f = .55 + .3 * hashUnit(t * 3 + 9);
|
|
24165
24179
|
return toDot(l, n.radius(SOLVING_BASE_RADIUS_PX), u, f);
|
|
@@ -24170,33 +24184,10 @@ var clamp01$5 = (e) => Math.max(0, Math.min(1, e)), rotateX = (e, t) => {
|
|
|
24170
24184
|
z: Math.sin(p) * f
|
|
24171
24185
|
}, solvingTurnAngle(o, s)), SOLVING_TILT), i, a), S = shadeByDepth(h.depth) - SOLVING_LANDMARK_INK_BOOST;
|
|
24172
24186
|
return toDot(h, n.radius(SOLVING_LANDMARK_RADIUS_PX), S, SOLVING_LANDMARK_ALPHA);
|
|
24173
|
-
})
|
|
24174
|
-
let n = solvingSeamYUnit(t), o = n * a, s = Math.sqrt(Math.max(0, 1 - n * n)) * a, c = Array.from({ length: 13 }, (e, t) => {
|
|
24175
|
-
let n = t / SOLVING_SEAM_SEGMENTS * TWO_PI$1;
|
|
24176
|
-
return project(rotateX({
|
|
24177
|
-
x: Math.cos(n) * s,
|
|
24178
|
-
y: o,
|
|
24179
|
-
z: Math.sin(n) * s
|
|
24180
|
-
}, SOLVING_TILT), i, a);
|
|
24181
|
-
});
|
|
24182
|
-
return Array.from({ length: SOLVING_SEAM_SEGMENTS }, (e, t) => toStroke(c[t], c[t + 1], u, SOLVING_SEAM_INK, SOLVING_SEAM_ALPHA));
|
|
24183
|
-
}).flat(), p = n.radius(SOLVING_MERIDIAN_WIDTH_PX), h = Array.from({ length: SOLVING_TIER_COUNT * SOLVING_LANDMARKS_PER_TIER }, (e, t) => {
|
|
24184
|
-
let n = Math.floor(t / SOLVING_LANDMARKS_PER_TIER), o = SOLVING_LANDMARK_PHASE + t % SOLVING_LANDMARKS_PER_TIER / SOLVING_LANDMARKS_PER_TIER * TWO_PI$1, c = Math.min(SOLVING_MERIDIAN_Y_LIMIT, 1 - 2 * n / SOLVING_TIER_COUNT), l = Math.max(-.9, 1 - 2 * (n + 1) / SOLVING_TIER_COUNT), u = Array.from({ length: SOLVING_MERIDIAN_POINTS_PER_TIER }, (e, t) => {
|
|
24185
|
-
let u = c + (l - c) * t / (SOLVING_MERIDIAN_POINTS_PER_TIER - 1), f = Math.sqrt(Math.max(0, 1 - u * u)) * a;
|
|
24186
|
-
return project(rotateX(rotateY({
|
|
24187
|
-
x: Math.cos(o) * f,
|
|
24188
|
-
y: u * a,
|
|
24189
|
-
z: Math.sin(o) * f
|
|
24190
|
-
}, solvingTurnAngle(n, s)), SOLVING_TILT), i, a);
|
|
24191
|
-
});
|
|
24192
|
-
return u.slice(1).map((e, t) => {
|
|
24193
|
-
let n = u[t];
|
|
24194
|
-
return toStroke(n, e, p, shadeByDepth((n.depth + e.depth) / 2) - SOLVING_MERIDIAN_INK_BOOST, SOLVING_MERIDIAN_ALPHA);
|
|
24195
|
-
});
|
|
24196
|
-
}).flat();
|
|
24187
|
+
});
|
|
24197
24188
|
return {
|
|
24198
24189
|
dots: [...c, ...l],
|
|
24199
|
-
strokes: [
|
|
24190
|
+
strokes: []
|
|
24200
24191
|
};
|
|
24201
24192
|
}, LISTENING_RING_COUNT = {
|
|
24202
24193
|
64: 5,
|
|
@@ -24279,7 +24270,7 @@ var clamp01$5 = (e) => Math.max(0, Math.min(1, e)), rotateX = (e, t) => {
|
|
|
24279
24270
|
64: 1,
|
|
24280
24271
|
32: .85,
|
|
24281
24272
|
20: .7
|
|
24282
|
-
}, STRAND_DEPTH_INK = .45, STRAND_SHADE_STEP = .1, strandBaseAngle = (e) => e / STRAND_COUNT * Math.PI * 2, strandPoint = (e, t, n, i, a) => {
|
|
24273
|
+
}, STRAND_DEPTH_INK = .45, STRAND_SHADE_STEP = .1, STRAND_GHOST_BASE_COUNT = 110, STRAND_GHOST_RADIUS_PX = .5, STRAND_GHOST_INK = .3, STRAND_GHOST_ALPHA_BASE = .16, STRAND_GHOST_ALPHA_DEPTH = .22, weavingGhostCount = (e) => Math.max(20, e.count(STRAND_GHOST_BASE_COUNT)), strandBaseAngle = (e) => e / STRAND_COUNT * Math.PI * 2, strandPoint = (e, t, n, i, a) => {
|
|
24283
24274
|
let o = t / (n - 1) * Math.PI * 2, s = STRAND_WAVE_AMPLITUDE * Math.sin(o * STRAND_WAVE_COUNT + a * STRAND_WAVE_SPEED + strandBaseAngle(e));
|
|
24284
24275
|
return rotateX(rotateY(rotateX({
|
|
24285
24276
|
x: i * Math.cos(s) * Math.cos(o),
|
|
@@ -24287,29 +24278,39 @@ var clamp01$5 = (e) => Math.max(0, Math.min(1, e)), rotateX = (e, t) => {
|
|
|
24287
24278
|
z: i * Math.cos(s) * Math.sin(o)
|
|
24288
24279
|
}, STRAND_INCLINATION), strandBaseAngle(e) + a * STRAND_ROTATE_SPEED), STRAND_TILT);
|
|
24289
24280
|
}, weaving = (e, t) => {
|
|
24290
|
-
let { sizing: n, originPx: i, sphereRadius: a } = sphereGeometry(t), o = Math.max(MIN_STRAND_POINTS, n.countAlongPath(STRAND_POINTS_BASE_COUNT)), s = Array.from({ length: STRAND_COUNT }, (t, n) => Array.from({ length: o }, (t, s) => project(strandPoint(n, s, o, a, e), i, a)))
|
|
24281
|
+
let { sizing: n, originPx: i, sphereRadius: a } = sphereGeometry(t), o = Math.max(MIN_STRAND_POINTS, n.countAlongPath(STRAND_POINTS_BASE_COUNT)), s = Array.from({ length: STRAND_COUNT }, (t, n) => Array.from({ length: o }, (t, s) => project(strandPoint(n, s, o, a, e), i, a))), c = s.flatMap((e, i) => e.map((e) => ({
|
|
24282
|
+
x: e.x,
|
|
24283
|
+
y: e.y,
|
|
24284
|
+
depth: e.depth,
|
|
24285
|
+
radius: n.radius(STRAND_DOT_BASE_RADIUS) * STRAND_DOT_SIZE_FACTOR[t.size],
|
|
24286
|
+
ink: clamp01$1((1 - e.depth) * STRAND_DEPTH_INK + i * STRAND_SHADE_STEP),
|
|
24287
|
+
alpha: .55 + e.depth * .4
|
|
24288
|
+
}))), l = s.flatMap((e, i) => e.slice(1).map((a, o) => {
|
|
24289
|
+
let s = e[o], c = (s.depth + a.depth) / 2;
|
|
24290
|
+
return {
|
|
24291
|
+
x1: s.x,
|
|
24292
|
+
y1: s.y,
|
|
24293
|
+
x2: a.x,
|
|
24294
|
+
y2: a.y,
|
|
24295
|
+
depth: c,
|
|
24296
|
+
width: n.radius(STRAND_STROKE_BASE_WIDTH) * STRAND_STROKE_SIZE_FACTOR[t.size],
|
|
24297
|
+
ink: clamp01$1((1 - c) * STRAND_DEPTH_INK + i * STRAND_SHADE_STEP),
|
|
24298
|
+
alpha: .6 + c * .35
|
|
24299
|
+
};
|
|
24300
|
+
})), u = weavingGhostCount(n), f = Array.from({ length: u }, (t, o) => {
|
|
24301
|
+
let s = project(rotateX(rotateY(sampleSphere(o, u, a), e * STRAND_ROTATE_SPEED), STRAND_TILT), i, a);
|
|
24302
|
+
return {
|
|
24303
|
+
x: s.x,
|
|
24304
|
+
y: s.y,
|
|
24305
|
+
depth: s.depth,
|
|
24306
|
+
radius: n.radius(STRAND_GHOST_RADIUS_PX),
|
|
24307
|
+
ink: STRAND_GHOST_INK,
|
|
24308
|
+
alpha: clamp01$1(STRAND_GHOST_ALPHA_BASE + STRAND_GHOST_ALPHA_DEPTH * s.depth)
|
|
24309
|
+
};
|
|
24310
|
+
});
|
|
24291
24311
|
return {
|
|
24292
|
-
dots:
|
|
24293
|
-
|
|
24294
|
-
y: e.y,
|
|
24295
|
-
depth: e.depth,
|
|
24296
|
-
radius: n.radius(STRAND_DOT_BASE_RADIUS) * STRAND_DOT_SIZE_FACTOR[t.size],
|
|
24297
|
-
ink: clamp01$1((1 - e.depth) * STRAND_DEPTH_INK + i * STRAND_SHADE_STEP),
|
|
24298
|
-
alpha: .55 + e.depth * .4
|
|
24299
|
-
}))),
|
|
24300
|
-
strokes: s.flatMap((e, i) => e.slice(1).map((a, o) => {
|
|
24301
|
-
let s = e[o], c = (s.depth + a.depth) / 2;
|
|
24302
|
-
return {
|
|
24303
|
-
x1: s.x,
|
|
24304
|
-
y1: s.y,
|
|
24305
|
-
x2: a.x,
|
|
24306
|
-
y2: a.y,
|
|
24307
|
-
depth: c,
|
|
24308
|
-
width: n.radius(STRAND_STROKE_BASE_WIDTH) * STRAND_STROKE_SIZE_FACTOR[t.size],
|
|
24309
|
-
ink: clamp01$1((1 - c) * STRAND_DEPTH_INK + i * STRAND_SHADE_STEP),
|
|
24310
|
-
alpha: .6 + c * .35
|
|
24311
|
-
};
|
|
24312
|
-
}))
|
|
24312
|
+
dots: [...c, ...f],
|
|
24313
|
+
strokes: l
|
|
24313
24314
|
};
|
|
24314
24315
|
}, TWO_PI = Math.PI * 2, FORM_RADIUS_RATIO = .4, clamp01 = (e) => Math.max(0, Math.min(1, e)), FAR_INK = .6, depthToInk = (e) => clamp01((1 - e) * FAR_INK), depthToAlpha = (e) => clamp01(.5 + e * .5), depthToRadiusFactor = (e) => .7 + e * .3, dotFrom = (e, t, n, i) => ({
|
|
24315
24316
|
x: e.x,
|
|
@@ -24318,26 +24319,36 @@ var clamp01$5 = (e) => Math.max(0, Math.min(1, e)), rotateX = (e, t) => {
|
|
|
24318
24319
|
radius: n.radius(t) * depthToRadiusFactor(e.depth) * i,
|
|
24319
24320
|
ink: depthToInk(e.depth),
|
|
24320
24321
|
alpha: depthToAlpha(e.depth)
|
|
24321
|
-
}), place = (e, t, n, i, a, o, s, c) => dotFrom(project(rotateX(rotateY(e, t), n), i, a), o, s, c), EMPTY_STROKES = [], RIBBON_PER_THREAD_BASE = 36, RIBBON_BASE_DOT_RADIUS =
|
|
24322
|
+
}), place = (e, t, n, i, a, o, s, c) => dotFrom(project(rotateX(rotateY(e, t), n), i, a), o, s, c), EMPTY_STROKES = [], RIBBON_PER_THREAD_BASE = 36, RIBBON_BASE_DOT_RADIUS = 1.2, RIBBON_THREADS = {
|
|
24322
24323
|
64: 5,
|
|
24323
24324
|
32: 4,
|
|
24324
24325
|
20: 3
|
|
24325
|
-
}, RIBBON_HALF_WIDTH = .3, RIBBON_AXIS_TILT = .68, RIBBON_RIPPLE_WAVES = 3, RIBBON_RIPPLE_SPEED = 1.15, RIBBON_RIPPLE_AMPLITUDE = .18, RIBBON_THREAD_JITTER = .1, RIBBON_SPIN_SPEED = .48, RIBBON_CAMERA_TILT = .45, RIBBON_EDGE_ALPHA_FLOOR = .5, RIBBON_EDGE_INK_LIFT = .22, composing = (e, t) => {
|
|
24326
|
-
let n = modeSizing(t.size, t.density, t.dotScale), i = t.size * FORM_RADIUS_RATIO, a = t.size / 2, o = RIBBON_THREADS[t.size], s = n.countAlongPath(RIBBON_PER_THREAD_BASE), c = o * s, l =
|
|
24326
|
+
}, RIBBON_HALF_WIDTH = .3, RIBBON_AXIS_TILT = .68, RIBBON_RIPPLE_WAVES = 3, RIBBON_RIPPLE_SPEED = 1.15, RIBBON_RIPPLE_AMPLITUDE = .18, RIBBON_THREAD_JITTER = .1, RIBBON_SPIN_SPEED = .48, RIBBON_CAMERA_TILT = .45, RIBBON_EDGE_ALPHA_FLOOR = .5, RIBBON_EDGE_INK_LIFT = .22, RIBBON_GHOST_BASE_COUNT = 110, RIBBON_GHOST_RADIUS_PX = .5, RIBBON_GHOST_INK = .3, RIBBON_GHOST_ALPHA_BASE = .16, RIBBON_GHOST_ALPHA_DEPTH = .22, composing = (e, t) => {
|
|
24327
|
+
let n = modeSizing(t.size, t.density, t.dotScale), i = t.size * FORM_RADIUS_RATIO, a = t.size / 2, o = RIBBON_THREADS[t.size], s = n.countAlongPath(RIBBON_PER_THREAD_BASE), c = o * s, l = Math.max(20, n.count(RIBBON_GHOST_BASE_COUNT)), u = Array.from({ length: l }, (e, t) => {
|
|
24328
|
+
let o = project(rotateX(sampleSphere(t, l, i), RIBBON_CAMERA_TILT), a, i);
|
|
24329
|
+
return {
|
|
24330
|
+
x: o.x,
|
|
24331
|
+
y: o.y,
|
|
24332
|
+
depth: o.depth,
|
|
24333
|
+
radius: n.radius(RIBBON_GHOST_RADIUS_PX),
|
|
24334
|
+
ink: RIBBON_GHOST_INK,
|
|
24335
|
+
alpha: clamp01(RIBBON_GHOST_ALPHA_BASE + RIBBON_GHOST_ALPHA_DEPTH * o.depth)
|
|
24336
|
+
};
|
|
24337
|
+
});
|
|
24327
24338
|
for (let t = 0; t < c; t += 1) {
|
|
24328
|
-
let c = t % o,
|
|
24339
|
+
let c = t % o, l = Math.floor(t / o), f = o > 1 ? c / (o - 1) * 2 - 1 : 0, p = l / s * TWO_PI, h = Math.sin(p * RIBBON_RIPPLE_WAVES + e * RIBBON_RIPPLE_SPEED) * RIBBON_RIPPLE_AMPLITUDE, S = f * RIBBON_HALF_WIDTH + h, C = rotateZ({
|
|
24329
24340
|
x: Math.cos(S) * Math.cos(p) * i,
|
|
24330
24341
|
y: Math.sin(S) * i,
|
|
24331
24342
|
z: Math.cos(S) * Math.sin(p) * i
|
|
24332
24343
|
}, RIBBON_AXIS_TILT), k = 1 - RIBBON_THREAD_JITTER / 2 + hashUnit(t * 7 + 1) * RIBBON_THREAD_JITTER, R = place(C, e * RIBBON_SPIN_SPEED, RIBBON_CAMERA_TILT, a, i, RIBBON_BASE_DOT_RADIUS, n, k), te = Math.abs(f);
|
|
24333
|
-
|
|
24344
|
+
u.push({
|
|
24334
24345
|
...R,
|
|
24335
24346
|
ink: clamp01(R.ink + te * RIBBON_EDGE_INK_LIFT),
|
|
24336
24347
|
alpha: clamp01(R.alpha * (1 - te * (1 - RIBBON_EDGE_ALPHA_FLOOR)))
|
|
24337
24348
|
});
|
|
24338
24349
|
}
|
|
24339
24350
|
return {
|
|
24340
|
-
dots:
|
|
24351
|
+
dots: u,
|
|
24341
24352
|
strokes: EMPTY_STROKES
|
|
24342
24353
|
};
|
|
24343
24354
|
}, BREATHING_BASE_COUNT = 32, BREATHING_BASE_DOT_RADIUS = 1.7, BREATHING_WORLD_RADIUS_RATIO = .34, BREATHING_AMPLITUDE = .09, BREATHING_SPEED = .55, BREATHING_SHAPE_HARMONIC = 5, BREATHING_SHAPE_SPEED = .22, BREATHING_SHAPE_AMPLITUDE = .035, BREATHING_SPIN_SPEED = .12, BREATHING_TILT = .62, breathing = (e, t) => {
|