Skip to content

Commit

Permalink
feat: add useLoop hook with play/pause controls
Browse files Browse the repository at this point in the history
  • Loading branch information
jsulpis committed Nov 1, 2024
1 parent 67517c8 commit f3e2cf3
Show file tree
Hide file tree
Showing 44 changed files with 663 additions and 174 deletions.
10 changes: 10 additions & 0 deletions lib/.gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,13 @@ tests/__screenshots__/particles/particles-chromium.png filter=lfs diff=lfs merge
tests/__screenshots__/particles/particles-firefox.png filter=lfs diff=lfs merge=lfs -text
tests/__screenshots__/particles/particles-iphone.png filter=lfs diff=lfs merge=lfs -text
tests/__screenshots__/pointer/pointer-chromium.png filter=lfs diff=lfs merge=lfs -text
tests/__screenshots__/play-pause-controls---global/play-pause-controls---global-android.png filter=lfs diff=lfs merge=lfs -text
tests/__screenshots__/play-pause-controls---global/play-pause-controls---global-firefox.png filter=lfs diff=lfs merge=lfs -text
tests/__screenshots__/play-pause-controls---global/play-pause-controls---global-iphone.png filter=lfs diff=lfs merge=lfs -text
tests/__screenshots__/play-pause-controls---global/play-pause-controls---global-safari.png filter=lfs diff=lfs merge=lfs -text
tests/__screenshots__/play-pause-controls---local/play-pause-controls---local-chromium.png filter=lfs diff=lfs merge=lfs -text
tests/__screenshots__/play-pause-controls---local/play-pause-controls---local-firefox.png filter=lfs diff=lfs merge=lfs -text
tests/__screenshots__/play-pause-controls---local/play-pause-controls---local-iphone.png filter=lfs diff=lfs merge=lfs -text
tests/__screenshots__/play-pause-controls---local/play-pause-controls---local-safari.png filter=lfs diff=lfs merge=lfs -text
tests/__screenshots__/play-pause-controls---global/play-pause-controls---global-chromium.png filter=lfs diff=lfs merge=lfs -text
tests/__screenshots__/play-pause-controls---local/play-pause-controls---local-android.png filter=lfs diff=lfs merge=lfs -text
5 changes: 3 additions & 2 deletions lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@
"prepack": "pnpm build",
"release": "changelogen --release --clean",
"test": "playwright test",
"test:local": "docker build -t usegl . && docker run --rm -v $(pwd)/test-results:/app/test-results usegl /bin/sh -c 'xvfb-run pnpm run test'",
"test:ui": "playwright test --ui",
"typecheck": "tsc --noEmit && astro check",
"updateScreenshots": "docker build -t usegl . && docker run --rm -v $(pwd)/test-results:/app/test-results -v $(pwd)/tests/__screenshots__:/app/tests/__screenshots__ usegl"
"test:update": "docker build -t usegl . && docker run --rm -v $(pwd)/test-results:/app/test-results -v $(pwd)/tests/__screenshots__:/app/tests/__screenshots__ usegl",
"typecheck": "tsc --noEmit && astro check"
},
"devDependencies": {
"@astrojs/check": "0.9.4",
Expand Down
25 changes: 25 additions & 0 deletions lib/playground/src/components/GlobalPlayPause.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
import PlayPause from "./PlayPause.astro";
---

<script>
import { pauseAllLoops, playAllLoops } from "usegl";

document.querySelector("[title=Play]").addEventListener("click", (event) => {
if ((event.currentTarget as HTMLElement).ariaChecked === "true") {
playAllLoops();
} else {
pauseAllLoops();
}
});
</script>

<PlayPause />

<style is:global>
button {
position: absolute;
bottom: 0.9rem;
left: 0.9rem;
}
</style>
73 changes: 73 additions & 0 deletions lib/playground/src/components/PlayPause.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<button
type="button"
title="Play"
role="switch"
aria-checked="false"
onclick="this.title=this.title==='Play' ? 'Pause' : 'Play';this.ariaChecked=this.ariaChecked==='false'"
>
<svg class="playsvg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512">
<!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
<path
fill="currentColor"
d="M73 39c-14.8-9.1-33.4-9.4-48.5-.9S0 62.6 0 80L0 432c0 17.4 9.4 33.4 24.5 41.9s33.7 8.1 48.5-.9L361 297c14.3-8.7 23-24.2 23-41s-8.7-32.2-23-41L73 39z"
>
</path>
</svg>
<svg class="pausesvg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
<path
fill="currentColor"
d="M48 64C21.5 64 0 85.5 0 112L0 400c0 26.5 21.5 48 48 48l32 0c26.5 0 48-21.5 48-48l0-288c0-26.5-21.5-48-48-48L48 64zm192 0c-26.5 0-48 21.5-48 48l0 288c0 26.5 21.5 48 48 48l32 0c26.5 0 48-21.5 48-48l0-288c0-26.5-21.5-48-48-48l-32 0z"
>
</path>
</svg>
</button>

<style>
button {
display: grid;
grid-template: auto / auto;
place-items: center;

background: transparent;
border: none;
color: white;
cursor: pointer;
font-size: min(1em, 2svmin);
padding: 1em;
border-radius: 4px;
transition: background-color 100ms;

&:hover,
&:focus-visible {
background: hsla(0, 0%, 100%, 0.1);
}

&:active {
background: hsla(0, 0%, 100%, 0.15);
}

&[aria-checked="true"] {
.playsvg {
display: none;
}
.pausesvg {
display: block;
}
}

&[aria-checked="false"] {
.playsvg {
display: block;
}
.pausesvg {
display: none;
}
}
}

svg {
width: 3em;
aspect-ratio: 1;
}
</style>
4 changes: 2 additions & 2 deletions lib/playground/src/components/RenderCount.astro
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#renders {
color: white;
position: absolute;
bottom: 1.5em;
right: 1.5em;
bottom: 1.5rem;
right: 1.5rem;
}
</style>
1 change: 1 addition & 0 deletions lib/playground/src/layouts/Layout.astro
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import RenderCount from "../components/RenderCount.astro";
grid-template-columns: auto 1fr;
font-family: Verdana, Geneva, Tahoma, sans-serif;
background: black;
color: white;
color-scheme: dark;
}

