🐛 Checkout bundle.js
This commit is contained in:
parent
d5a6933de9
commit
88e598f794
|
@ -1,2 +1 @@
|
|||
node_modules
|
||||
bundle.js
|
||||
|
|
|
@ -0,0 +1,531 @@
|
|||
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
const wrapNode = require('./lib/node');
|
||||
|
||||
/**
|
||||
* Import given node into `the-dom`
|
||||
*
|
||||
* @param {Node} node Node to import
|
||||
* @return {Object} Wrapped node
|
||||
*/
|
||||
exports.import = (node) => wrapNode(node);
|
||||
|
||||
/**
|
||||
* Import an HTML document into `the-dom`
|
||||
*
|
||||
* @param {HTMLDocument} doc Document to import
|
||||
* @return {Object} A hash with doctype, body, head, html props
|
||||
*/
|
||||
exports.html = doc => ({
|
||||
create: name => doc.createElement(name),
|
||||
body: wrapNode(doc.body),
|
||||
head: wrapNode(doc.head),
|
||||
html: wrapNode(doc.documentElement),
|
||||
doctype: wrapNode(doc.doctype)
|
||||
});
|
||||
|
||||
},{"./lib/node":3}],2:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
const utils = require('./utils');
|
||||
|
||||
const split = utils.split;
|
||||
const iterateArray = utils.iterateArray;
|
||||
|
||||
/**
|
||||
* Create an object to manipulate given node's CSS classes
|
||||
*
|
||||
* @param {HTMLElement} node Input element
|
||||
* @see `Set` documentation for behaviour information
|
||||
* @return {Object} Set-like object
|
||||
*/
|
||||
const wrapClass = node => {
|
||||
const res = {
|
||||
add: function (el) {
|
||||
if (!this.has(el)) {
|
||||
const classes = split(node.className);
|
||||
|
||||
classes.push(el);
|
||||
node.className = classes.join(' ');
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
delete: el => {
|
||||
const classes = split(node.className), pos = classes.indexOf(el);
|
||||
|
||||
if (pos > -1) {
|
||||
classes.splice(pos, 1);
|
||||
node.className = classes.join(' ');
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
has: el => split(node.className).indexOf(el) !== -1,
|
||||
clear: () => node.className = '',
|
||||
|
||||
get size() {
|
||||
return split(node.className).length;
|
||||
},
|
||||
|
||||
keys: () => iterateArray(split(node.className)),
|
||||
values: () => iterateArray(split(node.className)),
|
||||
entries: () => iterateArray(split(node.className).map(el => [el, el])),
|
||||
|
||||
forEach: function (callback, thisArg) {
|
||||
for (let cls of this) {
|
||||
callback.call(thisArg, cls, cls, this);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
res[Symbol.iterator] = res.values;
|
||||
return res;
|
||||
};
|
||||
|
||||
module.exports = wrapClass;
|
||||
|
||||
},{"./utils":5}],3:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
const wrapClass = require('./class');
|
||||
const wrapStyle = require('./style');
|
||||
const split = require('./utils').split;
|
||||
|
||||
/**
|
||||
* Ensure a node is not wrapped before using it in native methods
|
||||
*
|
||||
* @param {Node|Object} node A node, wrapped or not
|
||||
* @return {Node} Unwrapped node
|
||||
*/
|
||||
const unwrap = node =>
|
||||
(typeof node !== 'object' || node === null || !node.node) ? node : node.node;
|
||||
|
||||
/**
|
||||
* Turn a NodeList/HTMLCollection into an array
|
||||
* for easy manipulation
|
||||
*
|
||||
* @param {NodeList|HTMLCollection} list Input collection
|
||||
* @return {Array} Wrapping array
|
||||
*/
|
||||
const wrapList = list => {
|
||||
const length = list.length;
|
||||
let result = [];
|
||||
|
||||
for (let i = 0; i < length; i += 1) {
|
||||
result.push(wrapNode(list.item(i)));
|
||||
}
|
||||
|
||||
return Object.assign(result, {
|
||||
on: (evts, handler) => {
|
||||
result.forEach(node => node.on(evts, handler));
|
||||
},
|
||||
|
||||
off: (evts, handler) => {
|
||||
result.forEach(node => node.off(evts, handler));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an object of shortcuts to manipulate
|
||||
* given node more easily
|
||||
*
|
||||
* @param {Node} Input node
|
||||
* @return {Object} DOM shortcuts
|
||||
*/
|
||||
const wrapNode = node => {
|
||||
if (node === null || typeof node !== 'object') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
node,
|
||||
|
||||
// search among children
|
||||
find: query => wrapNode(node.querySelector(query)),
|
||||
findAll: query => wrapList(node.querySelectorAll(query)),
|
||||
|
||||
// access node's relative tree (parent, children, siblings)
|
||||
equal: el => unwrap(el) === node,
|
||||
|
||||
get following() {
|
||||
return wrapNode(node.nextElementSibling);
|
||||
},
|
||||
|
||||
get preceding() {
|
||||
return wrapNode(node.previousElementSibling);
|
||||
},
|
||||
|
||||
get parent() {
|
||||
return wrapNode(node.parentNode);
|
||||
},
|
||||
|
||||
get children() {
|
||||
return wrapList(node.children);
|
||||
},
|
||||
|
||||
// check relative positions
|
||||
precedes: el => !!(unwrap(el).compareDocumentPosition(node) & 2),
|
||||
follows: el => !!(unwrap(el).compareDocumentPosition(node) & 4),
|
||||
contains: el => !!(unwrap(el).compareDocumentPosition(node) & 8),
|
||||
contained: el => !!(unwrap(el).compareDocumentPosition(node) & 16),
|
||||
|
||||
// get and set element attributes
|
||||
get name() {
|
||||
return node.tagName.toLowerCase().trim();
|
||||
},
|
||||
|
||||
get type() {
|
||||
switch (node.nodeType) {
|
||||
case 1: return 'element';
|
||||
case 3: return 'text';
|
||||
case 7: return 'processing-instruction';
|
||||
case 8: return 'comment';
|
||||
case 9: return 'document';
|
||||
case 10: return 'document-type';
|
||||
case 11: return 'document-fragment';
|
||||
default: return null;
|
||||
}
|
||||
},
|
||||
|
||||
getAttr: attr => node.getAttribute(attr),
|
||||
setAttr: (attr, value) => node.setAttribute(attr, value),
|
||||
|
||||
// place an element in the DOM tree
|
||||
append: subnode => node.appendChild(unwrap(subnode)),
|
||||
attach: parent => unwrap(parent).appendChild(node),
|
||||
remove: child => {
|
||||
if (child) {
|
||||
node.removeChild(unwrap(child));
|
||||
return;
|
||||
}
|
||||
|
||||
node.parentNode.removeChild(node);
|
||||
},
|
||||
|
||||
// manipulate element's CSS (see wrapClass, wrapStyle)
|
||||
class: wrapClass(node),
|
||||
style: wrapStyle(node),
|
||||
|
||||
// change an element's content
|
||||
get text() {
|
||||
return node.textContent;
|
||||
},
|
||||
|
||||
set text(val) {
|
||||
node.textContent = val;
|
||||
},
|
||||
|
||||
get html() {
|
||||
return node.innerHTML;
|
||||
},
|
||||
|
||||
set html(val) {
|
||||
node.innerHTML = val;
|
||||
},
|
||||
|
||||
// listen to events
|
||||
on: (evts, handler) => {
|
||||
split(evts).forEach(evt => {
|
||||
node.addEventListener(evt, handler);
|
||||
});
|
||||
},
|
||||
|
||||
off: (evts, handler) => {
|
||||
split(evts).forEach(evt => {
|
||||
node.removeEventListener(evt, handler);
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = wrapNode;
|
||||
|
||||
},{"./class":2,"./style":4,"./utils":5}],4:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
const iterateArray = require('./utils').iterateArray;
|
||||
|
||||
/**
|
||||
* Create an object to manipulate given node's CSS styles
|
||||
*
|
||||
* @param {HTMLElement} node Input element
|
||||
* @see `Map` documentation for behaviour information
|
||||
* @return {Object} Map-like object
|
||||
*/
|
||||
const wrapStyle = node => {
|
||||
const res = {
|
||||
set: function (prop, value) {
|
||||
node.style.setProperty(prop, value);
|
||||
return this;
|
||||
},
|
||||
|
||||
delete: prop => node.style.removeProperty(prop) !== '',
|
||||
has: prop => [].slice.call(node.style).indexOf(prop) > -1,
|
||||
|
||||
get: prop => {
|
||||
const result = node.style.getPropertyValue(prop);
|
||||
|
||||
if (result.trim() === '') {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
clear: () => {
|
||||
const length = node.style.length;
|
||||
|
||||
for (let i = 0; i < length; i += 1) {
|
||||
node.style.removeProperty(node.style[i]);
|
||||
}
|
||||
},
|
||||
|
||||
get size() {
|
||||
return node.style.length;
|
||||
},
|
||||
|
||||
keys: () => iterateArray([].slice.call(node.style)),
|
||||
values: () => iterateArray([].slice.call(node.style).map(
|
||||
prop => node.style.getPropertyValue(prop))),
|
||||
entries: () => iterateArray([].slice.call(node.style).map(
|
||||
prop => [prop, node.style.getPropertyValue(prop)])),
|
||||
|
||||
forEach: function (callback, thisArg) {
|
||||
for (let cls of this) {
|
||||
callback.call(thisArg, cls, cls, this);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
res[Symbol.iterator] = res.values;
|
||||
return res;
|
||||
};
|
||||
|
||||
module.exports = wrapStyle;
|
||||
|
||||
},{"./utils":5}],5:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
const whitespace = /\s+/g;
|
||||
|
||||
/**
|
||||
* Split a list of whitespace separated tokens,
|
||||
* excluding empty ones
|
||||
*
|
||||
* @param {string} str Input string
|
||||
* @return {Array} Split tokens
|
||||
*/
|
||||
exports.split = str => str.split(whitespace).filter(el => el.trim().length);
|
||||
|
||||
/**
|
||||
* Create an iterator on an array
|
||||
*
|
||||
* @param {Array} arr Array to iterate on
|
||||
* @return {Object} Iterator for given array
|
||||
*/
|
||||
exports.iterateArray = (arr) => {
|
||||
let next = 0;
|
||||
|
||||
return {
|
||||
next: () => next < arr.length ?
|
||||
{value: arr[next++], done: false} :
|
||||
{done: true}
|
||||
};
|
||||
};
|
||||
|
||||
},{}],6:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
var _theDom = require('the-dom');
|
||||
|
||||
var _utils = require('./utils');
|
||||
|
||||
var _html = (0, _theDom.html)(document);
|
||||
|
||||
var body = _html.body;
|
||||
var create = _html.create;
|
||||
|
||||
var content = body.find('#content');
|
||||
var plotting = body.find('#plotting');
|
||||
var ctx = plotting.node.getContext('2d');
|
||||
|
||||
var padding = 40; // padding between the canvas edges and the points
|
||||
var image = undefined,
|
||||
width = undefined,
|
||||
height = undefined;
|
||||
var lastUpdate = -Infinity;
|
||||
|
||||
/**
|
||||
* Create a fractal of given width, height, based on
|
||||
* a polygon of given amount of vertices, using the
|
||||
* chaos game applied with given fraction
|
||||
*
|
||||
* @param {number} width Fractal width
|
||||
* @param {number} height Fractal height
|
||||
* @param {number} fraction Fraction to use
|
||||
* @param {Array} colors Color of each vertex
|
||||
* @return {ImageData} Generated pixel data
|
||||
*/
|
||||
var chaos = function chaos(width, height, fraction, colors) {
|
||||
var cx = Math.floor(width / 2);
|
||||
var cy = Math.floor(height / 2);
|
||||
var radius = Math.min(cx, cy);
|
||||
|
||||
var count = colors.length;
|
||||
var vertices = [];
|
||||
var angleStep = 2 * Math.PI / count;
|
||||
var initialAngle = undefined;
|
||||
|
||||
// creating 0-width image data will throw an error
|
||||
if (width <= 0 || height <= 0) {
|
||||
return ctx.createImageData(1, 1);
|
||||
}
|
||||
|
||||
var image = ctx.createImageData(width, height);
|
||||
var data = image.data;
|
||||
|
||||
// we will rotate around an inscribed circle to calculate
|
||||
// the vertices' positions. We adapt the initial angle so
|
||||
// that usual polygons look better
|
||||
if (count === 3) {
|
||||
initialAngle = -Math.PI / 2;
|
||||
} else if (count === 4) {
|
||||
initialAngle = Math.PI / 4;
|
||||
} else {
|
||||
initialAngle = 0;
|
||||
}
|
||||
|
||||
for (var i = 0; i < count; i += 1) {
|
||||
var current = angleStep * i + initialAngle;
|
||||
|
||||
vertices.push([Math.floor(Math.cos(current) * radius + cx), Math.floor(Math.sin(current) * radius + cy)]);
|
||||
}
|
||||
|
||||
// now we apply the chaos algorithm:
|
||||
// for any point, the next point is a `fraction` of the
|
||||
// distance between it and a random vertex
|
||||
var point = vertices[0];
|
||||
var iterations = 200000;
|
||||
var drop = 1000;
|
||||
|
||||
while (iterations--) {
|
||||
var vertexNumber = (0, _utils.randomNumber)(0, count);
|
||||
var vertex = vertices[vertexNumber],
|
||||
color = colors[vertexNumber];
|
||||
|
||||
point = [Math.floor((point[0] - vertex[0]) * fraction + vertex[0]), Math.floor((point[1] - vertex[1]) * fraction + vertex[1])];
|
||||
|
||||
// skip the first 1000 points
|
||||
if (drop === 0) {
|
||||
var i = (point[1] * width + point[0]) * 4;
|
||||
|
||||
data[i] = color[0];
|
||||
data[i + 1] = color[1];
|
||||
data[i + 2] = color[2];
|
||||
data[i + 3] = 255;
|
||||
} else {
|
||||
drop--;
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
};
|
||||
|
||||
/**
|
||||
* Render the scene, recalculating the points
|
||||
* positions if they need to
|
||||
*
|
||||
* @return {null}
|
||||
*/
|
||||
var render = function render() {
|
||||
// only recalculate every 16.67 ms
|
||||
if (+new Date() - lastUpdate > 16.67) {
|
||||
image = chaos(width - 2 * padding, height - 2 * padding, 1 / 2, [[255, 0, 0], [0, 255, 0], [0, 0, 255]]);
|
||||
|
||||
lastUpdate = +new Date();
|
||||
}
|
||||
|
||||
ctx.clearRect(0, 0, width, height);
|
||||
ctx.putImageData(image, padding, padding);
|
||||
};
|
||||
|
||||
/**
|
||||
* Resize the canvas to fit the new
|
||||
* window size and redraw the scene
|
||||
*
|
||||
* @return {null}
|
||||
*/
|
||||
var resize = function resize() {
|
||||
width = content.node.clientWidth;
|
||||
height = content.node.clientHeight;
|
||||
|
||||
plotting.setAttr('width', width);
|
||||
plotting.setAttr('height', height);
|
||||
|
||||
render();
|
||||
};
|
||||
|
||||
window.onresize = resize;
|
||||
resize();
|
||||
|
||||
},{"./utils":7,"the-dom":1}],7:[function(require,module,exports){
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Get a random whole number
|
||||
*
|
||||
* @param {number} min Minimal value for the number
|
||||
* @param {number} max Maximal value for the number (excluded)
|
||||
* @return {number} Random number
|
||||
*/
|
||||
;
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
var randomNumber = exports.randomNumber = function randomNumber(min, max) {
|
||||
return Math.floor(Math.random() * (max - min)) + min;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a random color
|
||||
*
|
||||
* @return {Array} RGB components
|
||||
*/
|
||||
var randomColor = exports.randomColor = function randomColor() {
|
||||
var color = [];
|
||||
|
||||
for (var i = 0; i < 3; i++) {
|
||||
color.push(Math.round(Math.random().toFixed(2) * 255));
|
||||
}
|
||||
|
||||
return color;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert a decimal number to its hexadecimal representation
|
||||
*
|
||||
* @param {number} input Number to be converted
|
||||
* @return {string} Number representation
|
||||
*/
|
||||
var hex = function hex(input) {
|
||||
var hex = parseInt(input, 10).toString(16);
|
||||
return hex.length === 1 ? '0' + hex : hex;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert a RGB color to its hexadecimal representation
|
||||
*
|
||||
* @param {Array} color RGB color
|
||||
* @return {string} Hex representation
|
||||
*/
|
||||
var rgbToHex = exports.rgbToHex = function rgbToHex(color) {
|
||||
return '#' + hex(color[0]) + hex(color[1]) + hex(color[2]);
|
||||
};
|
||||
|
||||
},{}]},{},[6]);
|
Loading…
Reference in New Issue