For my project, I created an animated children’s book. This project was really exciting to create as I was able to practice using simple and more complex animation. With having 10 pages, I focused on experimenting with different kinds of animations and page turning effects. All of the backgrounds were drawn by me! The animated objects were also drawn by me, or created in p5.js. For the sake of cleanliness and consistency, I decided that drawing the background images myself would be the best possible solution.
The code is structured by creating an array of functions that implements the functions by indexing through a page number counter.
Detailed page explanations below:

On page 4, the Giraffe suggests for the Lion to sleep with a spoon under his pillow to make it rain, so the user must move the spoon to the pillow. When the spoon is within the boundaries of the pillow, it flips to the next page. 
On page 5, I chose to do a simple page turning animation where the user must click within the boundary of the page turning image. While not nearly as complex as other pages, it was necessary to add this page for the sake of the story!

On page 9, the animals are having a party so I created an object animation of balloons floating to the top of the page. When the array length (i.e # of balloons) reaches 10 balloons, it moves to the next page.

On the last page, the animals begin to dance and I use a frame animation to flip through images of the animals moving. It also begins to rain and I created an object animation of rain falling from the top of the canvas.
Since I created a lot of my own images, I decided to package this project on my computer and run it on a local server.
To run this program:
- Download .zip file and extract it to your computer
- Open a command prompt, and type cd “path to file” (ex: C:\Users\Cassie Howard\Downloads\cmhoward-final-project\template-all)
- Then connect to python “python -m http.server”
- After it connects, open up http://localhost:8000 in your web browser.
If you get confused on how to move to the next page, remember the different page turning implementations i.e clicking on the jittering objects, completing the animation, or simply waiting (i.e for ten balloons to appear).
cmhoward-final-project
Code to drag objects inspired by:
Draggable Example (written by Daniel Shiffman)
code below! (it’s not NOT working, you just can’t see all of the background images until you connect to a local server!)
sketch-87
var page1;
var page2;
var page3;
var page4;
var spoon;
var page5;
var page6;
var page7;
var page8;
var page9;
var page10;
var turn_page;
var tomato;
var page = 0;
var clickFunctions = [click1, click2, click3, click4, click5, click6, click7, click8, click9, click10];
var drawFunctions = [draw1, draw2, draw3, draw4, draw5, draw6, draw7, draw8, draw9, draw10];
var sunX = [40, 50, 60, 50, 80, 50, 60, 50, 40, 50, 20, 50, 40];
var sunY = [26.5, 53, 80, 53, 53, 53, 26.5, 53, 80, 53, 53, 53, 26.5];
var tomatoY1 = 315;
var tomatoY2 = 300;
var tomatoFalling = false;
var draggingSpoon = false;
var rolloverSpoon = false;
var spoonX;
var spoonY;
var spoonW;
var spoonH;
var offsetSpoonX;
var offsetSpoonY;
var frames = [];
var filenames = [
"assets/coin_1.png",
"assets/coin_2.png",
"assets/coin_3.png",
"assets/coin_4.png"
];
var coinX = 50;
var coinY = 50;
var targetX;
var targetY;
var dx;
var dy;
var distanceFromCoinToTarget;
var draggingApple = false;
var rolloverApple = false;
var appleX;
var appleY;
var appleW;
var appleH;
var offsetAppleX;
var offsetAppleY;
var draggingApple2 = false;
var rolloverApple2 = false;
var apple2X;
var apple2Y;
var apple2W;
var apple2H;
var offsetApple2X;
var offsetApple2Y;
var balloons = [];
var bx;
var b;
var by;
var frames2 = [];
var filenames2 = [
"assets/dance_1.png",
"assets/dance_2.png",
];
var raindrops = [];
var rx;
var ry;
function setup() {
createCanvas(480, 480);
page1 = loadImage("assets/page_1.jpg");
page2 = loadImage("assets/page_2.jpg");
tomato = loadImage("assets/tomato.png");
page3 = loadImage("assets/page_3.jpg");
turn_page = loadImage("assets/turn_page.png");
page4 = loadImage("assets/page_4.jpg");
spoon = loadImage("assets/spoon.png");
spoonX = 100;
spoonY = 200;
spoonW = 50;
spoonH = 50;
page5 = loadImage("assets/page_5.jpg");
page6 = loadImage("assets/page_6.jpg");
for (var i = 0; i < filenames.length; i++) {
frames.push(loadImage(filenames[i]));
}
coinX = width / 2;
coinY = height / 2;
targetX = coinX;
targetY = coinY;
page7 = loadImage("assets/page_7.jpg");
apple = loadImage('assets/apple.png');
appleX = 240;
appleY = 355;
appleW = 50;
appleH = 50;
page8 = loadImage("assets/page_8.jpg");
apple2X = 100;
apple2Y = 355;
apple2W = 50;
apple2H = 50;
page9 = loadImage("assets/page_9.jpg");
for (var i = 0; i < 5; i++) {
var bx = random(0, width);
var b = random(50, 80);
var by = height;
balloons[i] = makeBalloon(bx, by, b);
}
page10 = loadImage("assets/page_10.jpg");
for (var i = 0; i < filenames2.length; i++) {
frames2.push(loadImage(filenames2[i]))
}
for (var i = 0; i < 5; i++) {
var rx = random(0, width);
var ry = 0;
raindrops[i] = makeRaindrop(rx, ry);
}
frameRate(5);
}
function mouseClicked() {
clickFunctions[page]();
}
function draw() {
drawFunctions[page]();
}
function mousePressed() {
if (mouseX > spoonX & mouseX < spoonX + spoonW && mouseY > spoonY && mouseY < spoonY + spoonH) {
draggingSpoon = true;
offsetSpoonX = spoonX - mouseX;
offsetSpoonY = spoonY - mouseY;
}
if (mouseX > appleX & mouseX < appleX + appleW && mouseY > appleY && mouseY < appleY + appleH) {
draggingApple = true;
offsetAppleX = appleX - mouseX;
offsetAppleY = appleY - mouseY;
}
if (mouseX > apple2X & mouseX < apple2X + apple2W && mouseY > apple2Y && mouseY < apple2Y + apple2H) {
draggingApple2 = true;
offsetApple2X = apple2X - mouseX;
offsetApple2Y = apple2Y - mouseY;
}
}
function draw1() {
noStroke();
background('white');
image(page1, 0, 0, page1.width, page1.height);
var sunPoints = sunX.length;
fill(254, 192, 68);
beginShape();
for (var i = 0; i < sunPoints; i++) {
var sunpX = sunX[i] + random(-2, 2);
var sunpY = sunY[i] + random(-2, 2);
vertex(sunpX, sunpY);
}
endShape(CLOSE);
ellipse(50, 53, 10, 10);
}
function click1() {
if (mouseX < 60 & mouseX > 40 && mouseY < 60 && mouseY > 40) {
page = 1;
};
}
function draw2() {
noStroke();
background('white');
image(page2, 0, 0, page2.width, page2.height);
if (tomatoFalling === true) {
tomatoY1 += 10;
tomatoY2 += 10;
} else {
tomatoY1 = random(350, 355);
tomatoY2 = random(300, 305);
}
image(tomato, random(260, 265), tomatoY1, 30, 30);
image(tomato, random(270, 275), tomatoY2, 30, 30);
image(tomato, random(315, 320), tomatoY1, 30, 30);
image(tomato, random(310, 315), tomatoY2, 30, 30);
image(tomato, random(360, 365), tomatoY1, 30, 30);
image(tomato, random(355, 360), tomatoY2, 30, 30);
if (tomatoY1 > page2.height & tomatoY2 > page2.height) {
page = 2;
}
}
function click2() {
if (mouseX < 365 & mouseX > 260 && mouseY > 300 && mouseY < 355) {
tomatoFalling = true;
}
}
function draw3() {
noStroke();
background('white');
image(page3, 0, 0, page3.width, page3.height);
image(turn_page, 430, 430, turn_page.width, turn_page.height);
}
function click3() {
if (mouseX < 480 & mouseX > 400 && mouseY < 480 && mouseY > 400) {
page = 3;
}
}
function draw4() {
noStroke();
background('white');
image(page4, 0, 0, page4.width, page4.height);
if (mouseX > spoonX & mouseX < spoonX + spoonW && mouseY > spoonY && mouseY < spoonY + spoonH) {
rolloverSpoon = true;
}
else {
rolloverSpoon = false;
}
if (draggingSpoon) {
spoonX = mouseX + offsetSpoonX;
spoonY = mouseY + offsetSpoonY;
}
image(spoon, spoonX, spoonY, spoonW, spoonH);
if (spoonX > 100 & spoonX < 200 && spoonY > 50 && spoonY < 100) {
page = 4;
}
}
function mouseReleased() {
dragging = false;
}
function click4() {
}
function draw5() {
noStroke();
background('white');
image(page5, 0, 0, page5.width, page5.height);
image(turn_page, 430, 430, turn_page.width, turn_page.height);
}
function click5() {
if (mouseX < 480 & mouseX > 400 && mouseY < 480 && mouseY > 400) {
page = 5;
}
}
function draw6() {
noStroke();
background('white');
image(page6, 0, 0, page6.width, page6.height);
dx = targetX - coinX;
dy = targetY - coinY;
distanceFromCoinToTarget = sqrt(dx*dx + dy*dy);
coinX = lerp(coinX, targetX, 0.1);
coinY = lerp(coinX, targetY, 0.1);
if (targetX < coinX) {
push();
scale(-1, 1);
image(frames[frameCount % frames.length], -coinX, coinY);
pop();
}
else {
image(frames[frameCount % frames.length], coinX, coinY);
}
if (coinY > 350) {
page = 6;
}
}
function click6() {
targetX = mouseX;
targetY = mouseY;
}
function draw7() {
noStroke();
background('white');
image(page7, 0, 0, page7.width, page7.height);
if (mouseX > appleX & mouseX < appleX + appleW && appleY > appleY && mouseY < appleY + appleH) {
rolloverApple = true;
}
else {
rolloverApple = false;
}
if (draggingApple) {
appleX = mouseX + offsetAppleX;
appleY = mouseY + offsetAppleY;
}
image(apple, appleX, appleY, appleW, appleH);
if (appleX > 75 & appleX < 125 && appleY > 300 && appleY < 350) {
page = 7;
}
}
function click7() {
}
function draw8() {
noStroke();
background('white');
image(page8, 0, 0, page8.width, page8.height);
if (mouseX > apple2X & mouseX < apple2X + apple2W && apple2Y > apple2Y && mouseY < apple2Y + apple2H) {
rolloverApple2 = true;
}
else {
rolloverApple2 = false;
}
if (draggingApple2) {
apple2X = mouseX + offsetApple2X;
apple2Y = mouseY + offsetApple2Y;
}
image(apple, apple2X, apple2Y, apple2W, apple2H);
if (apple2X > 230 & apple2X < 300 && apple2Y > 150 && apple2Y < 200) {
page = 8;
}
}
function click8() {
}
function draw9() {
background('white');
image(page9, 0, 0, page9.width, page9.height);
updateAndDisplayBalloons();
addNewBalloons();
if (balloons.length > 10) {
page = 9;
}
}
function updateAndDisplayBalloons() {
for (var i = 0; i < balloons.length; i++) {
balloons[i].move();
balloons[i].display();
}
}
function addNewBalloons() {
var newBalloonProb = .05;
var b = random(50, 80);
if (random(0, 1) < newBalloonProb) {
balloons.push(makeBalloon(random(0, width), height, random(50, 80)));
}
}
function balloonMove() {
this.y -= this.speed;
}
function balloonDisplay(){
push();
if (this.typeColor < 1) {
fill(255, 0, 0, 100);
}
if (this.typeColor > 1 & this.typeColor < 2) {
fill(0, 0, 255, 100);
}
if (this.typeColor > 2 & this.typeColor < 3) {
fill(128, 0, 128, 100);
}
ellipse(this.x, this.y, this.breadth/1.5, this.breadth);
stroke('black');
strokeWeight(1);
line(this.x, this.y + this.breadth/2, this.x, this.y + 100);
pop();
}
function makeBalloon(bx, by, b) {
var balloons = {x: bx, y: by, move: balloonMove, display: balloonDisplay, speed: 5, breadth: random(50, 80), place: random(50, 250), type: int(random(0, 3)), typeColor: random(0, 3)}
return balloons;
}
function click9() {
}
function draw10() {
background('white')
image(page10, 0, 0, page10.width, page10.height);
image(frames2[frameCount % frames2.length], 0, 180);
updateAndDisplayRaindrops();
addNewRaindrops();
}
function updateAndDisplayRaindrops() {
for (var i = 0; i < raindrops.length; i++) {
raindrops[i].move();
raindrops[i].display();
}
}
function addNewRaindrops() {
var newRaindropProb = .25;
if (random(0, 1) < newRaindropProb) {
raindrops.push(makeRaindrop(random(0, width), 0));
}
}
function raindropsMove() {
this.y += this.speed;
}
function raindropsDisplay(){
push();
fill(135, 206, 250, 100);
beginShape();
curveVertex(this.x, this.y);
curveVertex(this.x-5, this.y+15);
curveVertex(this.x, this.y+20);
curveVertex(this.x+5, this.y+15);
curveVertex(this.x, this.y);
endShape(CLOSE);
pop();
}
function makeRaindrop(rx, ry) {
var raindrops = {x: rx, y: ry, move: raindropsMove, display: raindropsDisplay, speed: 5, place: random(50, 250)}
return raindrops;
}
function click10() {
}