Expand Down
23 changes: 14 additions & 9 deletions lib/playground/src/pages/blob.astro
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
---
import GlobalPlayPause from "../components/GlobalPlayPause.astro";
import Layout from "../layouts/Layout.astro";
---

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

Expand All @@ -14,9 +15,9 @@ import Layout from "../layouts/Layout.astro";
fragment,
vertex,
uniforms: {
uTime: 0,
uPointer: [0, 0],
},
immediate: false,
});

const canvasGeometry = getCanvasGeometry(canvas);
Expand All @@ -32,14 +33,17 @@ import Layout from "../layouts/Layout.astro";
},
});

// loop(() => {
// const currentPointerCoord = { x: uniforms.uPointer[0], y: uniforms.uPointer[1] };
useLoop(
() => {
const currentPointerCoord = { x: uniforms.uPointer[0], y: uniforms.uPointer[1] };

// uniforms.uPointer = [
// currentPointerCoord.x + (targetPointer.x - currentPointerCoord.x) * 0.05,
// currentPointerCoord.y + (targetPointer.y - currentPointerCoord.y) * 0.05,
// ];
// });
uniforms.uPointer = [
currentPointerCoord.x + (targetPointer.x - currentPointerCoord.x) * 0.05,
currentPointerCoord.y + (targetPointer.y - currentPointerCoord.y) * 0.05,
];
},
{ immediate: false }
);

