Layer
The Layer
component encapsulates a piece of your canvas rendering logic. Every layer re-renders when the dependencies of any layer’s render function change.
<script>
import { text } from './store';
// When the value of the `text` store changes, it triggers a render
// of the current layer as well as all other layers on the canvas.
const render = ({ context }) => context.fillText($text, 10, 10);
</script>
<Layer {render} />
Render functions are called in the order the layers are defined, so each layer will appear visually on top of the layers that precede it.
Props
render
A function that receives a props
object with the following properties:
render: (props: {
context: CanvasRenderingContext2D;
width: number;
height: number;
time: number;
}): void;
<!-- Render the time since initialization, centered on the canvas. -->
<Layer render={({ context, width, height, time }) => {
context.fillText(time, width / 2, height / 2);
}} />
setup
The setup
function has the same signature as render
but is only called once when the layer is initialized.
setup: (props: {
context: CanvasRenderingContext2D;
width: number;
height: number;
time: number;
}): void;
Event handling
When the layerEvents
prop on the parent Canvas
component is true
, individual Layer
instances can handle events that fall within the pixels they have rendered on the canvas. Event handlers receive a LayerEvent
with properties x
and y
representing the coordinates of the event relative to the parent canvas, as well as originalEvent
, which contains the original DOM event from the canvas
element.
<script>
import { Canvas, Layer } from 'svelte-canvas';
</script>
Â
<Canvas layerEvents>
<Layer onclick={(e) => console.log(e.x, e.y) />
</Canvas>
Layer
supports the following event types:
'click' | 'contextmenu' | 'dblclick' | 'auxclick' | 'mousedown' | 'mouseenter' | 'mouseleave' | 'mousemove' | 'mouseup' | 'wheel' | 'touchcancel' | 'touchend' | 'touchmove' | 'touchstart' | 'pointerenter' | 'pointerleave' | 'pointerdown' | 'pointermove' | 'pointerup' | 'pointercancel'
Under the hood, svelte-canvas
proxies all CanvasRenderingContext2D
methods to a second, offscreen canvas, using a unique fill and stroke color to identify each layer. When an event occurs on the main canvas, the color of the pixel at the event coordinates is read from the offscreen canvas and used to identify the corresponding layer. The event is then re-dispatched to the Layer
component.
Touch events
By default, svelte-canvas
does not call preventDefault
on layer touch events. To prevent touchmove
events from scrolling the page, call e.originalEvent.preventDefault()
in your layer event handler. Alternatively, you can style the parent canvas with touch-action: none
.
Types
Render
The Render
interface is used to type your setup and render functions.
interface Render {
(props: {
context: CanvasRenderingContext2D;
width: number;
height: number;
time: number;
}): void;
}
<script>
import { Layer, type Render } from 'svelte-canvas';
const render: Render = ({ context }) => { ... };
</script>
Â
<Layer {render} />
LayerEvent
The LayerEvent
type is used to type event objects received by layer event handlers.
type LayerEvent = {
x: number;
y: number;
originalEvent: MouseEvent | TouchEvent;
}
<script>
import { Layer, type LayerEvent } from 'svelte-canvas';
const handleClick = (e: LayerEvent) => {
console.log(e.x, e.y);
};
</script>
Â
<Layer onclick={handleClick} />