{ "name": "Fireworks 2020", "id": "39YcGvL2n5YfdQWw4", "sources": { "main": "/* Doesn't use a map. 8m of SK9822 wired in setions as:\n\n 6 3\n 7 2\n \n 1 8\n 4 5\n \n*/\n\nvar arms = 8\nvar pixPerArm = pixelCount / arms\n\nvar t1Override\nexport function slidert1Override(v) { t1Override = v }\nvar modeOverride\nexport function sliderModeOverride(v) { modeOverride = floor(v * numModes * 0.999) }\nvar dmOverride\nexport function sliderDMOverride(v) { dmOverride = floor(v * numDecayModes) }\n\nvar numModes = 8\nvar modeSetup = array(numModes)\nvar beforeRenders = array(numModes)\nvar hFns = array(numModes)\nvar sFns = array(numModes)\nvar vFns = array(numModes)\n\nradials = array(arms)\nfor (i = 0; i < arms; i ++) { radials[i] = array(pixPerArm) } \ncolorBox = array(4)\n\n\nvar t1, linearT1, dMode = 0\nvar speed, thisModePeriod = 1, thisModeMs = 0\nvar width1 = 5, c1 = 0, sparkle1 = 0\nexport var mode = 0\nexport var w, w1, w2\nexport function beforeRender(delta) {\n thisModeMs += delta\n t1 = thisModeMs / (thisModePeriod * 1000)\n\n if (t1 >= 1) { newMode() }\n // t1 = t1Override\n // dMode = dmOverride\n linearT1 = t1\n t1 = decayModes[dMode](t1)\n et1 = 2 * t1 - 0.5 // \"Extended\" t1 - helps create smooth ends and space between modes\n beforeRenders[mode](delta)\n}\n\nfunction newMode() {\n mode = floor(random(numModes))\n if (modeOverride > 0) { mode = modeOverride } // Mode slider leftmost == auto\n dMode = floor(random(numDecayModes))\n thisModeMs = 0\n t1 = 0\n thisModePeriod = 1 + random(10)\n \n modeSetup[mode]()\n}\n\nexport function render(index) {\n h = hFns[mode](index)\n s = sFns[mode](index)\n v = vFns[mode](index)\n hsv(h, s, v)\n}\n\nfunction indexToUnit(index) {\n arm = floor(index / pixPerArm)\n inbound = (arm % 2) == 0\n pixIntoArm = index % pixPerArm\n pixFromCenter = inbound ? (pixPerArm - pixIntoArm - 1) : pixIntoArm\n return pixFromCenter / pixPerArm\n}\n\n// Arm remap array -> takes physical segment, returns index of segment where \n// 0 is the first clockwise arm from straight up, and proceeds clockwise.\nvar aRa = array(arms);\naRa[0] = 5; aRa[1] = 1; aRa[2] = 0; aRa[3] = 4;\naRa[4] = 3; aRa[5] = 7; aRa[6] = 6; aRa[7] = 2; \nfunction indexToRadial(index) {\n arm = floor(index / pixPerArm)\n return aRa[arm]\n}\nfunction indexToUnitRadial(index) {\n return indexToRadial(index) / arms\n}\n\nvar numDecayModes = 3\nvar decayModes = array(numDecayModes)\ndecayModes[0] = (u) => { return 1 - (1/pow((1 + u), 5)) } // Power\ndecayModes[1] = (u) => { return 1 - exp(-3 * u) } // Exponential\ndecayModes[2] = (u) => { return u } // Linear\n\n\n// The actual modes\n\nmodeSetup[0] = () => { }\nbeforeRenders[0] = (delta) => { }\nhFns[0] = (index) => { return t1 + index/pixelCount }\nsFns[0] = (index) => { return 1 }\nvFns[0] = (index) => { return abs(indexToUnit(index) - t1) < 1 / (pixelCount / arms) }\n\n\nmodeSetup[1] = () => { \n c1 = random(0.03) - 0.01\n width1 = random(1) // 0..1 units, applied to pixPerArm\n sparkle1 = floor(random(2))\n}\nbeforeRenders[1] = (delta) => { }\nhFns[1] = (index) => { return c1 }\nsFns[1] = (index) => { return 1 }\nvFns[1] = (index) => { \n v = 1 - abs(et1 - indexToUnit(index)) / width1\n v = clamp(v, 0, 1)\n if (sparkle1 && random(t1) > 0.5) v = 0\n return v * v\n}\n\n\nmodeSetup[2] = () => { thisModePeriod = 1 + random(3) }\nbeforeRenders[2] = (delta) => { }\nhFns[2] = (index) => { return 0 }\nsFns[2] = (index) => { return 0 }\nvFns[2] = (index) => { return t1 < 0.33 ? square(t1*30,1-3*t1) : 0 }\n\n\nvar gamma1 = 1\nmodeSetup[3] = () => { gamma1 = 1 + floor(random(6)) }\nbeforeRenders[3] = (delta) => { }\nhFns[3] = (index) => { return t1 + index/pixelCount }\nsFns[3] = (index) => { return 1 }\nvFns[3] = (index) => { v = triangle(t1); return pow(v, gamma1) }\n\n\n// Peony\nmodeSetup[4] = () => { \n colorBox[0] = 0\n colorBox[1] = 0.02\n colorBox[2] = 0.7\n colorBox[3] = random(1)\n color1 = colorBox[floor(random(4))]\n}\nbeforeRenders[4] = (delta) => { }\nhFns[4] = (index) => { return color1 + random(0.02) }\nsFns[4] = (index) => { return (random(1) < (2 * t1 - 1) && random(1) < 0.02) ? 0 : 1 }\nvFns[4] = (index) => { \n fadeEnd = clamp(-1/(0.2)*(linearT1-0.8) + 1,0,1);\n return fadeEnd * (indexToUnit(index) < (t1*1.2)) }\n\n\n// Fill whole strip linearly\nvar startingOffset = 0\nmodeSetup[5] = () => { \n colorBox[0] = 0.33\n colorBox[1] = 0.13\n colorBox[2] = 0.66\n colorBox[3] = 0.96\n color1 = colorBox[floor(random(4))]\n startingOffset = floor(random(pixelCount))\n}\nbeforeRenders[5] = (delta) => { }\nhFns[5] = (index) => { return color1 + random(0.02) }\nsFns[5] = (index) => { return sqrt((t1)) }\nvFns[5] = (index) => { \n progressOutwards = ((index + startingOffset ) % pixelCount)/pixelCount < t1\n fadeEnd = clamp(-1/(0.2)*(linearT1-0.8) + 1,0,1)\n return progressOutwards * fadeEnd\n}\n\n\n// Radials on delays\nmodeSetup[6] = () => { width1 = 0.3 }\nbeforeRenders[6] = (delta) => { }\nhFns[6] = (index) => { return color1 + t1 + indexToUnitRadial(index) }\nsFns[6] = (index) => { return 1 }\nvFns[6] = (index) => { \n v = 1 - abs(et1 - indexToUnitRadial(index) - indexToUnit(index)) / width1\n v = clamp(v, 0, 1)\n fadeEnd = clamp(-1/(0.2)*(linearT1-0.8) + 1,0,1)\n v *= fadeEnd\n return v\n}\n\n\n// Wave phase offsets\nexport var colorMode = 0\nmodeSetup[7] = () => {\n colorMode = floor(random(4))\n width1 = random(30)\n colorBox[0] = (i) => { return indexToUnitRadial(i) }\n colorBox[1] = (i) => { return 0.2 * i/pixelCount }\n colorBox[2] = (i) => { return 0 }\n colorBox[3] = (i) => { return 0 + random(0.02) }\n}\nbeforeRenders[7] = (delta) => { }\nhFns[7] = (index) => { return colorBox[colorMode](index) }\nsFns[7] = (index) => { return 1 }\nvFns[7] = (index) => { \n pos = indexToUnit(index)\n radial = indexToUnitRadial(index)\n v = triangle((pos - t1 + linearT1)*4) * triangle(pos - t1 * (width1 - 4))\n v = clamp(v, 0, 1)\n \n fadeEnd = clamp(-1/(0.2)*(linearT1-0.8) + 1,0,1)\n v *= fadeEnd\n return v * v\n}\n\n" }, "preview": "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" }