Interactive NFT by @andriibakulin
<code>
let gEntities = [];
class Entity
{
constructor(x, y)
{
const distance = Math.sqrt(x**2 + y**2);
const winMinSize = Math.min(window.innerWidth, window.innerHeight);
this.x = x;
this.y = y;
this.r = 5 + 15 * distance / winMinSize;
this.rotation = 0;
this.rotSpeed = Math.sign(Math.random()-0.5) * Math.min(30 + distance/3, 75);
this.outRange = winMinSize / 16;
this.color = getAngle(x,y) / 360 * 255;
this.alpha = 255;
}
next(dt)
{
this.rotation += dt * this.rotSpeed;
this.color = this.normalizeColor(this.color - dt * 32);
this.alpha -= dt * 128;
return this.alpha > 0;
}
render()
{
resetMatrix();
translate(window.innerWidth/2, window.innerHeight/2);
rotate(this.rotation);
noStroke();
fill(this.color, 255, this.alpha);
circle(this.x, this.y, this.r);
for (let i=0; i<3; i++)
{
circle(this.x + this.getRandomOutRange(), this.y + this.getRandomOutRange(), this.r * 0.33);
}
strokeWeight(1);
stroke(this.color, 255, this.alpha * 0.5);
line(0,0, this.x, this.y);
}
getRandomOutRange()
{
return (Math.random() - 0.5) * this.outRange;
}
normalizeColor(color)
{
color %= 255;
return color < 0 ? color + 255 : color;
}
}
function setup()
{
createCanvas(window.innerWidth, window.innerHeight)
pixelDensity(1);
frameRate(60);
colorMode(HSB, 255);
angleMode(DEGREES);
background(0);
}
function windowResized()
{
resizeCanvas(window.innerWidth, window.innerHeight);
}
let gEntityAddTimeout = 0;
function draw()
{
const dt = deltaTime/1000;
if (gEntityAddTimeout <= 0)
{
let x = mouseIsPressed ? mouseX - window.innerWidth / 2 : 0;
let y = mouseIsPressed ? mouseY - window.innerHeight / 2 : 0;
gEntities.push(new Entity(x, y));
gEntityAddTimeout = 1/60;
}
else
{
gEntityAddTimeout -= dt;
}
background(0);
for (const idx in gEntities)
{
const ent = gEntities[idx];
ent.render();
if (!ent.next(dt))
gEntities.splice(idx,1);
}
}
function getAngle(x, y)
{
const angle = Math.atan2(y, x);
const degrees = 180*angle/Math.PI;
return (360+Math.round(degrees))%360;
}
</code>