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>