Take the cone down and turn it blue

Lower alpha through the whole fill (0.34 -> 0.19 at the strings, falling with
depth) and the core is a LIT BLUE rather than near-white, which is what was
washing it out. The stroked edges come down and turn blue with it.

Worth recording, because it will come up again: the cone's opacity and how well
you can tell above-the-plane from below-the-plane are the same dial. The plane is
flat -- a body above it is drawn clean on top, a body below is seen through it --
so the distinction just IS the cone's alpha. Fainter cone and sharper split pull
against each other; the fainter cone wins and the cut line carries the signal.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Opus 5 committed 2026-08-03 16:04:04 +02:00
1 parent 8f16d085f0
commit b44fcd8465
3 files changed
+14 -6

No files matched your search

+5
View File
@@ -443,6 +443,11 @@ that holds that height all the way out instead of sloping to the ground — that
makes the rest possible. Sloping, it lay flat on the grass across the whole far half, so there was
nothing for it to cut exactly where the crowd stands.
- **The cone's opacity and the over/under read are the SAME dial, and they pull against each other.**
The plane is flat: a body above it is drawn clean on top, a body below is seen THROUGH it — so how
clearly you can tell the two apart just is how opaque the cone is. Oliver asked for a fainter,
bluer cone AND a clearer split; the first wins, and the CUT LINE carries the signal instead. Do not
try to "fix" the split by raising the cone alpha again — that is the thing he asked to come down.
- **The fill is TWO gradients**, matching the reference Oliver sent: a horizontal one across the
width (near-white down the centre line, falling to the weapon's blue at the edges) and a depth one
along the length. Canvas has no 2D gradient, so the wedge is filled in eight slices along its
+1 -1
View File
@@ -179,6 +179,6 @@
</div>
</div>
</div>
<script type="module" src="main.js?v=105"></script>
<script type="module" src="main.js?v=106"></script>
</body>
</html>
+8 -5
View File
@@ -631,13 +631,16 @@ function drawBeamWedge(dirX, dirZ, ox, oy, oz, alpha, from) {
const wa = wAt(ua), wb = wAt(ub), wm = wAt(um);
const a1 = corner(ua, -wa), a2 = corner(ua, wa), b2 = corner(ub, wb), b1 = corner(ub, -wb);
const el = corner(um, -wm), er = corner(um, wm); // the across axis, at this slice's width
const k = (0.34 - 0.24 * um) * alpha; // depth: strongest at the strings
// Lower opacity and BLUER. It was near-white down the core at almost double this alpha, which
// veiled the whole cone evenly — and once everything under it is equally washed out, the split
// stops reading: you cannot tell the part above the plane from the part below.
const k = (0.19 - 0.13 * um) * alpha; // depth: strongest at the strings
const g = ctx.createLinearGradient(el.x, el.y, er.x, er.y);
g.addColorStop(0, `rgba(${r},${g_},${b},${k * 0.55})`); // edge: the weapon's blue
g.addColorStop(0, `rgba(${r},${g_},${b},${k * 0.5})`); // edge: the weapon's blue
g.addColorStop(0.34, `rgba(${r},${g_},${b},${k})`);
g.addColorStop(0.5, `rgba(215,238,255,${k * 1.5})`); // core: near-white, the hot line
g.addColorStop(0.5, `rgba(118,188,255,${k * 1.35})`); // core: a LIT blue, not white
g.addColorStop(0.66, `rgba(${r},${g_},${b},${k})`);
g.addColorStop(1, `rgba(${r},${g_},${b},${k * 0.55})`);
g.addColorStop(1, `rgba(${r},${g_},${b},${k * 0.5})`);
ctx.fillStyle = g;
ctx.beginPath(); ctx.moveTo(a1.x, a1.y); ctx.lineTo(a2.x, a2.y); ctx.lineTo(b2.x, b2.y); ctx.lineTo(b1.x, b1.y);
ctx.closePath(); ctx.fill();
@@ -645,7 +648,7 @@ function drawBeamWedge(dirX, dirZ, ox, oy, oz, alpha, from) {
// ...and the OUTER LINES. The reference reads as a plane because its edges are drawn, not just
// implied by where the fill stops.
const c1 = corner(u0, -w0), c2 = corner(u0, w0), c3 = corner(1, w1), c4 = corner(1, -w1);
ctx.strokeStyle = `rgba(190,225,255,${0.5 * alpha})`;
ctx.strokeStyle = `rgba(120,190,255,${0.45 * alpha})`;
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(c2.x, c2.y); ctx.lineTo(c3.x, c3.y);