phiaq-Animated Loop
The gif I created went through a couple of revisions because my initial idea was too difficult to create (I was going to have the fox transform into a bear), but I settled on this, which is within my scope. For my gif, rather than exploring different animations, I focused of coding drawing with geometry. I had a lot of fun coding the triangles of the creature and the skull of my creature. I used “adjustable center elliptic window” for the easing function on my paws because I wanted it to be subtle and less dramatic because of the center animal animation. For improvement, I’d like the paws to be moving at a same rate, and I think having a body would improve because it looks awkward moving around. In the future, I want to add more details, complex animations, and colors to the drawing.
Sketches
Code
// This is a template for creating a looping animation in Processing/Java. // When you press the 'F' key, this program will export a series of images // into a "frames" directory located in its sketch folder. // These can then be combined into an animated gif. // Known to work with Processing 3.3.6 // Prof. Golan Levin, January 2018 // Thanks to Prof. Golan Levin's Processing Animation tempate and Pattern Master //=================================================== // Global variables. String myNickname = "nickname"; int nFramesInLoop = 300; int nElapsedFrames; boolean bRecording; //=================================================== void setup() { size (600, 600); bRecording = false; nElapsedFrames = 0; } //=================================================== void keyPressed() { if ((key == 'f') || (key == 'F')) { bRecording = true; nElapsedFrames = 0; } } //=================================================== void draw() { // Compute a percentage (0...1) representing where we are in the loop. float percentCompleteFraction = 0; if (bRecording) { percentCompleteFraction = (float) nElapsedFrames / (float)nFramesInLoop; } else { percentCompleteFraction = (float) (frameCount % nFramesInLoop) / (float)nFramesInLoop; } // Render the design, based on that percentage. renderMyDesign (percentCompleteFraction); // If we're recording the output, save the frame to a file. if (bRecording) { saveFrame("frames/" + myNickname + "_frame_" + nf(nElapsedFrames, 4) + ".png"); nElapsedFrames++; if (nElapsedFrames >= nFramesInLoop) { bRecording = false; } } } //=================================================== void renderMyDesign (float percent) { //blendMode(SUBTRACT); background(0); //blendMode(DARKEST); smooth(); stroke (0, 0, 0); strokeWeight(2); float size = 350; noStroke(); translate(width/2,(height/2)+50); //SKULL fill(255); //ears ellipse(0,0,size-70,size-70); fill(0); rect(-size,0,size*2,size); fill(255); triangle((-size/4.5)-40,0,0,size/3,(size/4.5)+40,0); fill(0); //eyes ellipse(-size/5.5,-size/15,size/4,(size/4)-20); ellipse(size/5.5,-size/15,size/4,(size/4)-20); fill(60);//inner grey ellipse(-size/5.5,-size/15,(size/4)-25,(size/4)-45); ellipse(size/5.5,-size/15,(size/4)-25,(size/4)-45); fill(120);//most grey ellipse(-size/5.5,-size/15,(size/4)-35,(size/4)-65); ellipse(size/5.5,-size/15,(size/4)-35,(size/4)-65); //nostrils fill(0); triangle((-size/6)+40,0,0,(size/6)-30,(size/6)-40,0); stroke(255); strokeWeight(5); line(0,0,0,100); //teeth stroke(0); float nose_len = (size/6)-30; float nose_wid = (-size/6)+40; line(-nose_wid-20,nose_len+10,-nose_wid-20,(size/6)+10); line(-nose_wid-30,nose_len+10,-nose_wid-30,(size/6)+10); line(nose_wid+30,nose_len+10,nose_wid+30,(size/6)+10); float pulse = sin(2.0*percent*TWO_PI); float opacity = map(pulse,-1,1,255,100); //FOX noStroke(); float ellipseW = map(pulse,-1,1,size-20,size-30); float ellipseH = map(pulse,-1,1,size,size+10); fill(230,86,35,opacity); //semicircle pushMatrix(); rotate(-HALF_PI); arc(0, 0, ellipseW, ellipseH,-HALF_PI, HALF_PI); //black bottom covering fill(0,0,0,opacity); popMatrix(); //triangle mouth float trix1 = map(pulse,-1,1,-size/3-20,(-size/3)-40); float trix3 = map(pulse,-1,1,size/3+20,(size/3)+40); fill(255,89,18,140); triangle(trix1,0,0,size/2.4,trix3,0); //fill(255,255,255,140); //ellipse(0,-size/10,(size/2)+70,(size/2)-100); //dark triangle shadow fill(184,69,39,opacity); triangle(-size/4.5,0,0,size/3,size/4.5,0); //snout fill(20,40,50,opacity); triangle(-size/9,0,size/9,0,0,size/9); //triangle top of nose fill(255,255,255,opacity); triangle(-size/9,0,0,-size/10,size/9,0); //eye fill(0,0,0,opacity); triangle(-size/3,-size/7,-size/6,-size/7,-size/9,-size/13);//left triangle(size/9,-size/13,size/6,-size/7,size/3,-size/7);//right //ears //smaller ears fill(255,255,255,254); triangle(-size/3.6,-size/4,-size/4,-size/1.5,-size/7,-size/4); triangle(size/3.6,-size/4,size/4,-size/1.5,size/7,-size/4); //bigears fill(255,102,43,opacity); triangle(-size/2.5,-size/4,-size/4,-size/1.3,-size/9,-size/4); fill(255,102,43,opacity); triangle(size/2.5,-size/4,size/4,-size/1.3,size/9,-size/4); triangle(size/3,-size/4,size/4,-size/1.5,size/7,-size/4); //whiskers for right strokeWeight(2); stroke(255); line(size/9,size/11,size/3,size/11); line(size/12,size/8,size/4,size/8); line(size/8,size/15,size/2.5,size/15); //whisker for left line(-size/9,size/11,-size/3,size/11); line(-size/12,size/8,-size/4,size/8); line(-size/8,size/15,-size/2.5,size/15); //black mouth stroke(0,0,0,opacity); line(0,size/9,0,(size/6)+10);//vertical line(-size/13,(size/6)+10,size/13,(size/6)+10); noStroke(); //left paw skeleton line((size/3)+10,size/3,(size/3)+10,size/2); line((size/3),size/3,(size/3),size/2); line((size/3)-10,size/3,(size/3)-10,size/2); float ease2 = function_AdjustableCenterEllipticWindow(percent,.3); float x = map(ease2,0,1,-size/3,(-size/3)+20); fill(255,255,255); ellipse(x,size/3,(size/4.5)-20,(size/6)-20); ellipse(-x,size/3,(-size/4.5)+20,(size/6)-20); //right paw skeleton strokeWeight(7); stroke(0,0,0); line((x)+10,size/3,(x)+10,size/2); line((x),size/3,(x),size/2); line((x)-10,size/3,(x)-10,size/2); line((-x)+10,size/3,(-x)+10,size/2); line((-x),size/3,(-x),size/2); line((-x)-10,size/3,(-x)-10,size/2); //orange paw noStroke(); fill(255,102,43,opacity); ellipse(x,size/3,-size/4.5,size/6); ellipse(-x,size/3,-size/4.5,size/6); } //------------------------------------------------------------------ float function_AdjustableCenterEllipticWindow (float x, float a){ //functionName = "Adjustable-Center Elliptic Window"; float min_param_a = 0.0 + EPSILON; float max_param_a = 1.0 - EPSILON; a = constrain(a, min_param_a, max_param_a); float y = 0; if (x<=a){ y = (1.0/a) * sqrt(sq(a) - sq(x-a)); } else { y = (1.0/(1-a)) * sqrt(sq(1.0-a) - sq(x-a)); } return y; } |