xxxxxxxxxx
300
//2020.9.9 Living Wallpaper
//Tale
// Made by using the template for creating a looping animation in p5.js (JavaScript).
// When you press the 'F' key, this program will export a series of images into
// your default Downloads folder. These can then be made into an animated gif.
// This code is known to work with p5.js version 0.6.0
// Prof. Golan Levin, 28 January 2018
// INSTRUCTIONS FOR EXPORTING FRAMES (from which to make a GIF):
// 1. Run a local server, using instructions from here:
// https://github.com/processing/p5.js/wiki/Local-server
// 2. Set the bEnableExport variable to true.
// 3. Set the myNickname variable to your name.
// 4. Run the program from Chrome, press 'f'.
// Look in your 'Downloads' folder for the generated frames.
// 5. Note: Retina screens may export frames at twice the resolution.
//===================================================
// User-modifiable global variables.
var myNickname = "tale";
var nFramesInLoop = 120;
var bEnableExport = false;
// Other global variables you don't need to touch.
var nElapsedFrames;
var bRecording;
var theCanvas;
//===================================================
function setup() {
theCanvas = createCanvas(1280, 720);
bRecording = false;
nElapsedFrames = 0;
}
//===================================================
function keyTyped() {
if (bEnableExport) {
if ((key === 'f') || (key === 'F')) {
bRecording = true;
frameRate(2); // while we're exporting
nElapsedFrames = 0;
}
}
}
//===================================================
function draw() {
// Compute a percentage (0...1) representing where we are in the loop.
var percentCompleteFraction = 0;
if (bRecording) {
percentCompleteFraction = float(nElapsedFrames) / float(nFramesInLoop);
} else {
percentCompleteFraction = float(frameCount % nFramesInLoop) / float(nFramesInLoop);
}
// Render the design, based on that percentage.
// This function renderMyDesign() is the one for you to change.
renderMyDesign(percentCompleteFraction);
// If we're recording the output, save the frame to a file.
// Note that the output images may be 2x large if you have a Retina mac.
// You can compile these frames into an animated GIF using a tool like:
if (bRecording && bEnableExport) {
var frameOutputFilename = myNickname + "_frame_" + nf(nElapsedFrames, 4) + ".png";
print("Saving output image: " + frameOutputFilename);
saveCanvas(theCanvas, frameOutputFilename, 'png');
nElapsedFrames++;
if (nElapsedFrames >= nFramesInLoop) {
bRecording = false;
frameRate(60);
}
}
}
//===================================================
function renderMyDesign(percent) {
//background
var bg;
if (percent<.5) bg = "black";
else bg = "#F0FDFF";
background(bg);
smooth();
stroke("white");
fill("white");
strokeWeight(7);
//----------------------
//assigning variables
var t = percent * 8 * PI;
var cxOffset = 400;
var cyOffset = 450;
var radius = 240;
var speed = 0.2;
//----------------------
//Top left sun
var sr = 50;
for (i = 0; i < 6; i++) {
var sx = 140 + cos(t - .2 * i) * sr;
var sy = 100 + sin(t - .2 * i) * sr;
noStroke();
if(percent>.5)fill("yellow");
else fill("blue");
ellipse(sx, sy, 12, 12);
}
//trees
var eased = doubleExponentialSigmoid(percent, 0.6);
var xPos = map(eased, 0, 1, -200, width+3500);
fill("#DEAB73");
rect(xPos-35, 400, 70,100);
fill("#056417");
ellipse(xPos, 350, 140, 160);
ellipse(xPos-50,370, 120,100);
ellipse(xPos+50,370, 120,100);
push();
translate(-350,0);
fill("#E69A8DFF");
rect(xPos-35, 400, 70,100);
fill("#5F4B8BFF");
ellipse(xPos, 350, 140, 160);
ellipse(xPos-50,370, 120,100);
ellipse(xPos+50,370, 120,100);
pop();
push();
translate(-700,0);
fill("#5BB84B1FF");
rect(xPos-35, 400, 70,100);
fill("#FC766AFF");
ellipse(xPos, 350, 140, 160);
ellipse(xPos-50,370, 120,100);
ellipse(xPos+50,370, 120,100);
pop();
push();
translate(-1050,0);
fill("#00B1D2FF");
rect(xPos-35, 400, 70,100);
fill("#FDDB27FF");
ellipse(xPos, 350, 140, 160);
ellipse(xPos-50,370, 120,100);
ellipse(xPos+50,370, 120,100);
pop();
push();
translate(-1400,0);
fill("#DEAB73");
rect(xPos-35, 400, 70,100);
fill("#056417");
ellipse(xPos, 350, 140, 160);
ellipse(xPos-50,370, 120,100);
ellipse(xPos+50,370, 120,100);
pop();
//building
push();
translate(-2900,0);
fill("#98F76B");
rect(xPos-35, 200, 200,300);
pop();
push();
translate(-3100,0);
fill("#FF9740");
rect(xPos-35, 200, 200,300);
pop();
push();
translate(-3400,0);
fill("#34A8BA");
rect(xPos-35, 200, 200,300);
pop();
//car
fill("red");
var ease = bounceInOut(percent);
ease = (eased + 0.7) % 1.0;
var yPos = map(ease, 0, 1, 455, 470);
var yP = map(ease, 0, 1, 540, 550);
var w = 660;
rect(width/2-w/2, yPos, w, 200);
ellipse(width/2-w/2-120,yP,310,250);
ellipse(width/2+w/2+120,yP,310,250);
ellipse(width/2-w/4, yPos, 400, 200);
fill("black");
ellipse(width/2-w/2-100,yP+60,260,230);
ellipse(width/2+w/2+100,yP+60,260,230);
fill(bg);
ellipse(width/2-80, yPos-10, 140, 80);
fill("red");
rect(width/2-w/2+130, yPos, 200, 50);
//Bottom right
var br = 100;
push();
translate(47,40);
for (i = 0; i < 15; i++) {
var bx = 1110 + sin(t - .18 * i) * br;
var by = 570 + cos(t - .18 * i) * br;
noStroke();
fill("white");
ellipse(bx-100, by, 14, 14);
}
//bottom left
var br = 100;
for (i = 0; i < 15; i++) {
var bx = 1110 + sin(t - .18 * i) * br;
var by = 570 + cos(t - .18 * i) * br;
noStroke();
fill("white");
ellipse(width-bx, by, 14, 14);
}
pop();
}
// Symmetric double-element sigmoid function ('_a' is the slope)
// See https://github.com/IDMNYU/p5.js-func/blob/master/lib/p5.func.js
// From: https://idmnyu.github.io/p5.js-func/
//===================================================
function doubleExponentialSigmoid(_x, _a) {
if (!_a) _a = 0.75; // default
var min_param_a = 0.0 + Number.EPSILON;
var max_param_a = 1.0 - Number.EPSILON;
_a = constrain(_a, min_param_a, max_param_a);
_a = 1 - _a;
var _y = 0;
if (_x <= 0.5) {
_y = (pow(2.0 * _x, 1.0 / _a)) / 2.0;
} else {
_y = 1.0 - (pow(2.0 * (1.0 - _x), 1.0 / _a)) / 2.0;
}
return (_y);
}
function bounceOut(_x){
if(_x < 4/11.0)
{
return((121 * _x * _x)/16.0);
}
else if(_x < 8/11.0)
{
return((363/40.0 * _x * _x) - (99/10.0 * _x) + 17/5.0);
}
else if(_x < 9/10.0)
{
return((4356/361.0 * _x * _x) - (35442/1805.0 * _x) + 16061/1805.0);
}
else
{
return((54/5.0 * _x * _x) - (513/25.0 * _x) + 268/25.0);
}
}
function bounceIn (_x) {
return(1 - this.bounceOut(1 - _x));
}
function bounceInOut(_x) {
if(_x < 0.5)
{
return(0.5 * this.bounceIn(_x*2));
}
else
{
return(0.5 * this.bounceOut(_x * 2 - 1) + 0.5);
}
}
function elasticOut(_x) {
return(sin(-13 * HALF_PI * (_x + 1)) * pow(2, -10 * _x) + 1);
}