260129

const { animate } = anime;
const W = 800;
const H = 800;
const NUM_ROWS = 3;
const NUM = 20;
const TRIANGLE_SIZE = 50;
const R_SIZE = 250;
const OFFSET = 3;
const DELAY = 0.48;

let palette = [];
let animeValue = {
  count: 0,
};
let rotateValue = {
  count: 0,
};
function setup() {
  createCanvas(W, H, WEBGL);
  palette = colorArray[1].colors;
  background(palette[4]);
  animate(animeValue, {
    count: 1,
    duration: 5000,
    ease: 'linear',
    loop: true,
  });
  animate(rotateValue, {
    count: 1,
    duration: 2000,
    ease: 'outInExpo',
    loop: true,
  });
}

function draw() {
  background(palette[4]);
  orbitControl();
  push();
  noStroke();
  let animeCount = animeValue.count;
  let rotateCount = rotateValue.count;
  translate(0, -H / 2, 0);
  for (let i = 0; i < NUM_ROWS; i++) {
    push();
    rotateY(TAU / NUM_ROWS * i);
    for (let j = 0; j < NUM; j++) {

      // 今の三角形の位置
      let { x, y, z } = getPosition(j, i, animeCount);
      // 前の三角形の位置
      let jNext = (j === NUM - 1) ? j - 1 : j + 1;
      let { x: xNext, y: yNext, z: zNext } = getPosition(jNext, i, animeCount);

      // 前の三角形→今の三角形 の差分
      let dx, dy, dz;
      if (j === NUM - 1) {
        dx = x - xNext;
        dy = y - yNext;
        dz = z - zNext;
      } else {
        dx = xNext - x;
        dy = yNext - y;
        dz = zNext - z;
      }

      // 回転角Y方向(垂直方向)の傾き
      // dx, dzの差分から進行方向の角度
      let angleY = atan2(dx, dz);
      // XZ平面での2点間の距離
      let horizontalLen = sqrt(dx * dx + dz * dz);
      // dyとXZ平面の距離から 垂直方向の角度
      let angleX = -atan2(dy, horizontalLen);

      push();
      translate(x, y, z);
      rotateY(angleY);
      rotateX(-PI / 2 + angleX);

      push();
      stroke(palette[6]);
      push();
      if (!(i === 1)) {
        fill(palette[int((i + j) % (palette.length - 3))]);
      } else {
        fill(palette[5]);
      }
      translate(TRIANGLE_SIZE / 2, 0, 0);
      rotateY(rotateCount * TAU + (i + j));
      translate(-TRIANGLE_SIZE / 2, 0, 0);
      triangle(0, 0, TRIANGLE_SIZE, 0, TRIANGLE_SIZE / 2, TRIANGLE_SIZE);
      pop();

      push();
      if (!(i === 1)) {
        fill(palette[int((i % j) % (palette.length - 3))]);
      } else {
        fill(palette[5]);
      }
      translate(TRIANGLE_SIZE / 2, 0, 0);
      rotateY(rotateCount * TAU + (i + j) * DELAY);
      translate(-TRIANGLE_SIZE / 2, 0, 0);
      translate(0, -OFFSET, 0);
      triangle(0, 0, TRIANGLE_SIZE, 0, TRIANGLE_SIZE / 2, -TRIANGLE_SIZE);
      pop();
      pop();
      pop();
    }
    pop();
  }
  pop();

  // noLoop();
}


function getPosition(idx, row, cVal) {
  let theta = idx * TAU / NUM + cVal * TAU;
  let y = idx * H / NUM;
  let r = (!(row === 1)) ? R_SIZE : R_SIZE / 2;
  if (row === 1) {
    r *= cos(theta * 3);
  }
  let x = cos(theta) * r;
  let z = sin(theta) * r;

  return { x, y, z };
}

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

genuary2026 

Day29:Genetic evolution and mutation.

const { animate } = anime;
const W = 800;
const H = 800;
const NUM_ROWS = 3;
const NUM = 20;
const TRIANGLE_SIZE = 50;
const R_SIZE = 250;
const OFFSET = 3;
const DELAY = 0.48;

let palette = [];
let animeValue = {
  count: 0,
};
let rotateValue = {
  count: 0,
};
function setup() {
  createCanvas(W, H, WEBGL);
  palette = colorArray[1].colors;
  background(palette[4]);
  animate(animeValue, {
    count: 1,
    duration: 5000,
    ease: 'linear',
    loop: true,
  });
  animate(rotateValue, {
    count: 1,
    duration: 2000,
    ease: 'outInExpo',
    loop: true,
  });
}

function draw() {
  background(palette[4]);
  orbitControl();
  push();
  noStroke();
  let animeCount = animeValue.count;
  let rotateCount = rotateValue.count;
  translate(0, -H / 2, 0);
  for (let i = 0; i < NUM_ROWS; i++) {
    push();
    rotateY(TAU / NUM_ROWS * i);
    for (let j = 0; j < NUM; j++) {

      // 今の三角形の位置
      let { x, y, z } = getPosition(j, i, animeCount);
      // 前の三角形の位置
      let jNext = (j === NUM - 1) ? j - 1 : j + 1;
      let { x: xNext, y: yNext, z: zNext } = getPosition(jNext, i, animeCount);

      // 前の三角形→今の三角形 の差分
      let dx, dy, dz;
      if (j === NUM - 1) {
        dx = x - xNext;
        dy = y - yNext;
        dz = z - zNext;
      } else {
        dx = xNext - x;
        dy = yNext - y;
        dz = zNext - z;
      }

      // 回転角Y方向(垂直方向)の傾き
      // dx, dzの差分から進行方向の角度
      let angleY = atan2(dx, dz);
      // XZ平面での2点間の距離
      let horizontalLen = sqrt(dx * dx + dz * dz);
      // dyとXZ平面の距離から 垂直方向の角度
      let angleX = -atan2(dy, horizontalLen);

      push();
      translate(x, y, z);
      rotateY(angleY);
      rotateX(-PI / 2 + angleX);

      push();
      stroke(palette[6]);
      push();
      if (!(i === 1)) {
        fill(palette[int((i + j) % (palette.length - 3))]);
      } else {
        fill(palette[5]);
      }
      translate(TRIANGLE_SIZE / 2, 0, 0);
      rotateY(rotateCount * TAU + (i + j));
      translate(-TRIANGLE_SIZE / 2, 0, 0);
      triangle(0, 0, TRIANGLE_SIZE, 0, TRIANGLE_SIZE / 2, TRIANGLE_SIZE);
      pop();

      push();
      if (!(i === 1)) {
        fill(palette[int((i % j) % (palette.length - 3))]);
      } else {
        fill(palette[5]);
      }
      translate(TRIANGLE_SIZE / 2, 0, 0);
      rotateY(rotateCount * TAU + (i + j) * DELAY);
      translate(-TRIANGLE_SIZE / 2, 0, 0);
      translate(0, -OFFSET, 0);
      triangle(0, 0, TRIANGLE_SIZE, 0, TRIANGLE_SIZE / 2, -TRIANGLE_SIZE);
      pop();
      pop();
      pop();
    }
    pop();
  }
  pop();

  // noLoop();
}


function getPosition(idx, row, cVal) {
  let theta = idx * TAU / NUM + cVal * TAU;
  let y = idx * H / NUM;
  let r = (!(row === 1)) ? R_SIZE : R_SIZE / 2;
  if (row === 1) {
    r *= cos(theta * 3);
  }
  let x = cos(theta) * r;
  let z = sin(theta) * r;

  return { x, y, z };
}

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

Last Updated:

260129