One commited on
Commit
721da3f
Β·
verified Β·
1 Parent(s): 9755d7d

Upload index.html

Browse files
Files changed (1) hide show
  1. index.html +105 -5
index.html CHANGED
@@ -22,11 +22,13 @@
22
  <script>
23
  (() => {
24
  "use strict";
25
- // ============ Aquarium v12 ALT-FG β€” hilly terrain + foreground grass (50% size) =====
26
- // Based on v10 ALT (rolling-hills sand bed), plus front-glass foreground grass planted
27
- // in the low band below the sand line and drawn on top of everything. The fg clumps are
28
- // 50% smaller than the original fg version: half height, half width, half spread β€”
29
- // so they read as near-glass flora without swallowing the hilly scene.
 
 
30
  const canvas = document.getElementById("tank");
31
  const ctx = canvas.getContext("2d");
32
  let W = 0, H = 0;
@@ -57,6 +59,61 @@ class Fish {
57
  this.angle = Math.random() < 0.5 ? rand(-0.4, 0.4) : Math.PI + rand(-0.4, 0.4);
58
  this.hue = pick(HUES);
59
  this.tailType = pick(TAIL_TYPES); // v11: random tail-fin style for variety
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  this.phase = rand(0, Math.PI * 2);
61
  // v9: after dark, most fish bed down low in the grass β€” only a small share still
62
  // hovers by the seaweed, and each of those keeps to its own stalk (no pile-ups)
@@ -343,6 +400,49 @@ class Fish {
343
  c.fillStyle = g;
344
  c.fill(bodyPath);
345
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
346
  // v7: efficient iridescence β€” a sheen whose hue shimmers with the swim phase,
347
  // so scales appear to catch the light while moving. One gradient + one fill.
348
  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 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");
33
  const ctx = canvas.getContext("2d");
34
  let W = 0, H = 0;
 
59
  this.angle = Math.random() < 0.5 ? rand(-0.4, 0.4) : Math.PI + rand(-0.4, 0.4);
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++) {
72
+ const th = rand(0, Math.PI * 2);
73
+ const rr = Math.sqrt(Math.random()) * 0.9; // uniform in ellipse, kept off the rim
74
+ let style;
75
+ if (pale) {
76
+ // cream/ivory spots β€” pearl-gourami / leopard pattern
77
+ style = `hsla(${this.hue + rand(-24, 24)},${rand(45, 70)}%,${rand(82, 94)}%,${rand(0.35, 0.6).toFixed(2)})`;
78
+ } else {
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++) {
98
+ const t = nStr > 1 ? i / (nStr - 1) : 0; // 0 behind head β†’ 1 near tail base
99
+ let style;
100
+ if (darkBars) {
101
+ // classic dark tiger bars
102
+ style = `hsla(${this.hue + rand(-14, 14)},${rand(65, 90)}%,${rand(18, 30)}%,${rand(0.5, 0.75).toFixed(2)})`;
103
+ } else {
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,
111
+ });
112
+ }
113
+ } else {
114
+ this.spots = null;
115
+ this.stripes = null;
116
+ }
117
  this.phase = rand(0, Math.PI * 2);
118
  // v9: after dark, most fish bed down low in the grass β€” only a small share still
119
  // hovers by the seaweed, and each of those keeps to its own stalk (no pile-ups)
 
400
  c.fillStyle = g;
401
  c.fill(bodyPath);
402
 
403
+ // v13: random spots on ~20% of fish β€” clipped to the body so they never spill,
404
+ // riding the traveling wave (wy) so they flex with the undulating body, and drawn
405
+ // BEFORE the additive sheen so the iridescent shimmer still plays across them.
406
+ if (this.spots) {
407
+ c.save();
408
+ c.clip(bodyPath);
409
+ for (const sp of this.spots) {
410
+ const sx = sp.x * s;
411
+ c.fillStyle = sp.style;
412
+ c.beginPath();
413
+ c.arc(sx, sp.y * s + wy(sx), sp.r * s, 0, Math.PI * 2);
414
+ c.fill();
415
+ }
416
+ c.restore();
417
+ }
418
+
419
+ // v14: tiger stripes on ~20% of fish (mutually exclusive with spots) β€” vertical bars
420
+ // across the body. Each bar is a thin polygon sampled along its width so it bends
421
+ // with the traveling wave (wy), clipped to the outline, drawn BEFORE the additive
422
+ // sheen so the iridescent shimmer still plays across the stripes.
423
+ if (this.stripes) {
424
+ c.save();
425
+ c.clip(bodyPath);
426
+ for (const st of this.stripes) {
427
+ const sx = st.x * s; // bar center, fish-local x
428
+ const hw = st.w * s / 2; // half-width
429
+ const M = 5; // samples across the bar so it follows wy(x)
430
+ c.fillStyle = st.style;
431
+ c.beginPath();
432
+ for (let j = 0; j <= M; j++) {
433
+ const x = sx - hw + (j / M) * (2 * hw);
434
+ if (j === 0) c.moveTo(x, wy(x) - s * 0.55); else c.lineTo(x, wy(x) - s * 0.55);
435
+ }
436
+ for (let j = M; j >= 0; j--) {
437
+ const x = sx - hw + (j / M) * (2 * hw);
438
+ c.lineTo(x, wy(x) + s * 0.55);
439
+ }
440
+ c.closePath();
441
+ c.fill();
442
+ }
443
+ c.restore();
444
+ }
445
+
446
  // v7: efficient iridescence β€” a sheen whose hue shimmers with the swim phase,
447
  // so scales appear to catch the light while moving. One gradient + one fill.
448
  const shimmer = Math.sin(this.phase * 1.6) * 0.5 + 0.5; // 0..1 as it swims