xxxxxxxxxx
120
// == configs ==============================================
const RGB_OFFSET = 1.0;
const N_HISTORY = 20;
const SAVE_GIF = false;
// == utils ================================================
function saturate(x) {
return constrain(x, 0.0, 1.0);
}
function mod(x, y) {
return x - y * floor(x / y);
}
function ease(x, k) {
x = saturate(1.0 - x);
return 1.0 - ((k + 1.0) * pow(x, k) - k * pow(x, k + 1.0));
}
// == color curve ==========================================
function intTri(a, b) {
return (
saturate(1 - a) ** 2.0 - saturate(1 - b) ** 2.0 +
saturate(1 + b) ** 2.0 - saturate(1 + a) ** 2.0
) / 2.0;
}
function colorInt(a, b) {
const totalWidth = 2.0 + 2.0 * RGB_OFFSET;
a = a * totalWidth - 1.0;
b = b * totalWidth - 1.0;
const colR = intTri(a, b);
a -= RGB_OFFSET;
b -= RGB_OFFSET;
const colG = intTri(a, b);
a -= RGB_OFFSET;
b -= RGB_OFFSET;
const colB = intTri(a, b);
return color(
floor(256 * colR),
floor(256 * colG),
floor(256 * colB),
);
}
// == setup ================================================
const pgHistory = [];
function setup() {
createCanvas(256, 256);
for (let i = 0; i < N_HISTORY; i ++) {
pg = createGraphics(256, 256);
pg.background(0, 0, 0);
pgHistory.push(pg);
}
}
// == draw buffer ==========================================
function drawFrame(pg, t) {
pg.background(0, 0, 0);
pg.push();
{
pg.translate(128, 128);
pg.scale(128);
let x = -0.375;
let y = -0.375;
x += 0.75 * ease(saturate(mod(2.0 * t, 4.0) - 0.0), 5.0);
y += 0.75 * ease(saturate(mod(2.0 * t, 4.0) - 1.0), 5.0);
x -= 0.75 * ease(saturate(mod(2.0 * t, 4.0) - 2.0), 5.0);
y -= 0.75 * ease(saturate(mod(2.0 * t, 4.0) - 3.0), 5.0);
pg.translate(x, y);
pg.rotate(HALF_PI * ease(fract(2.0 * t), 5.0));
pg.fill(255, 255, 255);
pg.noStroke();
pg.rect(-0.25, -0.25, 0.5, 0.5);
}
pg.pop();
}
// == draw main ============================================
function draw() {
const t = frameCount / 60.0;
const pg = pgHistory.pop();
drawFrame(pg, t);
pgHistory.unshift(pg);
background(0, 0, 0);
push();
{
blendMode(ADD);
for (let i = 0; i < N_HISTORY; i ++) {
const pg = pgHistory[i];
if (pg != null) {
const a = i / N_HISTORY;
tint(colorInt(a, a + 1.0 / N_HISTORY));
image(pg, 0, 0, width, height);
}
}
}
pop();
if (SAVE_GIF && frameCount == 120) {
saveGif('rgb-delay', 120, { units: 'frames' });
}
}