0xfc3d126d…1282sent to0x499f4943…3001·#16,831,900·view on Etherscan
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);
};
```