The board's furniture and the reel's fists, painted as cels
The last of the inked look. Walls carry stone joints and highlights, doors their grain, hinges, and a brass lock plate whose keyhole turns to a cross when jammed; battle scars fracture and branch with the damage; illusion walls drift as tapered wisps with breathing glints; the wall of fire burns in flat three-tone flames on a stepped flicker; warp mouths and destinations are painted curls. Through a wizard's eyes the punch is a three-tone hand with an ink contour and a hand-cut POW, the same on every platform where the emoji glyph was not, and the incoming fist no longer reverses late in its travel. The inked stand-ins for missing conjuration files match. Goldens re-blessed: every board frame, and the web's third ring. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
8dfd0e0c29
commit
34b621b5cb
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
// A standing WALL OF FIRE: board furniture, not a flourish — it burns for
|
||||
// as long as the spell holds, so the animation is pure CSS on a handful
|
||||
// of shapes (no turbulence filters; those are budgeted for one-shot fx).
|
||||
// of flat cel shapes, with a short held-pose flicker.
|
||||
import { holdToPeek } from "./peek";
|
||||
let { x, y, kind, onpeek }: {
|
||||
x: number; y: number; kind: "V" | "H";
|
||||
@@ -10,7 +10,6 @@
|
||||
} = $props();
|
||||
const TIP = "a wall of fire — passing through burns for 4";
|
||||
const { press, release } = holdToPeek(() => onpeek?.(TIP));
|
||||
const uid = $props.id();
|
||||
const CELL = 48;
|
||||
const WALL = 7;
|
||||
const cx = $derived(kind === "V" ? (x + 1) * CELL : x * CELL + CELL / 2);
|
||||
@@ -34,69 +33,56 @@
|
||||
|
||||
<g transform={`translate(${cx} ${cy})`} class="fw">
|
||||
<title>{TIP}</title>
|
||||
<defs>
|
||||
<linearGradient id={`fw-bar-${uid}`} x1="0" y1="1" x2="0" y2="0">
|
||||
<stop offset="0" stop-color="#7c1a14" />
|
||||
<stop offset="0.5" stop-color="#ef3b08" />
|
||||
<stop offset="1" stop-color="#ffad22" />
|
||||
</linearGradient>
|
||||
<linearGradient id={`fw-tongue-${uid}`} x1="0" y1="1" x2="0" y2="0">
|
||||
<stop offset="0" stop-color="#ef3b08" />
|
||||
<stop offset="0.55" stop-color="#ff9d16" />
|
||||
<stop offset="1" stop-color="#fff09a" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<!-- the burning bar itself, seated on the wall line -->
|
||||
{#if kind === "V"}
|
||||
<rect x={-WALL / 2} y={-CELL / 2 - 2} width={WALL} height={CELL + 4} rx="3"
|
||||
fill={`url(#fw-bar-${uid})`} class="fw-bar"
|
||||
fill="#bd3b1b" class="fw-bar"
|
||||
role="img" onpointerdown={press} onpointerup={release} onpointerleave={release} />
|
||||
{:else}
|
||||
<rect x={-CELL / 2 - 2} y={-WALL / 2} width={CELL + 4} height={WALL} rx="3"
|
||||
fill={`url(#fw-bar-${uid})`} class="fw-bar"
|
||||
fill="#bd3b1b" class="fw-bar"
|
||||
role="img" onpointerdown={press} onpointerup={release} onpointerleave={release} />
|
||||
{/if}
|
||||
<!-- tongues of flame, each licking on its own beat -->
|
||||
<!-- Drawn flame poses share the original bases and hit area. -->
|
||||
{#each TONGUES as f (f.t)}
|
||||
<path
|
||||
d={`M ${px(f.t) - 3.4} ${py(f.t) + 1}
|
||||
C ${px(f.t) - 3.6} ${py(f.t) - f.h * 0.45}, ${px(f.t) - 1.4} ${py(f.t) - f.h * 0.7}, ${px(f.t)} ${py(f.t) - f.h}
|
||||
C ${px(f.t) + 1.4} ${py(f.t) - f.h * 0.7}, ${px(f.t) + 3.6} ${py(f.t) - f.h * 0.45}, ${px(f.t) + 3.4} ${py(f.t) + 1} Z`}
|
||||
fill={`url(#fw-tongue-${uid})`}
|
||||
class="fw-tongue"
|
||||
style={`transform-origin: ${px(f.t)}px ${py(f.t) + 1}px; animation-delay: ${f.d}s`}
|
||||
/>
|
||||
<g transform={`translate(${px(f.t)} ${py(f.t)})`} class="fw-art">
|
||||
<g class="fw-tongue" style={`animation-delay: ${-f.d}s`}>
|
||||
<path d={`M -3.5 1 Q -6 ${-f.h*.35} -1.7 ${-f.h*.61} Q 1 ${-f.h*.81} -.5 ${-f.h} Q 5 ${-f.h*.82} 2.5 ${-f.h*.47} Q 6 ${-f.h*.6} 5 ${-f.h*.75} Q 9 ${-f.h*.27} 3.4 1 Z`}
|
||||
fill="#ef681e" stroke="#922e1a" stroke-width="0.65" stroke-linejoin="round" />
|
||||
<path d={`M -1.8 1 Q -3 ${-f.h*.25} 1 ${-f.h*.58} Q .1 ${-f.h*.2} 3 ${-f.h*.34} Q 4 ${-f.h*.12} 1.8 1 Z`} fill="#ffd34e" />
|
||||
<path d={`M -.5 1 Q -1 ${-f.h*.12} 1.2 ${-f.h*.28} L 1.4 1 Z`} fill="#fff09a" />
|
||||
</g>
|
||||
</g>
|
||||
{/each}
|
||||
<!-- embers drifting off the top -->
|
||||
{#each EMBERS as em (em.t)}
|
||||
<circle cx={px(em.t)} cy={py(em.t) - 6} r="1.4" class="fw-ember"
|
||||
style={`animation-delay: ${em.d}s`} />
|
||||
<path d={`M ${px(em.t)} ${py(em.t)-9} q -3 3 -.5 5 q 3 -1 .5 -5 Z`} class="fw-ember"
|
||||
style={`animation-delay: ${-em.d}s`} />
|
||||
{/each}
|
||||
</g>
|
||||
|
||||
<style>
|
||||
.fw-tongue, .fw-ember { pointer-events: none; }
|
||||
.fw-art, .fw-ember { pointer-events: none; }
|
||||
.fw-bar {
|
||||
stroke: #7c1a14;
|
||||
stroke-width: 1;
|
||||
filter: drop-shadow(0 0 3px rgba(255, 140, 30, 0.7));
|
||||
animation: fw-glow 1.3s ease-in-out infinite alternate;
|
||||
animation: fw-coals 1.3s steps(2, end) infinite alternate;
|
||||
}
|
||||
.fw-tongue {
|
||||
animation: fw-lick 0.9s ease-in-out infinite alternate;
|
||||
transform-origin: 0px 1px;
|
||||
animation: fw-lick 0.9s steps(3, end) infinite alternate;
|
||||
}
|
||||
.fw-ember {
|
||||
fill: #ffd166;
|
||||
opacity: 0;
|
||||
animation: fw-rise 2.6s ease-out infinite;
|
||||
}
|
||||
@keyframes fw-glow {
|
||||
from { filter: drop-shadow(0 0 2px rgba(255, 120, 20, 0.5)); }
|
||||
to { filter: drop-shadow(0 0 6px rgba(255, 150, 40, 0.95)); }
|
||||
@keyframes fw-coals {
|
||||
from { fill: #bd3b1b; }
|
||||
to { fill: #d64b1c; }
|
||||
}
|
||||
@keyframes fw-lick {
|
||||
from { transform: scale(0.95, 0.72); opacity: 0.82; }
|
||||
to { transform: scale(1.04, 1.12); opacity: 1; }
|
||||
from { transform: scale(0.95, 0.82) rotate(-4deg); opacity: 1; }
|
||||
to { transform: scale(1.04, 1.08) rotate(3deg); opacity: 1; }
|
||||
}
|
||||
@keyframes fw-rise {
|
||||
0% { opacity: 0; transform: translateY(0); }
|
||||
|
||||
Reference in New Issue
Block a user