-
Is paused:
+
Is paused:
= width - size ? width - size : x + speed;
}
- if (input.current.includes(" ")) {
+ if (input.current.includes("a")) {
if (!isShooting) {
isShooting = true;
BULLETS.push(Bullet({ x: x, y }, context));
diff --git a/example/app/07-bounce-text.js b/example/app/07-bounce-text.js
index d197895..4759642 100644
--- a/example/app/07-bounce-text.js
+++ b/example/app/07-bounce-text.js
@@ -2,7 +2,7 @@
import { useCanvas } from "@kirkegaard/react-use-canvas";
export function BounceText() {
- const string = "REACT CANVAS";
+ const string = "CANVAS<3";
const size = 42;
const spacing = 4;
const trail = 10;
diff --git a/example/app/globals.css b/example/app/globals.css
index 2ac9881..2a99b1d 100644
--- a/example/app/globals.css
+++ b/example/app/globals.css
@@ -1,4 +1,21 @@
:root {
+ --shadow-color: 0deg 0% 0%;
+ --shadow-elevation-low: 0px 0.1px 0.2px hsl(var(--shadow-color) / 0),
+ 0px 0.1px 0.2px hsl(var(--shadow-color) / 0.05),
+ 0px 0.3px 0.5px hsl(var(--shadow-color) / 0.1);
+ --shadow-elevation-medium: 0px 0.1px 0.2px hsl(var(--shadow-color) / 0),
+ 0px 0.3px 0.5px hsl(var(--shadow-color) / 0.04),
+ 0.1px 0.7px 1.1px hsl(var(--shadow-color) / 0.08),
+ 0.1px 1.4px 2.1px hsl(var(--shadow-color) / 0.12);
+ --shadow-elevation-high: 0px 0.1px 0.2px hsl(var(--shadow-color) / 0),
+ 0.1px 0.6px 0.9px hsl(var(--shadow-color) / 0.02),
+ 0.1px 1.1px 1.7px hsl(var(--shadow-color) / 0.04),
+ 0.1px 1.6px 2.4px hsl(var(--shadow-color) / 0.06),
+ 0.2px 2.2px 3.3px hsl(var(--shadow-color) / 0.07),
+ 0.2px 3.1px 4.7px hsl(var(--shadow-color) / 0.09),
+ 0.3px 4.3px 6.5px hsl(var(--shadow-color) / 0.11),
+ 0.5px 5.9px 8.9px hsl(var(--shadow-color) / 0.13);
+
--max-width: 1100px;
--border-radius: 12px;
--font-mono: ui-monospace, Menlo, Monaco, "Cascadia Mono", "Segoe UI Mono",
@@ -43,7 +60,7 @@
@media (prefers-color-scheme: dark) {
:root {
--foreground-rgb: 255, 255, 255;
- --background-start-rgb: 10, 10, 10;
+ --background-start-rgb: 100, 10, 10;
--background-end-rgb: 0, 0, 0;
--primary-glow: radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0));
@@ -88,12 +105,22 @@ body {
body {
color: rgb(var(--foreground-rgb));
- background: linear-gradient(
- to bottom,
- transparent,
- rgb(var(--background-end-rgb))
- )
- rgb(var(--background-start-rgb));
+
+ background-image: linear-gradient(
+ 45deg,
+ hsl(260deg 100% 2%) 0%,
+ hsl(236deg 45% 5%) 11%,
+ hsl(216deg 50% 7%) 22%,
+ hsl(205deg 67% 8%) 33%,
+ hsl(198deg 91% 8%) 44%,
+ hsl(193deg 100% 8%) 56%,
+ hsl(188deg 100% 9%) 67%,
+ hsl(181deg 100% 9%) 78%,
+ hsl(172deg 100% 10%) 89%,
+ hsl(164deg 100% 11%) 100%
+ );
+
+ padding: 2rem 0.8rem;
display: flex;
justify-content: center;
@@ -105,6 +132,13 @@ h3 {
margin-bottom: 1rem;
}
+h1 {
+ font-size: 3.6rem;
+ background: linear-gradient(90deg, #e21143, #ffb03a);
+ background-clip: text;
+ color: transparent;
+}
+
p {
margin: 1rem 0;
}
@@ -113,9 +147,10 @@ section {
margin-bottom: 2rem;
padding: 1rem;
- background-color: rgba(25, 25, 25, 0.5);
+ background-color: rgba(0, 0, 0, 0.2);
+
+ box-shadow: var(--shadow-elevation-high);
- border: 2px solid rgba(20, 20, 20, 0.5);
border-radius: 1rem;
}
diff --git a/example/app/midi/page.js b/example/app/midi/page.js
deleted file mode 100644
index 79c47ee..0000000
--- a/example/app/midi/page.js
+++ /dev/null
@@ -1,228 +0,0 @@
-"use client";
-
-import { useEffect, useState } from "react";
-import { useMIDI, useMIDINote, useMIDIControl } from "@react-midi/hooks";
-
-import { useWindowSize } from "@uidotdev/usehooks";
-import { useCanvas } from "@kirkegaard/react-use-canvas";
-
-const vs = `#version 300 es
-
-in vec4 position;
-
-void main() {
- gl_Position = position;
-}
-`;
-
-const fs = `#version 300 es
-precision highp float;
-
-out vec4 outColor;
-
-uniform mat4 u_midi01;
-uniform mat4 u_midi02;
-uniform float u_time;
-uniform vec2 u_resolution;
-
-float box2(vec2 p,vec2 b) {
- p = abs(p)-b;
- return length(max(vec2(0.),p))+min(0.,max(p.x,p.y));
-}
-
-vec3 erot(vec3 p, vec3 ax, float t) {
- return mix(dot(ax,p)*ax,p,cos(t))+cross(ax,p)*sin(t);
-}
-
-void main() {
- vec2 uv = (gl_FragCoord.xy - .5 * u_resolution.xy) / u_resolution.y;
-
- vec3 col = vec3(0);
- vec3 p, d = normalize(vec3(uv, .75));
-
- for(float i = 0., e = 0., j = 0.; i++ < 35.0 * u_midi01[2][2];) {
- p = d * j / u_midi01[2][1];
- p.z += 1.0 + u_time / 1. * u_midi01[0][3];
- p.xy -= 3.15;
- p = asin(sin(p / 2.) * .8) * 1.2;
- float sc = .4 * u_midi01[2][0];
-
- for(float j = 0.0; j++ < 6.;) {
- p.xy = abs(p.xy) - .35;
- p.xy *= 1. + u_midi01[0][0];
- p = erot(p, normalize(vec3(
- u_midi01[1][0],
- u_midi01[1][1],
- u_midi01[1][2]
- )), -.785);
- sc *= 1.25;
- }
-
- float h = box2(
- erot(
- p,
- vec3(.0, .0, 1.2),
- floor(1.0 + length(uv * uv) + pow(dot(uv, uv), 1.0) * .5)).xy,
- vec2(.01)
- );
-
- h = min(h, box2(p.xz, vec2(u_midi01[3][0] / 2.)));
- h = min(h, box2(p.yz, vec2(u_midi01[3][1] / 2.)));
- h /= sc;
- j += e = max(.001, h);
-
- col += (.8 + .3 * cos(vec3(.075, 2.1, .16) * i + floor(1. / 10. + length(uv * uv)))) * .1 / exp((.8 + p.z * .01) * i * i * e);
- }
-
- float r = u_midi02[1][0] * (1. + u_midi02[0][0]);
- float g = u_midi02[1][1] * (1. + u_midi02[0][1]);
- float b = u_midi02[1][2] * (1. + u_midi02[0][2]);
- float a = u_midi02[1][3] * (1. + u_midi02[0][3]);
-
- col *= vec3(r, g, b);
-
- outColor = vec4(col, 1.0);
-}
-`;
-
-function compileShader(gl, shaderSource, shaderType) {
- const shader = gl.createShader(shaderType);
- gl.shaderSource(shader, shaderSource);
- gl.compileShader(shader);
-
- const status = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
- if (!status) {
- throw Error(`Could not compile shader: ${gl.getShaderInfoLog(shader)}`);
- }
-
- return shader;
-}
-
-function createProgram(gl, vertexShader, fragmentShader) {
- const program = gl.createProgram();
- gl.attachShader(program, vertexShader);
- gl.attachShader(program, fragmentShader);
-
- gl.linkProgram(program);
-
- const status = gl.getProgramParameter(program, gl.LINK_STATUS);
- if (!status) {
- throw Error(`Program failed to link: ${gl.getProgramInfoLog(program)}`);
- }
-
- return program;
-}
-
-function createUniform(gl, program, type, name) {
- const location = gl.getUniformLocation(program, name);
- return (...values) => {
- gl[`uniform${type}`](location, ...values);
- };
-}
-
-const normalize = (val, min, max) => (val - min) / (max - min);
-
-export default function FullPage() {
- const [midi, setMidi] = useState([
- [
- 0.1889763779527559, 0, 0, 0.007874015748031496, 0.06299212598425197, 0,
- 0.25196850393700787, 0, 0.6535433070866141, 1, 1, 0, 0,
- 0.031496062992125984, 0, 0,
- ],
- [
- 0.8818897637795275, 0.08661417322834646, 0.1889763779527559, 1, 0,
- 0.47244094488188976, 0.5905511811023622, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- ],
- ]);
-
- const { inputs } = useMIDI();
- const { control: value, value: control } = useMIDIControl(inputs[0]);
-
- let uniformTime = null;
- let uniformResolution = null;
-
- let uniformMidi01 = null;
- let uniformMidi02 = null;
-
- const setup = ({ context: gl, width, height }) => {
- const vertexShader = compileShader(gl, vs, gl.VERTEX_SHADER);
- const fragmentShader = compileShader(gl, fs, gl.FRAGMENT_SHADER);
- const program = createProgram(gl, vertexShader, fragmentShader);
-
- const positionAttributeLocation = gl.getAttribLocation(program, "position");
-
- const vao = gl.createVertexArray();
- gl.bindVertexArray(vao);
-
- const positionBuffer = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
-
- gl.bufferData(
- gl.ARRAY_BUFFER,
- new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]),
- gl.STATIC_DRAW
- );
-
- gl.enableVertexAttribArray(positionAttributeLocation);
- gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
- gl.viewport(0, 0, width, height);
-
- uniformTime = createUniform(gl, program, "1f", "u_time");
- uniformResolution = createUniform(gl, program, "2f", "u_resolution");
- uniformMidi01 = createUniform(gl, program, "Matrix4fv", "u_midi01");
- uniformMidi02 = createUniform(gl, program, "Matrix4fv", "u_midi02");
-
- gl.useProgram(program);
-
- gl.bindVertexArray(vao);
- };
-
- const draw = ({ context: gl, time, width, height }) => {
- uniformTime(time);
- uniformResolution(width, height);
- uniformMidi01(false, midi[0]);
- uniformMidi02(false, midi[1]);
- gl.drawArrays(gl.TRIANGLES, 0, 6);
- };
-
- const boards = [
- { start: 32, end: 47 },
- { start: 48, end: 55 },
- ];
-
- useEffect(() => {
- for (const [index, board] of boards.entries()) {
- if (control >= board.start && control <= board.end) {
- const k = Math.round(
- normalize(control, board.start, board.end) * (board.end - board.start)
- );
- const v = normalize(value, 0, 127);
- midi[index][k] = v;
- window.localStorage.setItem("midi", JSON.stringify(midi));
- }
- }
- }, [value]);
-
- useEffect(() => {
- const current = window.localStorage.getItem("midi");
- if (current) {
- setMidi(JSON.parse(current));
- }
- }, []);
-
- const { height, width } = useWindowSize();
- const { ref } = useCanvas({
- setup,
- draw,
- options: {
- height,
- width,
- contextType: "webgl2",
- contextAttributes: {
- antialias: false,
- },
- },
- });
-
- return
;
-}
diff --git a/example/app/page.js b/example/app/page.js
index 97259ca..82c65aa 100644
--- a/example/app/page.js
+++ b/example/app/page.js
@@ -61,15 +61,13 @@ export default function Home() {
WebGL
If you're willing to write a shader pipeline, you can even use it
- to render shaders! Here's one created by{" "}
- kishimisu . I do
- have plans for integrating a proper pipeline in the hook but for now
- you'll have to write your own. Or copy the one from the example
- :)
-
-
- I've also added another example where
- you can use midi controllers to control the shader.
+ to render shaders!{" "}
+
+ Here's an old one from some time ago
+
+ . I do have plans for integrating a proper pipeline in the hook but
+ for now you'll have to write your own. Or copy the one from the
+ examples :)
diff --git a/example/app/page.module.css b/example/app/page.module.css
index 17c3910..695d5e5 100644
--- a/example/app/page.module.css
+++ b/example/app/page.module.css
@@ -1,4 +1,4 @@
.main {
width: 100%;
- max-width: 600px;
+ max-width: 800px;
}
diff --git a/example/package.json b/example/package.json
index 517d345..ad76460 100644
--- a/example/package.json
+++ b/example/package.json
@@ -10,7 +10,6 @@
},
"dependencies": {
"@kirkegaard/react-use-canvas": "^0.1.3",
- "@react-midi/hooks": "^2.0.1",
"@uidotdev/usehooks": "^2.4.1",
"next": "14.1.3",
"react": "^18",
diff --git a/src/index.js b/src/index.js
index 1d81287..48a7b06 100644
--- a/src/index.js
+++ b/src/index.js
@@ -80,6 +80,10 @@ export const useCanvas = ({ setup, draw, options = {} }) => {
setup({ context, height, width });
}
render();
+ } else {
+ throw Error(
+ `Unable to get context of type "${contextType}". Is webgl enabled?`
+ );
}
}