A free and open-source JavaScript library for accessible creative coding
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Complete event system for mouse, keyboard, touch, and device motion interactions with both event callback functions and real-time input polling for responsive interactive applications.
Mouse interaction handling with position tracking and button state management.
/**
* Current mouse X coordinate relative to canvas
* @type {number}
*/
var mouseX;
/**
* Current mouse Y coordinate relative to canvas
* @type {number}
*/
var mouseY;
/**
* Previous mouse X coordinate from last frame
* @type {number}
*/
var pmouseX;
/**
* Previous mouse Y coordinate from last frame
* @type {number}
*/
var pmouseY;
/**
* Mouse X coordinate relative to browser window
* @type {number}
*/
var winMouseX;
/**
* Mouse Y coordinate relative to browser window
* @type {number}
*/
var winMouseY;
/**
* Previous window mouse X coordinate
* @type {number}
*/
var pwinMouseX;
/**
* Previous window mouse Y coordinate
* @type {number}
*/
var pwinMouseY;
/**
* Currently pressed mouse button (LEFT, RIGHT, CENTER)
* @type {string}
*/
var mouseButton;
/**
* Whether any mouse button is currently pressed
* @type {boolean}
*/
var mouseIsPressed;
/**
* Called when a mouse button is pressed
* Override this function to handle mouse press events
* @param {MouseEvent} [event] - Mouse event object
*/
function mousePressed(event) {}
/**
* Called when a mouse button is released
* Override this function to handle mouse release events
* @param {MouseEvent} [event] - Mouse event object
*/
function mouseReleased(event) {}
/**
* Called when mouse moves with no buttons pressed
* Override this function to handle mouse movement
* @param {MouseEvent} [event] - Mouse event object
*/
function mouseMoved(event) {}
/**
* Called when mouse moves with button pressed (dragging)
* Override this function to handle mouse dragging
* @param {MouseEvent} [event] - Mouse event object
*/
function mouseDragged(event) {}
/**
* Called when mouse is clicked (press and release)
* Override this function to handle mouse clicks
* @param {MouseEvent} [event] - Mouse event object
*/
function mouseClicked(event) {}
/**
* Called when mouse is double-clicked
* Override this function to handle double-clicks
* @param {MouseEvent} [event] - Mouse event object
*/
function doubleClicked(event) {}
/**
* Called when mouse wheel is scrolled
* Override this function to handle scroll events
* @param {WheelEvent} event - Wheel event object with delta information
*/
function mouseWheel(event) {}Keyboard input handling with key state tracking and event callbacks.
/**
* Most recently pressed key as a string
* Special keys return descriptive names (e.g., 'ArrowUp')
* @type {string}
*/
var key;
/**
* Numeric code of the most recently pressed key
* @type {number}
*/
var keyCode;
/**
* Whether any key is currently pressed
* @type {boolean}
*/
var keyIsPressed;
/**
* Check if a specific key is currently being held down
* @param {number} code - Key code to check
* @returns {boolean} True if key is currently pressed
*/
function keyIsDown(code);
/**
* Called when a key is pressed down
* Override this function to handle key press events
* @param {KeyboardEvent} [event] - Keyboard event object
*/
function keyPressed(event) {}
/**
* Called when a key is released
* Override this function to handle key release events
* @param {KeyboardEvent} [event] - Keyboard event object
*/
function keyReleased(event) {}
/**
* Called when a key is typed (excludes special keys)
* Override this function to handle character input
* @param {KeyboardEvent} [event] - Keyboard event object
*/
function keyTyped(event) {}Multi-touch support for mobile and touch-enabled devices.
/**
* Array of current touch points, each with x, y, and id properties
* @type {Touch[]}
*/
var touches;
/**
* Called when a touch begins
* Override this function to handle touch start events
* @param {TouchEvent} [event] - Touch event object
*/
function touchStarted(event) {}
/**
* Called when a touch point moves
* Override this function to handle touch movement
* @param {TouchEvent} [event] - Touch event object
*/
function touchMoved(event) {}
/**
* Called when a touch ends
* Override this function to handle touch end events
* @param {TouchEvent} [event] - Touch event object
*/
function touchEnded(event) {}Device sensor input for mobile devices with accelerometer and gyroscope.
/**
* Device acceleration along X-axis (excluding gravity)
* @type {number}
*/
var accelerationX;
/**
* Device acceleration along Y-axis (excluding gravity)
* @type {number}
*/
var accelerationY;
/**
* Device acceleration along Z-axis (excluding gravity)
* @type {number}
*/
var accelerationZ;
/**
* Previous frame's X acceleration
* @type {number}
*/
var pAccelerationX;
/**
* Previous frame's Y acceleration
* @type {number}
*/
var pAccelerationY;
/**
* Previous frame's Z acceleration
* @type {number}
*/
var pAccelerationZ;
/**
* Device rotation around X-axis (pitch)
* @type {number}
*/
var rotationX;
/**
* Device rotation around Y-axis (roll)
* @type {number}
*/
var rotationY;
/**
* Device rotation around Z-axis (yaw)
* @type {number}
*/
var rotationZ;
/**
* Previous frame's X rotation
* @type {number}
*/
var pRotationX;
/**
* Previous frame's Y rotation
* @type {number}
*/
var pRotationY;
/**
* Previous frame's Z rotation
* @type {number}
*/
var pRotationZ;
/**
* Called when device is moved
* Override this function to handle device motion
*/
function deviceMoved() {}
/**
* Called when device orientation changes
* Override this function to handle device rotation
*/
function deviceTurned() {}
/**
* Called when device is shaken
* Override this function to handle shake gestures
*/
function deviceShaken() {}// Mouse button constants
const LEFT = 'left';
const RIGHT = 'right';
const CENTER = 'center';
// Key code constants for special keys
const BACKSPACE = 8;
const DELETE = 46;
const ENTER = 13;
const RETURN = 13;
const TAB = 9;
const ESCAPE = 27;
const SHIFT = 16;
const CONTROL = 17;
const OPTION = 18;
const ALT = 18;
const UP_ARROW = 38;
const DOWN_ARROW = 40;
const LEFT_ARROW = 37;
const RIGHT_ARROW = 39;Basic Mouse Interaction:
let circles = [];
function setup() {
createCanvas(400, 300);
}
function draw() {
background(220);
// Draw all circles
fill('blue');
for (let circle of circles) {
ellipse(circle.x, circle.y, circle.size);
}
// Show current mouse position
fill('red');
ellipse(mouseX, mouseY, 20);
// Show mouse trail
stroke('gray');
line(pmouseX, pmouseY, mouseX, mouseY);
}
function mousePressed() {
// Add circle where mouse was clicked
circles.push({
x: mouseX,
y: mouseY,
size: random(20, 60)
});
}
function doubleClicked() {
// Clear all circles on double-click
circles = [];
}Keyboard Input Handling:
let message = '';
let boxX = 200;
let boxY = 150;
function setup() {
createCanvas(400, 300);
}
function draw() {
background(220);
// Move box with arrow keys
if (keyIsPressed) {
if (keyCode === UP_ARROW) boxY -= 2;
if (keyCode === DOWN_ARROW) boxY += 2;
if (keyCode === LEFT_ARROW) boxX -= 2;
if (keyCode === RIGHT_ARROW) boxX += 2;
}
// Draw moveable box
fill('blue');
rect(boxX - 25, boxY - 25, 50, 50);
// Display typed message
fill('black');
textSize(16);
text('Type something: ' + message, 20, 30);
text('Use arrow keys to move box', 20, 50);
}
function keyPressed() {
if (keyCode === BACKSPACE) {
// Remove last character
message = message.substring(0, message.length - 1);
} else if (keyCode === ENTER) {
// Clear message on enter
message = '';
}
}
function keyTyped() {
// Add typed character to message
if (key !== BACKSPACE && key !== ENTER) {
message += key;
}
}Multi-touch Drawing:
let trails = {};
function setup() {
createCanvas(400, 300);
background(220);
}
function draw() {
// Fade background slightly
fill(220, 20);
noStroke();
rect(0, 0, width, height);
// Draw current touch points
for (let touch of touches) {
fill('red');
circle(touch.x, touch.y, 40);
// Draw trail for this touch
if (trails[touch.id]) {
stroke('blue');
strokeWeight(3);
let trail = trails[touch.id];
for (let i = 1; i < trail.length; i++) {
line(trail[i-1].x, trail[i-1].y, trail[i].x, trail[i].y);
}
}
}
}
function touchStarted() {
// Start a new trail for each touch
for (let touch of touches) {
trails[touch.id] = [{x: touch.x, y: touch.y}];
}
return false; // Prevent default
}
function touchMoved() {
// Add to trails
for (let touch of touches) {
if (trails[touch.id]) {
trails[touch.id].push({x: touch.x, y: touch.y});
// Limit trail length
if (trails[touch.id].length > 20) {
trails[touch.id].shift();
}
}
}
return false; // Prevent default
}
function touchEnded() {
// Clean up ended touches
let activeTouchIds = touches.map(t => t.id);
for (let id in trails) {
if (!activeTouchIds.includes(parseInt(id))) {
delete trails[id];
}
}
}Device Motion Visualization:
let history = [];
function setup() {
createCanvas(400, 300);
}
function draw() {
background(220);
// Add current acceleration to history
if (accelerationX !== undefined) {
history.push({
x: accelerationX,
y: accelerationY,
z: accelerationZ
});
// Limit history length
if (history.length > 100) {
history.shift();
}
}
// Draw acceleration history as lines
if (history.length > 1) {
stroke('red');
strokeWeight(2);
for (let i = 1; i < history.length; i++) {
let x1 = map(i - 1, 0, history.length - 1, 50, width - 50);
let y1 = map(history[i-1].x, -10, 10, height - 50, 50);
let x2 = map(i, 0, history.length - 1, 50, width - 50);
let y2 = map(history[i].x, -10, 10, height - 50, 50);
line(x1, y1, x2, y2);
}
stroke('green');
for (let i = 1; i < history.length; i++) {
let x1 = map(i - 1, 0, history.length - 1, 50, width - 50);
let y1 = map(history[i-1].y, -10, 10, height - 50, 50);
let x2 = map(i, 0, history.length - 1, 50, width - 50);
let y2 = map(history[i].y, -10, 10, height - 50, 50);
line(x1, y1, x2, y2);
}
stroke('blue');
for (let i = 1; i < history.length; i++) {
let x1 = map(i - 1, 0, history.length - 1, 50, width - 50);
let y1 = map(history[i-1].z, -10, 10, height - 50, 50);
let x2 = map(i, 0, history.length - 1, 50, width - 50);
let y2 = map(history[i].z, -10, 10, height - 50, 50);
line(x1, y1, x2, y2);
}
}
// Display current values
fill('black');
textSize(14);
text('Acceleration:', 20, 30);
text(`X: ${(accelerationX || 0).toFixed(2)}`, 20, 50);
text(`Y: ${(accelerationY || 0).toFixed(2)}`, 20, 70);
text(`Z: ${(accelerationZ || 0).toFixed(2)}`, 20, 90);
// Legend
fill('red');
text('X', 150, 50);
fill('green');
text('Y', 150, 70);
fill('blue');
text('Z', 150, 90);
}
function deviceShaken() {
// Clear history when device is shaken
history = [];
background(random(255), random(255), random(255));
}Advanced Mouse Interaction with States:
let mode = 'draw';
let shapes = [];
let currentShape = null;
function setup() {
createCanvas(400, 300);
}
function draw() {
background(220);
// Draw all completed shapes
for (let shape of shapes) {
drawShape(shape);
}
// Draw current shape being created
if (currentShape) {
drawShape(currentShape);
}
// Show mode
fill('black');
textSize(16);
text(`Mode: ${mode} (press 'd' for draw, 'e' for erase)`, 10, 20);
text(`Shapes: ${shapes.length}`, 10, 40);
}
function drawShape(shape) {
fill(shape.color);
noStroke();
for (let point of shape.points) {
circle(point.x, point.y, shape.size);
}
}
function mousePressed() {
if (mode === 'draw') {
currentShape = {
points: [{x: mouseX, y: mouseY}],
color: color(random(255), random(255), random(255), 150),
size: random(10, 30)
};
} else if (mode === 'erase') {
// Remove shapes near mouse
shapes = shapes.filter(shape => {
return !shape.points.some(point =>
dist(mouseX, mouseY, point.x, point.y) < 30
);
});
}
}
function mouseDragged() {
if (mode === 'draw' && currentShape) {
currentShape.points.push({x: mouseX, y: mouseY});
}
}
function mouseReleased() {
if (mode === 'draw' && currentShape) {
shapes.push(currentShape);
currentShape = null;
}
}
function keyPressed() {
if (key === 'd') mode = 'draw';
if (key === 'e') mode = 'erase';
if (key === 'c') shapes = []; // Clear all
}Install with Tessl CLI
npx tessl i tessl/npm-p5