Files
wizwar6e/packages/web/src/IllusionShimmer.svelte
T
Eric WagonerandClaude Fable 5 9eeb89caca Every edge answers a hover: tooltips for walls, doors, fire, illusions
Only the special door lock states carried titles. Now plain walls ('a
wall'), locked doors, the wall of fire (with its 4-damage warning), the
untested shimmer ('tap to test your eyes'), the known-illusion ghost,
and battle cracks (damage taken so far) all speak on hover. The
firewall's hover target is its bar; the flames stay click-through.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0138A8CjeQRpvzKxuMfz1Bqc
2026-08-18 10:36:41 -04:00

43 lines
1.6 KiB
Svelte

<script lang="ts">
// An UNTESTED illusion wall: the wall renders solid underneath (it is a
// wall to you until your eyes rule) — this is the tell-tale shimmer laid
// over it, and the tap target that offers the belief test.
let { x, y, kind, onclick }: {
x: number; y: number; kind: "V" | "H";
onclick?: () => void;
} = $props();
const CELL = 48;
const x1 = $derived(kind === "V" ? (x + 1) * CELL : x * CELL + 2);
const y1 = $derived(kind === "V" ? y * CELL + 2 : (y + 1) * CELL);
const x2 = $derived(kind === "V" ? (x + 1) * CELL : (x + 1) * CELL - 2);
const y2 = $derived(kind === "V" ? (y + 1) * CELL - 2 : (y + 1) * CELL);
</script>
<line {x1} {y1} {x2} {y2} class="illusion-shimmer" />
{#if onclick}
<line {x1} {y1} {x2} {y2} class="illusion-hit"
role="button" tabindex="-1" aria-label="a shimmering wall — test your eyes"
onclick={(ev) => { ev.stopPropagation(); onclick?.(); }}
onkeydown={() => {}}><title>this wall shimmers oddly — tap to test your eyes</title></line>
{/if}
<style>
.illusion-shimmer {
stroke: #cfc3f0;
stroke-width: 3;
stroke-dasharray: 4 5;
stroke-linecap: round;
pointer-events: none;
animation: shimmer-drift 1.4s linear infinite;
}
.illusion-hit { stroke: transparent; stroke-width: 14; cursor: pointer; }
@keyframes shimmer-drift {
0% { stroke-dashoffset: 0; opacity: 0.9; }
50% { opacity: 0.4; }
100% { stroke-dashoffset: -18; opacity: 0.9; }
}
@media (prefers-reduced-motion: reduce) {
.illusion-shimmer { animation: none; opacity: 0.7; }
}
</style>