Last active
August 27, 2017 06:08
-
-
Save gncgnc/86d3d4e2d99081739d8ab0c27b78da14 to your computer and use it in GitHub Desktop.
Code for grid-drop
This file contains 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
var gif, canvElt, | |
numFrames = 45, | |
duration = 1500, | |
recording = true, | |
time = 0, | |
gridW = 10, // number of cells in a row/column | |
margin = 0.15, | |
pts = [] | |
; | |
function setup() { | |
canvElt = createCanvas(1000, 1000); | |
ellipseMode(CENTER) | |
strokeJoin(MITER) | |
strokeCap(SQUARE) | |
// generate the data of the grid and its shattered version | |
var cellW = (1-2*margin)*width / gridW | |
for (var i = 0; i < gridW+1; i++) { | |
for (var j = 0; j < gridW+1; j++) { | |
var x = width*margin + cellW*i, | |
y = width*margin + cellW*j, | |
p = { | |
inix: x, | |
iniy: y, | |
// add a random amount to x and y to "shatter" the grid | |
endx: x + cellW*random(-0.35,0.35), | |
endy: y + cellW*random(-0.35,0.35) | |
} | |
pts[i + j*(gridW+1)] = p | |
} | |
} | |
stroke(255) | |
noFill() | |
strokeWeight(width/200) | |
} | |
function draw() { | |
background(0) | |
time = ((frameCount+numFrames*0.5)%numFrames)/numFrames // goes from 0 to 1 as the gif progresses | |
// some animation stuff to make it appear like it's falling | |
var sc = time < 0.4 ? | |
anim(1, 0.8, quintEaseOut, 0, 0.4) : | |
anim(0.8, 1, quintEase, 0.6, 1) | |
translate(width*0.5, height*0.5) | |
scale(sc) | |
translate(width*-0.5, height*-0.5) | |
// animate points to shattered positions | |
pts.forEach(p => { | |
p.x = anim(p.inix, p.endx, quintEase, 0.35, 0.5), | |
p.y = anim(p.iniy, p.endy, quintEase, 0.35, 0.5) | |
if (time > 0.6) { | |
p.x = anim(p.endx, p.inix, quintEase, 0.6, 1) | |
p.y = anim(p.endy, p.iniy, quintEase, 0.6, 1) | |
} | |
point(p.x,p.y) | |
}) | |
// draw the grid with new animated positions | |
for (var i = 0; i < gridW; i++) { | |
beginShape(QUAD_STRIP) | |
for (var j = 0; j < gridW+1; j++) { | |
var p = pts[i + j*(gridW+1)], | |
pn = pts[i + j*(gridW+1) + 1] | |
vertex(p.x, p.y) | |
vertex(pn.x, pn.y) | |
} | |
endShape() | |
} | |
// glitch the grid when it's being shattered using the shiftRows function | |
if (time > 0.45) { | |
var img = get() | |
img.loadPixels() | |
for (var i = 0; i < 40; i++) { | |
var r = random(height) | |
shiftRows(img, r, height*random(0.1,0.2), map(time, .35, 1, 1,0) * width*random(-0.03,0.03), random([0,1])) | |
} | |
img.updatePixels() | |
resetMatrix() | |
image(img,0,0) | |
} | |
} | |
// actually a quad ease, too lazy to change function names lol | |
var quintEaseOut = function(t) { | |
return t**2 | |
} | |
var quintEase = function(t) { | |
return ease(t,5) | |
} | |
// glorified lerp with start and end times, easing; used to animate stuff | |
function anim(from, to, ease, startTime, endTime) { | |
// handle inputs | |
startTime = (typeof startTime === "undefined") ? 0 : startTime; | |
endTime = (typeof endTime === "undefined") ? 1 : endTime; | |
ease = ease || function(t) {return t} | |
// if before start time, return initial value | |
if (time < startTime) { | |
return from; | |
// if after end time, return final value | |
} else if (time > endTime) { | |
return to; | |
// if between start and end time, return lerped and eased value | |
} else { | |
// normalize time to be between start and end time | |
var t = (time - startTime) / (endTime - startTime) | |
return lerp(from, to, ease(t)); | |
} | |
} | |
function shiftRows (im, r0, h, shift, channel) { | |
var r1 = int(r0 + h); r0 = int(r0); shift = int(shift) // sanitize inputs | |
// shift the specified "channel" (r,g,b or a) in a span of rows from "r0" to "r1", "shift" number of pixels | |
for (var i=r0; i<=r1; i++) { | |
var startInd = 4 * i * im.width + channel, | |
endInd = 4 * (i+1) * im.width, | |
row = im.pixels.slice(startInd, endInd) | |
for (var j=0; j<row.length; j+=4) { | |
im.pixels[startInd+j] = row[mod(j+shift*4,row.length)] | |
} | |
} | |
} | |
// mathematical mod, always returns values in range [0, m-1], even for negative values | |
function mod(n, m) { | |
return ((n % m) + m) % m; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment