Interactive NFT by @andriibakulin
<code> const ITEMS_COUNT_PER_ROW = 12;let gEntities = []; let gSizeArea; let gSizeItem;
class Entity { constructor(xi, yi) { this.xi = xi; this.yi = yi; this.color = 128; this.power = 0; }
next(dt)
{
this.color += dt * 100;
}
render()
{
const x = gSizeItem * (this.xi+0.5);
const y = gSizeItem * (this.yi+0.5);
let size = 10;
let power = 0;
let kThreshhold;
if (mouseIsPressed)
{
let distance = Math.sqrt((x - mouseX)**2 + (y - mouseY)**2);
power = distance / (gSizeArea * 0.33);
power = Math.min(power, 1.0);
power = Math.max(power, 0.0);
power = 1 - power;
kThreshhold = power * 0.05;
if (kThreshhold < 0.03)
kThreshhold = 0.03;
}
else
{
kThreshhold = 0.02;
}
if (Math.abs(this.power-power) > kThreshhold)
{
if (this.power < power) power = this.power + kThreshhold;
else power = this.power - kThreshhold;
}
size += gSizeItem * power * 2;
this.drawInstance(x, y, +1, power, size)
if (power > 0)
this.drawInstance(x, y, -1, power, size)
this.power = power;
}
drawInstance(x, y, direction, power, size)
{
const colorV = this.colorValue(power*100);
resetMatrix();
translate(x, y);
rotate(power * direction * 90);
stroke(colorV, 255, 255);
fill(colorV, 255, 255, 64);
rect(-size*1.5, -size*0.05, size*3, +size*0.1);
}
colorValue(offset)
{
return (this.color + offset) % 255;
}
}
function setup() { gSizeArea = getAreaSize(); gSizeItem = gSizeArea / ITEMS_COUNT_PER_ROW;
createCanvas(gSizeArea, gSizeArea);
pixelDensity(1);
frameRate(60);
colorMode(HSB, 255);
angleMode(DEGREES);
background(0);
for (let yi=0; yi<ITEMS_COUNT_PER_ROW; yi++)
{
for (let xi=0; xi<ITEMS_COUNT_PER_ROW; xi++)
{
gEntities.push(new Entity(xi, yi));
}
}
}
function windowResized() { gSizeArea = getAreaSize(); gSizeItem = gSizeArea / ITEMS_COUNT_PER_ROW;
resizeCanvas(gSizeArea, gSizeArea);
}
function draw() { const dt = deltaTime/1000;
background(0);
for (const idx in gEntities)
{
const ent = gEntities[idx];
ent.render();
ent.next(dt);
}
}
function getAreaSize() { return Math.min(window.innerWidth, window.innerHeight); } </code>