_❯Kirby

A hand-built decorative SVG character rendered as a pure-CSS animated illustration — no raster assets, no external library.

SVGillustrationdecorative
Kirby
1import { useState } from "react";
2import { Kirby } from "@/components/misc/kirby/kirby.component";
3import { LabsDemoLayout } from "../../components/labs-experiment-frame/labs-experiment-frame.component";
4import {
5 ControlGroup,
6 ControlPanel,
7 ResetButton,
8 SliderControl,
9} from "../../components/labs-control/labs-control.component";
10import * as styles from "./kirby.demo.css";
11
12const DEFAULT_SCALE = 1;
13const DEFAULT_ROTATION = 0;
14
15export function KirbyDemo() {
16 const [scale, setScale] = useState(DEFAULT_SCALE);
17 const [rotation, setRotation] = useState(DEFAULT_ROTATION);
18
19 const reset = () => {
20 setScale(DEFAULT_SCALE);
21 setRotation(DEFAULT_ROTATION);
22 };
23
24 return (
25 <LabsDemoLayout
26 stage={
27 <div className={styles.stageInner}>
28 <div
29 className={styles.kirbyWrapper}
30 style={{ transform: `scale(${scale}) rotate(${rotation}deg)` }}
31 >
32 <Kirby />
33 </div>
34 </div>
35 }
36 controls={
37 <ControlPanel>
38 <ControlGroup title="Scale">
39 <SliderControl
40 label="Size"
41 value={scale}
42 min={0.5}
43 max={4}
44 step={0.1}
45 onChange={setScale}
46 format={(v) => `${v.toFixed(1)}x`}
47 />
48 </ControlGroup>
49
50 <ControlGroup title="Rotation">
51 <SliderControl
52 label="Angle"
53 value={rotation}
54 min={-180}
55 max={180}
56 onChange={setRotation}
57 format={(v) => `${v}°`}
58 />
59 </ControlGroup>
60
61 <ResetButton onReset={reset} />
62 </ControlPanel>
63 }
64 />
65 );
66}