For my project, I created a story of Santa Clause delivering presents and running into a penguin. Now that Halloween is over, it is Christmas time.
I used Illustrator to create vector drawings correlating to the canvas size.
sketch
//general story
//Santa Clause was delivering presents when he ran into a penguin
let snowflakes = [];
function setup() {
createCanvas(400, 200);
useSound();
}
function soundSetup() {
osc = new p5.Oscillator();
osc.amp(0.25);
osc.setType('square');
osc.start();
}
// Frequencies in Hz for each of the white and black keys, left to right
var white_freqs = [261.625, 293.665, 329.63, 349.23, 392, 440, 493.88, 523.25];
var black_freqs = [277, 311, 0, 370, 415, 466]; // index 2 not used
function draw() {
background(0, 0, 68);
noStroke();
fill(230, 249, 255);
rect(0, 180, 400, 200);
penguin();
tree();
santa();
elf();
present();
let t = frameCount / 60; // update time
// create a random number of snowflakes each frame
for (let i = 0; i < random(5); i++) {
snowflakes.push(new snowflake()); // append snowflake object
}
// loop through snowflakes with a for..of loop
for (let flake of snowflakes) {
flake.update(t); // update snowflake position
flake.display(); // draw snowflake
}
}
// snowflake class
function snowflake() {
// initialize coordinates
this.posX = 0;
this.posY = random(-50, 0);
this.initialangle = random(0, 2 * PI);
this.size = random(2, 5);
// radius of snowflake spiral
// chosen so the snowflakes are uniformly spread out in area
this.radius = sqrt(random(pow(width / 2, 2)));
this.update = function(time) {
// x position follows a circle
let w = 0.6; // angular speed
let angle = w * time + this.initialangle;
this.posX = width / 2 + this.radius * sin(angle);
// different size snowflakes fall at slightly different y speeds
this.posY += pow(this.size, 0.5);
// delete snowflake if past end of screen
if (this.posY > height) {
let index = snowflakes.indexOf(this);
snowflakes.splice(index, 1);
}
};
this.display = function() {
ellipse(this.posX, this.posY, this.size);
};
}
function mousePressed() {
if(mouseY >= 0 & mouseY < 200 && mouseX >= 25 && mouseX < 325) {
var keynum = constrain(floor((mouseX - 25) / 50), 0, 5);
if(keynum != 2) {
osc.start();
osc.freq(black_freqs[keynum]);
}
}
}
function penguin() {
push();
noStroke();
translate(0, 0);
fill(50);
rectMode(CENTER);
//face
ellipse(49.5, 90.5, 39, 39);
fill(20);
//wings
ellipse(35, 131.5, 8, 55);
//wings
ellipse(64, 131.5, 8, 55);
fill(50);
//body
rect(49.5, 142, 29, 82);
//belly
fill(255);
ellipse(50, 137.5, 16, 55);
fill(255, 255, 0);
//foot
ellipse(35.5, 182.5, 15, 9);
//foot
ellipse(64.5, 182.5, 15, 9);
fill(255, 255, 0);
//beak
ellipse(37, 90.5, 22, 3);
fill(255);
//eyes
ellipse(40.5, 83.5, 3, 3);
//eyes
ellipse(55.5, 83.5, 3, 3);
pop();
}
function tree() {
push();
noStroke();
translate(0, 0);
fill(210, 105, 30);
rectMode(CENTER);
rect(100, 162, 7, 43);
//triangle 1
fill(34, 139, 34);
beginShape();
vertex(100, 69.7388);
vertex(82.5, 130.5);
vertex(117.8899, 130.5);
endShape();
//triangle 2
beginShape();
vertex(100, 100.7388);
vertex(82.5, 161.5);
vertex(117.8899, 161.5);
endShape();
fill(255, 255, 0);
//star
ellipse(100, 71, 9 ,9);
pop();
}
function santa() {
push();
noStroke();
translate(0, 0);
//body
fill(255, 0, 0);
ellipse(200, 150.5, 44, 61);
fill(255);
ellipse(200, 70, 9, 9);
//face
fill(255, 230, 204);
ellipse(200.5, 110.5, 31, 31);
//hat
fill(255, 0, 0);
beginShape();
vertex(200.0522, 70);
vertex(187.2356, 101.5);
vertex(213.1543, 101.5);
endShape();
//boots
fill(0);
ellipse(189.5, 179.5, 15, 9);
ellipse(211.5, 179.5, 15, 9);
fill(255);
//buttons
ellipse(200, 135, 9, 9);
ellipse(200, 150, 9, 9);
ellipse(200, 165, 9, 9);
//eyes
fill(0);
ellipse(193, 110, 4, 4);
ellipse(209, 110, 4, 4);
pop();
}
function elf() {
push();
noStroke();
translate(0, 0);
rectMode(CENTER);
//arm
fill(0, 102, 0);
rect(242, 155.5, 7, 30);
rect(258, 155.5, 7, 30);
//body
fill(51, 153, 51);
rect(250, 159, 17, 43);
//face
fill(255, 230, 204);
ellipse(249.5, 130.5, 29, 29);
//ears
ellipse(234.5, 131, 3, 14);
ellipse(264.5, 131, 3, 14);
//shoes
fill(255, 0, 0);
ellipse(241.5, 181, 15, 6);
ellipse(258.5, 181, 15, 6);
//hat
beginShape();
vertex(249.0522, 94);
vertex(236.2356, 125.5);
vertex(263.1543, 125.5);
endShape();
//hat top
fill(255);
ellipse(249, 92, 9, 9);
//eyes
fill(0);
ellipse(243, 129, 4, 4);
ellipse(256, 129, 4, 4);
pop();
}
function present() {
push();
noStroke();
translate(0, 0);
rectMode(CENTER);
//present
fill(204, 0, 0);
rect(299.5, 166.5, 35, 35);
//ribbon
fill(255, 204, 0);
rect(299.5, 166.5, 5, 35);
rect(299.5, 166.5, 35, 3);
noFill();
strokeWeight(2);
stroke(255, 204, 0);
ellipse(295, 148, 10, 8);
ellipse(304, 148, 10, 8);
pop();
}