# Mounted particle system
Mount a manual burst effect and trigger it with pointer input.

## APIs demonstrated

- [Particles2D](/reference/components/particles-2d/) from `@pibbl/core/particles`
- [useParticleSystem](/reference/hooks/use-particle-system/) from `@pibbl/core/particles`
- [PibblParticleBurstOverrides](/reference/types/particles/) from `@pibbl/core/particles`
- [PibblParticleCommonProps](/reference/types/particles/) from `@pibbl/core/particles`
- [PibblParticleExecution](/reference/types/particles/) from `@pibbl/core/particles`
- [PibblParticleSystem](/reference/types/particles/) from `@pibbl/core/particles`
- [PibblParticleSystemOptions](/reference/types/particles/) from `@pibbl/core/particles`
- [PibblParticleSystemStatus](/reference/types/particles/) from `@pibbl/core/particles`
- [Particles2DProps](/reference/types/particles/) from `@pibbl/core/particles`
- [Particles2DStyle](/reference/types/particles/) from `@pibbl/core/particles`

## Complete example

[Plain source](/minimal/particles/system.tsx). Run as a browser module after the document body exists. TSX uses `jsx: "react-jsx"` and `jsxImportSource: "@pibbl/core"`.

```tsx
import { pibbl } from "@pibbl/core";
import {
  defineParticleEffect2D,
  particleRange,
  Particles2D,
  useParticleSystem,
  type PibblParticleBurstOverrides,
  type PibblParticleCommonProps,
  type PibblParticleExecution,
  type PibblParticleSystem,
  type PibblParticleSystemOptions,
  type PibblParticleSystemStatus,
  type Particles2DProps,
  type Particles2DStyle,
} from "@pibbl/core/particles";

const effect = defineParticleEffect2D({
  emitters: [
    {
      name: "spark",
      capacity: 80,
      emission: [{ type: "rate", particlesPerSecond: 12 }, { type: "manual" }],
      shape: { type: "line", from: [135, 135], to: [185, 135] },
      initial: {
        lifetimeMilliseconds: 1200,
        velocity: [particleRange(-35, 35), particleRange(-95, -45)],
        size: particleRange(4, 7),
        color: "#f97316",
      },
      renderer: { type: "circle" },
    },
  ],
});
const canvas = document.createElement("canvas");
canvas.width = 320;
canvas.height = 220;
document.body.append(canvas);
const output = document.createElement("p");
document.body.append(output);
const burstButton = document.createElement("button");
burstButton.textContent = "Burst";
document.body.append(burstButton);
const burst: PibblParticleBurstOverrides = { count: 20, position: [160, 135] };
let activeSystem: PibblParticleSystem<"spark"> | undefined;
burstButton.addEventListener("click", () => activeSystem?.emit("spark", burst));

function App() {
  const options: PibblParticleSystemOptions = { seed: 7, autoplay: true };
  const system: PibblParticleSystem<"spark"> = useParticleSystem(effect, options);
  activeSystem = system;
  const status: PibblParticleSystemStatus = system.status.get();
  const execution: PibblParticleExecution = system.execution.get();
  const style: Particles2DStyle = { width: 320, height: 220 };
  const common: PibblParticleCommonProps<Record<string, never>> = {
    onEvent: (event) => {
      if (event.type === "burst-accepted" || event.type === "burst-rejected") {
        output.textContent = `Particle event: ${event.type}`;
      }
    },
  };
  const props: Particles2DProps<"spark"> = { system, style, ...common };
  return (
    <Particles2D
      {...props}
      onPointerDown={() => {
        if (status === "paused") system.resume();
        else if (status === "running" && execution !== "unbound") {
          system.emit("spark", burst);
        }
      }}
    />
  );
}

const app = pibbl(canvas, <App />);
window.addEventListener("pagehide", () => app.dispose(), { once: true });

```

## Usage notes

- Press Burst or click the canvas to emit another spread of particles.

## Documentation version

Documentation built with @pibbl/core 0.0.2, revision 272a94a. ALPHA — NOT FOR PRODUCTION USE.
