font = loadFont('https://fonts.gstatic.com/s/sacramento/v15/buEzpo6gcdjy0EiZMBUG0CoV_NxLeiw.ttf')
createCanvas(windowWidth, windowHeight, WEBGL)
pipe = buildGeometry(() => {
const path = BezierPath.create([
right: { x: -100, y: -50 }
for (let i = 0; i <= numPoints; i++) {
const len = map(i, 0, numPoints, 0, path.getTotalLength())
const pt = path.getPointAtLength(len)
const tan = path.getTangentAtLength(len)
pts.push(createVector(pt.x, pt.y, 0))
tangents.push(createVector(tan.x, tan.y))
const normals = tangents.map((t) => t.copy().cross(createVector(0, 0, 1)))
const getR = (i) => lerp(10, 40, map(i, numPoints*0.1, numPoints*0.8, 0, 1, true))
for (let i = 0; i < numPoints; i++) {
beginShape(TRIANGLE_STRIP)
for (let j = 0; j <= circlePoints; j++) {
const angle = j/circlePoints * TWO_PI
for (let off of [0, 1]) {
const n1 = createVector(0, 0, 1)
const n2 = normals[i + off]
const pt = c.copy().add(n2.copy().mult(sin(angle)*r)).add(n1.copy().mult(cos(angle)*r))
rotateX(sin(millis() * 0.001) * PI * 0.1)
rotateY(sin(millis() * 0.0021) * PI * 0.025)
textAlign(CENTER, BOTTOM)
text(`Ceci n'est pas une pipe.`, 0, height * 0.4)