One commited on
Commit
2ff9a7f
Β·
verified Β·
1 Parent(s): c6f706b

Upload index.html

Browse files
Files changed (1) hide show
  1. index.html +53 -39
index.html CHANGED
@@ -22,11 +22,11 @@
22
  <script>
23
  (() => {
24
  "use strict";
25
- // ============ Aquarium v14 SPOTTY-2 β€” alt-fg base + spots OR tiger stripes (~20% ea) ===
26
- // Based on v13 SPOTTY (rolling hills, three tail styles, yellow-green foreground grass),
27
- // plus: a single spawn roll gives each fish one of three looks β€” ~20% dark/cream spots,
28
- // ~20% tiger stripes (betta/tiger-barb style bars across the body), or plain. The two
29
- // markings are mutually exclusive (no fish wears both). Stripes ride the traveling body
30
  // wave and sit under the additive iridescent sheen, so they catch light as each swims.
31
  // Iridescence + overhead streak unchanged.
32
  const canvas = document.getElementById("tank");
@@ -60,12 +60,12 @@ class Fish {
60
  this.hue = pick(HUES);
61
  this.tailType = pick(TAIL_TYPES); // v11: random tail-fin style for variety
62
 
63
- // v13/v14: random body markings β€” ~20% spots OR ~20% tiger stripes (mutually
64
- // exclusive; one roll per fish, never both). Sampled in units of `size` so they
65
- // scale with the fish, stored as pre-built fill styles β€” zero per-frame string work.
66
- const markRoll = Math.random();
67
- if (markRoll < 0.2) {
68
- this.spots = [];
69
  const nSpots = 7 + ((Math.random() * 9) | 0); // 7..15 spots
70
  const pale = Math.random() < 0.45; // cream/ivory vs dark spotting style
71
  for (let i = 0; i < nSpots; i++) {
@@ -79,19 +79,20 @@ class Fish {
79
  // dark spots β€” dace / leopard pattern
80
  style = `hsla(${this.hue + rand(-18, 18)},${rand(60, 85)}%,${rand(24, 34)}%,${rand(0.45, 0.7).toFixed(2)})`;
81
  }
82
- this.spots.push({
83
  x: Math.cos(th) * rr, // along body axis, in units of s
84
  y: Math.sin(th) * rr * 0.42, // across body (matches the 0.42 ellipse ratio)
85
  r: rand(0.05, 0.13), // spot radius, in units of s
86
  style,
87
  });
88
  }
89
- this.stripes = null;
90
- } else if (markRoll < 0.4) {
91
- // v14: tiger stripes β€” vertical bars across the body (betta / tiger-barb style),
92
- // spread from just behind the head to near the tail base with organic jitter.
93
- this.spots = null;
94
- this.stripes = [];
 
95
  const nStr = 5 + ((Math.random() * 4) | 0); // 5..8 bars
96
  const darkBars = Math.random() < 0.72; // mostly classic dark bars, sometimes pale
97
  for (let i = 0; i < nStr; i++) {
@@ -104,7 +105,7 @@ class Fish {
104
  // cream/ivory bars β€” pale tiger variant
105
  style = `hsla(${this.hue + rand(-24, 24)},${rand(45, 70)}%,${rand(80, 93)}%,${rand(0.35, 0.6).toFixed(2)})`;
106
  }
107
- this.stripes.push({
108
  x: 0.72 - t * 1.62 + rand(-0.07, 0.07), // +0.72s β†’ -0.90s along the body
109
  w: rand(0.08, 0.2), // bar width, in units of s
110
  style,
@@ -117,6 +118,19 @@ class Fish {
117
  tPh: rand(0, Math.PI * 2),
118
  });
119
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  } else {
121
  this.spots = null;
122
  this.stripes = null;
@@ -407,27 +421,10 @@ class Fish {
407
  c.fillStyle = g;
408
  c.fill(bodyPath);
409
 
410
- // v13: random spots on ~20% of fish β€” clipped to the body so they never spill,
411
- // riding the traveling wave (wy) so they flex with the undulating body, and drawn
 
412
  // BEFORE the additive sheen so the iridescent shimmer still plays across them.
413
- if (this.spots) {
414
- c.save();
415
- c.clip(bodyPath);
416
- for (const sp of this.spots) {
417
- const sx = sp.x * s;
418
- c.fillStyle = sp.style;
419
- c.beginPath();
420
- c.arc(sx, sp.y * s + wy(sx), sp.r * s, 0, Math.PI * 2);
421
- c.fill();
422
- }
423
- c.restore();
424
- }
425
-
426
- // v14.1: tiger stripes on ~20% of fish (mutually exclusive with spots). Each bar is
427
- // a wavy, tapering band β€” its centerline bends and its width varies down the body,
428
- // so no stripe reads as a straight line. Sampled along both edges so it still rides
429
- // the traveling wave (wy); clipped to the outline and drawn BEFORE the additive
430
- // sheen so the iridescent shimmer still plays across the stripes.
431
  if (this.stripes) {
432
  c.save();
433
  c.clip(bodyPath);
@@ -460,6 +457,23 @@ class Fish {
460
  c.restore();
461
  }
462
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
463
  // v7: efficient iridescence β€” a sheen whose hue shimmers with the swim phase,
464
  // so scales appear to catch the light while moving. One gradient + one fill.
465
  const shimmer = Math.sin(this.phase * 1.6) * 0.5 + 0.5; // 0..1 as it swims
 
22
  <script>
23
  (() => {
24
  "use strict";
25
+ // ============ Aquarium v15 SPOTTY-3 β€” alt-fg base + spots / stripes / BOTH (~20/20/10) ==
26
+ // Based on v14 SPOTTY-2 (rolling hills, three tail styles, yellow-green foreground grass),
27
+ // plus: a single spawn roll gives each fish one of four looks β€” ~20% dark/cream spots,
28
+ // ~20% tiger stripes (betta/tiger-barb style bars across the body), ~10% BOTH (spots
29
+ // over stripes), or plain. Stripes ride the traveling body
30
  // wave and sit under the additive iridescent sheen, so they catch light as each swims.
31
  // Iridescence + overhead streak unchanged.
32
  const canvas = document.getElementById("tank");
 
60
  this.hue = pick(HUES);
61
  this.tailType = pick(TAIL_TYPES); // v11: random tail-fin style for variety
62
 
63
+ // v13/v14/v15: random body markings β€” one roll per fish decides the look:
64
+ // ~20% spots, ~20% tiger stripes, ~10% BOTH (spots over stripes), else plain.
65
+ // Sampled in units of `size` so they scale with the fish; stored as pre-built
66
+ // fill styles β€” zero per-frame string work.
67
+ const genSpots = () => {
68
+ const arr = [];
69
  const nSpots = 7 + ((Math.random() * 9) | 0); // 7..15 spots
70
  const pale = Math.random() < 0.45; // cream/ivory vs dark spotting style
71
  for (let i = 0; i < nSpots; i++) {
 
79
  // dark spots β€” dace / leopard pattern
80
  style = `hsla(${this.hue + rand(-18, 18)},${rand(60, 85)}%,${rand(24, 34)}%,${rand(0.45, 0.7).toFixed(2)})`;
81
  }
82
+ arr.push({
83
  x: Math.cos(th) * rr, // along body axis, in units of s
84
  y: Math.sin(th) * rr * 0.42, // across body (matches the 0.42 ellipse ratio)
85
  r: rand(0.05, 0.13), // spot radius, in units of s
86
  style,
87
  });
88
  }
89
+ return arr;
90
+ };
91
+ const genStripes = () => {
92
+ // v14/v14.1: tiger stripes β€” vertical bars across the body (betta / tiger-barb
93
+ // style), spread from just behind the head to near the tail base with organic
94
+ // jitter; each bar bends and tapers instead of being a straight line.
95
+ const arr = [];
96
  const nStr = 5 + ((Math.random() * 4) | 0); // 5..8 bars
97
  const darkBars = Math.random() < 0.72; // mostly classic dark bars, sometimes pale
98
  for (let i = 0; i < nStr; i++) {
 
105
  // cream/ivory bars β€” pale tiger variant
106
  style = `hsla(${this.hue + rand(-24, 24)},${rand(45, 70)}%,${rand(80, 93)}%,${rand(0.35, 0.6).toFixed(2)})`;
107
  }
108
+ arr.push({
109
  x: 0.72 - t * 1.62 + rand(-0.07, 0.07), // +0.72s β†’ -0.90s along the body
110
  w: rand(0.08, 0.2), // bar width, in units of s
111
  style,
 
118
  tPh: rand(0, Math.PI * 2),
119
  });
120
  }
121
+ return arr;
122
+ };
123
+ const markRoll = Math.random();
124
+ if (markRoll < 0.2) {
125
+ this.spots = genSpots();
126
+ this.stripes = null;
127
+ } else if (markRoll < 0.4) {
128
+ this.spots = null;
129
+ this.stripes = genStripes();
130
+ } else if (markRoll < 0.5) {
131
+ // v15: the mixed breed β€” stripes as the base pattern, spots scattered over them
132
+ this.spots = genSpots();
133
+ this.stripes = genStripes();
134
  } else {
135
  this.spots = null;
136
  this.stripes = null;
 
421
  c.fillStyle = g;
422
  c.fill(bodyPath);
423
 
424
+ // v15: stripes first when both are present β€” bars form the base pattern,
425
+ // spots scatter on top. Each is clipped to the body so nothing spills, and both
426
+ // ride the traveling wave (wy) so they flex with the undulating body, drawn
427
  // BEFORE the additive sheen so the iridescent shimmer still plays across them.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
428
  if (this.stripes) {
429
  c.save();
430
  c.clip(bodyPath);
 
457
  c.restore();
458
  }
459
 
460
+ // v13: random spots on ~20% of fish (or over the stripes for the 10% mixed) β€”
461
+ // clipped to the body so they never spill, riding the traveling wave (wy) so they
462
+ // flex with the undulating body, and drawn BEFORE the additive sheen so the
463
+ // iridescent shimmer still plays across them.
464
+ if (this.spots) {
465
+ c.save();
466
+ c.clip(bodyPath);
467
+ for (const sp of this.spots) {
468
+ const sx = sp.x * s;
469
+ c.fillStyle = sp.style;
470
+ c.beginPath();
471
+ c.arc(sx, sp.y * s + wy(sx), sp.r * s, 0, Math.PI * 2);
472
+ c.fill();
473
+ }
474
+ c.restore();
475
+ }
476
+
477
  // v7: efficient iridescence β€” a sheen whose hue shimmers with the swim phase,
478
  // so scales appear to catch the light while moving. One gradient + one fill.
479
  const shimmer = Math.sin(this.phase * 1.6) * 0.5 + 0.5; // 0..1 as it swims