{"name":"dev_PARTY #011","description":"Interactive NFT by @andriibakulin\n\n<code>\nconst ITEMS_COUNT = 64;\n\nlet gEntities = [];\nlet gSizeArea;\nlet gDistance;\nlet gDistanceSqr;\n\nclass Point\n{\n    constructor(x=null, y=null)\n    {\n        this.x = x;\n        this.y = y;\n    }\n\n    move(x, y, delta)\n    {\n        if (this.x === null || this.y === null)\n        {\n            this.x = x;\n            this.y = y;\n            return;\n        }\n\n        const dx = x - this.x;\n        const dy = y - this.y;\n\n        this.x = Math.abs(dx) <= delta ? x\n            : (dx < 0 ? this.x - delta : this.x + delta);\n\n        this.y = Math.abs(dy) <= delta ? y\n            : (dy < 0 ? this.y - delta : this.y + delta);\n    }\n}\n\nclass Entity\n{\n    constructor(index, count)\n    {\n        this.index = index;\n        this.count = count;\n        this.seq01 = index / count;\n\n        this.color  = this.seq01 * 255;\n        this.offset = this.seq01 * Math.PI;\n        this.angel  = this.seq01 * Math.PI * 2;\n\n        this.p0 = new Point();\n    }\n\n    next(dt)\n    {\n        this.color += dt * 100;\n        this.offset += dt;\n\n        this.angel -= dt/3;\n    }\n\n    render()\n    {\n        let center = gSizeArea/2;\n        let radius = gSizeArea/4;\n\n        let circleX = Math.sin(this.angel) * radius;\n        let circleY = Math.cos(this.angel) * radius;\n\n        let colorV = this.colorValue(this.offset);\n\n        let endX = center + circleX;\n        let endY = center + circleY;\n\n        // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\n        let dstOffset = 0;\n\n        if (mouseIsPressed)\n        {\n            let dstLengthSqr = (mouseX-endX)**2 + (mouseY-endY)**2;\n\n            if (dstLengthSqr < gDistanceSqr)\n            {\n                dstOffset = Math.sqrt(dstLengthSqr) / gDistance;\n            }\n        }\n\n        // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\n        resetMatrix();\n        translate(endX, endY);\n\n        const x0 = dstOffset > 0 ? circleX * (1 - dstOffset) : 0;\n        const y0 = dstOffset > 0 ? circleY * (1 - dstOffset) : 0;\n\n        this.p0.move(x0, y0, 3);\n\n        if (!(this.p0.x == 0 && this.p0.y == 0))\n        {\n            if (dstOffset == 0)\n                dstOffset = 0.5;\n\n            strokeWeight(2);\n            stroke(colorV, 255, 255 * dstOffset);\n            line(-this.p0.x, -this.p0.y, +this.p0.x, +this.p0.y);\n\n            strokeWeight(2 + 8 * dstOffset);\n            stroke(colorV, 255, 255);\n            point(-this.p0.x*1.25, -this.p0.y*1.25);\n\n            strokeWeight(5);\n            stroke(colorV, 255, 128);\n            point(+this.p0.x*1.5, +this.p0.y*1.5);\n            point(0,0);\n        }\n\n        strokeWeight(10);\n        stroke(colorV, 255, 255);\n        point(+this.p0.x, +this.p0.y);\n    }\n\n    colorValue(offset)\n    {\n        return (this.color + offset) % 255;\n    }\n}\n\nfunction setup()\n{\n    updateConsts();\n    createCanvas(gSizeArea, gSizeArea);\n\n    pixelDensity(1);\n    frameRate(60);\n\n    colorMode(HSB, 255);\n    angleMode(DEGREES);\n\n    background(0);\n\n    for (let index=0; index<ITEMS_COUNT; index++)\n    {\n        gEntities.push(new Entity(index, ITEMS_COUNT));\n    }\n}\n\nfunction windowResized()\n{\n    updateConsts();\n    resizeCanvas(gSizeArea, gSizeArea);\n}\n\nfunction updateConsts()\n{\n    gSizeArea = getAreaSize();\n    gDistance = gSizeArea / 2;\n    gDistanceSqr = gDistance ** 2;\n}\n\nfunction draw()\n{\n    const dt = deltaTime/1000;\n\n    background(0);\n\n    for (const idx in gEntities)\n    {\n        const ent = gEntities[idx];\n        ent.render();\n        ent.next(dt);\n    }\n}\n\nfunction getAreaSize()\n{\n    return Math.min(window.innerWidth, window.innerHeight);\n}\n</code>","tags":["codeart","interactive","procedural","generative","generativeart","realtime","p5js","p5func"],"symbol":"OBJKT","artifactUri":"ipfs://Qmd1qCHwUZpjfQAcak4oD8Ne4TyhAkLaYbEfVgDp3z4K1z","displayUri":"ipfs://QmW8zb9whYPa4Ed9Wzw6cQ33uLLa3yEEQwnDNtHLQRrgab","thumbnailUri":"ipfs://QmNrhZHUaEqxhyLfqoq1mtHSipkWHeT31LNHb1QEbDHgnc","creators":["tz1Ys42frYhgxHxXtqoY42GiuRPZ9ykbP86Y"],"formats":[{"uri":"ipfs://Qmd1qCHwUZpjfQAcak4oD8Ne4TyhAkLaYbEfVgDp3z4K1z","mimeType":"application/x-directory"}],"decimals":0,"isBooleanAmount":false,"shouldPreferSymbol":false}