let img; let tiles = []; let mode = 0; // 0 = image, 1 = mosaic, 2 = radius reveal let timeCounter = 0; let params = { fillPercent: 1, appearSpeed: 0.08, minDelay: 0, maxDelay: 30, waveCount: 1, contentJumble: 0.1, prog1: 50, prog2: 70, prog3: 100, // Ripple Specifics waveSpeed: 2, // Pixels per frame the wave travels rippleStrength: 1.4, rippleLife: 0.05 // How fast it returns to normal }; let waveOrigins = []; let viewRadius = 150; function preload() { img = loadImage("Asset 4.png"); } function setup() { createCanvas(500, 500); imageMode(CENTER); rectMode(CENTER); noStroke(); buildGrid(); // Initialize first grid } function draw() { background("#000000"); if (mode === 0) { image(img, width / 2, height / 2, width, height); return; } timeCounter++; let done = true; for (let t of tiles) { t.update(timeCounter); t.show(); if (!t.done) done = false; } if (mode === 1 && done && !mouseIsPressed) noLoop(); } function mousePressed() { // Trigger the spreading ripple let clickX = mouseX; let clickY = mouseY; for (let t of tiles) { t.triggerRipple(clickX, clickY, timeCounter); } loop(); } function keyPressed() { if (key === '1' || key === '2') { tiles = []; timeCounter = 0; waveOrigins = []; for (let i = 0; i < params.waveCount; i++) { waveOrigins.push({ x: random(width * 0.1, width * 0.9), y: random(height * 0.1, height * 0.9) }); } buildGrid(); mode = int(key); loop(); } if (key === '0') { mode = 0; loop(); } } function buildGrid() { tiles = []; let base = params.prog1; let cols = floor(width / base); let rows = floor(height / base); let occupied = Array(cols).fill().map(() => Array(rows).fill(false)); let sizes = [params.prog1, params.prog2, params.prog3]; for (let j = 0; j < rows; j++) { for (let i = 0; i < cols; i++) { if (occupied[i][j]) continue; if (random() > params.fillPercent) continue; let shuffled = shuffle(sizes.slice()); for (let s of shuffled) { let wCells = floor(s / base); let hCells = wCells; if (i + wCells > cols || j + hCells > rows) continue; let fits = true; for (let dx = 0; dx < wCells; dx++) { for (let dy = 0; dy < hCells; dy++) { if (occupied[i + dx][j + dy]) { fits = false; break; } } if (!fits) break; } if (!fits) continue; for (let dx = 0; dx < wCells; dx++) { for (let dy = 0; dy < hCells; dy++) { occupied[i + dx][j + dy] = true; } } let x = i * base; let y = j * base; let offsetX = random(-params.contentJumble, params.contentJumble) * img.width * 0.5; let offsetY = random(-params.contentJumble, params.contentJumble) * img.height * 0.5; let imgX = constrain(int(map(x, 0, width, 0, img.width) + offsetX), 0, img.width - s); let imgY = constrain(int(map(y, 0, height, 0, img.height) + offsetY), 0, img.height - s); let cropped = img.get(imgX, imgY, s, s); let minD = Infinity; for (let o of waveOrigins) { let d = dist(x + s / 2, y + s / 2, o.x, o.y); if (d < minD) minD = d; } let norm = map(minD, 0, dist(0,0,width,height), 0, 1); let delay = lerp(params.minDelay, params.maxDelay, norm); tiles.push(new Tile(x, y, s, cropped, delay)); break; } } } } class Tile { constructor(x, y, s, imgCrop, delay) { this.x = x; this.y = y; this.baseS = s; this.currentS = 0; // Start at 0 for the entrance animation this.targetS = s; this.img = imgCrop; this.delay = delay; this.t = 0; this.opacity = 0; this.done = false; // Ripple properties this.rippleTriggerTime = -1; this.isRippling = false; } triggerRipple(mx, my, currentTime) { let d = dist(this.x + this.baseS/2, this.y + this.baseS/2, mx, my); // Calculate when the wave hits this specific tile this.rippleTriggerTime = currentTime + (d / params.waveSpeed); this.isRippling = true; } update(counter) { // 1. Handle Initial Appearance (from original code) if (counter >= this.delay && !this.done) { this.t += params.appearSpeed; let tNorm = min(this.t, 1); this.currentS = this.baseS * easeOutBack(tNorm); this.opacity = tNorm; if (this.t >= 1) { this.done = true; this.currentS = this.baseS; } } // 2. Handle Click Ripple (Spreading Wave) if (this.isRippling && counter >= this.rippleTriggerTime) { this.targetS = this.baseS * params.rippleStrength; this.isRippling = false; // Triggered! } // Smoothly settle back to base size if (this.done) { this.currentS = lerp(this.currentS, this.targetS, 0.15); this.targetS = lerp(this.targetS, this.baseS, params.rippleLife); } } show() { if (timeCounter < this.delay) return; if (mode === 2) { let d = dist(mouseX, mouseY, this.x + this.baseS / 2, this.y + this.baseS / 2); if (d > viewRadius) return; } push(); translate(this.x + this.baseS / 2, this.y + this.baseS / 2); tint(255, this.opacity * 255); image(this.img, 0, 0, this.currentS + 1, this.currentS + 1); noFill(); stroke("#edff00"); strokeWeight(1); rect(0, 0, this.currentS, this.currentS); pop(); } } function easeOutBack(t) { const c1 = 1.70158; const c3 = c1 + 1; return 1 + c3 * pow(t - 1, 3) + c1 * pow(t - 1, 2); }

Kyoorius X The Clio Awards

A Strategic Partnership
To Elevate Indian Creativity To The Global Stage


The partnership brings together two institutions united by a shared belief in the power of creativity to shape culture, business, and society.

What Happened In 2025

You may also know us from:

Kyoorius has always been at the forefront of creative communities. All our platforms stand to raise, reward, and recognise the talent in advertising, media, marketing, and design.

We regularly partner with brands & organisations to help them do the same with their existing or potential communities.

LET’S WORK TOGETHER

Curation & Advisory

If there is a community, audience, or a niche that you would like to bring into your fold and connect with, get in touch with us.

Kyoorius performs a deep-dive into your problem to find the best method to build you an IP that gives you return-on-relationships for years to come.

In the past, we have worked with Deloitte, The Times Group, Skoda, STAR, and many more…

Event Participation

Over the last 18 years, Kyoorius has built numerous large platforms for engagement. From the Kyoorius Creative Awards, to Designyatra, to ZeeMelt, and so on…

We do this through meticulous event partnerships. Not generic sponsorship packages. This includes workshops, expositions, competitions, etc.

In the past we have worked with Zee, Pidilite, Colours, ABP News, and many more…

In the past, our solutions have worked for brands like:

Let’s Talk