/*
* Angela Lee
* Section E
* ahl2@andrew.cmu.edu
* Project 11 Generative Landscape
*/
// tallest mountains
var tallMtnDetail = 0.005; // detail in mountains
var tallMtnSpeed = 0.0001; // speed of mountains
// medium mountains
var medMtnDetail = 0.0075;
var medMtnSpeed = 0.0002;
// beach
var beachDetail = 0.003;
var beachSpeed = 0.0004;
// array for ripples
var ripples = [];
var yellow, pink;
function setup() {
createCanvas(480, 300);
frameRate(10);
// boundaries for ripples
var top = height * 5/8 + 10;
var bottom = height - 10;
// first ripples
for (var i = 0; i < 10; i++) {
var rippleX = random(width);
var rippleY = random(top, bottom);
ripples[i] = makeRipples(rippleX, rippleY);
}
// gradient for the water
yellow = color(255, 219, 140);
pink = color(247, 132, 124);
}
function draw() {
noStroke();
background(255, 156, 161);
makeSun(); // setting sun
makeTallMtn(); // tallest mountains
makeMedMtn(); // middle mountains
//makeWater();
gradientWater();
// ripple functions
updateRipple();
removeRipple();
addRipple();
makeBeach();
}
//----------------- FUNCTIONS BELOW THIS LINE -----------------------------
// SETTING SUN
function makeSun() {
// sun rays
noStroke();
fill(255, 161, 135);
ellipse(width/2, height * 3/8, 275, 275);
// sun
stroke(255);
strokeWeight(1);
fill(247, 217, 82);
ellipse(width/2, height * 3/8, 175, 175);
}
// TALLEST MOUNTAINS
function makeTallMtn() {
fill(252, 119, 165);
strokeWeight(1);
beginShape();
vertex(0, height);
for (var x = 0; x < width; x++) {
var t = (x * tallMtnDetail) + (millis() * tallMtnSpeed);
var y = map(noise(t), 0, 1, height / 8 * 2, height / 8 * 4);
vertex(x, y);
}
vertex(width, height);
endShape();
}
// MEDIUM MOUTAINS
function makeMedMtn() {
fill(230, 99, 160);
strokeWeight(1);
beginShape();
vertex(0, height);
for (var x = 0; x < width; x++) {
var t = (x * medMtnDetail) + (millis() * medMtnSpeed);
var y = map(noise(t), 0, 1, height / 8 * 3, height / 8 * 5);
vertex(x, y);
}
vertex(width, height);
endShape();
}
// OCEAN
function gradientWater() {
noFill();
for (var y = height * 5/8; y < height; y++) {
var inter = map(y, height * 5/8, height, 0, 1);
var c = lerpColor(yellow, pink, inter);
stroke(c);
line(0, y, width, y);
}
}
// BEACH
function makeBeach() {
fill(252, 195, 182);
strokeWeight(1);
beginShape();
vertex(0, height);
for (var x = 0; x < width; x++) {
var t = (x * beachDetail) + (millis() * beachSpeed);
var y = map(noise(t), 0, 1, height * 7/8, height * 19/20);
vertex(x, y);
}
vertex(width, height);
endShape();
}
//----------------- RIPPLE OBJ & FUNCTIONS BELOW THIS LINE -----------------------------
// RIPPLE OBJECT
function makeRipples(xPos, yPos) {
var makeRipple = {x: xPos,
y: yPos,
// longer ripples are in the front, shorter ones in the back
length: map(yPos, height * 5/8, height, 5, 75),
// thinner ripples in the back, thicker ones in the front
weight: map(yPos, height * 5/8, height, 1, 4),
// faster ripples in the front, slower ripples in the back
speed: map(yPos, height * 5/8, height, 1, 4),
move: moveRipple,
draw: drawRipple}
return makeRipple;
}
// MOVING THE RIPPLE
function moveRipple() {
// x position changes by speed
this.x += this.speed;
// if the ripple leaves the frame, reset x position
// to the left side of the frame
if (this.x > width + this.length) {
this.x === -this.length;
}
}
// ADDING RIPPLES
// using a tiny probability, add ripples
function addRipple() {
if (random(0, 1) < 0.075) {
ripples.push(makeRipples(-75, random(height * 5/8, height)));
}
}
// REMOVING RIPPLES
function removeRipple() {
// an array for ripples to keep
var keepRipples = [];
for (var i = 0; i < ripples.length; i++) {
if (ripples[i].x < width) {
keepRipples.push(ripples[i]);
}
}
ripples = keepRipples;
}
// UPDATE AND DISPLAY RIPPLE
function updateRipple() {
for (var i = 0; i < ripples.length; i++) {
ripples[i].move();
ripples[i].draw();
}
}
// DRAWING THE RIPPLE
function drawRipple() {
strokeWeight(this.weight);
stroke(255);
line(this.x, this.y, this.x + this.length, this.y);
}
For my landscape, I was inspired the 80s vaporwave illustration style and color. I created a sunset scene and had fun with showing depth through details. For instance, the sizes and speeds of the mountains and ripples are all dependent on the “distance” they would be away from the viewer (the farther something is, the slower and smaller it is).
I’m using a grace day for this project 🙂