//Robert Managad
//Section-E
//rmanagad@andrew.cmu.edu
//Final Project -- Trigonometric Loading Icons
//This code loops on the basis of the trigonometric functions cosine, sine, and tangent.
//It can be modified to produce three distinct animations, depending on the trig function used,
// and on the axis be affected.
var spins = [];
var drips = [];
var warps = [];
var pluss = [];
function setup() {
createCanvas(420, 420);
//Spin Loop, center
push();
for (var i = 0; i < 12; i++){
var spinposition = createVector(i * 20, i);
var spinradius = i * 1; // Radius increases by 200% for every iteration of i, up to 12.
spins[i] = new Spin(spinposition, spinradius); //holds circle function in the array
}
pop();
//Drip loop, top center
for (var i = 0; i < 8; i++){
var dripposition = createVector(i*18, i);
var dripradius = i * 2;
drips[i] = new Drip(dripposition, dripradius);
}
//Warp loop, left center
for (var i = 0; i < 12; i++){
var warpposition = createVector(i*20, i);
var warpradius = i * 1.5;
warps[i] = new Warp(warpposition, warpradius);
}
//Plus loop, left center
for (var i = 0; i < 12; i++){
var plusposition = createVector(i*20, i);
var plusradius = i * 1.5;
pluss[i] = new Plus(plusposition, plusradius);
}
}
function draw() {
background(0);
//drip draw
for(var i = drips.length - 1; i >= 0; i--){
var drip = drips[i];
drip.update();
drip.display();
}
//rectangle mask
fill(0);
noStroke();
rect(140, 130, 140, 300);
//warp draw
for(var i = warps.length - 1; i >= 0; i--){
var warp = warps[i];
warp.update();
warp.display();
}
//spin draw
for(var i = spins.length - 1; i >= 0; i--){
var spin = spins[i];
spin.update();
spin.display();
}
//plus draw
for(var i = pluss.length - 1; i >= 0; i--){
var plus = pluss[i];
plus.update();
plus.display();
}
}
//--------------------
//elements of each circle are compounded into the Spin function.
function Spin(spinposition, spinradius){
this.position = spinposition;
this.radius = spinradius;
this.direction = 1;
this.time = 0; //controls the placement of the starting anchor, time to jump towards.
//updates position every time draw is called.
this.update = function(){
this.time += this.direction * this.radius * 0.007; //holds value of velocity. Higher radius value = higher speed.
this.position.y = (200 + 90 * cos(this.time))/2;
this.position.x = (200 + 90 * sin(this.time))/2;
//trig function directs the animation (slowing down in middle/accelerating the circles as they approach the edges)
}
//holds visual presentation
this.display = function(){
noFill();
stroke(255);
strokeWeight(1.5);
ellipse(this.position.x - 20, this.position.y - 20, this.radius, this.radius);
}
}
//---------------------
function Drip(dripposition, dripradius){
this.position = dripposition;
this.radius = dripradius;
this.direction = 1;
this.time = 0; //controls the placement of the starting anchor, time to jump towards.
//updates position every time draw is called.
this.update = function(){
this.time += this.direction * this.radius * 0.004; //holds value of velocity. Higher radius value = higher speed.
this.position.y = (200 + 90 * tan(this.time))/3;
//trig function directs the animation (slowing down in middle/accelerating the circles as they approach the edges)
}
//holds visual presentation
this.display = function(){
noFill();
stroke(255);
strokeWeight(1.5);
ellipse(this.position.x + 275, this.position.y - 10, this.radius, this.radius);
}
}
//------------------------
function Warp(warpposition, warpradius){
this.position = warpposition;
this.radius = warpradius;
this.direction = 1;
this.time = 0; //controls the placement of the starting anchor, time to jump towards.
//updates position every time draw is called.
this.update = function(){
this.time += this.direction * this.radius * 0.002; //holds value of velocity. Higher radius value = higher speed.
this.position.y = 200 + 30 * cos(this.time);
this.position.x = 200 + 30 * tan(this.time);
//trig function directs the animation (slowing down in middle/accelerating the circles as they approach the edges)
}
//holds visual presentation
this.display = function(){
noFill();
stroke(255);
strokeWeight(1.5);
ellipse(this.position.x , this.position.y + 160, this.radius, this.radius);
}
}
//----------------------------
function Plus(plusposition, plusradius){
this.position = plusposition;
this.radius = plusradius;
this.direction = 1;
this.time = 0; //controls the placement of the starting anchor, time to jump towards.
//updates position every time draw is called.
this.update = function(){
this.time += this.direction * this.radius * 0.002; //holds value of velocity. Higher radius value = higher speed.
this.position.y = 200 + 40 * 1/cos(this.time)/3;
this.position.x = 200 + 40 * 1/sin(this.time)/3;
//trig function directs the animation (slowing down in middle/accelerating the circles as they approach the edges)
}
//holds visual presentation
this.display = function(){
noFill();
stroke(255);
strokeWeight(1.5);
ellipse(this.position.x , this.position.y, this.radius, this.radius);
}
}
If gifs below are frozen: right-click and open the image in a new tab.
My final project culminated in a series of six loading icons. I used trigonometric functions to calculate x and y positions — because of their cyclical behaviours, sin, cosine, and tangent worked well for looping animations. Individual animation gifs can be seen above. Process work can be seen below
From a design standpoint, I developed these loading icons with several human factors in mind — from longevity and human attention span, to interactivity and engagement. Repetition in form, symmetry in composition and shape, and cyclical rhythm all contribute to keeping people from becoming disengaged with the content. As a component living in a transitionary space, the loading icon serves to bridge one space to the next.