260126

const { animate } = anime;
const W = 800;
const H = 800;
const DEPTH_COUNT = 3;

let palette = [];
let animeValue = {
  count: 0,
};
let depthCount = 0;

function setup() {
  createCanvas(W, H, WEBGL);
  palette = colorArray[1].colors;
  background(palette[4]);
  animate(animeValue, {
    count: 1,
    duration: 2500,
    ease: 'inSine',
    loop: true,
    loopDelay: 400,
    alternate: true,
    onLoop: function () {
      if (animeValue.count < 0.5) {
        if (depthCount >= DEPTH_COUNT) {
          depthCount = 0;
        }
        depthCount++;
      }
    },
  });
}

function draw() {
  background(palette[4]);
  // orbitControl();

  let boxSize = 200;
  let boxNum = 2;
  push();
  translate(-boxSize * (boxNum - 1) / 2, -boxSize * (boxNum - 1) / 2, -boxSize * (boxNum - 1) / 2);
  noFill();
  drawBoxGrid(boxSize, boxNum, 0, DEPTH_COUNT);
  pop();
  // noLoop();
}


function drawBoxGrid(boxSize, boxNum, depth, maxDepth) {
  if (depth >= maxDepth) {
    return;
  }

  let f = animeValue.count;
  let animatedF = (depth === depthCount - 1) ? f : 0;
  for (let x = 0; x < boxNum; x++) {
    for (let y = 0; y < boxNum; y++) {
      for (let z = 0; z < boxNum; z++) {
        push();
        translate(x * boxSize, y * boxSize, z * boxSize);
        rotateX(x * TAU / 4);
        rotateY(y * TAU / 4);
        rotateZ(z * TAU / 4);

        push();
        strokeWeight(maxDepth - depth);
        stroke(palette[depth % palette.length + 1]);
        let radius = boxSize;
        let segments = 3;
        let v1 = createVector(radius, 0, 0);
        let v2 = createVector(0, radius, radius);
        translate(-boxSize / 2, -boxSize / 2, -boxSize / 2);
        // ref: https://beta.p5js.org/reference/p5/splineproperties/
        splineProperties({
          tightness: 1,
          ends: EXCLUDE
        });
        beginShape();
        splineVertex(boxSize, 0, 0);
        for (let i = 0; i <= segments; i++) {
          let t = i / segments;
          let v = p5.Vector.slerp(v1, v2, animatedF * t);
          let bulge = sin(t * TAU / 8);
          v.add(createVector(bulge, bulge, bulge));
          splineVertex(v.x, v.y, v.z);
        }
        splineVertex(0, boxSize, boxSize);
        endShape();
        pop();


        push();
        strokeWeight(0.5);
        stroke(palette[5]);
        box(boxSize);
        pop();

        // 再帰的に小さいボックスグリッドを描画
        if (depth < maxDepth - 1) {
          let smallerBoxSize = boxSize / boxNum;
          push();

          translate(-boxSize / 2 + smallerBoxSize * (boxNum - 1) / 2,
            -boxSize / 2 + smallerBoxSize * (boxNum - 1) / 2,
            -boxSize / 2 + smallerBoxSize * (boxNum - 1) / 2);
          drawBoxGrid(smallerBoxSize, boxNum, depth + 1, maxDepth);
          pop();
        }

        pop();
      }
    }
  }
}

const colorArray = [
  {
    id: 0,
    colors: ['#253276', '#dfdad3', '#ffffff', '#000000'],
  },
  {
    id: 1,
    colors: [
      '#9dbdba',
      '#f8b042',
      '#e47763',
      '#253276',
      '#dfdad3',
      '#FFFFFF',
      '#000000',
    ],
  },
];

genuary2026 

Day26:Recursive Grids. Split the canvas into a grid of some kind and recurse on each cell again and again.

const { animate } = anime;
const W = 800;
const H = 800;
const DEPTH_COUNT = 3;

let palette = [];
let animeValue = {
  count: 0,
};
let depthCount = 0;

function setup() {
  createCanvas(W, H, WEBGL);
  palette = colorArray[1].colors;
  background(palette[4]);
  animate(animeValue, {
    count: 1,
    duration: 2500,
    ease: 'inSine',
    loop: true,
    loopDelay: 400,
    alternate: true,
    onLoop: function () {
      if (animeValue.count < 0.5) {
        if (depthCount >= DEPTH_COUNT) {
          depthCount = 0;
        }
        depthCount++;
      }
    },
  });
}

function draw() {
  background(palette[4]);
  // orbitControl();

  let boxSize = 200;
  let boxNum = 2;
  push();
  translate(-boxSize * (boxNum - 1) / 2, -boxSize * (boxNum - 1) / 2, -boxSize * (boxNum - 1) / 2);
  noFill();
  drawBoxGrid(boxSize, boxNum, 0, DEPTH_COUNT);
  pop();
  // noLoop();
}


function drawBoxGrid(boxSize, boxNum, depth, maxDepth) {
  if (depth >= maxDepth) {
    return;
  }

  let f = animeValue.count;
  let animatedF = (depth === depthCount - 1) ? f : 0;
  for (let x = 0; x < boxNum; x++) {
    for (let y = 0; y < boxNum; y++) {
      for (let z = 0; z < boxNum; z++) {
        push();
        translate(x * boxSize, y * boxSize, z * boxSize);
        rotateX(x * TAU / 4);
        rotateY(y * TAU / 4);
        rotateZ(z * TAU / 4);

        push();
        strokeWeight(maxDepth - depth);
        stroke(palette[depth % palette.length + 1]);
        let radius = boxSize;
        let segments = 3;
        let v1 = createVector(radius, 0, 0);
        let v2 = createVector(0, radius, radius);
        translate(-boxSize / 2, -boxSize / 2, -boxSize / 2);
        // ref: https://beta.p5js.org/reference/p5/splineproperties/
        splineProperties({
          tightness: 1,
          ends: EXCLUDE
        });
        beginShape();
        splineVertex(boxSize, 0, 0);
        for (let i = 0; i <= segments; i++) {
          let t = i / segments;
          let v = p5.Vector.slerp(v1, v2, animatedF * t);
          let bulge = sin(t * TAU / 8);
          v.add(createVector(bulge, bulge, bulge));
          splineVertex(v.x, v.y, v.z);
        }
        splineVertex(0, boxSize, boxSize);
        endShape();
        pop();


        push();
        strokeWeight(0.5);
        stroke(palette[5]);
        box(boxSize);
        pop();

        // 再帰的に小さいボックスグリッドを描画
        if (depth < maxDepth - 1) {
          let smallerBoxSize = boxSize / boxNum;
          push();

          translate(-boxSize / 2 + smallerBoxSize * (boxNum - 1) / 2,
            -boxSize / 2 + smallerBoxSize * (boxNum - 1) / 2,
            -boxSize / 2 + smallerBoxSize * (boxNum - 1) / 2);
          drawBoxGrid(smallerBoxSize, boxNum, depth + 1, maxDepth);
          pop();
        }

        pop();
      }
    }
  }
}

const colorArray = [
  {
    id: 0,
    colors: ['#253276', '#dfdad3', '#ffffff', '#000000'],
  },
  {
    id: 1,
    colors: [
      '#9dbdba',
      '#f8b042',
      '#e47763',
      '#253276',
      '#dfdad3',
      '#FFFFFF',
      '#000000',
    ],
  },
];

Last Updated:

260126