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>
47 lines
1.3 KiB
Svelte
47 lines
1.3 KiB
Svelte
<script lang="ts">
|
|
import type { FxOf } from "../fx";
|
|
import { center } from "./geom";
|
|
|
|
let { fx }: { fx: FxOf<"absorb"> } = $props();
|
|
const uid = $props.id();
|
|
const c = $derived(center(fx.at));
|
|
</script>
|
|
|
|
<defs>
|
|
<linearGradient id={`absorb-shine-${uid}`} x1="0" y1="0" x2="1" y2="1">
|
|
<stop offset="0" stop-color="#fffdf4" />
|
|
<stop offset="0.5" stop-color="#f6f0df" />
|
|
<stop offset="1" stop-color="#d8ccb0" />
|
|
</linearGradient>
|
|
</defs>
|
|
|
|
<circle cx={c.x} cy={c.y} r="14" class="pull" />
|
|
<rect x={c.x - 9} y={c.y - 13} width="18" height="26" rx="2"
|
|
fill={`url(#absorb-shine-${uid})`} class="card"
|
|
style={`transform-origin: ${c.x}px ${c.y}px`} />
|
|
|
|
<style>
|
|
.card {
|
|
stroke: #43331f;
|
|
stroke-width: 1.5;
|
|
animation: swallow 0.65s ease-in forwards;
|
|
}
|
|
.pull {
|
|
transform-box: fill-box;
|
|
transform-origin: center;
|
|
fill: none;
|
|
stroke: rgba(180, 138, 224, 0.6);
|
|
stroke-width: 2;
|
|
stroke-dasharray: 5 6;
|
|
animation: pull-in 0.6s ease-in forwards;
|
|
}
|
|
@keyframes swallow {
|
|
0% { opacity: 0.95; transform: scale(1) rotate(0deg); }
|
|
100% { opacity: 0; transform: scale(0.05) rotate(140deg); }
|
|
}
|
|
@keyframes pull-in {
|
|
0% { opacity: 0.8; transform: scale(1.6) rotate(0deg); }
|
|
100% { opacity: 0; transform: scale(0.2) rotate(-90deg); }
|
|
}
|
|
</style>
|