// Today in the class i was reminded of this video which i have watched years back:
// https://www.youtube.com/watch?v=Hq8j5vsqCCo - Steve Jobs Video
// https://youtu.be/hqi0114mwtY?si=28TNQZ0BrdReyeDT
// Some useful references
// https://people.csail.mit.edu/sparis/bf_course/slides/02_gaussian_blur.pdf
// https://blog.elixxier.com/en/lighting-design-the-easy-way-secrets-of-inverse-square-law/
/* Note: If you draw slow enough, you are kinda able to mimic the dataset images...*/
const HEIGHT = 28 * 27; // Height of the grid 756
const WIDTH = 28 * 27; // Width of the grid 756
const ROWS = 28; // 28 rows in the grid
const COLS = 28; // 28 columns in the grid
const rectWidth = WIDTH / COLS; // Width of each grid block
const rectHeight = HEIGHT / ROWS; // Height of each grid block
let penWidth = 1.5; // Pen width .. it works good with this number... although you can play around with this..
class Spot {
constructor(x, y, i, j) {
this.x = x;
this.y = y;
this.i = i; // Column index
this.j = j; // Row index
this.intensity = 0;
}
// Checks if the mouse is hovering over this spot
// ref: https://editor.p5js.org/kjhollen/sketches/B_yKRLdj8
isMouseOver() {
return (
mouseX > this.x &&
mouseX < this.x + rectWidth &&
mouseY > this.y &&
mouseY < this.y + rectHeight
);
}
// Draw the spot on the screen
draw() {
fill(0 + this.intensity);
noStroke();
rect(this.x, this.y, rectWidth, rectHeight); // Draw the spot on the screen...
}
// make the spot gradually darker based on its distance from the pen
applyIntensity(distance) {
// the brush was making the actual doodle also shaded..
// so if the pixel (or spot) if part of doodle ... we just leave it white..
// you can comment it and see what happens..
if (this.intensity >= 255) {
return;
}
let maxDist = penWidth * Math.sqrt(2); // Max distance for intensity falloff
let intensity = 255 * (1 - distance / maxDist); // Intensity decreases the further the spot is from the pen
this.intensity += intensity;
// keeping it between 0 and 255...
if (this.intensity < 0) {
this.intensity = 0; // Set it to 0 if it's less than 0
} else if (this.intensity > 255) {
this.intensity = 255; // Set it to 255 if it's greater than 255
}
}
}
class Grid {
constructor(rows, cols) {
this.rows = rows;
this.cols = cols;
this.spots = [];
// Set up all the spots in the grid.. will be drawn later
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
let x = i * rectWidth; // X position of this spot
let y = j * rectHeight; // Y position of this spot
this.spots.push(new Spot(x, y, i, j)); // Add the new spot to the grid
}
}
}
// Draw all the spots
draw() {
for (let spot of this.spots) {
spot.draw(); // spot class draw.
}
}
// This is where the "pen" effect happens. It goes through each spot and adjusts its intensity
applyPen(x, y) {
for (let spot of this.spots) {
let distX = spot.i - x; // Get the distance between the pen's X position and the spot
let distY = spot.j - y; // Get the distance between the pen's Y position and the spot
let distance = Math.sqrt(distX * distX + distY * distY); // Calculate the total distance using Pythagoras
// If the spot is within the pen's range..kinda like the brush area
if (distance <= penWidth * 1.5) {
spot.applyIntensity(distance); // Adjust the intensity for this spot based on the distance
}
}
}
}
let grid; // This will hold the grid object
function setup() {
createCanvas(WIDTH, HEIGHT);
grid = new Grid(ROWS, COLS); // Initialize the grid
}
function draw() {
grid.draw(); // Draw the whole grid
// If the mouse is being clicked... apply the pen effect
if (mouseIsPressed) {
let col = Math.floor(mouseX / rectWidth); // Find which column the mouse is over
let row = Math.floor(mouseY / rectHeight); // Find which row the mouse is over
// Only do this if the mouse is inside the grid
if (col >= 0 && col < COLS && row >= 0 && row < ROWS) {
grid.applyPen(col, row); // Apply the pen effect to the grid based on the mouse position
}
}
}