A Pen by Darryl Huffman on CodePen.
Created
April 20, 2018 05:05
-
-
Save CodeMyUI/e07d57ec9ad5e5d58fbb53878cbfc16d to your computer and use it in GitHub Desktop.
Spilled Paint v2
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
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> | |
<script> | |
$(document).ready(function(){ | |
var slider = new gooSlider('body'); | |
var l1,l2; | |
$('body').click(function(){ | |
var c = 'hsla('+ (Math.floor(Math.random()*7) * 50) +',56%,68%,1)'; | |
if(c != l1 && c != l2){ | |
slider.wave(c, function(){}); | |
l2 = l1; | |
l1 = c; | |
} else { | |
$('body').click(); | |
} | |
}); | |
var count = 5, | |
cur = 0; | |
function start(){ | |
slider.wave('hsla('+ (Math.floor(Math.random()*7) * 50) +',82%,64%,1)', function(){}); | |
cur++; | |
if(cur<count){ | |
setTimeout(function(){ | |
start(); | |
}, 1500) | |
} | |
} | |
start(); | |
}); | |
</script> | |
<div id="info">Click to spill more paint!</div> |
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
window.requestFrame = (function(){ | |
return window.requestAnimationFrame || | |
window.webkitRequestAnimationFrame || | |
window.mozRequestAnimationFrame || | |
function( callback ){ | |
window.setTimeout(callback, 1000 / 60); | |
}; | |
})(); | |
var gooSlider = function(parent, id){ | |
var size = { | |
x: $(parent).width(), | |
y: $(parent).height() | |
}; | |
var canvas = $('<canvas/>').attr({width: size.x, height: size.y, id: id}).appendTo(parent), | |
context = canvas.get(0).getContext("2d"); | |
var startTime = new Date().getTime(); // timing stuff | |
var currentTime = 0; // more timing, it just makes it so it always falls at the same rate | |
var dripDist = 100; // distance between each "drip" | |
var dripsAmount = Math.floor(size.x / dripDist) + 2; // amount of drips that will go across screen | |
waves = []; // this will contain the information for each wave (color, drip positions, etc...) | |
this.waves = waves; // making the waves variable available to the outside world | |
noise.seed(Math.random()); | |
this.wave = function(settings, call){ // this creates the wave object. You pass through the color of the "wave" and the callback for when the wave covers the screen. | |
if(typeof call != 'function') { call = function(){} } | |
var it = { | |
drips: [], | |
callback: call, | |
defaults: { | |
color: '#99db81', | |
minSpeed: 1, | |
maxSpeed: 3 | |
}, | |
settings: {} | |
}; | |
if(typeof settings == 'object'){ | |
it.settings = $.extend(true, it.defaults, settings); | |
} else { | |
it.settings = $.extend(true, it.defaults, {color: settings}); | |
} | |
for(var i = 0; i < dripsAmount; i++){ | |
it.drips.push(0); | |
} | |
waves.push(it); // add the object to the waves array so it's animated. | |
} | |
function loop(){ | |
var now = new Date().getTime(); | |
currentTime = (now - startTime) / 10000; // more timing.. | |
//context.clearRect(0,0,size.x,size.y); | |
for(var i = 0; i <= waves.length; i++){ // for each wave | |
if(waves[i] != undefined){ // make sure it's still getting animated | |
var done = true; // this tells me if we're on the last animation frame for this wave or not | |
var points = []; // this will contain the points for the wave | |
for(var c = 0; c < waves[i].drips.length; c++){ // for each drip in the wave | |
waves[i].drips[c] += waves[i].settings.minSpeed + ((noise.simplex2((i*dripsAmount)+c,currentTime) + 1) * waves[i].settings.maxSpeed); // add the "speed" of that drop to the y position | |
points.push({ // add this point to be animated | |
x: dripDist*c, | |
y: waves[i].drips[c] | |
}); | |
if(waves[i].drips[c] < size.y){ // if this point is not to the bottom of the screen yet, set done to false. Once all points are below the screen, done will be set to true and the animation for this wave will end and the callback will be... called. | |
done = false; // ^^ | |
} | |
} | |
if(done == true){ // The continuation of the comment above | |
waves[i].callback(); // callback | |
waves[i].callback = function(){}; // callback | |
waves[i-1] = undefined; // stop the waves before this ones animation. | |
// The reason why I do that ^ instead of setting this one to undefined, is to fix an issue where the previous wave will be undrawn before the current wave reaches the bottom. Which results in random colors flashing at the bottom which is no good. | |
} else { | |
context.beginPath(); // this is the animation | |
context.strokeStyle = waves[i].settings.color; // set the color of the wave | |
context.fillStyle = waves[i].settings.color; // ^^ | |
context.moveTo(0, 0); // move to the top left | |
context.lineTo(points[0].x, points[0].y); // draw to the first point | |
var p = 0; | |
for (p = 1; p < points.length - 2; p ++){ // loop through almost all of the points, but leave the last 2 alone and we'll code that in by hand | |
var xc = (points[p].x + points[p + 1].x) / 2; // math for x offset | |
var yc = ((points[p].y + points[p + 1].y) / 2); // ^^ but for y | |
context.quadraticCurveTo(points[p].x, points[p].y, xc, yc); // draw the curve to this new point, using the x and y offsets | |
} | |
// curve through the last two points | |
context.quadraticCurveTo(points[p].x, points[p].y, points[p+1].x,points[p+1].y); // draw the last two by hand | |
context.lineTo(size.x, 0); // draw a line to the top right so the fill works properly | |
context.stroke(); | |
context.fill(); | |
} | |
} | |
} | |
requestFrame(loop); | |
} | |
this.clear = function(){ // this will come in handy for practical uses | |
waves = []; | |
context.clearRect(0,0,size.x,size.y); | |
} | |
loop(); // start the animation | |
} | |
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
<script src="https://codepen.io/darrylhuffman/pen/zogYQW.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> |
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
html, body { | |
height: 100%; | |
width: 100%; | |
padding: 0px; | |
margin: 0px; | |
overflow: hidden; | |
display: flex; | |
} | |
#info { | |
margin: auto; | |
position: relative; | |
z-index: 2; | |
color: #ffffff; | |
font-family: sans-serif; | |
pointer-events: none; | |
-webkit-touch-callout: none; | |
-webkit-user-select: none; | |
-khtml-user-select: none; | |
-moz-user-select: none; | |
-ms-user-select: none; | |
user-select: none | |
} | |
canvas { | |
z-index: 1; | |
position: absolute; | |
top: 0px; | |
left: 0px; | |
width: 100%; | |
height: 100%; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment