memoscan
← all memos

Memo 0xaa2c82aa…684ba4 on Ethereum

WayOfTheWormH0x8ed8d8169998a1414ca45f16e84127bed7ed38642a4acf41f7c1ceeb8eae6eef``` "Who, then, will wiggle where The Worm wills?"; let propCache, isSetup = false; const vDim = 800, size = vDim * 0.75, vFrameRate = 30, steps = 500, dlAdv = (steps / 12) | 0, bgColor = "#0A0A09", wormPink = "#EC008C", themes = { ephemeral: ["#FFF", "#F8CB1B"], mech: [wormPink, "#ADFF2F"], wriggler: ["#FF0040", "#7300E6B2", false, "#FFF"], classic: [wormPink, "#ADFF2F"], prophet: ["#8052FF", "#FFFFFFCC"], saint: ["#FFB152", "#9169FFCC"], ephemeral_h: [bgColor, "#F8CB1B", "#FFFFFF"], mech_h: [bgColor, "#ADFF2F", "#FFFFFF"], wriggler_h: [bgColor, "#7300E6B2", "#FFFFFF", "#FF0040"], classic_h: [bgColor, "#FFFFFFCC", wormPink], prophet_h: [bgColor, "#FFFFFFCC", "#8052FF", "#9169FF"], saint_h: [bgColor, "#9169FFCC", "#FFB152"], }, drawWorm = (points) => { if (!config.flourishFlag) config.flourishFlag = {}; const length = points.length, headLength = (steps * 0.075) | 0, segmentLength = (steps / 8) | 0; let mechFlourish, flourishPosition; p.noStroke(); // Start drawing outline. for (let i = 0; i < dlAdv; i++) { p.fill(!i ? config.wormOutline : config.wormOutline + "44"); p.circle(...points[i].slice(0, 2), config.wormOutlineSize); } for (let i = 0; i < length; i++) { // Draw ahead for outline. if (i + dlAdv < length) { p.fill( i + dlAdv === length - 1 ? config.wormOutline: config.wormOutline + "44" ); p.circle(...points[i + dlAdv].slice(0, 2), config.wormOutlineSize); } let sOff = (length - headLength) % segmentLength, segment = (segmentLength + ((sOff - i) % segmentLength)) % segmentLength, tail = i < segmentLength, head = i + headLength >= length; // Draw mech segments. if (config.form === "mech" && !tail && i < length - headLength / 2) { if (!segment) { if (i < length - headLength) { flourishPosition = i - 2; mechFlourish = config.flourishFlag[i]; if (!mechFlourish) { mechFlourish = config.flourishFlag[i] = p.random([ -1, -1, -1, 1, 2, p.random(1, 2), p.random(3.1, 3.9), ]); } } p.fill(config.wormOutline); p.circle(...points[i - 2].slice(0, 2), config.wormSize + 8); p.fill( config.form === "mech" && !config.hologram && head ? "#FFF" : config.wormColor ); p.circle(...points[i - 2].slice(0, 2), config.wormSize); p.circle(...points[i - 1].slice(0, 2), config.wormSize); } if (segment && !head && mechFlourish >= 3) { let f0 = points[i - 2], f1 = points[i - 1], a = p.atan2(f1[1] - f0[1], f1[0] - f0[0]), o = p.PI * ((2 / 3) * (mechFlourish - 2)), line = [ f0[0] + (config.wormSize / 2) * p.cos(a + o), f0[1] + (config.wormSize / 2) * p.sin(a + o), ]; p.fill(config.wormOutline); p.circle(...line, 6.5); } else if ( segment && segment < segmentLength / 2 && mechFlourish >= 0 ) { let f0 = points[flourishPosition], f1 = points[flourishPosition + 1], a = p.atan2(f1[1] - f0[1], f1[0] - f0[0]), o = p.PI * ((2 / 3) * mechFlourish), bolt = [ f0[0] + (config.wormSize / 2 - 12) * p.cos(a + o), f0[1] + (config.wormSize / 2 - 12) * p.sin(a + o), ]; mechFlourish = -1; p.fill(config.wormOutline); p.circle(...bolt, 8); } if (segment < steps / 100) continue; } // Wriggler horns. if (config.wriggler && i === length - 1) { p.fill(config.wormOutline); p.stroke(config.wormOutline); p.strokeWeight(3); p.triangle( points[i][0] + 0.45 * config.wormSize * p.cos((13 * p.PI) / 20), points[i][1] - 0.45 * config.wormSize * p.sin((13 * p.PI) / 20), points[i][0] + 0.65 * config.wormSize * p.cos((14 * p.PI) / 20), points[i][1] - 0.65 * config.wormSize * p.sin((14 * p.PI) / 20), points[i][0] + 0.45 * config.wormSize * p.cos((15 * p.PI) / 20), points[i][1] - 0.45 * config.wormSize * p.sin((15 * p.PI) / 20) ); p.triangle( points[i][0] + 0.45 * config.wormSize * p.cos((7 * p.PI) / 20), points[i][1] - 0.45 * config.wormSize * p.sin((7 * p.PI) / 20), points[i][0] + 0.65 * config.wormSize * p.cos((6 * p.PI) / 20), points[i][1] - 0.65 * config.wormSize * p.sin((6 * p.PI) / 20), points[i][0] + 0.45 * config.wormSize * p.cos((5 * p.PI) / 20), points[i][1] - 0.45 * config.wormSize * p.sin((5 * p.PI) / 20) ); p.noStroke(); } // Draw the actual worm body. p.fill( config.form === "mech" && !config.hologram && head ? "#FFF": config.wormColor ); p.circle(...points[i].slice(0, 2), config.wormSize); } }, drawFaceNormal = (l) => { p.fill(config.theme[3] || config.wormOutline); p.noStroke(); p.circle(l[0] - config.wormSize / 6, l[1] - config.wormSize / 24, 6); p.circle(l[0] + config.wormSize / 6, l[1] - config.wormSize / 24, 6); p.noFill(); p.strokeWeight(5); p.stroke(config.wormOutline); p.arc( l[0], l[1] + 5 + config.wormSize / 12, config.wormSize / 5, config.wormSize / 5, 0, p.PI ); if (config.wriggler) { p.line( l[0] - (5 * config.wormSize) / 24, l[1] - config.wormSize / 6, l[0] - config.wormSize / 8, l[1] - config.wormSize / 12 ); p.line( l[0] + (5 * config.wormSize) / 24, l[1] - config.wormSize / 6, l[0] + config.wormSize / 8, l[1] - config.wormSize / 12 ); } }, drawFuckFace = (l, v) => { p.fill("#FFF"); p.stroke(bgColor); p.strokeWeight(3.5); p.ellipse( l[0] - config.wormSize / 6, l[1] - config.wormSize / 12, config.wormSize / 3, config.wormSize / 2.8 ); p.ellipse( l[0] + config.wormSize / 6, l[1] - config.wormSize / 12, config.wormSize / 3, config.wormSize / 2.8 ); p.fill(bgColor); p.noStroke(); p.circle( l[0] + v[0] - config.wormSize / 6, l[1] + v[1] - config.wormSize / 12, config.wormSize / 6 ); p.circle( l[0] + v[0] + config.wormSize / 6, l[1] + v[1] - config.wormSize / 12, config.wormSize / 6 ); p.fill(config.wormOutline); p.stroke(config.wormOutline); p.strokeWeight(5); p.arc( l[0], l[1] + config.wormSize / 5, config.wormSize / 5, config.wormSize / 5, 0, p.PI, p.CHORD ); }, drawFacePeaceful = (l) => { p.stroke(config.theme[3] || config.wormOutline); p.strokeWeight(5); p.noFill(); p.arc( l[0] - config.wormSize / 4.8, l[1] - config.wormSize / 24, config.wormSize / 6, config.wormSize / 6, p.PI / 12, (p.PI * 11) / 12 ); p.arc( l[0] + config.wormSize / 4.8, l[1] - config.wormSize / 24, config.wormSize / 6, config.wormSize / 6, p.PI / 12, (p.PI * 11) / 12 ); p.line( l[0] - config.wormSize / 12, l[1] + 5 + config.wormSize / 12, l[0] + config.wormSize / 12, l[1] + 5 + config.wormSize / 12 ); }, drawSingleHalo = (l, a = 0, o = 0.7) => { p.stroke(config.mech && !config.hologram ? wormPink : "#FFFFFF"); p.strokeWeight(4); p.noFill(); p.push(); p.translate(l[0], l[1] - config.wormSize * o); p.rotate(a); p.ellipse(0, 0, config.wormSize * 0.7, config.wormSize / 5); p.pop(); }, drawDoubleHalo = (l) => { drawSingleHalo(l, p.PI / 6, 0.8); drawSingleHalo(l, -p.PI / 6, 0.8); }, drawGrid = (_, vFrame) => { if (config.inverseGrid) { p.background(config.gridColor.substring(0, 7)); p.stroke(bgColor); } else { p.stroke(config.gridColor); } p.strokeWeight(12); let drift = (vFrame % config.driftSpeed) / config.driftSpeed; for (let i = 1; i < config.horizon; i++) { let y = vDim * (-0.16 + 1.2 * p.tan(p.atan2(1, ((i + drift) * 10) / config.horizon))); p.line(-vDim / 2, y, vDim / 2, y); } for (let i = 0; i < 2 * config.horizon; i++) { let x = vDim * (-4 + (4 * i) / config.horizon); p.line(0, vDim * -0.1, x, vDim / 2); } p.noStroke(); p.fill("#DEADC0DE"); const gradient = p.drawingContext.createLinearGradient( 0, -vDim / 2, 0, vDim / 2 ); gradient.addColorStop(0.48, bgColor); gradient.addColorStop(0.6, bgColor + "00"); p.drawingContext.fillStyle = gradient; p.square(-vDim / 2, -vDim / 2, vDim); }, drawRays = (x, vFrame) => { p.push(); const window = 4, slice = x.slice(-window), sum = slice.reduce((a, x) => [a[0] + x[0], a[1] + x[1]]), drift = p.sin(((p.PI / 16) * vFrame) / config.driftSpeed); p.translate(sum[0] / window, sum[1] / window); p.stroke(config.bgFeatureColor); p.strokeWeight(8); for (let i = 0; i < 48; i++) { p.rotate(p.PI / 24); p.line(-vDim / 2, (drift * vDim) / 16, vDim, 0); } p.pop(); }, drawTriangle = (_, vFrame) => { p.background("#100539"); const angle = p.PI * (((config.triangleDirection * vFrame) % 2000) / 1000 - 0.5); p.noStroke(); p.fill(config.triangleColor + "24"); p.triangle( vDim * 0.8 * p.cos(angle), vDim * 0.8 * p.sin(angle), vDim * 0.8 * p.cos(angle + (2 / 3) * p.PI), vDim * 0.8 * p.sin(angle + (2 / 3) * p.PI), vDim * 0.8 * p.cos(angle + (4 / 3) * p.PI), vDim * 0.8 * p.sin(angle + (4 / 3) * p.PI) ); p.fill(config.triangleColor + "12"); p.triangle( vDim * 0.7 * p.cos(angle), vDim * 0.7 * p.sin(angle), vDim * 0.7 * p.cos(angle + (2 / 3) * p.PI), vDim * 0.7 * p.sin(angle + (2 / 3) * p.PI), vDim * 0.7 * p.cos(angle + (4 / 3) * p.PI), vDim * 0.7 * p.sin(angle + (4 / 3) * p.PI) ); p.noStroke(); p.fill("#DEADC0DE"); const gradient = p.drawingContext.createRadialGradient( 0, 0, 0, 0, 0, vDim * (5 / 6 + (1 / 6) * p.sin(6 * angle)) ); gradient.addColorStop(0, config.triangleGradient + "cc"); gradient.addColorStop(0.5, config.triangleGradient + "4d"); gradient.addColorStop(1, config.triangleGradient + "00"); p.drawingContext.fillStyle = gradient; p.square(-vDim / 2, -vDim / 2, vDim); }; let config; p.myCustomRedrawAccordingToNewPropsHandler = (props) => { if (!props.transactionHash || !props.square) return; if (!isSetup) { propCache = props; return; } // Seed the p5js random seed using 32 bits from the hash. const seedOffset = 2 + 8 * (props.tokenId % 8); p.randomSeed( +("0x" + props.transactionHash.substring(seedOffset, seedOffset + 8)) ); // Set up the style. let formNum = p.random(), faceNum = p.random(), form = formNum < 0.33 ? "ephemeral": formNum < 0.61 ? "mech": formNum < 0.65 ? "prophet": formNum < 0.97 ? "classic": formNum < 0.996 ? "wriggler": "saint", classic = form === "classic", mech = form === "mech", ephemeral = form === "ephemeral", wriggler = form === "wriggler", prophet = form === "prophet", saint = form === "saint", hologram = p.random() < 0.62, theme = themes[form + (hologram ? "_h" : "")], wormColor = theme[0], wormOutline = theme[2] || bgColor, bgFeatureColor = theme[1], wormSize = p.randomGaussian(60 + p.random(20), 10), wormOutlineSize = wormSize + 9, cycle = p.randomGaussian(60, 5) | 0, length = size * p.random(0.29, 0.52) - wormSize, flusterSpeed = p.random(3) | 0, fluster = p.random(size / 6), xInc = (p.random(8) | 0) + 1, yInc = (p.random(8) | 0) + 1, xOff = p.random(p.TWO_PI), yOff = p.random(p.TWO_PI), flusterInc = (p.random(8) | 0) + 6, flusterOff = p.random(5), dSteps = steps, speed = length * xInc + length * yInc + 2 * fluster * flusterInc, jSpeed = length * xInc + length * yInc + (fluster * flusterInc * flusterInc) / 3, dur = (steps * 2 * (1 + p.abs(p.randomGaussian()))) / speed, jit = (steps / jSpeed) * (1.2 + 0.6 * p.abs(p.randomGaussian())); if (wriggler && p.random() < 0.2) { jit *= -1; } if (p.random() < 0.12) { const inc = (1 + p.random(4)) | 0; dur *= inc; dSteps *= inc; } if (p.random() < 0.04) { jit *= p.random(0.1, 0.4); } let bgr = p.random(), bgStats = {}, [bg, drawBackground] = bgr < 0.4 ? ["Grid", drawGrid]: bgr < 0.55 ? ["Rays", drawRays]: bgr < 0.8 ? ["Light", drawTriangle]: ["Void", () => {}]; if (bg === "Grid") { bgStats = { gridColor: p.random() < 0.1 ? "#FFFFFF": wriggler || prophet || p.random() < 0.2 ? bgFeatureColor: "#ADFF2F", horizon: p.randomGaussian(p.random(10, 20), 2) | 0, inverseGrid: p.random() < 0.1, }; if (bgStats.inverseGrid) { bg = "Inverted Grid"; } } else if (bg === "Rays") { const factor = p.randomGaussian(p.random(0.1, 0.3), 0.02); jit *= factor; flusterSpeed *= factor; } else if (bg === "Light") { bgStats = { triangleDirection: p.random([-1, 1]), triangleColor: wriggler ? bgFeatureColor.substring(0, 7): p.random([wormPink, "#38BCE6"]), triangleGradient: p.random([ "#36bce6", "#9f7af2", ...(classic ? ["#f8cb1b"] : []), ...(wriggler ? ["#ff5d40"] : []), ]), }; } let [face, drawFace] = wriggler ? ["Scheming", drawFaceNormal]: faceNum < 0.08 ? ["Peaceful", drawFacePeaceful]: faceNum < 0.11 && !hologram ? ["Lil Fk", drawFuckFace]: ["Smile", drawFaceNormal]; config = { square: props.square, startTime: p.millis(), drawBackground: drawBackground, drawFace: drawFace, drawHalo: ephemeral ? drawSingleHalo: mech ? drawDoubleHalo: (prophet || saint) && p.random() < 0.4 ? drawSingleHalo: () => {}, form: form, theme: theme, classic: classic, wriggler: wriggler, mech: mech, hologram: hologram, bgFeatureColor: bgFeatureColor, ...bgStats, wormColor: wormColor, wormSize: wormSize, wormOutline: wormOutline, wormOutlineSize: wormOutlineSize, driftSpeed: p.randomGaussian(20, 3), cycle: cycle, length: length, jit: jit, dur: dur, dSteps: dSteps, xInc: xInc, xOff: xOff, xOffSize: p.random(1, 5) | 0, xOffSpeed: p.random(3) | 0, yInc: yInc, yOff: yOff, yOffSize: p.random(1, 5) | 0, yOffSpeed: p.random(3) | 0, fluster: fluster, flusterSpeed: flusterSpeed, flusterOff: flusterOff, flusterAmpOff: p.random(cycle), flusterInc: flusterInc, }; window.config = config; // Metadata. let subject = mech ? "Mech Worm MK1": ephemeral ? "The Ephemeral Worm": wriggler ? "The Wriggler": prophet ? "Worm Prophet": saint ? "Worm Saint": "The Earthly Worm"; if (hologram) { subject += wriggler || saint ? " Apparition": prophet ? " Revelation": " Hologram"; } console.log("metadata: ", { Subject: subject, Background: bg, Expression: face, transactionHash: props.transactionHash, }); p.windowResized(); }; p.draw = () => { if (!isSetup || !config) return; p.scale(p.width / vDim); p.translate(vDim / 2, vDim / 2); p.strokeJoin(p.ROUND); const vFrame = (vFrameRate * (p.millis() - config.startTime)) / 1000; let points = []; let { jit } = config; if (config.paused) { jit *= -25 * p.cos((p.TWO_PI * vFrame) / 200); } else { jit *= vFrame; } for (let i = 0; i < config.dSteps; i++) { let j = (jit * p.PI) / 60 + (i / config.dSteps) * config.dur; points.push([ config.length * p.sin(j * config.xInc + config.xOff) + config.fluster * p.sin(config.flusterOff + j * config.flusterInc), config.length * p.cos(j * config.yInc + config.yOff) + config.fluster * p.cos(config.flusterOff + j * config.flusterInc), ]); } p.background(bgColor); config.drawBackground([...points], vFrame); drawWorm([...points]); const ultimate = points.pop(), penultimate = points.pop(), faceVector = [ultimate[0] - penultimate[0], ultimate[1] - penultimate[1]]; config.drawFace( [ultimate[0] + faceVector[0], ultimate[1] + faceVector[1]], faceVector ); config.drawHalo(points.pop()); }; p.setup = () => { isSetup = true; if (propCache) { p.updateWithProps(propCache); } }; p.windowResized = () => { if (!isSetup || !config || !config.square) return; const SCALE = 0.8, WIDTH = (window.innerWidth / config.square) * SCALE, HEIGHT = (window.innerHeight / config.square) * SCALE, DIM = p.min(WIDTH, HEIGHT); p.resizeCanvas(DIM, DIM); }; ```