Eric repainted the maze. The first-person materials are painterly sandstone, flagstone, and iron; the hand-drawn token set is redrawn with matching chests and hats; the standing conjurations — hedges, jello, dust, safe, warp light — and the effect billboards are redone in the same hand; and the board's flourishes trade their filters and gradients for flat cel silhouettes cut from five shared shapes, which read better against the counters and cost a phone nothing. Thirty scene goldens re-blessed against the new walls. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
66 lines
1.8 KiB
Svelte
66 lines
1.8 KiB
Svelte
<script lang="ts">
|
|
import type { FxOf } from "../fx";
|
|
import { center, impact } from "./geom";
|
|
let { fx }: { fx: FxOf<"hit"> } = $props();
|
|
const c = $derived(center(fx.at));
|
|
const DEBRIS = [40, 165, 285];
|
|
</script>
|
|
|
|
<!-- Contact flash: an instant of white -->
|
|
<path
|
|
d={impact(c.x,c.y,13)}
|
|
class="flash" style={`transform-origin: ${c.x}px ${c.y}px`}
|
|
/>
|
|
<!-- Compressed impact ring: squashed, then out -->
|
|
<path d={impact(c.x,c.y,12)} class="ring" />
|
|
{#each DEBRIS as deg, i (deg)}
|
|
<line
|
|
x1={c.x + 8 * Math.cos((deg * Math.PI) / 180)}
|
|
y1={c.y + 8 * Math.sin((deg * Math.PI) / 180)}
|
|
x2={c.x + 13 * Math.cos((deg * Math.PI) / 180)}
|
|
y2={c.y + 13 * Math.sin((deg * Math.PI) / 180)}
|
|
class={`debris d${i}`}
|
|
style={`transform-origin: ${c.x}px ${c.y}px`}
|
|
/>
|
|
{/each}
|
|
|
|
<style>
|
|
.flash {
|
|
fill: #fffdf0;
|
|
stroke: #c0392b;
|
|
stroke-width: 1;
|
|
animation: flash-snap 0.28s ease-out forwards;
|
|
}
|
|
.ring {
|
|
transform-box: fill-box;
|
|
transform-origin: center;
|
|
fill: none;
|
|
stroke: #c0392b;
|
|
stroke-width: 2;
|
|
animation: ring-punch 0.4s cubic-bezier(0.2, 0.9, 0.3, 1) forwards;
|
|
}
|
|
.debris {
|
|
stroke: #7c221a;
|
|
stroke-width: 2;
|
|
stroke-linecap: round;
|
|
opacity: 0;
|
|
animation: debris-fly 0.35s ease-out 0.05s forwards;
|
|
}
|
|
.debris.d1 { animation-delay: 0.08s; }
|
|
.debris.d2 { animation-delay: 0.11s; }
|
|
@keyframes flash-snap {
|
|
0% { opacity: 1; transform: scale(0.4); }
|
|
35% { opacity: 1; transform: scale(1.25); }
|
|
100% { opacity: 0; transform: scale(0.9); }
|
|
}
|
|
@keyframes ring-punch {
|
|
0% { opacity: 0.95; transform: scale(0.5, 0.35); }
|
|
45% { opacity: 0.9; transform: scale(1.6, 1.3); }
|
|
100% { opacity: 0; transform: scale(2.2, 1.9); }
|
|
}
|
|
@keyframes debris-fly {
|
|
0% { opacity: 0.9; transform: scale(0.8); }
|
|
100% { opacity: 0; transform: scale(1.7); }
|
|
}
|
|
</style>
|