Skip to content

Commit

Permalink
feat!: change onPointerEvents to usePointerEvents and add more events
Browse files Browse the repository at this point in the history
  • Loading branch information
jsulpis committed Nov 12, 2024
1 parent 8d1851e commit ddeabd9
Show file tree
Hide file tree
Showing 12 changed files with 109 additions and 63 deletions.
11 changes: 5 additions & 6 deletions lib/playground/src/pages/pointer/blob.astro
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Layout from "../../layouts/Layout.astro";
---

<script>
import { onPointerEvents, useLoop, useWebGLCanvas, useBoundingRect } from "usegl";
import { usePointerEvents, useLoop, useWebGLCanvas } from "usegl";
import { fragment, vertex } from "../../shaders/blob";
import { incrementRenderCount } from "../../components/renderCount";

Expand All @@ -20,13 +20,12 @@ import Layout from "../../layouts/Layout.astro";
immediate: false,
});

const { center, rect } = useBoundingRect(canvas);
const targetPointer = { x: 0, y: 0 };

onPointerEvents(canvas, {
move: ({ x, y }) => {
targetPointer.x = (x - center.x) / (rect.width / 2);
targetPointer.y = (center.y - y) / (rect.height / 2);
usePointerEvents(canvas, {
move: ({ pointer, canvasRect, canvasCenter }) => {
targetPointer.x = (pointer.x - canvasCenter.x) / (canvasRect.width / 2);
targetPointer.y = (canvasCenter.y - pointer.y) / (canvasRect.height / 2);
},
leave: () => {
targetPointer.x = targetPointer.y = 0;
Expand Down
26 changes: 16 additions & 10 deletions lib/playground/src/pages/pointer/pointer.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Layout from "../../layouts/Layout.astro";
---

<script>
import { useBoundingRect, onPointerEvents, useWebGLCanvas } from "usegl";
import { usePointerEvents, useWebGLCanvas } from "usegl";
import { incrementRenderCount } from "../../components/renderCount";

const canvas = document.querySelector("canvas");
Expand All @@ -14,29 +14,35 @@ import Layout from "../../layouts/Layout.astro";
varying vec2 vUv;
uniform vec2 uPointerPosition;
uniform vec2 uResolution;
uniform vec3 uCircleColor;

void main() {
vec2 uv = (vUv - .5) * uResolution / min(uResolution.x, uResolution.y);
float dist = distance(uv, uPointerPosition);
float circle = 1. - smoothstep(.099, .101, dist);
gl_FragColor = vec4(vec3(circle), 1.);
float circleMask = 1. - smoothstep(.099, .101, dist);
vec3 circle = mix(vec3(0.), uCircleColor, circleMask);
gl_FragColor = vec4(circle, 1.);
}
`,
uniforms: {
uPointerPosition: [0, 0],
uCircleColor: [1, 1, 1],
},
});

const { rect } = useBoundingRect(canvas);

onPointerEvents(canvas, {
move: ({ clientX, clientY }) => {
const { left, bottom, width, height } = rect;
usePointerEvents(canvas, {
move: ({ pointer, canvasCenter, canvasRect }) => {
uniforms.uPointerPosition = [
(clientX - (left + width / 2)) / Math.min(width, height),
(bottom - height / 2 - clientY) / Math.min(width, height),
(pointer.x - canvasCenter.x) / Math.min(canvasRect.width, canvasRect.height),
(canvasCenter.y - pointer.y) / Math.min(canvasRect.width, canvasRect.height),
];
},
down: () => {
uniforms.uCircleColor = [1, 0, 0];
},
up: () => {
uniforms.uCircleColor = [1, 1, 1];
},
});

onAfterRender(incrementRenderCount);
Expand Down
34 changes: 0 additions & 34 deletions lib/src/helpers/pointer.ts

This file was deleted.

13 changes: 12 additions & 1 deletion lib/src/hooks/useBoundingRect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@ export interface UseBoundingRectOptions {
windowScroll?: boolean;
}

export interface BoundingRect {
width: number;
height: number;
top: number;
right: number;
bottom: number;
left: number;
x: number;
y: number;
}

/**
* Dynamically get the bounding rectangle of an HTML element
*/
Expand All @@ -24,7 +35,7 @@ export function useBoundingRect(target: HTMLElement, options: UseBoundingRectOpt
windowScroll = typeof window !== "undefined",
} = options;

const rect = {
const rect: BoundingRect = {
width: 0,
height: 0,
top: 0,
Expand Down
62 changes: 62 additions & 0 deletions lib/src/hooks/usePointerEvents.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import type { BoundingRect } from "./useBoundingRect";
import { useBoundingRect } from "./useBoundingRect";

type HandlerArgs = {
pointer: {
x: number;
y: number;
};
canvasRect: BoundingRect;
canvasCenter: {
x: number;
y: number;
};
};

type PointerEventsHandlers = {
enter?: ({ pointer, canvasRect, canvasCenter }: HandlerArgs) => void;
move?: ({ pointer, canvasRect, canvasCenter }: HandlerArgs) => void;
leave?: ({ pointer, canvasRect, canvasCenter }: HandlerArgs) => void;
down?: ({ pointer, canvasRect, canvasCenter }: HandlerArgs) => void;
up?: ({ pointer, canvasRect, canvasCenter }: HandlerArgs) => void;
};

/**
* Listen to common pointer events and provide additional infos about the canvas
*/
export function usePointerEvents(canvas: HTMLCanvasElement, handlers: PointerEventsHandlers) {
const { rect: canvasRect, center: canvasCenter } = useBoundingRect(canvas);

const activeHandlers = Object.fromEntries(
Object.entries(handlers)
.filter(([, handler]) => typeof handler === "function")
.map(([handlerName, handlerFunction]) => [
handlerName,
(e: PointerEvent) => {
handlerFunction({
pointer: { x: e.clientX, y: e.clientY },
canvasRect,
canvasCenter,
});
},
]),
);

function listen() {
for (const [event, handler] of Object.entries(activeHandlers)) {
canvas.addEventListener(`pointer${event as keyof PointerEventsHandlers}`, handler, {
passive: true,
});
}
}

function stop() {
for (const [event, handler] of Object.entries(activeHandlers)) {
canvas.removeEventListener(`pointer${event as keyof PointerEventsHandlers}`, handler);
}
}

listen();

return { stop, listen };
}
3 changes: 1 addition & 2 deletions lib/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,4 @@ export { useWebGLContext } from "./hooks/useWebGLContext";
export { useLoop, playAllLoops, pauseAllLoops } from "./hooks/useLoop";
export { useResizeObserver } from "./hooks/useResizeObserver";
export { useBoundingRect } from "./hooks/useBoundingRect";

export { onPointerEvents } from "./helpers/pointer";
export { usePointerEvents } from "./hooks/usePointerEvents";
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions lib/tests/screenshots.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ test("pointer move", async ({ page, viewport, baseURL }) => {
await page.mouse.move((viewport?.width || 0) * 0.5, (viewport?.height || 0) * 0.45);

await expect(page.getByText("Renders: 2")).toBeVisible();

await page.mouse.down();

await page.waitForTimeout(100);

await expect(page.locator("main")).toHaveScreenshot();
Expand Down

0 comments on commit ddeabd9

Please sign in to comment.