Releases: hxtnv/q5-react
v1.3.0
Introducing event listeners
You can now tap into the native q5.js listeners for mouse and keyboard events. Simply provide a third argument to the useCreateCanvas
hook like so:
import Q5Canvas, { useCreateCanvas } from "q5-react";
function MyComponent() {
const myCanvas = useCreateCanvas(
{ myMessage: "Hello, world!" }, // initial state
(p, state) => {
p.background(0);
p.fill(255);
p.ellipse(p.mouseX, p.mouseY, 20, 20);
p.textSize(24);
p.text(state.get().myMessage, 100, 100);
},
{
mousePressed: (button, position) => {
console.log(`Mouse button ${button} pressed at ${position.x}, ${position.y}`);
},
mouseReleased: (button, position) => {
console.log(`Mouse button ${button} released at ${position.x}, ${position.y}`);
},
keyPressed: (key) => {
console.log(`Key "${key}" has been pressed`);
},
keyReleased: (key) => {
console.log(`Key "${key}" has been released`);
},
}
);
return <Q5Canvas canvas={myCanvas} size={500} />;
}
v1.2.0
New Unified API with useCreateCanvas
The biggest change in this release is the introduction of useCreateCanvas, a hook that combines state management and drawing functions into a single, cohesive API:
const myCanvas = useCreateCanvas<MyStateType>(
// initial state
{ count: 0, position: { x: 100, y: 100 } },
// draw function with state access
(p, state, { pressedKeys }) => {
// your drawing code here
p.background(0);
p.ellipse(state.get().position.x, state.get().position.y, 20, 20);
}
);
// use it in your component
<Q5Canvas canvas={myCanvas} size={500} />
React-like State Updates
State updates now support both object updates and function updates (similar to React's useState
):
// object update
state.set({ count: 5 });
// function update (with access to previous state)
state.set(prev => ({ count: prev.count + 1 }));
v1.1.0
This version introduces two new additions.
useCanvasState
This hook allows you to define a type safe state for your canvas to store various information that are needed during the render process, for example player position, player health, game state etc. It can be updated from within the draw
function or anywhere within your React app, such as a websocket event. Here are some examples:
import { useCanvasState } from 'q5-react';
type MyCountStateType = {
count: number;
position: { x: number; y: number };
};
const canvasState = useCanvasState<MyCountStateType>("my-count-state", {
count: 0,
position: { x: 100, y: 100 },
});
// updates can come from anywhere
// in this example we use a timer
useEffect(() => {
const interval = setInterval(
() => canvasState.set({ count: canvasState.get().count + 1 }),
1000
);
return () => clearInterval(interval);
}, []);
To read a value, use canvasState.get()
. This will return the entire canvas state as an object.
createDraw
This function returns a type safe draw function including the state provided to the canvas as well as information about current keys and mouse buttons being pressed to allow for user interaction. It can be defined anywhere, doesn't have to be inside the component where the canvas is being rendered. Example usage:
const draw = createDraw<MyCountStateType>(
(p, state, { pressedKeys, pressedMouseButtons }) => {
p.background(0);
p.fill(255);
for (let i = 0; i < state.count; i++) {
p.ellipse(i * 10 + 5, 50, 10, 10);
}
const text = `Count is: ${state.count}`;
p.textSize(24);
p.text(text, p.width / 2 - p.textWidth(text) / 2, p.height / 2);
p.ellipse(state.position.x, state.position.y, 20, 20);
if (pressedKeys.has("ArrowLeft")) {
state.position.x -= 3;
}
if (pressedKeys.has("ArrowUp")) {
state.position.y -= 3;
}
if (pressedKeys.has("ArrowRight")) {
state.position.x += 3;
}
if (pressedKeys.has("ArrowDown")) {
state.position.y += 3;
}
if (pressedMouseButtons.has(p.LEFT)) {
state.position.x -= 3;
} else if (pressedMouseButtons.has(p.RIGHT)) {
state.position.x += 3;
}
}
);
// in your component
<Q5Canvas state={canvasState} draw={draw} size={500} />
v1.0.9
This version introduces fullscreen functions exposed when providing a function as a child to the Q5Canvas component. Example usage:
<Q5Canvas draw={draw} size={500}>
{({ toggleFullscreen }) => (
<button onClick={toggleFullscreen}>Toggle fullscreen</button>
)}
</Q5Canvas>