let d;
let c1;
let c2;

function setup() {
  const s = min(windowWidth, windowHeight);
  createCanvas(s, s);
  d = s;
  c1 = random(0, 255);
  c2 = random(0, 255);
}

function draw() {
  background(255, 100);
  noStroke();
  fill(0);

  const distanceRatio = getDistanceRatio(d)[0];
  const angle = getDistanceRatio(d)[1];
  generateMountain(angle,distanceRatio);

}

function getDistanceRatio(d) {
  let angle = atan2(mouseY - d / 2, mouseX - d / 2);
  const distance = dist(mouseX, mouseY, d / 2, d / 2);
  let distanceRatio = map(distance, 0, d / 2, 0, 4);
  return [distanceRatio, angle];
}

function mountain(gx, gy, rx, h, topRatio) {
  ellipseMode(CENTER);
  push();
  translate(gx, gy);
  let ratio;
  for (let i = 0; i > -h; i -= 1) {
    ratio = map(i, 0, -h, 1, topRatio);
    ratio = pow(ratio, 3);
    fill(map(i, 0, -h, 255, 0));
    ellipse(0, i, rx * ratio, rx * ratio);
  }
  colorMode(HSB);
  fill(c1, c2, 100);
  ellipse(0, -h, rx * ratio, rx * ratio);
  pop();
}

function generateMountain(angle,distanceRatio){
    push();
  translate(d / 2, d / 2);
  rotate(angle + HALF_PI);

  const span = width / 3.4;
  const ns = 0.2;
  const noffs = 0.35;
  const cycle = 480;
  const nRad = ((frameCount % cycle) / cycle) * TAU;

  const nx = cos(nRad) * noffs;
  const ny = sin(nRad) * noffs;

  const h =
    (span / 2) * distanceRatio * (pow(noise(nx, ny * 1.2), 2) * 1.2 + 0.1);
  const topRatio = noise(nx * 3, ny * 3, 10) + 0.1;
  const rx = span / 1.2;
  mountain(0, 0, rx, h, topRatio);
  pop();
}

I don't think there's much to say about this week's code. By encapsulating the previous week 2 code into a function, the code block will look much neater and easier to understand. The order of the code is as shown above.

Frame 1.png