@sveltecraft/p5-svelte
v0.0.2
Published
A Svelte component wrapper for p5.js sketches
Downloads
27
Readme
@sveltecraft/p5-svelte
A Svelte component wrapper for p5.js sketches.
Installation
⚠️ Warning p5.js 2.0+ has a slightly different API than older versions. In the new version, asset preloading is done in
setupinstead of thepreloadfunction.
npm i @sveltecraft/p5-svelte p5Global Mode
If you want to copy-paste standard p5.js examples without the p. prefix, use the p5 attachment function with Svelte's {@attach} directive:
<script>
import { p5 } from '@sveltecraft/p5-svelte';
let x = 0;
let y = 0;
let diameter = $state(50);
function setup() {
createCanvas(800, 600);
noStroke();
}
function draw() {
background(10);
x = lerp(x, mouseX, 0.05);
y = lerp(y, mouseY, 0.05);
fill(255);
circle(x, y, diameter);
}
</script>
<div {@attach p5({ setup, draw })}></div>
<label>
diameter
<input type="range" bind:value={diameter} min={10} max={200} />
{diameter}
</label>The p5() function runs p5 in its native global mode — all p5 methods (createCanvas, background, fill, …) and properties (mouseX, mouseY, width, height, …) are available as globals. The attachment lifecycle is managed automatically by Svelte (mounts with the element, cleans up on unmount).
TypeScript: p5 global functions are injected at runtime, so your editor may report them as unknown. Install
@types/p5and add/// <reference types="@types/p5/global" />to your entry point for full type support.
Instance Mode
Import the P5Sketch component and the optional Sketch type. After that create a sketch function with a setup and draw function. Since we're using instance mode we have to prefix any p5 method with p which we receive as an argument:
<script lang="ts">
import P5Sketch, { type Sketch } from '@sveltecraft/p5-svelte';
let x = 0;
let y = 0;
let diameter = $state(50);
const sketch: Sketch = (p) => {
p.setup = () => {
p.createCanvas(800, 600);
p.noStroke();
};
p.draw = () => {
p.background(4);
x = p.lerp(x, p.mouseX, 0.05);
y = p.lerp(y, p.mouseY, 0.05);
p.fill(255);
p.circle(x, y, diameter);
};
};
</script>
<P5Sketch {sketch} />
<label>
diameter
<input type="range" bind:value={diameter} min={10} max={200} />
{diameter}
</label>Multiple Sketches
You can create as many sketches as you want:
<script lang="ts">
import P5Sketch, { type Sketch } from '@sveltecraft/p5-svelte';
const walker: Sketch = (p) => {
// ...
};
const randomNumberDistribution: Sketch = (p) => {
// ...
};
</script>
<!-- walker -->
<P5Sketch sketch={walker} />
<!-- random number distribution -->
<P5Sketch sketch={randomNumberDistribution} />Abstracting Code
If you want to abstract your code into a class or function keep in mind you have to pass the p5 object to it:
<script lang="ts">
import type p5 from 'p5';
class Walker {
p: p5;
x = 0;
y = 0;
constructor(p: p5) {
this.p = p;
this.x = this.p.width / 2;
this.y = this.p.height / 2;
}
show() {
this.p.stroke(255);
this.p.point(this.x, this.y);
}
step() {
let xstep = this.p.random(-1, 1);
let ystep = this.p.random(-1, 1);
this.x += xstep;
this.y += ystep;
}
}
const sketch: Sketch = (p) => {
let walker: Walker;
p.setup = () => {
walker = new Walker(p);
p.createCanvas(400, 400);
p.background(10);
};
p.draw = () => {
walker.step();
walker.show();
};
};
</script>
<P5Sketch {sketch} />Addons
This section shows how to use legacy addons that only work with a global p5 instance and ones that support instance mode. You have to install addons using npm instead of using a CDN.
Legacy Global Mode Addons
Addons like p5.sound work only in global mode, so we have to load them using the addons array before the sketch initializes:
<script lang="ts">
import P5Sketch, { type Sketch } from '@sveltecraft/p5-svelte';
// 🚫 this doesn't work
import 'p5.sound';
// 👍 pass your legacy addons here
const addons = [() => import('p5.sound')];
const sketch: Sketch = (p) => {
let sound: any;
p.setup = async () => {
sound = await (p as any).loadSound('/sfx.mp3');
p.createCanvas(400, 400);
};
p.draw = () => {
p.background(10);
};
p.mousePressed = () => {
sound.play();
};
};
</script>
<!-- pass the addons -->
<P5Sketch {sketch} {addons} />Addons like p5.sound look for window.p5 at load time to extend the library. By passing addons as an array, the component:
- Loads
p5dynamically - Assigns
p5towindow.p5before loading addons - Waits for all addons to load
- Then initializes your sketch
This ensures addons are properly registered before your sketch runs.
Instance Mode Addons
Addons like p5.brush support global and instance mode. You can learn how to use it by reading their docs. Here's an example of using the p5.brush addon:
<script lang="ts">
import P5Sketch, { type Sketch } from '@sveltecraft/p5-svelte';
import * as brush from 'p5.brush';
const sketch: Sketch = (p) => {
brush.instance(p);
p.setup = () => {
p.createCanvas(400, 400, p.WEBGL);
};
p.draw = () => {
// ...
};
};
</script>
<P5Sketch {sketch} />API
P5Sketch Props
sketch(required): A function that receives a p5 instance and definessetupanddrawmethodsaddons(optional): Array of async functions that load p5 addonsstyle(optional): CSS styles to apply to the canvas containerclass(optional): CSS class to apply to the canvas container
p5() Options (Global Mode)
setup(optional): p5 setup function using global p5 methodsdraw(optional): p5 draw function using global p5 methodsaddons(optional): Array of async functions that load p5 addons
