<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<!DOCTYPE html><html lang='en' class=''>
<head><script src='//production-assets.codepen.io/assets/editor/live/console_runner-079c09a0e3b9ff743e39ee2d5637b9216b3545af0de366d4b9aad9dc87e26bfd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/events_runner-73716630c22bbc8cff4bd0f07b135f00a0bdc5d14629260c3ec49e5606f98fdd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/css_live_reload_init-2c0dc5167d60a5af3ee189d570b1835129687ea2a61bee3513dee3a50c115a77.js'></script><meta charset='UTF-8'><meta name="robots" content="noindex"><link rel="shortcut icon" type="image/x-icon" href="//production-assets.codepen.io/assets/favicon/favicon-8ea04875e70c4b0bb41da869e81236e54394d63638a1ef12fa558a4a835f1164.ico" /><link rel="mask-icon" type="" href="//production-assets.codepen.io/assets/favicon/logo-pin-f2d2b6d2c61838f7e76325261b7195c27224080bc099486ddd6dccb469b8e8e6.svg" color="#111" /><link rel="canonical" href="https://codepen.io/ajm13/pen/qPYEyp" />
<style class="cp-pen-styles">body {
margin: 0;
height: 100vh;
background-color: #1d1f20;
}
::-webkit-scrollbar {
display: none;
}
#container {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}
canvas {
max-width: 100%;
max-height: 100%;
}</style></head><body>
<div id="container">
<canvas id="noise"></canvas>
</div>
<script src='//production-assets.codepen.io/assets/common/stopExecutionOnTimeout-b2a7b3fe212eaa732349046d8416e00a9dec26eb7fd347590fbced3ab38af52e.js'></script><script src='https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js'></script><script src='https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js'></script><script src='https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.5/dat.gui.min.js'></script>
<script>// from https://gist.github.com/mjackson/5311256
/**
* Converts an RGB color value to HSL. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes r, g, and b are contained in the set [0, 255] and
* returns h, s, and l in the set [0, 1].
*
* @param Number r The red color value
* @param Number g The green color value
* @param Number b The blue color value
* @return Array The HSL representation
*/
function rgb2hsl(r, g, b) {
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if (max == min) {
h = s = 0; // achromatic
} else {
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return [ h, s, l ];
}
/**
* Converts an HSL color value to RGB. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes h, s, and l are contained in the set [0, 1] and
* returns r, g, and b in the set [0, 255].
*
* @param Number h The hue
* @param Number s The saturation
* @param Number l The lightness
* @return Array The RGB representation
*/
function hsl2rgb(h, s, l) {
var r, g, b;
if (s == 0) {
r = g = b = l; // achromatic
} else {
function hue2rgb(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1/6) return p + (q - p) * 6 * t;
if (t < 1/2) return q;
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return [ r * 255, g * 255, b * 255 ];
}</script>
<script >var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) {if (window.CP.shouldStopExecution(1)){break;} var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); }
window.CP.exitedLoop(1);
} return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {if (window.CP.shouldStopExecution(2)){break;} arr2[i] = arr[i]; }
window.CP.exitedLoop(2);
return arr2; } else { return Array.from(arr); } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var tau = 2 * Math.PI;
var _ref = _,
_random = _ref.random;
var abs = Math.abs,
max = Math.max,
sin = Math.sin,
cos = Math.cos;
// a collection of Vector methods
var Vector = function () {
function Vector() {
var x = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
_classCallCheck(this, Vector);
this.x = x;
this.y = y;
}
_createClass(Vector, [{
key: "clone",
value: function clone() {
return new Vector(this.x, this.y);
}
}, {
key: "add",
value: function add(v) {
this.x += v.x;
this.y += v.y;
return this;
}
}, {
key: "mul",
value: function mul(x) {
this.x *= x;
this.y *= x;
return this;
}
}, {
key: "dist",
value: function dist(v) {
var dx = void 0,
dy = void 0;
return Math.sqrt((dx = this.x - v.x) * dx, (dy = this.y - v.y) * dy);
}
}, {
key: "norm",
value: function norm() {
var r = this.r;
return new Vector(this.x / r, this.y / r);
}
}, {
key: "r",
get: function get() {
return Math.sqrt(this.x * this.x + this.y * this.y);
},
set: function set(r) {
var n = this.norm();
this.x = r * n.x;
this.y = r * n.y;
return r;
}
}, {
key: "a",
get: function get() {
return Math.atan2(this.y, this.x);
},
set: function set(a) {
var r = this.r;
this.x = r * cos(a);
this.y = r * sin(a);
return a;
}
}], [{
key: "fromPolar",
value: function fromPolar(r, a) {
var x = r * cos(a),
y = r * sin(a);
return new Vector(x, y);
}
}]);
return Vector;
}();
// canvas' built-in drawing methods have a lot of
// overhead. this buffer class is for optimized
// drawing of pixels with alpha. it works by directly
// manipulating pixel data and flushing to the canvas
// by calling putImageData
var CanvasBuffer = function () {
function CanvasBuffer(canvas) {
_classCallCheck(this, CanvasBuffer);
this.ctx = canvas.getContext("2d");
this.width = canvas.width;
this.height = canvas.height;
this.center = new Vector(this.width / 2, this.height / 2);
this.ncenter = this.center.clone().mul(-1);
this.clear();
}
_createClass(CanvasBuffer, [{
key: "clear",
value: function clear() {
this.ctx.fillStyle = "#000";
this.ctx.fillRect(0, 0, this.width, this.height);
this.buf = this.ctx.getImageData(0, 0, this.width, this.height);
}
// draws floating point coordinate pixel
// with bilinear interpolation
}, {
key: "drawPixel",
value: function drawPixel(x, y, c) {
var fx = ~~x,
fy = ~~y,
dx = x - fx,
dy = y - fy;
this.drawCell(fx, fy, c, (1 - dx) * (1 - dy));
this.drawCell(fx + 1, fy, c, dx * (1 - dy));
this.drawCell(fx, fy + 1, c, (1 - dx) * dy);
this.drawCell(fx + 1, fy + 1, c, dx * dy);
}
// set color of cell with alpha, for drawPixel
}, {
key: "drawCell",
value: function drawCell(x, y, c, a) {
if (x < 0 || x >= this.width) return;
if (y < 0 || y >= this.height) return;
var data = this.buf.data,
i = 4 * (x + y * this.width),
r = data[i + 0],
g = data[i + 1],
b = data[i + 2];
a *= c[3];
r += c[0] * a;
g += c[1] * a;
b += c[2] * a;
// overflow color math so red + red = white
var ro = max(0, r - 255),
go = max(0, g - 255),
bo = max(0, b - 255),
to = (ro + bo + go) / 6;
data[i + 0] = r + to;
data[i + 1] = g + to;
data[i + 2] = b + to;
}
}, {
key: "flush",
value: function flush() {
this.ctx.putImageData(this.buf, 0, 0);
}
}]);
return CanvasBuffer;
}();
// a class for generating composite noise textures
// and reading values of the texture at a position
var Noise = function () {
function Noise(settings) {
_classCallCheck(this, Noise);
this.width = settings.width;
this.height = settings.height;
this.type = settings.type;
this.strength = settings.strength;
this.canvas = Noise.compositeNoise(this.width, this.height, settings.startOctave, settings.endOctave);
var ctx = this.canvas.getContext('2d');
this.data = ctx.getImageData(0, 0, this.width, this.height).data;
}
// create w by h noise
_createClass(Noise, [{
key: "getNoise",
// returns noise value from -1.0 to 1.0
value: function getNoise(x, y) {
var ch = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
// bitwise ~~ to floor
var i = (~~x + ~~y * this.width) * 4;
return this.data[i + ch] / 127.5 - 1;
}
}], [{
key: "noise",
value: function noise(w, h) {
var cv = document.createElement('canvas'),
ctx = cv.getContext('2d');
cv.width = w;
cv.height = h;
var img = ctx.getImageData(0, 0, w, h),
data = img.data;
for (var i = 0, l = data.length; i < l; i += 4) {if (window.CP.shouldStopExecution(3)){break;}
data[i + 0] = _random(0, 255);
data[i + 1] = _random(0, 255);
data[i + 2] = _random(0, 255);
data[i + 3] = 255;
}
window.CP.exitedLoop(3);
ctx.putImageData(img, 0, 0);
return cv;
}
// create composite noise with multiple octaves
}, {
key: "compositeNoise",
value: function compositeNoise(w, h, soct, eoct) {
var cv = document.createElement('canvas'),
ctx = cv.getContext('2d');
cv.width = w;
cv.height = h;
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, w, h);
ctx.globalCompositeOperation = 'lighter';
ctx.globalAlpha = 1 / (eoct - soct);
for (var i = soct; i < eoct; i++) {if (window.CP.shouldStopExecution(4)){break;}
var noise = Noise.noise(w >> i, h >> i);
ctx.drawImage(noise, 0, 0, w, h);
}
window.CP.exitedLoop(4);
return cv;
}
}]);
return Noise;
}();
var Particle = function () {
function Particle(system) {
var x = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
var y = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
_classCallCheck(this, Particle);
this.system = system;
this.pos = new Vector(x, y);
this.vel = new Vector();
this.col = [255, 255, 255, 0.1];
}
_createClass(Particle, [{
key: "update",
value: function update() {
var _pos = this.pos,
x = _pos.x,
y = _pos.y,
noise = this.system.noise,
dx = noise.getNoise(x, y, 0),
dy = noise.getNoise(x, y, noise.type == 2 ? 0 : 1),
d = new Vector(dx, dy).mul(noise.strength);
this.col[3] *= 0.99;
this.vel.mul(1 - this.system.friction);
this.vel.add(d);
if (noise.type == 0 && this.vel.r > this.system.speed || noise.type == 1) this.vel.r = this.system.speed;
}
}]);
return Particle;
}();
var ParticleSystem = function () {
function ParticleSystem(settings, noise, buffer) {
_classCallCheck(this, ParticleSystem);
this.noise = noise;
this.buffer = buffer;
this.particles = [];
this.num = settings.numParticles;
this.subFrames = settings.subFrames;
this.speed = settings.speed;
this.friction = settings.friction;
for (var i = 0; i < this.num; i++) {if (window.CP.shouldStopExecution(5)){break;}
this.particles.push(new Particle(this));
}
window.CP.exitedLoop(5);
var r = this.buffer.height / 2 * (5 / 6);
switch (settings.shape) {
case 'circle':
this.circle(r);break;
case 'triangle':
this.polygon(r, 3);break;
case 'triangle2':
this.polygon(r, 3, tau / 2);break;
case 'square':
this.polygon(r, 4, tau / 8);break;
case 'square2':
this.polygon(r, 4);break;
case 'hexagon':
this.polygon(r, 6);break;
case 'hexagon2':
this.polygon(r, 6, tau / 12);break;
case 'star':
this.star(r);break;
case 'random':
this.random(r);break;
}
this.setVels(settings.velocity, this.speed);
if (settings.colorType == 'solid') this.colorify(settings.color.concat(settings.alpha));
if (settings.colorType == 'rainbow') this.rainbowify(settings.alpha);
}
_createClass(ParticleSystem, [{
key: "circle",
value: function circle(radius) {
var thickness = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = this.particles[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {if (window.CP.shouldStopExecution(6)){break;}
var p = _step.value;
// get random radius and angle
var r1 = radius + thickness * _random(-0.5, 0.5),
a1 = _random(0, tau),
r2 = _random(0, 1, true),
a2 = _random(0, tau);
var pos = Vector.fromPolar(r1, a1),
vel = Vector.fromPolar(-3, a1);
pos.add(this.buffer.center);
p.pos = pos;
p.vel = vel;
}
window.CP.exitedLoop(6);
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
}, {
key: "polygon",
value: function polygon(radius, sides) {
var angle = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
// calculate lines of polygon
var lines = [];
for (var i = 0; i < sides; i++) {if (window.CP.shouldStopExecution(7)){break;}
var a = i * tau / sides - tau / 4 + angle,
x1 = radius * cos(a),
y1 = radius * sin(a),
x2 = radius * cos(a + tau / sides),
y2 = radius * sin(a + tau / sides);
lines.push({ x1: x1, y1: y1, x2: x2, y2: y2 });
}
window.CP.exitedLoop(7);
var yd = (abs(lines[0].y1) - abs(lines[sides >> 1].y1)) / 2;
if (lines[0].y1 > lines[sides >> 1].y1) yd *= -1;
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = this.particles[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {if (window.CP.shouldStopExecution(8)){break;}
var p = _step2.value;
// choose random line
var _lines$_random = lines[_random(0, sides - 1)],
_x8 = _lines$_random.x1,
_x9 = _lines$_random.x2,
_y = _lines$_random.y1,
_y2 = _lines$_random.y2;
// lerp between points
var t = _random(0, 1, true),
x = _x8 + t * (_x9 - _x8),
y = _y + t * (_y2 - _y);
var pos = new Vector(x, y);
// center on canvas
pos.add(this.buffer.center);
pos.y += yd;
p.pos = pos;
}
window.CP.exitedLoop(8);
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
}
}, {
key: "star",
value: function star(radius) {
// calculate lines of star
var lines = [];
for (var i = 0; i < 5; i++) {if (window.CP.shouldStopExecution(9)){break;}
var a = i * tau / 5 - tau / 4,
x1 = radius * cos(a),
y1 = radius * sin(a),
x2 = radius * cos(a + tau * 2 / 5),
y2 = radius * sin(a + tau * 2 / 5);
lines.push({ x1: x1, y1: y1, x2: x2, y2: y2 });
}
window.CP.exitedLoop(9);
// centering factor
var yd = (abs(lines[0].y1) - abs(lines[2].y1)) / 2;
var _iteratorNormalCompletion3 = true;
var _didIteratorError3 = false;
var _iteratorError3 = undefined;
try {
for (var _iterator3 = this.particles[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {if (window.CP.shouldStopExecution(10)){break;}
var p = _step3.value;
// choose random line
var _lines$_random2 = lines[_random(0, 4)],
_x10 = _lines$_random2.x1,
_x11 = _lines$_random2.x2,
_y3 = _lines$_random2.y1,
_y4 = _lines$_random2.y2;
// magic number is tip to valley on star
var t = _random(0, 0.381966011250105);
if (_random(0, 1)) t = 1 - t;
// lerp between points
var x = _x10 + t * (_x11 - _x10),
y = _y3 + t * (_y4 - _y3);
var pos = new Vector(x, y);
// center on canvas
pos.add(this.buffer.center);
pos.y += yd;
p.pos = pos;
}
window.CP.exitedLoop(10);
} catch (err) {
_didIteratorError3 = true;
_iteratorError3 = err;
} finally {
try {
if (!_iteratorNormalCompletion3 && _iterator3.return) {
_iterator3.return();
}
} finally {
if (_didIteratorError3) {
throw _iteratorError3;
}
}
}
}
}, {
key: "fn",
value: function fn(_fn, domain) {
var _iteratorNormalCompletion4 = true;
var _didIteratorError4 = false;
var _iteratorError4 = undefined;
try {
for (var _iterator4 = this.particles[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {if (window.CP.shouldStopExecution(11)){break;}
var p = _step4.value;
var x = _random.apply(undefined, _toConsumableArray(domain).concat([1])),
y = _fn(x),
t = (x + domain[0]) / (domain[1] - domain[0]),
rgb = hsl2rgb(t, 1, 0.5);
var pos = new Vector(x, y);
pos.add(this.buffer.center);
rgb.push(p.col[3]);
p.col = rgb;
p.pos = pos;
}
window.CP.exitedLoop(11);
} catch (err) {
_didIteratorError4 = true;
_iteratorError4 = err;
} finally {
try {
if (!_iteratorNormalCompletion4 && _iterator4.return) {
_iterator4.return();
}
} finally {
if (_didIteratorError4) {
throw _iteratorError4;
}
}
}
}
}, {
key: "random",
value: function random() {
var _iteratorNormalCompletion5 = true;
var _didIteratorError5 = false;
var _iteratorError5 = undefined;
try {
for (var _iterator5 = this.particles[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {if (window.CP.shouldStopExecution(12)){break;}
var p = _step5.value;
var x = _random(0, this.buffer.width, true),
y = _random(0, this.buffer.height, true);
p.pos = new Vector(x, y);
}
window.CP.exitedLoop(12);
} catch (err) {
_didIteratorError5 = true;
_iteratorError5 = err;
} finally {
try {
if (!_iteratorNormalCompletion5 && _iterator5.return) {
_iterator5.return();
}
} finally {
if (_didIteratorError5) {
throw _iteratorError5;
}
}
}
}
// 0 = frozen, 1 = outward, 2 = inward
}, {
key: "setVels",
value: function setVels(dir, speed) {
var _iteratorNormalCompletion6 = true;
var _didIteratorError6 = false;
var _iteratorError6 = undefined;
try {
for (var _iterator6 = this.particles[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {if (window.CP.shouldStopExecution(13)){break;}
var p = _step6.value;
if (dir == 0) {
p.vel.mul(0);
} else {
var vel = p.pos.clone().add(this.buffer.ncenter);
vel.r = (dir == 2 ? -1 : 1) * speed;
p.vel = vel;
}
}
window.CP.exitedLoop(13);
} catch (err) {
_didIteratorError6 = true;
_iteratorError6 = err;
} finally {
try {
if (!_iteratorNormalCompletion6 && _iterator6.return) {
_iterator6.return();
}
} finally {
if (_didIteratorError6) {
throw _iteratorError6;
}
}
}
}
}, {
key: "update",
value: function update() {
var n = this.subFrames;
// break up into n steps to make smooth lines
var _iteratorNormalCompletion7 = true;
var _didIteratorError7 = false;
var _iteratorError7 = undefined;
try {
for (var _iterator7 = this.particles[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {if (window.CP.shouldStopExecution(15)){break;}
var p = _step7.value;
p.update(this.noise);
var step = p.vel.clone().mul(1 / n);
for (var i = 0; i < n; i++) {if (window.CP.shouldStopExecution(14)){break;}
this.buffer.drawPixel(p.pos.x, p.pos.y, p.col);
p.pos.add(step);
}
window.CP.exitedLoop(14);
}
window.CP.exitedLoop(15);
} catch (err) {
_didIteratorError7 = true;
_iteratorError7 = err;
} finally {
try {
if (!_iteratorNormalCompletion7 && _iterator7.return) {
_iterator7.return();
}
} finally {
if (_didIteratorError7) {
throw _iteratorError7;
}
}
}
this.buffer.flush();
}
}, {
key: "rainbowify",
value: function rainbowify(alpha) {
var _iteratorNormalCompletion8 = true;
var _didIteratorError8 = false;
var _iteratorError8 = undefined;
try {
for (var _iterator8 = this.particles[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {if (window.CP.shouldStopExecution(16)){break;}
var p = _step8.value;
var c = p.pos.clone().add(this.buffer.ncenter),
a = (c.a + tau / 4) / tau,
rgb = hsl2rgb(a, 1, 0.5);
rgb.push(alpha);
p.col = rgb;
}
window.CP.exitedLoop(16);
} catch (err) {
_didIteratorError8 = true;
_iteratorError8 = err;
} finally {
try {
if (!_iteratorNormalCompletion8 && _iterator8.return) {
_iterator8.return();
}
} finally {
if (_didIteratorError8) {
throw _iteratorError8;
}
}
}
}
}, {
key: "colorify",
value: function colorify(col) {
var _iteratorNormalCompletion9 = true;
var _didIteratorError9 = false;
var _iteratorError9 = undefined;
try {
for (var _iterator9 = this.particles[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) {if (window.CP.shouldStopExecution(17)){break;}
var p = _step9.value;
p.col = col.slice();
}
window.CP.exitedLoop(17);
} catch (err) {
_didIteratorError9 = true;
_iteratorError9 = err;
} finally {
try {
if (!_iteratorNormalCompletion9 && _iterator9.return) {
_iterator9.return();
}
} finally {
if (_didIteratorError9) {
throw _iteratorError9;
}
}
}
}
}]);
return ParticleSystem;
}();
var ParticleNoise = function () {
function ParticleNoise(canvas) {
_classCallCheck(this, ParticleNoise);
this.canvas = canvas;
this.renderID = 0;
}
_createClass(ParticleNoise, [{
key: "generate",
value: function generate(settings) {
var width = settings.width,
height = settings.height,
shape = settings.shape,
startOctave = settings.startOctave,
endOctave = settings.endOctave,
numParticles = settings.numParticles,
numFrames = settings.numFrames;
this.frame = 0;
this.numFrames = numFrames;
this.shape = shape;
this.canvas.width = width;
this.canvas.height = height;
this.buffer = new CanvasBuffer(this.canvas);
this.noise = new Noise(settings);
this.particles = new ParticleSystem(settings, this.noise, this.buffer);
this.stop();
this.render();
}
}, {
key: "render",
value: function render() {
this.frame++;
this.particles.update();
// update progress bar at 30fps
if (this.frame == this.numFrames || this.frame % 2 == 0) settings.progress = 100 * this.frame / this.numFrames;
if (this.frame < this.numFrames) this.renderID = window.requestAnimationFrame(this.render.bind(this));else {
this.renderID = 0;
if (settings.autogenerate) this.generate(settings);
}
}
}, {
key: "save",
value: function save() {
var rnd = new Array(5).fill(0).map(function () {
return Math.floor(36 * Math.random()).toString(36);
}).join('');
var name = "noise-" + this.shape + "-" + rnd + ".png";
this.canvas.toBlob(function (blob) {
saveAs(blob, name);
});
}
}, {
key: "stop",
value: function stop() {
if (this.renderID) {
window.cancelAnimationFrame(this.renderID);
this.renderID = 0;
settings.progress = 0;
}
}
}, {
key: "invert",
value: function invert() {
this.stop();
var ctx = this.canvas.getContext('2d');
var img = ctx.getImageData(0, 0, this.canvas.width, this.canvas.height);
for (var i = 0; i < img.data.length; i += 4) {if (window.CP.shouldStopExecution(18)){break;}
img.data[i + 0] = 255 - img.data[i + 0];
img.data[i + 1] = 255 - img.data[i + 1];
img.data[i + 2] = 255 - img.data[i + 2];
}
window.CP.exitedLoop(18);
ctx.putImageData(img, 0, 0);
}
}]);
return ParticleNoise;
}();
var PN = new ParticleNoise(document.getElementById('noise'));
var dpr = 2; //window.devicePixelRatio
var settings = {
width: window.innerWidth * dpr,
height: window.innerHeight * dpr,
type: 0,
strength: 1,
startOctave: 5,
endOctave: 8,
numParticles: 10000,
numFrames: 300,
subFrames: 4,
progress: 0,
shape: 'triangle',
colorType: 'rainbow',
color: [127, 0, 255],
alpha: 0.1,
velocity: 0,
speed: 3,
friction: 0.05,
autogenerate: true,
save: function save() {
return PN.save();
},
stop: function stop() {
return PN.stop();
},
invert: function invert() {
return PN.invert();
},
generate: function generate() {
return PN.generate(settings);
}
};
settings.generate();
var gui = new dat.GUI();
var rndr = gui.addFolder('rendering');
rndr.add(settings, 'width');
rndr.add(settings, 'height');
rndr.add(settings, 'numParticles', 10, 3e4, 1);
rndr.add(settings, 'numFrames', 1, 600, 1);
rndr.add(settings, 'subFrames', 1, 10, 1);
rndr.open();
var col = gui.addFolder('particles');
col.add(settings, 'shape', ['circle', 'triangle', 'triangle2', 'square', 'square2', 'hexagon', 'hexagon2', 'star', 'random']);
col.add(settings, 'velocity', { 'none': 0, 'outward': 1, 'inward': 2 }).name('initial velocity');
col.add(settings, 'speed', 0.1, 10);
col.add(settings, 'friction', 0, 1);
col.add(settings, 'colorType', ['solid', 'rainbow']);
col.addColor(settings, 'color');
col.add(settings, 'alpha', 0, 1);
col.open();
var nz = gui.addFolder('noise');
nz.add(settings, 'type', { 'ink': 0, 'loop': 1, 'streak': 2 });
nz.add(settings, 'strength', 0.1, 10, 0.1);
nz.add(settings, 'startOctave', 0, 10, 1).onChange(update);
nz.add(settings, 'endOctave', 0, 11, 1).onChange(update);
nz.open();
gui.add(settings, 'invert');
gui.add(settings, 'save');
gui.add(settings, 'stop');
gui.add(settings, 'autogenerate');
gui.add(settings, 'progress', 0, 100, 1).listen();
gui.add(settings, 'generate');
function update() {
var _iteratorNormalCompletion10 = true;
var _didIteratorError10 = false;
var _iteratorError10 = undefined;
try {
for (var _iterator10 = nz.__controllers[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {if (window.CP.shouldStopExecution(19)){break;}
var c = _step10.value;
switch (c.property) {
case "endOctave":
var min = settings.startOctave + 1;
if (c.getValue() < min) c.setValue(min);
break;
}
}
window.CP.exitedLoop(19);
} catch (err) {
_didIteratorError10 = true;
_iteratorError10 = err;
} finally {
try {
if (!_iteratorNormalCompletion10 && _iterator10.return) {
_iterator10.return();
}
} finally {
if (_didIteratorError10) {
throw _iteratorError10;
}
}
}
}
//# sourceURL=pen.js
</script>
</body></html>