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.