function getCanvasGeometry(canvas: HTMLCanvasElement) {
const canvasGeometry = { center: { x: 0, y: 0 }, width: 0, height: 0 };
Expand All @@ -64,5 +68,6 @@ import Layout from "../layouts/Layout.astro";
</script>

<Layout title="Blob">
<GlobalPlayPause />
<canvas></canvas>
</Layout>
108 changes: 54 additions & 54 deletions lib/playground/src/pages/gradient.astro
Original file line number Diff line number Diff line change
@@ -1,36 +1,57 @@
---
import GlobalPlayPause from "../components/GlobalPlayPause.astro";
import Layout from "../layouts/Layout.astro";
---

<script>
import {
loop,
useEffectPass,
useRenderPass,
onCanvasResize,
useWebGLContext,
useCompositor,
useWebGLCanvas,
} from "usegl";
import { incrementRenderCount } from "../components/renderCount";

const redColorPass = useEffectPass({
// const redColorPass = useEffectPass({
// fragment: /* glsl */ `
// uniform sampler2D uTexture;
// uniform float uStrength;
// varying vec2 vUv;

// void main() {
// vec3 color = mix(texture(uTexture, vUv).rgb, texture(uTexture, vUv).rrr, uStrength);
// gl_FragColor = vec4(color, 1.);
// }
// `,
// uniforms: {
// uStrength: 0.0,
// },
// });

const { onAfterRender } = useWebGLCanvas({
canvas: document.querySelector("canvas"),
fragment: /* glsl */ `
uniform sampler2D uTexture;
uniform float uStrength;
varying vec2 vUv;
uniform float uTime;

void main() {
vec3 color = mix(texture(uTexture, vUv).rgb, texture(uTexture, vUv).rrr, uStrength);
gl_FragColor = vec4(color, 1.);
gl_FragColor = vec4(vUv, sin(uTime) / 2. + .5, 1.);
}
`,
uniforms: {
uStrength: 0.0,
},
immediate: false,
// postEffects: [redColorPass],
});

// useWebGLCanvas({
// canvas: document.querySelector("canvas"),
// loop(({ time }) => {
// redColorPass.uniforms.uStrength = Math.sin(time / 500) / 2 + 0.5;
// });

// const canvas = document.querySelector("canvas");
// const { gl, setSize } = useWebGLContext(canvas);

// const renderPass = useRenderPass(gl, {
// fragment: /* glsl */ `
// varying vec2 vUv;
// uniform float uTime;
Expand All @@ -39,63 +60,42 @@ import Layout from "../layouts/Layout.astro";
// gl_FragColor = vec4(vUv, sin(uTime) / 2. + .5, 1.);
// }
// `,
// vertex: /* glsl */ `
// attribute vec3 aPosition;
// varying vec2 vUv;

// void main() {
// vUv = aPosition.xy;
// gl_Position = vec4(2.0 * aPosition - 1.0, 1.0);
// }
// `,
// uniforms: {
// uTime: 0,
// },
// postEffects: [redColorPass],
// });

// loop(({ time }) => {
// redColorPass.uniforms.uStrength = Math.sin(time / 500) / 2 + 0.5;
// attributes: {
// aPosition: {
// data: [-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1],
// size: 2,
// },
// },
// });

const canvas = document.querySelector("canvas");
const { gl, setSize } = useWebGLContext(canvas);

const renderPass = useRenderPass(gl, {
fragment: /* glsl */ `
varying vec2 vUv;
uniform float uTime;

void main() {
gl_FragColor = vec4(vUv, sin(uTime) / 2. + .5, 1.);
}
`,
vertex: /* glsl */ `
attribute vec3 aPosition;
varying vec2 vUv;

void main() {
vUv = aPosition.xy;
gl_Position = vec4(2.0 * aPosition - 1.0, 1.0);
}
`,
uniforms: {
uTime: 0,
},
attributes: {
aPosition: {
data: [-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1],
size: 2,
},
},
});

const compositor = useCompositor(gl, renderPass, [redColorPass]);
// const compositor = useCompositor(gl, renderPass, [redColorPass]);

// loop(({ time }) => {
// redColorPass.uniforms.uStrength = Math.sin(time / 500) / 2 + 0.5;
// compositor.render();
// });

onCanvasResize(canvas, ({ devicePixelSize }) => {
setSize(devicePixelSize.width, devicePixelSize.height);
compositor.render();
});
// onCanvasResize(canvas, ({ devicePixelSize }) => {
// setSize(devicePixelSize.width, devicePixelSize.height);
// compositor.render();
// });

renderPass.onAfterRender(incrementRenderCount);
onAfterRender(incrementRenderCount);
</script>

<Layout title="Gradient">
<GlobalPlayPause />
<canvas></canvas>
</Layout>
Loading

0 comments on commit f3e2cf3

Please sign in to comment.