xxxxxxxxxx
173
//https://www.iwc.com/content/dam/rcq/iwc/19/42/72/4/1942724.png
let moon,
moonRef,
glow,
moonDisc,
moonDial,
showMoonRef = false,
glowBlurLevel = 32, //>8 slows down launch so turn down during dev
rotation = 0,
rotationRate = 0.005,
doRotation = true;
let w = 800,
h = 800,
cx = w/2,
cy = h/2;
function preload() {
moonRef = loadImage("assets/moon.png"); //prerendering buffers requires preloaded assets
}
function setup() {
createCanvas(w, h);
//moon = generateMoon(w*0.85); //procedural moon
moon = generatePhotoMoon(w*0.85, moonRef); //posterized moon photo
glow = generateGlow(w*.95);
moonDisc = generateMoonDisc(moon, glow, w);
moonDial = generateMoonDial(w);
imageMode(CENTER);
}
function draw() {
background(200,169,146);
tint(255, 255, 255, 255);
push();
translate(cx, cy);
//rotate(TWO_PI * mouseX / width);
rotate(rotation);
if (doRotation) rotation+=rotationRate;
image(moonDisc, 0,0);
pop();
image(moonDial, cx, cy);
}
//Creates a dial window for the lunar complication:
function generateMoonDial(d) {
let mw = createGraphics(d, d);
let mainColor = color(228,199,176);
mw.stroke(mainColor);
mw.noFill();
mw.strokeWeight(10);
mw.ellipse(d/2, d/2, d, d);
mw.fill(mainColor);
mw.noStroke();
mw.arc(d/2, d/2, d, d, 0, PI);
let windowSize = d/2*1.13,
windowY = d*0.6,
lateralOffset = d*0.01;
//mw.ellipse(d/4-lateralOffset, windowY, windowSize, windowSize);
mw.arc(d/4-lateralOffset, windowY, windowSize, windowSize, PI, TWO_PI)
//mw.ellipse(3*d/4+lateralOffset, windowY, windowSize, windowSize);
mw.arc(3*d/4+lateralOffset, windowY, windowSize, windowSize, PI, TWO_PI)
mw.ellipse(d/2, d/2, d/8, d/8);
//procedural drop shadow/blur:
let top = createGraphics(d, d);
top.copy(mw, 0,0,d,d,0,0,d,d);
mw.filter(THRESHOLD, .99);
mw.filter(BLUR, 16);
mw.copy(top, 0,0,d,d,0,0,d,d);
return mw;
}
//uses moon and glow assets to create a lunar phase
//complication dial - two glowing moons and a starfield
function generateMoonDisc(mImg, gImg, d) {
let disc = createGraphics(d, d);
disc.fill(42,63,93);
disc.noStroke();
disc.ellipse(d/2, d/2, d, d);
disc.imageMode(CENTER);
disc.push();
disc.translate(d/2, d/2);
for (let i=0; i<1000; i++) {
disc.stroke(255);
disc.strokeWeight(random(0.5, 2.5));
let t = random(0, TWO_PI);
let r = random(0, d/2-4);
disc.point(cos(t) * r, sin(t) * r);
}
disc.pop();
let mSize = 0.35 * d,
gSize = 0.45 * d,
lateralOffset = d*0.04;
disc.image(gImg, d/4-lateralOffset, d/2, gSize, gSize);
disc.image(gImg, 3*d/4+lateralOffset, d/2, gSize, gSize);
disc.image(mImg, d/4-lateralOffset, d/2, mSize, mSize);
disc.image(mImg, 3*d/4+lateralOffset, d/2, mSize, mSize);
return disc;
}
//returns a buffer with a posterized moon image
function generatePhotoMoon(dm, img) {
let m = createGraphics(dm, dm),
scale = 1.171;
m.imageMode(CENTER);
m.tint(200, 200, 255);
m.image(img, dm/2, dm/2, dm*scale, dm*scale);
m.filter(POSTERIZE, 8);
//m.filter(GRAY);
return m;
}
function generateGlow(dm) {
let g = createGraphics(dm, dm);
g.fill(255);
g.noStroke();
let scale = 0.9;
g.ellipse(dm/2, dm/2, dm*scale, dm*scale);
g.filter(BLUR, glowBlurLevel);
return g;
}
//Fun but... hard to make look the best
function generateMoon(dm) {
let base = color(198,191,178),
dark = color(66,66,68),
light = color(215,213,198);
let m = createGraphics(dm, dm);
m.noStroke();
m.fill(base);
m.ellipse(dm/2, dm/2, dm, dm);
m.fill(dark);
crater(0.24, 0.7, 0.2, dm, m);
crater(0.175, 0.5, 0.28, dm, m);
crater(0.172, 0.4, 0.29, dm, m);
crater(0.2, 0.3, 0.27, dm, m);
crater(0.3, 0.35, 0.28, dm, m);
crater(0.4, 0.25, 0.25, dm, m);
crater(0.6, 0.28, 0.2, dm, m);
crater(0.7, 0.45, 0.2, dm, m);
crater(0.9, 0.4, 0.125, dm, m);
m.fill(light);
crater(0.38, 0.85, 0.075, dm, m);
crater(0.28, 0.42, 0.075, dm, m);
m.stroke(light);
m.strokeWeight(3);
m.noFill();
m.filter(BLUR, 1);
return m;
}
//helper function to draw circles using
//coordinates based on % of overall moon size
function crater(x,y,d, dm, m) {
m.ellipse(x*dm, y*dm, d*dm, d*dm);
}
function streak(x1,y1,x2, y2, d, dm, m) {
m.ellipse(x*dm, y*dm, d*dm, d*dm);
}
function keyPressed() {
if (key=='r') showMoonRef = !showMoonRef;
if (key==' ') doRotation = !doRotation;
if (key=='f') {
let fs = fullscreen();
fullscreen(!fs);
}
}