xxxxxxxxxx
263
// require https://cdn.jsdelivr.net/npm/tweakpane@3.0.7/dist/tweakpane.min.js
// require https://cdn.jsdelivr.net/npm/p5@latest/lib/p5.min.js
const EXPORT = false;
const OUTPUT_FRAME_RATE = 60;
const FRAME_RATE = EXPORT ? 1 : OUTPUT_FRAME_RATE;
const DURATION = 3; // in sec
const FRAMES_TO_SAVE = Math.floor( OUTPUT_FRAME_RATE * DURATION );
const IMAGE_PIXEL_SIZE = 20;
const BG_COLOR = 238; // compform gray
const pixelIDs = [];
const pane = new Tweakpane.Pane();
const PARAMS = {
frameRate: 0,
frame: 0,
};
function setup() {
createCanvas(960, 540);
pixelDensity(2);
// add monitoring
const f1 = pane.addFolder({
title: "Monitoring",
expanded: true,
});
f1.addMonitor(PARAMS, "frameRate");
f1.addMonitor(PARAMS, "frameRate", {
view: "graph",
min: 0,
max: FRAME_RATE * 1.1,
});
f1.addMonitor(PARAMS, "frame");
frameRate(FRAME_RATE);
if( EXPORT ){
console.log( "Expected Frames", FRAMES_TO_SAVE )
}
setupPixels();
}
function draw() {
background( BG_COLOR );
if( frameCount < FRAME_RATE * 1.5 ){
drawColorfullPixel( 0, FRAME_RATE * 1.5 );
}
// show final logo for the last half second
if( frameCount > FRAME_RATE * 1.5 ){
const opacity = map( frameCount, FRAME_RATE * 1.5, FRAME_RATE * 3, 255, 0, true);
// compform gray
background( BG_COLOR );
textFont("Miriam Libre");
textSize( 60 );
textAlign(CENTER);
text( "COMP_FORM", width/2, height/2 );
background( BG_COLOR, opacity );
drawPenroseTriangle( width/2 + 220, height/2 + 80, 100, 3, FRAME_RATE * 2, FRAME_RATE * DURATION )
}
// monitoring
PARAMS.frameRate = frameRate();
PARAMS.frame = frameCount;
// export
if (EXPORT) {
saveFrame("bumper", frameCount);
}
// end video
if( frameCount >= FRAMES_TO_SAVE ){
console.log("Done 🎬");
noLoop();
}
}
const setupPixels = () => {
let ID = 0;
for( let w = 0; w < width / IMAGE_PIXEL_SIZE; w++ ){
for( let h = 0; h < height / IMAGE_PIXEL_SIZE; h++ ){
pixelIDs.push(ID);
ID++;
}
}
}
const drawColorfullPixel = ( startFrame = 0, endFrame = 30 ) => {
push();
colorMode(HSB, 100);
const img = createImage(width / IMAGE_PIXEL_SIZE, height / IMAGE_PIXEL_SIZE);
img.loadPixels();
for (let y = 0; y < img.height; y++) {
for (let x = 0; x < img.width; x++) {
const c = color( hue, 100, 100);
img.set(x, y, c);
}
}
img.updatePixels();
noSmooth();
image(img, 0, 0, width, height);
pop();
/*
const factor = 0.02
const img = createImage(width / IMAGE_PIXEL_SIZE, height / IMAGE_PIXEL_SIZE);
img.loadPixels();
for (let y = 0; y < img.height; y++) {
for (let x = 0; x < img.width; x++) {
const n = noise( factor * ( x + frameCount ), factor * ( y + frameCount ) );
const hue = map( n, 0, 1, 0, 100, true );
const opacity = map( frameCount, (endFrame-startFrame) * 0.8, endFrame, 100, 0, true );
const c = color( hue, 100, 100);
c.setAlpha( opacity )
img.set(x, y, c);
}
}
img.updatePixels();
noSmooth();
image(img, 0, 0, width, height);
pop();
*/
}
const drawPenroseTriangle = ( pX = 0, pY = 0, l = 100, sw = 3, startF = 0, endF = 30 ) => {
push();
noFill();
strokeWeight( sw );
const cF = map( frameCount, startF, endF, 0, 100, true );
const sh = tan( radians( 30 ) ) * ( l / 2 );
const h = l/2 * sqrt( 3 );
const t1x1 = pX - l/2
const t1y1 = pY + sh
const t1x2 = pX + l/2
const t1y2 = pY + sh
const t1x3 = pX
const t1y3 = pY - ( h - sh )
const t2x1 = lerp( t1x1, t1x2, 0.5 )
const t2y1 = lerp( t1y1, t1y2, 0.5 )
const t2x2 = lerp( t1x2, t1x3, 0.5 )
const t2y2 = lerp( t1y2, t1y3, 0.5 )
const t2x3 = lerp( t1x3, t1x1, 0.5 )
const t2y3 = lerp( t1y3, t1y1, 0.5 )
const t3x1 = lerp( t2x2, t2x1, 0.5 )
const t3y1 = lerp( t2y2, t2y1, 0.5 )
const t3x2 = lerp( t1x1, t1x2, 0.75 )
const t3y2 = lerp( t1y1, t1y2, 0.75 )
const t3x3 = lerp( t1x2, t1x3, 0.25 )
const t3y3 = lerp( t1y2, t1y3, 0.25 )
const drawTriangle = ( x1, y1, x2, y2, x3, y3, tSF, tEF ) => {
const tCF = map( cF, tSF, tEF, 0, 3, true );
if( tCF <= 0 ){
// do nothing
}else if( tCF < 1 ){
const lerpX = lerp( x1, x3, tCF );
const lerpY = lerp( y1, y3, tCF );
line( x1, y1, lerpX, lerpY )
}else if( tCF < 2 ){
const lerpX = lerp( x3, x2, tCF - 1 );
const lerpY = lerp( y3, y2, tCF - 1 );
line( x3, y3, lerpX, lerpY )
line( x1, y1, x3, y3 )
}else{
const lerpX = lerp( x2, x1, tCF - 2 );
const lerpY = lerp( y2, y1, tCF - 2 );
line( x2, y2, lerpX, lerpY )
line( x1, y1, x3, y3 )
line( x3, y3, x2, y2 )
}
}
// Outer Triangle
drawTriangle( t1x1,t1y1,t1x2,t1y2,t1x3,t1y3, 0, 30 );
// Inner Triangle
drawTriangle( t2x1,t2y1,t2x2,t2y2,t2x3,t2y3, 30, 60 );
// Bottom Right Triangle
drawTriangle( t3x1,t3y1,t3x2,t3y2,t3x3,t3y3, 60, 90 );
if( cF >= 90 ){
const tOpacity = map( cF, 90, 100, 0, 255 )
const tColor = color(0)
const tColorEmpty = color( BG_COLOR )
tColor.setAlpha( tOpacity )
tColorEmpty.setAlpha( tOpacity )
push();
noStroke()
fill(tColor)
triangle( t1x1,t1y1,t1x2,t1y2,t1x3,t1y3 );
fill(tColorEmpty)
triangle( t2x1,t2y1,t2x2,t2y2,t2x3,t2y3 );
triangle( t3x1,t3y1,t3x2,t3y2,t3x3,t3y3 );
pop();
}
pop();
}
const saveFrame = (name, frameNumber, extension = "png") => {
frameNumber = floor(frameNumber);
const paddedNumber = ("0000" + frameNumber).substr(-4, 4);
save(name + "_" + paddedNumber + "." + extension);
};