In order to animate anything in Processing, the draw( ) function must be included in your project. Within the draw( ) function, some parameters of the design must be changing over time, such as size, color. frameCount, modulus can be used to create a timer that controls animation of size, color. Mouse horizontal movement is used to modify the hue of the accent color.
We can use frameCount, modulus to create a timer that cycles from 0 to some maxValue.
Copy float maxTime = 100 ;
float fractionSize = map(frameCount % maxTime , 0 , maxTime , 0.2 , 1.0 )
cellSize = cellSize * fractionSize;
Copy float fractionSize = map(frameCount % maxTime , 0 , maxTime , 0.2 , 2.0 )
//fraction is larger than 1.0, so size will be doubled
Similar logic to above, but this will cause the fraction to range from .2 to 2.0, since the map function extends the mapping for values outside the range.
Copy float halfMax = maxTime / 2 ;
float fractionSize2 = map(frameCount % maxTime , 0 , halfMax , 0.2 , 1.0 )
float fractionLerp = map(frameCount%maxTime, 0, maxTime, 0.0,1.0) ; //for lerpColor, keep range: 0.0-1.0
Add the code below into the animation color logic, horizontal mouse movement will change the accent color hue.
Copy ///use mouseX to create interactive accent color
float hueMx = map( mouseX, 0, width, 120,250); //color change with mouseX movement
color accentMx = color( hueMx, 100,100);
color curColor = lerpColor( accentMx,aqua, fractionColor)
Copy
void setup() {
size( 400 , 400 ) ;
colorMode(HSB , 360 , 100 , 100 ) ;
background( 0 ) ;
}
void draw() {
//fade background
fill( 0 , 5 ) ; //transparant black
rect( 0 , 0 , width , height) ;
//mousePress to pause
//press any key to restart animation
if (mousePressed) {
noLoop() ;
}
updateArrayDisplay() ;
} //end draw
//press any key to restart animation
void keyPressed() {
loop() ;
}
void updateArrayDisplay() {
//fixed values
float artWorkSize = width;
float regionSize = artWorkSize / 2 ;
int rows = 10 ;
int cols = 10 ;
float cellSize = regionSize / cols;
//use changing framecount to change size and color over time
float maxFC = 100 ; //max value for frameCount timer
float fractionSize = map(frameCount % maxFC , 0 , maxFC , 0.2 , 2.0 ) ; //makes larger than original size
float fractionColor = map(frameCount % maxFC , 0 , maxFC , 0.0 , 1.0 ) ; //for lerpColor
color purple = color( 280 , 100 , 100 ) ;
color aqua = color( 180 , 100 , 100 ) ;
///use mouseX to create interactive accent color
float hueMx = map( mouseX , 0 , width , 120 , 250 ) ; //color change with mouseX movement
color accentMx = color( hueMx , 100 , 100 ) ;
//animated color - changes over time
color curColor = lerpColor( accentMx , aqua , fractionColor) ;
PShape [][] myShapes = new PShape [rows][cols]; //num elements is rows*cols
//repopulate data structure every frame
populate2DArray( myShapes , rows , cols , cellSize * fractionSize , purple , curColor) ;
//display in region1
displayShapeMatrix( myShapes , rows , cols , cellSize) ;
//region2
mirrorRegion2(myShapes , rows , cols , cellSize , artWorkSize) ;
//region3 - TODO change to use a function call
pushMatrix() ;
translate( 0 , height) ; //move origin to upper right
scale( 1 , - 1 ) ; //mirror across x-axix, make smaller
displayShapeMatrix( myShapes , rows , cols , cellSize) ;
popMatrix() ;
//region4 - TODO change to use a function call
pushMatrix() ;
translate(width , height) ; //move origin to upper right
scale( - 1 , - 1 ) ; //mirror across origin and make smaller
displayShapeMatrix( myShapes , rows , cols , cellSize) ;
popMatrix() ;
}
void mirrorRegion2( PShape [][] shapes , int rows , int cols , float cellSize , float artWorkSize ) {
pushMatrix() ;
translate(artWorkSize , 0 ) ; //move origin to upper right
scale( - 1 , 1 ) ; //mirror and scale smaller
displayShapeMatrix( shapes , rows , cols , cellSize) ;
popMatrix() ;
}
void displayShapeMatrix( PShape [][] shapes , int rows , int cols , float cellSize ) {
int xPos = 0 ;
int yPos = 0 ;
for ( int i = 0 ; i < rows; i ++ ) {
for ( int j = 0 ; j < cols; j ++ ) {
shape( shapes[i][j] , xPos , yPos) ; //display one shape
xPos += cellSize;
} //end inner loop - cols
xPos = 0 ; //reset xPos to 0 for next row
yPos += cellSize;
} //end outer loop - rows
} //end function
void populate2DArray( PShape [][] shapes , int rows , int cols , float cellSize , color c1 , color c2 ) {
for ( int i = 0 ; i < rows; i ++ ) {
for ( int j = 0 ; j < cols; j ++ ) {
int k = i + j; //used for a diagonal pattern
int l = min( i , j) ; //concentric pattern
float fractionk = map( k , 0 , rows + cols - 2 , 0.0 , 1.0 ) ;
float fractionl = map( l , 0 , rows - 1 , 0.0 , 1.0 ) ;
//use fractions to create color gradient patterns
color colorK = lerpColor( c1 , c2 , fractionk) ; //diagonal gradient
color colorL = lerpColor(color( 0 ) , c1 , fractionl) ; //concentric color
PShape curShape; //temp variable to hold a PShape
//odd even logic to determine PShape
if ( k % 2 == 0 ) {
curShape = createPosShape( cellSize * 2.0 , colorK) ; //make cutout shape larger
} else {
curShape = createShape(GROUP) ;
recursiveShapes( curShape , cellSize * .6 , 3 , colorL) ; //make circles smaller
} //end if-else
shapes[i][j] = curShape; //set the shape as the array element
} //end inner for-loop - cols
} //end outer for-loop - rows
} //end function populate2DArray
void recursiveShapes( PShape group , float len , int level , color c1 ) {
if ( level < 0 ) {
return ;
}
color curColor = color( hue( c1) , saturation(c1) , brightness(c1) * .8 ) ;
PShape s = createEllipse( len , curColor) ;
group . addChild (s);
recursiveShapes( group , len * .8 , level - 1 , curColor) ;
}
PShape createEllipse( float len , color c1) {
PShape s = createShape(ELLIPSE , 0 , 0 , len , len) ; //rect if k is even
s . setFill (c1);
return s;
}
PShape createPosShape( float len , color c1) {
PShape s = createShape() ;
s . beginShape ();
s . fill (c1 ); //HSB - blue full sat, bright
s . vertex ( 0 , 0 ); //point 1 for outer shape (clock-wise rotation for drawing points)
s . vertex ( len * .4 , 0 ); //point 2
s . vertex ( len * .6 , len * .6 ); //point 3
s . vertex ( 0 , len * .4 ); //point 4
s . vertex ( 0 , 0 ); //last point for outer shape
////start of inner cutout - counter-clockwise ordering
s . beginContour (); //make internal cutout
s . vertex ( len * .25 , len * .45 ); //inner cutouts - point 5
s . vertex (len * .5 , len * .5 ); //point 6
s . vertex ( len * .45 , len * .25 ); //point 7
s . endContour (); //end internal cutout
s . endShape (CLOSE); //end shape
return s;
}