diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..615ebc7b Binary files /dev/null and b/.DS_Store differ diff --git a/docs/.DS_Store b/docs/.DS_Store new file mode 100644 index 00000000..60cfb3e6 Binary files /dev/null and b/docs/.DS_Store differ diff --git a/docs/assets/.DS_Store b/docs/assets/.DS_Store new file mode 100644 index 00000000..2c9f6256 Binary files /dev/null and b/docs/assets/.DS_Store differ diff --git a/docs/assets/examples/clock.gif b/docs/assets/examples/clock.gif new file mode 100644 index 00000000..7d052999 Binary files /dev/null and b/docs/assets/examples/clock.gif differ diff --git a/docs/assets/examples/constrain.gif b/docs/assets/examples/constrain.gif new file mode 100644 index 00000000..f352dbdf Binary files /dev/null and b/docs/assets/examples/constrain.gif differ diff --git a/docs/assets/examples/easing.gif b/docs/assets/examples/easing.gif new file mode 100644 index 00000000..dc332814 Binary files /dev/null and b/docs/assets/examples/easing.gif differ diff --git a/docs/assets/examples/keyboard-functions.gif b/docs/assets/examples/keyboard-functions.gif new file mode 100644 index 00000000..9f5e5d21 Binary files /dev/null and b/docs/assets/examples/keyboard-functions.gif differ diff --git a/docs/assets/examples/keyboard.gif b/docs/assets/examples/keyboard.gif new file mode 100644 index 00000000..edb88ab8 Binary files /dev/null and b/docs/assets/examples/keyboard.gif differ diff --git a/docs/assets/examples/milliseconds.gif b/docs/assets/examples/milliseconds.gif new file mode 100644 index 00000000..339a8b64 Binary files /dev/null and b/docs/assets/examples/milliseconds.gif differ diff --git a/docs/assets/examples/mouse-1d.gif b/docs/assets/examples/mouse-1d.gif new file mode 100644 index 00000000..63115b50 Binary files /dev/null and b/docs/assets/examples/mouse-1d.gif differ diff --git a/docs/assets/examples/mouse-2d.gif b/docs/assets/examples/mouse-2d.gif new file mode 100644 index 00000000..0866f9d6 Binary files /dev/null and b/docs/assets/examples/mouse-2d.gif differ diff --git a/docs/assets/examples/mouse-functions.gif b/docs/assets/examples/mouse-functions.gif new file mode 100644 index 00000000..da14ac0e Binary files /dev/null and b/docs/assets/examples/mouse-functions.gif differ diff --git a/docs/assets/examples/mouse-press.gif b/docs/assets/examples/mouse-press.gif new file mode 100644 index 00000000..bc86d4eb Binary files /dev/null and b/docs/assets/examples/mouse-press.gif differ diff --git a/docs/assets/examples/mouse-signals.gif b/docs/assets/examples/mouse-signals.gif new file mode 100644 index 00000000..1b064883 Binary files /dev/null and b/docs/assets/examples/mouse-signals.gif differ diff --git a/docs/assets/examples/storing-input.gif b/docs/assets/examples/storing-input.gif new file mode 100644 index 00000000..34cd0c7c Binary files /dev/null and b/docs/assets/examples/storing-input.gif differ diff --git a/docs/examples/clock.md b/docs/examples/clock.md new file mode 100644 index 00000000..b03c8626 --- /dev/null +++ b/docs/examples/clock.md @@ -0,0 +1,80 @@ +# Clock + +This example displays the current time as an analog clock using sine and cosine functions to position the clock hands. + +It demonstrates: + +- reading the current time with `second()`, `minute()`, and `hour()` +- using trigonometric functions (`sin()` and `cos()`) to position elements in circular patterns +- the `map()` function to convert time values to angles +- drawing multiple elements at different scales +- using `HALF_PI` to rotate angle calculations + +From here, you can try: + +- adding a digital time display alongside the analog clock +- creating a 12-hour vs 24-hour clock toggle +- adding decorative elements like numbers around the clock face +- animating the transition between hour, minute, and second hands + +![animation of an analog clock displaying the current time](/assets/examples/clock.gif "An analog clock with moving hour, minute, and second hands") + +```lua +require("L5") + +local cx, cy +local secondsRadius +local minutesRadius +local hoursRadius +local clockDiameter + +function setup() + size(640, 360) + windowTitle("Clock") + describe("Display the current time") + + stroke(255) + + local radius = min(width, height) / 2 + secondsRadius = radius * 0.72 + minutesRadius = radius * 0.60 + hoursRadius = radius * 0.50 + clockDiameter = radius * 1.8 + + cx = width / 2 + cy = height / 2 +end + +function draw() + background(0) + + -- Draw the clock background + fill(80) + noStroke() + ellipse(cx, cy, clockDiameter, clockDiameter) + + -- Angles for sin() and cos() start at 3 o'clock; + -- subtract HALF_PI to make them start at the top + local s = map(second(), 0, 60, 0, TWO_PI) - HALF_PI + local m = map(minute() + map(second(), 0, 60, 0, 1), 0, 60, 0, TWO_PI) - HALF_PI + local h = map(hour() + map(minute(), 0, 60, 0, 1), 0, 24, 0, TWO_PI * 2) - HALF_PI + + -- Draw the hands of the clock + stroke(255) + strokeWeight(1) + line(cx, cy, cx + cos(s) * secondsRadius, cy + sin(s) * secondsRadius) + strokeWeight(2) + line(cx, cy, cx + cos(m) * minutesRadius, cy + sin(m) * minutesRadius) + strokeWeight(4) + line(cx, cy, cx + cos(h) * hoursRadius, cy + sin(h) * hoursRadius) + + -- Draw the minute ticks + strokeWeight(2) + for a = 0, 354, 6 do + local angle = radians(a) + local x = cx + cos(angle) * secondsRadius + local y = cy + sin(angle) * secondsRadius + point(x, y) + end +end +``` diff --git a/docs/examples/constrain.md b/docs/examples/constrain.md new file mode 100644 index 00000000..d4ae5ec6 --- /dev/null +++ b/docs/examples/constrain.md @@ -0,0 +1,62 @@ +# Constrain + +This example demonstrates constraining a shape's movement within a bounded area. A circle follows the mouse with easing applied, keeping it within a rectangular box. + +It demonstrates: + +- the `constrain()` function to limit values within a range +- smooth motion with easing +- mouse tracking with gradual animation +- using `abs()` to check for minimum movement thresholds +- different drawing modes with `ellipseMode()` and `rectMode()` + +From here, you can try: + +- creating multiple constrained objects that interact with each other +- using different easing values to create different speeds +- constraining to circular or other shaped boundaries +- adding keyboard controls to move the constrained object + +![animation of a circle following the mouse within a bounded box](/assets/examples/constrain.gif "A white circle that follows the mouse while staying constrained within a rectangular boundary") + +```lua +require("L5") + +local mx = 0 +local my = 0 +local easing = 0.05 +local radius = 24 +local edge = 100 +local inner = edge + radius + +function setup() + size(640, 360) + windowTitle("Constrain") + describe(" Move the mouse across the screen to move the circle. The program constrains the circle to its box.") + + noStroke() + ellipseMode(RADIUS) + rectMode(CORNERS) +end + +function draw() + background(51) + + -- Change the position of the drawn ellipse to the position of the mouse with easing + if (abs(mouseX - mx) > 0.1) then + mx = mx + (mouseX - mx) * easing + end + + if (abs(mouseY - my) > 0.1) then + my = my + (mouseY - my) * easing + end + + -- Constrain the position of the ellipse to the inner rectangle + mx = constrain(mx, inner, width - inner) + my = constrain(my, inner, height - inner) + fill(76) + rect(edge, edge, width - edge, height - edge) + fill(255) + ellipse(mx, my, radius, radius) +end +``` diff --git a/docs/examples/easing.md b/docs/examples/easing.md new file mode 100644 index 00000000..b1f7c759 --- /dev/null +++ b/docs/examples/easing.md @@ -0,0 +1,52 @@ +# Easing + +This example demonstrates smooth animation by moving a shape toward the mouse position with easing. The shape doesn't jump directly to the cursor but gradually glides toward it. + +It demonstrates: + +- creating smooth, natural-looking motion +- calculating the difference between current and target positions +- applying easing factors to create gradual movement +- following the mouse position without snap +- simple animation principles + +From here, you can try: + +- varying the easing value to create different speeds and smoothness levels +- having multiple shapes with different easing values +- creating easing toward different target positions (not just the mouse) +- implementing other interpolation methods like lerp or acceleration/velocity + +![animation of a circle smoothly following the mouse cursor](/assets/examples/easing.gif "A white circle that glides toward the mouse cursor with smooth easing") + +```lua +require("L5") + +local x = 0 +local y = 0 +local easing = 0.05 + +function setup() + size(640, 360) + windowTitle("Easing") + describe(" Move the mouse across the screen and the symbol will follow.") + + noStroke() +end + +function draw() + background(51) + + -- Change the position of the drawn ellipse to the position of the mouse with easing + + targetX = mouseX + dx = targetX - x + x = x + dx * easing + + targetY = mouseY + dy = targetY - y + y = y + dy * easing + + ellipse(x, y, 66) +end +``` diff --git a/docs/examples/index.md b/docs/examples/index.md index 171f23d1..a0a43ab1 100644 --- a/docs/examples/index.md +++ b/docs/examples/index.md @@ -1,30 +1,53 @@ -# Examples +# Examples ## Shapes and Colors -* [Shape Primitives](shapes-and-color-shape-primitives.md) - Draw 2D shapes -* [Color](shapes-and-color-color.md) - Add color to your sketch +- [Shape Primitives](shapes-and-color-shape-primitives.md) - Draw 2D shapes +- [Color](shapes-and-color-color.md) - Add color to your sketch ## Animations and Variables -* [Doodle Draw](doodle-draw.md) - Create a basic drawing program tracking mouse movements -* [Drawing Lines](animation-and-variables-drawing-lines.md) - A drawing program demonstrating HSB colorMode -* [Animation with Events](animation-and-variables-animation-with-events.md) - Pause and resume animation. -* [Conditions](animation-and-variables-conditions.md) - Use if and else statements to make decisions while your sketch runs. -* [Basic Pong](basic-pong.md) - A simple program demonstrating a basic implementation of pong with enemy AI player -* [Walking Lines](walking-lines.md) - Animated intersecting lines -* [10Print](10print.md) - An implementation of the classic maze-drawing algorithm -* [Conway's Game Of Life](conways-life.md) - An implementation of the zero-player game and simulation formulated by mathematician John Conway -* [Minimum Spanning Tree](min-span-tree.md) - An example of implementing Prim's algorithm for finding the shortest lengths to connect all randomly placed dots +- [Doodle Draw](doodle-draw.md) - Create a basic drawing program tracking mouse movements +- [Drawing Lines](animation-and-variables-drawing-lines.md) - A drawing program demonstrating HSB colorMode +- [Animation with Events](animation-and-variables-animation-with-events.md) - Pause and resume animation. +- [Conditions](animation-and-variables-conditions.md) - Use if and else statements to make decisions while your sketch runs. +- [Basic Pong](basic-pong.md) - A simple program demonstrating a basic implementation of pong with enemy AI player +- [Walking Lines](walking-lines.md) - Animated intersecting lines +- [10Print](10print.md) - An implementation of the classic maze-drawing algorithm +- [Conway's Game Of Life](conways-life.md) - An implementation of the zero-player game and simulation formulated by mathematician John Conway +- [Minimum Spanning Tree](min-span-tree.md) - An example of implementing Prim's algorithm for finding the shortest lengths to connect all randomly placed dots +- [Easing](easing.md) - Smooth animation with easing as a shape follows the mouse +- [Clock](clock.md) - Display the current time as an analog clock +- [Milliseconds](milliseconds.md) - Create time-based color patterns using elapsed milliseconds + +## Input and Interaction + +### Mouse Input + +- [Mouse 1D](mouse-1d.md) - Use horizontal mouse position to shift the balance between two rectangles +- [Mouse 2D](mouse-2d.md) - Control position and size of boxes using two-dimensional mouse movement +- [Mouse Press](mouse-press.md) - Create a crosshair that changes color when the mouse button is pressed +- [Mouse Functions](mouse-functions.md) - Click and drag a box around the screen +- [Mouse Signals](mouse-signals.md) - Visualize mouse input signals as real-time waveforms +- [Storing Input](storing-input.md) - Record and display mouse position trails over time + +### Keyboard Input + +- [Keyboard](keyboard.md) - Press letter keys to create forms in different positions +- [Keyboard Functions](keyboard-functions.md) - Interactive color typewriter with different output for uppercase and lowercase letters + +### Constraints and Movement + +- [Constrain](constrain.md) - Limit a shape's movement within a bounded area ## Imported Media -* [Daily Rituals](daily-rituals.md) - One a day daily ritual generator -* [Words](imported-media-words.md) - Load fonts and draw text -* [Copy Image Data](imported-media-copy-image-data.md) - Paint from an image file onto the canvas -* [Image Transparency](imported-media-image-transparency.md) - Make an image translucent on the canvas -* [Video Player](imported-media-video.md) - Create a player for video playback and stylize in the window +- [Daily Rituals](daily-rituals.md) - One a day daily ritual generator +- [Words](imported-media-words.md) - Load fonts and draw text +- [Copy Image Data](imported-media-copy-image-data.md) - Paint from an image file onto the canvas +- [Image Transparency](imported-media-image-transparency.md) - Make an image translucent on the canvas +- [Video Player](imported-media-video.md) - Create a player for video playback and stylize in the window -## Object-Orientation +## Object-Orientation -* [Random Robot Objects](random-robot-objects.md) - Demonstrates two different Lua patterns - classes with metatables and simple table objects +- [Random Robot Objects](random-robot-objects.md) - Demonstrates two different Lua patterns - classes with metatables and simple table objects diff --git a/docs/examples/keyboard-functions.md b/docs/examples/keyboard-functions.md new file mode 100644 index 00000000..2fbf4c02 --- /dev/null +++ b/docs/examples/keyboard-functions.md @@ -0,0 +1,108 @@ +# Keyboard Functions + +This example creates an interactive color typewriter where different letter cases produce different sized rectangles with different colors from the HSB color space. + +It demonstrates: + +- the `keyPressed()` callback function +- distinguishing between uppercase and lowercase keys +- using HSB color mode for easy hue variation +- managing state variables for continuous drawing +- wrapping text display horizontally and vertically +- creating visual feedback for keyboard input + +From here, you can try: + +- adding different shapes for different key categories +- incorporating `keyReleased()` for key release events +- creating a full text display that captures typed words +- creating animated transitions between letters + +![animation of a color typewriter with varying heights](/assets/examples/keyboard-functions.gif "Colored rectangles of different heights appearing continuously as keys are typed, wrapping across the screen") + +```lua +require("L5") + +local maxHeight = 40 +local minHeight = 20 +local letterHeight = maxHeight +local letterWidth = 20 + +local x = -letterWidth +local y = 0 + +local newletter = false + +local numChars = 26 +local colors = {} + +function setup() + size(640, 360) + windowTitle("Keyboard Functions") + describe("Press letter keys to create forms in time and space") + + noStroke() + colorMode(HSB, numChars) + background(numChars / 2) + + -- Set a hue value for each key + for i = 0, numChars - 1 do + colors[i] = color(i, numChars, numChars) + end +end + +function draw() + if newletter == true then + -- Draw the "letter" + local y_pos + if letterHeight == maxHeight then + y_pos = y + rect(x, y_pos, letterWidth, letterHeight) + else + y_pos = y + minHeight + rect(x, y_pos, letterWidth, letterHeight) + fill(numChars / 2) + rect(x, y_pos - minHeight, letterWidth, letterHeight) + end + newletter = false + end +end + +function keyPressed() + -- If the key is between 'A'(65) to 'Z' and 'a' to 'z'(122) + local keyByte = string.byte(key) + + if (keyByte >= string.byte('A') and keyByte <= string.byte('Z')) or + (keyByte >= string.byte('a') and keyByte <= string.byte('z')) then + local keyIndex + if keyByte <= string.byte('Z') then + keyIndex = keyByte - string.byte('A') + letterHeight = maxHeight + fill(colors[keyIndex]) + else + keyIndex = keyByte - string.byte('a') + letterHeight = minHeight + fill(colors[keyIndex]) + end + else + fill(0) + letterHeight = 10 + end + + newletter = true + + -- Update the "letter" position + x = x + letterWidth + + -- Wrap horizontally + if x > width - letterWidth then + x = 0 + y = y + maxHeight + end + + -- Wrap vertically + if y > height - letterHeight then + y = 0 + end +end +``` diff --git a/docs/examples/keyboard.md b/docs/examples/keyboard.md new file mode 100644 index 00000000..2d74f0dc --- /dev/null +++ b/docs/examples/keyboard.md @@ -0,0 +1,62 @@ +# Keyboard + +This example responds to keyboard input by detecting which letter key is pressed and drawing visual forms in different positions based on the key pressed. + +It demonstrates: + +- the `keyPressed()` callback function +- detecting letter keys using string byte operations +- converting character input to identifiable indices +- mapping key indices to screen positions +- creating dynamic visual output based on keyboard input + +From here, you can try: + +- detecting non-letter keys and handling them differently +- changing colors or shapes based on the key pressed +- storing key history to create patterns +- using arrow keys for directional input +- creating a keyboard input handler for game controls + +![animation of colored rectangles appearing as keys are pressed](/assets/examples/keyboard.gif "Colored rectangles drawn at different horizontal positions as letter keys are pressed") + +```lua +require("L5") + +function setup() + size(640, 360) + windowTitle("Keyboard") + describe("Press letter keys to create forms in time and space") + + noStroke() + background(0) + + rectWidth = width / 4 +end + +function draw() + -- Keep draw() here to continue looping while waiting for keys +end + +function keyPressed() + local keyIndex = -1 + -- Convert the built-in key variable from a string to its byte value + local keyByte = string.byte(key) + + if (keyByte >= string.byte('A') and keyByte <= string.byte('Z')) then + keyIndex = keyByte - string.byte('A') + elseif (keyByte >= string.byte('a') and keyByte <= string.byte('z')) then + keyIndex = keyByte - string.byte('a') + end + + if (keyIndex == -1) then + -- If it's not a letter key, clear the screen + background(0) + else + -- If it's a letter key, fill a rectangle + fill(millis() % 255) + x = map(keyIndex, 0, 25, 0, width - rectWidth) + rect(x, 0, rectWidth, height) + end +end +``` diff --git a/docs/examples/milliseconds.md b/docs/examples/milliseconds.md new file mode 100644 index 00000000..18462d8f --- /dev/null +++ b/docs/examples/milliseconds.md @@ -0,0 +1,41 @@ +# Milliseconds + +This example uses the `millis()` function to create color patterns that change based on elapsed time. Different vertical strips cycle through colors at different rates using the modulo operator. + +It demonstrates: + +- the `millis()` function to track elapsed time in milliseconds +- using the modulo operator (`%`) to create repeating time patterns +- the `colorMode()` function for dynamic color range control +- scaling and subdividing the screen +- creating time-based animation without explicit frame counting + +From here, you can try: + +- using milliseconds to animate object positions or sizes +- creating sound visualization based on elapsed time +- making patterns that synchronize to specific time intervals +- combining milliseconds with other time functions like `second()` and `minute()` + +![animation of vertical color strips cycling at different rates](/assets/examples/milliseconds.gif "Vertical colored stripes that cycle through colors at different speeds based on elapsed milliseconds") + +```lua +require("L5") + +function setup() + size(640, 360) + windowTitle("Milliseconds") + describe("How L5 keeps track of the number of milliseconds a program has run") + + noStroke() + scale = width / 20 +end + +function draw() + for i = 0, scale do + colorMode(RGB, (i + 1) * scale * 10) + fill(millis() % ((i + 1) * scale * 10)) + rect(i * scale, 0, scale, height) + end +end +``` diff --git a/docs/examples/mouse-1d.md b/docs/examples/mouse-1d.md new file mode 100644 index 00000000..921aa331 --- /dev/null +++ b/docs/examples/mouse-1d.md @@ -0,0 +1,48 @@ +# Mouse 1D + +This example creates a balanced visual display where moving the mouse left and right shifts the size and color balance between two rectangles. The horizontal mouse position controls a one-dimensional interaction. + +It demonstrates: + +- the `mouseX` variable for one-dimensional mouse tracking +- using mouse position to control both size and color +- the `map()` function to convert mouse coordinates to useful ranges +- creating complementary visual feedback +- using `rectMode(CENTER)` for easier rectangle positioning + +From here, you can try: + +- creating three or more balanced elements +- adding vertical mouse control (`mouseY`) +- implementing click detection to change behavior +- creating more complex relationships between mouse input and visual output +- adding animation that responds to mouse movement speed + +![animation of two balanced gray rectangles shifting in size](/assets/examples/mouse-1d.gif "Two gray rectangles that shift their sizes and positions based on horizontal mouse movement") + +```lua +require("L5") + +function setup() + size(640, 360) + windowTitle("Mouse 1D") + describe("Move the mouse left and right to shift the balance.") + + noStroke() + colorMode(RGB, height, height, height) + rectMode(CENTER) +end + +function draw() + background(0.0) + + local r1 = map(mouseX, 0, width, 0, height) + local r2 = height - r1 + + fill(r1) + rect(width / 2 + r1 / 2, height / 2, r1, r1) + + fill(r2) + rect(width / 2 - r2 / 2, height / 2, r2, r2) +end +``` diff --git a/docs/examples/mouse-2d.md b/docs/examples/mouse-2d.md new file mode 100644 index 00000000..76560549 --- /dev/null +++ b/docs/examples/mouse-2d.md @@ -0,0 +1,47 @@ +# Mouse 2D + +This example uses two-dimensional mouse tracking to control both the position and size of rectangles. Moving the mouse in different directions creates different visual effects with symmetrical and inverse squares. + +It demonstrates: + +- using both `mouseX` and `mouseY` for 2D control +- creating inverse mouse control (using width and height minus mouse position) +- mapping mouse coordinates to shape properties +- creating visual symmetry through complementary operations +- simple but effective interactive design + +From here, you can try: + +- creating grids of mouse-responsive elements +- adding click detection to change drawing mode +- creating smooth transitions between mouse positions +- implementing multiple interactive objects with different responses +- adding rotation or other transformations based on mouse position + +![animation of two translucent squares moving in opposite directions](/assets/examples/mouse-2d.gif "Two translucent rectangles that move with the mouse, one following it directly and one moving in the inverse direction") + +```lua +require("L5") + +function setup() + size(640, 360) + windowTitle("Mouse 2D") + describe("Moving the mouse changes the position and size of each box") + + noStroke() + rectMode(CENTER) +end + +function draw() + background(0.0) + + fill(255, 204) + rect(mouseX, height / 2, mouseY / 2 + 10, mouseY / 2 + 10) + + fill(255, 204) + + local inverseX = width - mouseX + local inverseY = height - mouseY + rect(inverseX, height / 2, (inverseY / 2) + 10, (inverseY / 2) + 10) +end +``` diff --git a/docs/examples/mouse-functions.md b/docs/examples/mouse-functions.md new file mode 100644 index 00000000..3704f398 --- /dev/null +++ b/docs/examples/mouse-functions.md @@ -0,0 +1,94 @@ +# Mouse Functions + +This example demonstrates mouse interaction events by allowing the user to click and drag a box around the screen. Different mouse states are highlighted with color changes. + +It demonstrates: + +- the `mousePressed()` callback function for detecting mouse button presses +- the `mouseDragged()` callback function for detecting drag events +- the `mouseReleased()` callback function for detecting mouse button releases +- tracking mouse offset for smooth dragging +- using state variables to control behavior +- creating interactive draggable objects + +From here, you can try: + +- creating multiple draggable objects +- implementing collision detection between draggable objects +- adding snap-to-grid functionality +- creating different drag behaviors (rotate, scale, etc.) +- storing the positions of dragged objects for saving/loading +- adding visual feedback like shadows or outlines during dragging + +![animation of a draggable gray square on a black background](/assets/examples/mouse-functions.gif "A gray square that changes color when hovering over it and can be dragged around the screen with the mouse") + +```lua +require("L5") + +local bx = 0 +local by = 0 +local boxSize = 75 +local overbox = false +local locked = false +local xOffset = 0.0 +local yOffset = 0.0 + +function setup() + size(640, 360) + windowTitle("Mouse Functions") + describe("Click on the box and drag it across the screen.") + + noStroke() + rectMode(RADIUS) + + bx = width / 2.0 + by = height / 2.0 + boxSize = 75 + overbox = false + locked = false + xOffset = 0.0 + yOffset = 0.0 +end + +function draw() + background(0) + + -- Test if the cursor is over the box + if ((mouseX > bx - boxSize and mouseX < bx + boxSize) and (mouseY > by - boxSize and mouseY < by + boxSize)) then + overbox = true + if (not locked) then + stroke(255) + fill(153) + end + + else + stroke(153) + fill(153) + overbox = false + end + + rect(bx, by, boxSize, boxSize) +end + +function mousePressed() + if (overbox) then + locked = true + fill(255, 255, 255) + else + locked = false + end + xOffset = mouseX - bx + yOffset = mouseY - by +end + +function mouseDragged() + if (locked) then + bx = mouseX - xOffset + by = mouseY - yOffset + end +end + +function mouseReleased() + locked = false +end +``` diff --git a/docs/examples/mouse-press.md b/docs/examples/mouse-press.md new file mode 100644 index 00000000..73d11714 --- /dev/null +++ b/docs/examples/mouse-press.md @@ -0,0 +1,44 @@ +# Mouse Press + +This example creates a crosshair that follows the mouse position. The stroke color changes when the mouse button is pressed, creating an inverted visual effect. + +It demonstrates: + +- the `mouseIsPressed` built-in variable to check if mouse button is held down +- creating dynamic visual feedback based on input state +- simple shapes (lines) controlled by mouse position +- conditional rendering based on input state + +From here, you can try: + +- drawing more complex shapes instead of just lines +- creating different visual modes based on mouse state +- adding trails or previous positions to create patterns +- adding keyboard modifiers to change behavior + +![animation of a crosshair that changes color when mouse button is pressed](/assets/examples/mouse-press.gif "A white and black crosshair following the mouse that inverts colors when the mouse button is pressed") + +```lua +require("L5") + +function setup() + size(640, 360) + windowTitle("Mouse Press") + describe("Move and press the mouse button to position the shape and invert the color") + + noSmooth() + fill(126) + background(102) +end + +function draw() + if (mouseIsPressed) then + stroke(255) + else + stroke(0) + end + + line(mouseX - 66, mouseY, mouseX + 66, mouseY) + line(mouseX, mouseY - 66, mouseX, mouseY + 66) +end +``` diff --git a/docs/examples/mouse-signals.md b/docs/examples/mouse-signals.md new file mode 100644 index 00000000..7d44b854 --- /dev/null +++ b/docs/examples/mouse-signals.md @@ -0,0 +1,90 @@ +# Mouse Signals + +This example visualizes mouse input signals in real-time by displaying three continuous signal graphs: mouse X position, mouse Y position, and mouse button press state. + +It demonstrates: + +- using tables/arrays to store historical data +- creating shifting buffer patterns (circular array technique) +- the modulo operator for array indexing +- visualizing continuous data streams +- `mouseIsPressed` for button state tracking +- converting time-series data into visual waveforms + +From here, you can try: + +- adding more signals (keyboard input, time-based values, etc.) +- using different visualization methods (bars, curves, dots) +- recording and playback of signal data +- analyzing signal patterns programmatically +- creating audio visualization based on mouse signals +- displaying statistical information about the signals + +![animation of three waveforms tracking mouse movement and clicks](/assets/examples/mouse-signals.gif "Three horizontal signal graphs showing mouse X position, mouse Y position, and mouse button state as continuous waveforms") + +```lua +require("L5") + +local xvals +local yvals +local bvals + +function setup() + size(640, 360) + windowTitle("Mouse Signals") + describe("Move and click the mouse to generate signals") + + noSmooth() + + xvals = {} + yvals = {} + bvals = {} + + for i = 1, width do + xvals[i] = 0 + yvals[i] = 0 + bvals[i] = 0 + end +end + +function draw() + background(102) + + -- Shift the values to the left + for i = 2, width do + xvals[i - 1] = xvals[i] + yvals[i - 1] = yvals[i] + bvals[i - 1] = bvals[i] + end + + -- Add the new values to the end of the array + xvals[width] = mouseX + yvals[width] = mouseY + + if mouseIsPressed then + bvals[width] = 0 + else + bvals[width] = height / 3 + end + + fill(255) + noStroke() + rect(0, height / 3, width, height / 3 + 1) + + for i = 1, width - 1 do + -- Draw the x-values + stroke(255) + point(i, map(xvals[i], 0, width, 0, height / 3 - 1)) + + -- Draw the y-values + stroke(0) + point(i, height / 3 + yvals[i] / 3) + end + + for i = 2, width do + -- Draw the mouse presses + stroke(255) + line(i, (2 * height / 3) + bvals[i], i, (2 * height / 3) + bvals[i - 1]) + end +end +``` diff --git a/docs/examples/storing-input.md b/docs/examples/storing-input.md new file mode 100644 index 00000000..1b68b096 --- /dev/null +++ b/docs/examples/storing-input.md @@ -0,0 +1,66 @@ +# Storing Input + +This example records mouse positions over time and displays them as a trail of circles. The most recent positions are drawn largest, creating a smooth motion trail effect. + +It demonstrates: + +- storing historical data in arrays +- implementing a circular buffer pattern +- using modulo operator (`%`) for array wrapping +- the `frameCount` variable for frame tracking +- creating motion trails with decreasing opacity/size +- efficient memory usage by reusing array slots + +From here, you can try: + +- adding color variation to the trail based on age +- implementing trails for multiple objects +- using trails for collision detection +- creating fade-out effects for old trail points +- storing different types of data (velocity, acceleration, etc.) +- playback of recorded input sequences +- using trails to visualize object paths over time + +![animation of mouse trail showing translucent circles](/assets/examples/storing-input.gif "A trail of translucent circles following the mouse cursor, with larger circles representing more recent positions") + +```lua +require("L5") + +local num = 60 +local mx +local my + +function setup() + size(640, 360) + windowTitle("Storing Input") + describe(" Move the mouse across the screen to change the position of the circles and store them") + + noStroke() + + mx = {} + my = {} + + for i = 0, num - 1 do + mx[i] = 0 + my[i] = 0 + end + + fill(255, 153) +end + +function draw() + background(51) + + -- Cycle through the array, using a different entry on each frame. + -- Using modulo (%) like this is faster than moving all the values over + local which = frameCount % num + mx[which] = mouseX + my[which] = mouseY + + for i = 0, num - 1 do + -- which+1 is the smallest (the oldest in the array) + local index = (which + 1 + i) % num + ellipse(mx[index], my[index], i, i) + end +end +```