Upload index.html
Browse files- index.html +45 -6
index.html
CHANGED
|
@@ -22,12 +22,12 @@
|
|
| 22 |
<script>
|
| 23 |
(() => {
|
| 24 |
"use strict";
|
| 25 |
-
// ============ Aquarium
|
| 26 |
-
// Based on
|
| 27 |
-
//
|
| 28 |
-
//
|
| 29 |
-
//
|
| 30 |
-
//
|
| 31 |
// Iridescence + overhead streak unchanged.
|
| 32 |
const canvas = document.getElementById("tank");
|
| 33 |
const ctx = canvas.getContext("2d");
|
|
@@ -135,6 +135,20 @@ class Fish {
|
|
| 135 |
this.spots = null;
|
| 136 |
this.stripes = null;
|
| 137 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
this.phase = rand(0, Math.PI * 2);
|
| 139 |
// v9: after dark, most fish bed down low in the grass β only a small share still
|
| 140 |
// hovers by the seaweed, and each of those keeps to its own stalk (no pile-ups)
|
|
@@ -524,6 +538,31 @@ class Fish {
|
|
| 524 |
c.arc(s * 0.61, -s * 0.1, s * 0.055, 0, Math.PI * 2);
|
| 525 |
c.fill();
|
| 526 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 527 |
c.restore();
|
| 528 |
|
| 529 |
// v7: overhead light streak β a soft line of light on whichever edge faces up,
|
|
|
|
| 22 |
<script>
|
| 23 |
(() => {
|
| 24 |
"use strict";
|
| 25 |
+
// ============ Aquarium v16 WHISKERS β alt-fg base + spots/stripes + whiskers (~10%) ==
|
| 26 |
+
// Based on v15 SPOTTY-3 (rolling hills, three tail styles, yellow-green foreground grass,
|
| 27 |
+
// ~20% spots / ~20% stripes / ~10% both), plus: an independent roll gives ~10% of fish
|
| 28 |
+
// whiskers (barbels) β a forward-curving pair from the snout in one of THREE lengths
|
| 29 |
+
// (short / medium / long), swaying gently as they swim. Whiskers are independent of the
|
| 30 |
+
// body markings, so a whiskered fish may also be spotted, striped, both, or plain.
|
| 31 |
// Iridescence + overhead streak unchanged.
|
| 32 |
const canvas = document.getElementById("tank");
|
| 33 |
const ctx = canvas.getContext("2d");
|
|
|
|
| 135 |
this.spots = null;
|
| 136 |
this.stripes = null;
|
| 137 |
}
|
| 138 |
+
// v16: whiskers (barbels) β an independent ~10% roll. A whiskered fish gets a
|
| 139 |
+
// forward-curving pair from the snout in one of three length tiers (~even split),
|
| 140 |
+
// so the tank shows short, medium and long whiskers. Independent of spots/stripes,
|
| 141 |
+
// so any marked fish can also wear them.
|
| 142 |
+
if (Math.random() < 0.1) {
|
| 143 |
+
const tier = Math.random(); // pick one of three lengths
|
| 144 |
+
this.whiskerLen = tier < 1 / 3 ? rand(0.45, 0.6)
|
| 145 |
+
: tier < 2 / 3 ? rand(0.8, 1.0)
|
| 146 |
+
: rand(1.25, 1.5); // in units of size s
|
| 147 |
+
this.whiskPh = rand(0, Math.PI * 2); // per-fish sway phase
|
| 148 |
+
this.whiskerAlpha = rand(0.45, 0.62); // delicate translucency
|
| 149 |
+
} else {
|
| 150 |
+
this.whiskerLen = null;
|
| 151 |
+
}
|
| 152 |
this.phase = rand(0, Math.PI * 2);
|
| 153 |
// v9: after dark, most fish bed down low in the grass β only a small share still
|
| 154 |
// hovers by the seaweed, and each of those keeps to its own stalk (no pile-ups)
|
|
|
|
| 538 |
c.arc(s * 0.61, -s * 0.1, s * 0.055, 0, Math.PI * 2);
|
| 539 |
c.fill();
|
| 540 |
|
| 541 |
+
// v16: whiskers (barbels) β a forward-curving pair from the snout on ~10% of fish,
|
| 542 |
+
// in one of three lengths. Drawn in fish-local space so they track the heading, and
|
| 543 |
+
// swaying gently with an independent phase so they read as soft feelers, not spikes.
|
| 544 |
+
if (this.whiskerLen) {
|
| 545 |
+
const L = this.whiskerLen * s; // chosen length tier at spawn
|
| 546 |
+
const swayW = Math.sin(this.phase * 1.2 + this.whiskPh); // gentle independent sway
|
| 547 |
+
c.save();
|
| 548 |
+
c.lineCap = "round";
|
| 549 |
+
c.strokeStyle = `hsla(${this.hue},55%,82%,${this.whiskerAlpha})`;
|
| 550 |
+
c.lineWidth = Math.max(1, s * 0.045);
|
| 551 |
+
for (const side of [-1, 1]) { // one whisker each side
|
| 552 |
+
const rootX = s * 0.6;
|
| 553 |
+
const rootY = side * s * 0.09; // just off the midline at the snout
|
| 554 |
+
const tipX = rootX + L * (0.85 + 0.12 * Math.sin(this.whiskPh));
|
| 555 |
+
const tipY = rootY + side * L * 0.36 + swayW * s * 0.1;
|
| 556 |
+
const ctrlX = rootX + L * 0.55;
|
| 557 |
+
const ctrlY = rootY - side * L * 0.1 - swayW * s * 0.07;
|
| 558 |
+
c.beginPath();
|
| 559 |
+
c.moveTo(rootX, rootY);
|
| 560 |
+
c.quadraticCurveTo(ctrlX, ctrlY, tipX, tipY);
|
| 561 |
+
c.stroke();
|
| 562 |
+
}
|
| 563 |
+
c.restore();
|
| 564 |
+
}
|
| 565 |
+
|
| 566 |
c.restore();
|
| 567 |
|
| 568 |
// v7: overhead light streak β a soft line of light on whichever edge faces up,
|