Eric's fireball lands as the house style — layered construction, gradient core, glow halo, a directional tail riding rotate="auto" — with its defs scoped per instance via $props.id(), so simultaneous fireballs cannot steal each other's gradients. The rest of the catalog is rebuilt in its image: the waterbolt becomes its cold sibling (spray tail, no turbulence — one heavy filter stack is enough); lightning grows a glowing core and branching forks; the burst blooms through a fire gradient with a shockwave and flying embers; the splash throws a crown of droplets; the shield raises a gradient dome with a rim strike; the pow star flashes white and radiates speed dashes; claws leave tapered gashes; the absorbed card spirals in along a pull ring; the soul is a proper little ghost with eyes, swaying as it rises; fireworks ride colored trails; Chaos catches card slips in its vortex; the pit opens a gradient hole that swallows a faller; ooze splats and flings blobs; the thornbush sheds leaves; slime closes over and pops bubbles; masonry dust goes soft with falling grit. Whiff, tacks, portal, and the sector ghosts keep their simpler forms on purpose — restraint is part of the style. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
64 lines
1.9 KiB
Svelte
64 lines
1.9 KiB
Svelte
<script lang="ts">
|
|
import type { FxOf } from "../fx";
|
|
import { center } from "./geom";
|
|
|
|
let { fx }: { fx: FxOf<"pow"> } = $props();
|
|
const uid = $props.id();
|
|
const c = $derived(center(fx.at));
|
|
const DASHES = [20, 95, 160, 250, 320];
|
|
</script>
|
|
|
|
<defs>
|
|
<radialGradient id={`pow-star-${uid}`}>
|
|
<stop offset="0" stop-color="#fffdf0" />
|
|
<stop offset="0.45" stop-color="#ffe94d" />
|
|
<stop offset="1" stop-color="#ffb02e" />
|
|
</radialGradient>
|
|
</defs>
|
|
|
|
<g class="pow" style={`transform-origin: ${c.x}px ${c.y}px`}>
|
|
<path
|
|
d={`M ${c.x} ${c.y - 14} l 4 8 9 -4 -4 9 8 5 -9 3 2 10 -8 -6 -6 8 -1 -10 -10 1 7 -7 -7 -7 10 0 1 -9 6 8 z`}
|
|
fill={`url(#pow-star-${uid})`}
|
|
/>
|
|
<circle cx={c.x} cy={c.y} r="4" class="flash" />
|
|
</g>
|
|
{#each DASHES as deg (deg)}
|
|
<line
|
|
x1={c.x + 16 * Math.cos((deg * Math.PI) / 180)}
|
|
y1={c.y + 16 * Math.sin((deg * Math.PI) / 180)}
|
|
x2={c.x + 24 * Math.cos((deg * Math.PI) / 180)}
|
|
y2={c.y + 24 * Math.sin((deg * Math.PI) / 180)}
|
|
class="dash"
|
|
style={`transform-origin: ${c.x}px ${c.y}px`}
|
|
/>
|
|
{/each}
|
|
|
|
<style>
|
|
.pow path { stroke: #b3372b; stroke-width: 1.6; }
|
|
.pow .flash { fill: #ffffff; animation: flash 0.3s ease-out forwards; }
|
|
.pow { animation: pow-hit 0.5s ease-out forwards; }
|
|
.dash {
|
|
stroke: #b3372b;
|
|
stroke-width: 2.5;
|
|
stroke-linecap: round;
|
|
animation: dash-out 0.4s ease-out 0.06s forwards;
|
|
opacity: 0;
|
|
}
|
|
@keyframes pow-hit {
|
|
0% { opacity: 0; transform: scale(0.3) rotate(-15deg); }
|
|
25% { opacity: 1; transform: scale(1.25) rotate(5deg); }
|
|
55% { transform: scale(1) rotate(0deg); }
|
|
100% { opacity: 0; transform: scale(1.05); }
|
|
}
|
|
@keyframes flash {
|
|
0% { opacity: 1; transform: scale(1); }
|
|
100% { opacity: 0; transform: scale(3); }
|
|
}
|
|
@keyframes dash-out {
|
|
0% { opacity: 0; transform: scale(0.7); }
|
|
30% { opacity: 0.9; }
|
|
100% { opacity: 0; transform: scale(1.3); }
|
|
}
|
|
</style>
|