|
|
@ -1,27 +1,49 @@
|
|
|
|
import { JSX, Component, createEffect } from "solid-js";
|
|
|
|
import { JSX, Component, createEffect, onCleanup } from "solid-js";
|
|
|
|
import { attachCanvas } from '../index';
|
|
|
|
import { attachCanvas } from '../index';
|
|
|
|
import styles from './PixelPerfectCanvas.module.css';
|
|
|
|
import styles from './PixelPerfectCanvas.module.css';
|
|
|
|
|
|
|
|
|
|
|
|
export type PixelPerfectCanvasProps = {
|
|
|
|
export type PixelPerfectCanvasProps = {
|
|
|
|
style?: JSX.CSSProperties,
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Style to be applied to the container.
|
|
|
|
|
|
|
|
**/
|
|
|
|
|
|
|
|
style?: Omit<JSX.CSSProperties, 'overflow' | 'overflow-x' | 'overflow-y'>,
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Class name(s) to give to the container. Make sure that they do not override the required
|
|
|
|
|
|
|
|
* properties (namely `overflow`)
|
|
|
|
|
|
|
|
**/
|
|
|
|
class?: string,
|
|
|
|
class?: string,
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Fallback text when canvases are not supported,
|
|
|
|
|
|
|
|
**/
|
|
|
|
children?: JSX.Element,
|
|
|
|
children?: JSX.Element,
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Callback called each time the canvas changes dimensions or DPR (devicePixelRatio).
|
|
|
|
|
|
|
|
**/
|
|
|
|
onResize?: (canvas: HTMLCanvasElement, width: number, height: number) => void,
|
|
|
|
onResize?: (canvas: HTMLCanvasElement, width: number, height: number) => void,
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Callback called after the event listeners for dimension and DPR changes are attached.
|
|
|
|
|
|
|
|
**/
|
|
|
|
onAttach?: (canvas: HTMLCanvasElement) => void,
|
|
|
|
onAttach?: (canvas: HTMLCanvasElement) => void,
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Callback called after the event listeners for dimension and DPR changes are detached.
|
|
|
|
|
|
|
|
**/
|
|
|
|
|
|
|
|
onDetach?: (canvas: HTMLCanvasElement) => void,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
|
|
|
|
* A canvas that is wrapped in a container (which will be styled with `style` or `class`),
|
|
|
|
|
|
|
|
* and that will automatically resize when the DPR changes or when the container resizes.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* `onAttach` is called after the canvas is attached (ie. after the event listeners for
|
|
|
|
|
|
|
|
* size change and DPR change are attached) and `onDetach` is called after the canvas is detached.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
|
|
|
|
* `onResize` is called after the canvas changes dimensions or DPR.
|
|
|
|
**/
|
|
|
|
**/
|
|
|
|
export const PixelPerfectCanvas: Component<PixelPerfectCanvasProps> = (props) => {
|
|
|
|
export const PixelPerfectCanvas: Component<PixelPerfectCanvasProps> = (props) => {
|
|
|
|
let canvasRef: HTMLCanvasElement;
|
|
|
|
let canvasRef: HTMLCanvasElement;
|
|
|
|
let containerRef: HTMLDivElement;
|
|
|
|
let containerRef: HTMLDivElement;
|
|
|
|
|
|
|
|
|
|
|
|
createEffect<ReturnType<typeof attachCanvas>>((old) => {
|
|
|
|
createEffect<ReturnType<typeof attachCanvas>>((old) => {
|
|
|
|
if (old) {
|
|
|
|
|
|
|
|
old.unbind();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const result = attachCanvas(canvasRef, {
|
|
|
|
const result = attachCanvas(canvasRef, {
|
|
|
|
container: containerRef,
|
|
|
|
container: containerRef,
|
|
|
|
onResize: props.onResize,
|
|
|
|
onResize: props.onResize,
|
|
|
@ -29,6 +51,11 @@ export const PixelPerfectCanvas: Component<PixelPerfectCanvasProps> = (props) =>
|
|
|
|
|
|
|
|
|
|
|
|
props.onAttach?.(result);
|
|
|
|
props.onAttach?.(result);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
onCleanup(() => {
|
|
|
|
|
|
|
|
result.unbind();
|
|
|
|
|
|
|
|
props.onDetach?.(result);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|