Last active
April 9, 2021 19:07
-
-
Save marcedwards/d9ad996998a79b3f970632fc8b497816 to your computer and use it in GitHub Desktop.
Split Lines in Processing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Split Lines. | |
// Created using Processing 3.5.3. | |
// | |
// Code by @marcedwards from @bjango. | |
// | |
// A GIF of this code can be seen here: | |
// https://twitter.com/marcedwards/status/1212718884224040965 | |
// | |
// Very, very, very heavily inspired by this animation: | |
// https://twitter.com/RandomBlendings/status/1212394190388289536 | |
// | |
// WARNING: This code is in an “eh, I guess it works” state. | |
// | |
PImage maskA; | |
PImage maskB; | |
PImage bufferA; | |
PImage bufferB; | |
float frameseed = timeNoise(8 * 20, 20, 8); | |
void setup() { | |
size(600, 600, P2D); | |
frameRate(30); | |
smooth(8); | |
noiseDetail(5, 0.8); | |
background(0); | |
maskA = createImage(width, height, RGB); | |
maskB = createImage(width, height, RGB); | |
bufferA = createImage(width, height, ARGB); | |
bufferB = createImage(width, height, ARGB); | |
bufferA.copy(g, 0, 0, width, height, 0, 0, width, height); | |
bufferB.copy(g, 0, 0, width, height, 0, 0, width, height); | |
} | |
void draw() { | |
int framestep = 8; | |
int totalframes = framestep * 20; | |
float frame = frameCount % framestep; | |
float anim = Ease.hermite5(frame / framestep) * 16; | |
float dx = cos(frameseed * TAU - HALF_PI) * anim; | |
float dy = sin(frameseed * TAU - HALF_PI) * anim; | |
if (frame == 0) { | |
frameseed = timeNoise(totalframes, 20, 8); | |
drawMasks(frameseed); | |
} | |
background(0); | |
bufferA.mask(maskA); | |
image(bufferA, -dx, -dy); | |
bufferB.mask(maskB); | |
image(bufferB, dx, dy); | |
//renderRange(totalframes * 8, totalframes); | |
} | |
void drawMasks(float seed) { | |
bufferA.copy(g, 0, 0, width, height, 0, 0, width, height); | |
background(0); | |
fill(255); | |
noStroke(); | |
drawLine(seed); | |
maskA.copy(g, 0, 0, width, height, 0, 0, width, height); | |
filter(INVERT); | |
maskB.copy(g, 0, 0, width, height, 0, 0, width, height); | |
image(bufferA, 0, 0); | |
noFill(); | |
stroke(255); | |
strokeWeight(4); | |
drawLine(seed); | |
bufferA.copy(g, 0, 0, width, height, 0, 0, width, height); | |
bufferB.copy(bufferA, 0, 0, width, height, 0, 0, width, height); | |
} | |
void drawLine(float seed) { | |
float rad = max(width, height) * 2; | |
pushMatrix(); | |
translate(width / 2, height / 2); | |
translate(cos(seed * 60 - seed) * 100, sin(seed * 60 - seed) * 100); | |
rotate(seed * TAU); | |
beginShape(); | |
for (float i = -1; i < 1; i += 0.001) { | |
float a = noise((i + 1 + seed) * 6, seed) * 0.1 - 0.05; | |
float x = cos(a) * rad * i; | |
float y = sin(a) * rad * i; | |
vertex(x, y); | |
} | |
vertex(-width, height); | |
endShape(CLOSE); | |
popMatrix(); | |
} | |
// | |
float timeLoop(float totalframes, float offset) { | |
return (frameCount + offset) % totalframes / totalframes; | |
} | |
float timeLoop(float totalframes) { | |
return timeLoop(totalframes, 0); | |
} | |
float timeNoise(float totalframes, float diameter, float zoffset) { | |
return noise(cos(timeLoop(totalframes) * TAU) * diameter + diameter, | |
sin(timeLoop(totalframes) * TAU) * diameter + diameter, | |
zoffset); | |
} | |
float timeNoise(float totalframes, float diameter) { | |
return timeNoise(totalframes, diameter, 0); | |
} | |
float timeNoise(float totalframes) { | |
return timeNoise(totalframes, 0.01, 0); | |
} | |
static class Ease { | |
static public float hermite5(float t) { | |
return t * t * t * (t * (t * 6 - 15) + 10); | |
} | |
static public float hermite5(float t, int repeat) { | |
for (int i = 0; i < repeat; i++) { | |
t = hermite5(t); | |
} | |
return t; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment