"use strict"; function _typeof(obj) { return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj; } (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'; var wrapNode = require('./lib/node'); /** * Import given node into `the-dom` * * @param {Node} node Node to import * @return {Object} Wrapped node */ exports.import = function (node) { return 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 = function (doc) { return { create: function create(name) { return 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'; var utils = require('./utils'); var split = utils.split; var 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 */ var wrapClass = function wrapClass(node) { var res = { add: function add(el) { if (!this.has(el)) { var classes = split(node.className); classes.push(el); node.className = classes.join(' '); } return this; }, delete: function _delete(el) { var classes = split(node.className), pos = classes.indexOf(el); if (pos > -1) { classes.splice(pos, 1); node.className = classes.join(' '); return true; } return false; }, has: function has(el) { return split(node.className).indexOf(el) !== -1; }, clear: function clear() { return node.className = ''; }, get size() { return split(node.className).length; }, keys: function keys() { return iterateArray(split(node.className)); }, values: function values() { return iterateArray(split(node.className)); }, entries: function entries() { return iterateArray(split(node.className).map(function (el) { return [el, el]; })); }, forEach: function forEach(callback, thisArg) { var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = this[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var cls = _step.value; callback.call(thisArg, cls, cls, this); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } }; res[Symbol.iterator] = res.values; return res; }; module.exports = wrapClass; }, { "./utils": 5 }], 3: [function (require, module, exports) { 'use strict'; var wrapClass = require('./class'); var wrapStyle = require('./style'); var 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 */ var unwrap = function unwrap(node) { return (typeof node === "undefined" ? "undefined" : _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 */ var wrapList = function wrapList(list) { var length = list.length; var result = []; for (var i = 0; i < length; i += 1) { result.push(wrapNode(list.item(i))); } return Object.assign(result, { on: function on(evts, handler) { result.forEach(function (node) { return node.on(evts, handler); }); }, off: function off(evts, handler) { result.forEach(function (node) { return node.off(evts, handler); }); } }); }; /** * Create an object of shortcuts to manipulate * given node more easily * * @param {Node} Input node * @return {Object} DOM shortcuts */ var wrapNode = function wrapNode(node) { if (node === null || (typeof node === "undefined" ? "undefined" : _typeof(node)) !== 'object') { return null; } return { node: node, // search among children find: function find(query) { return wrapNode(node.querySelector(query)); }, findAll: function findAll(query) { return wrapList(node.querySelectorAll(query)); }, // access node's relative tree (parent, children, siblings) equal: function equal(el) { return 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: function precedes(el) { return !!(unwrap(el).compareDocumentPosition(node) & 2); }, follows: function follows(el) { return !!(unwrap(el).compareDocumentPosition(node) & 4); }, contains: function contains(el) { return !!(unwrap(el).compareDocumentPosition(node) & 8); }, contained: function contained(el) { return !!(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: function getAttr(attr) { return node.getAttribute(attr); }, setAttr: function setAttr(attr, value) { return node.setAttribute(attr, value); }, // place an element in the DOM tree append: function append(subnode) { return node.appendChild(unwrap(subnode)); }, attach: function attach(parent) { return unwrap(parent).appendChild(node); }, remove: function 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: function on(evts, handler) { split(evts).forEach(function (evt) { node.addEventListener(evt, handler); }); }, off: function off(evts, handler) { split(evts).forEach(function (evt) { node.removeEventListener(evt, handler); }); } }; }; module.exports = wrapNode; }, { "./class": 2, "./style": 4, "./utils": 5 }], 4: [function (require, module, exports) { 'use strict'; var 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 */ var wrapStyle = function wrapStyle(node) { var res = { set: function set(prop, value) { node.style.setProperty(prop, value); return this; }, delete: function _delete(prop) { return node.style.removeProperty(prop) !== ''; }, has: function has(prop) { return [].slice.call(node.style).indexOf(prop) > -1; }, get: function get(prop) { var result = node.style.getPropertyValue(prop); if (result.trim() === '') { return undefined; } return result; }, clear: function clear() { var length = node.style.length; for (var i = 0; i < length; i += 1) { node.style.removeProperty(node.style[i]); } }, get size() { return node.style.length; }, keys: function keys() { return iterateArray([].slice.call(node.style)); }, values: function values() { return iterateArray([].slice.call(node.style).map(function (prop) { return node.style.getPropertyValue(prop); })); }, entries: function entries() { return iterateArray([].slice.call(node.style).map(function (prop) { return [prop, node.style.getPropertyValue(prop)]; })); }, forEach: function forEach(callback, thisArg) { var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = this[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var cls = _step2.value; callback.call(thisArg, cls, cls, this); } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } } }; res[Symbol.iterator] = res.values; return res; }; module.exports = wrapStyle; }, { "./utils": 5 }], 5: [function (require, module, exports) { 'use strict'; var whitespace = /\s+/g; /** * Split a list of whitespace separated tokens, * excluding empty ones * * @param {string} str Input string * @return {Array} Split tokens */ exports.split = function (str) { return str.split(whitespace).filter(function (el) { return el.trim().length; }); }; /** * Create an iterator on an array * * @param {Array} arr Array to iterate on * @return {Object} Iterator for given array */ exports.iterateArray = function (arr) { var _next = 0; return { next: function next() { return _next < arr.length ? { value: arr[_next++], done: false } : { done: true }; } }; }; }, {}], 6: [function (require, module, exports) { 'use strict' /** * Choose an index at random among a list of weights, * more weighted indices have a greater proability to be chosen * * @param {Array} weights List of weights * @return {number} Selected index */ ; Object.defineProperty(exports, "__esModule", { value: true }); var chooseIndex = function chooseIndex(weights) { var number = Math.random(); var sum = 0, index = 0; while (number >= sum) { sum += weights[index]; index += 1; } return index - 1; }; /** * Starting from the last point in `points`, add * `iterations` number of point generated by applying * transformations chosen at random among `transforms` * * @param {Array} points Initial set of points * @param {number} iterations Number of points to plot * @param {Array} transforms List of available transforms * @param {Array} weights Probability weights for each transform * @return {null} */ var applyChaos = exports.applyChaos = function applyChaos(points, iterations, transforms, weights) { var point = points[points.length - 1]; if (weights === undefined) { weights = Array.apply(null, Array(transforms.length)).map(function () { return 1 / transforms.length; }); } while (iterations--) { var index = chooseIndex(weights); point = transforms[index](point); points.push(point); } }; }, {}], 7: [function (require, module, exports) { 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var linearTransform = function linearTransform(a, b, c, d, e, f) { return function (point) { return [a * point[0] + b * point[1] + e, c * point[0] + d * point[1] + f]; }; }; var polygonTransforms = function polygonTransforms(vertices, frac) { return vertices.map(function (vertex) { return linearTransform(frac, 0, 0, frac, vertex[0] * (frac - 1), vertex[1] * (frac - 1)); }); }; var barnsley = exports.barnsley = [[linearTransform(0, 0, 0, 0.16, 0, 0), linearTransform(.85, .04, -.04, .85, 0, 1.6), linearTransform(.20, -.26, .23, .22, 0, 1.6), linearTransform(-.15, .28, .26, .24, 0, .44)], [.01, .85, .07, .07]]; var sierpinski = exports.sierpinski = [polygonTransforms([[.866, .5], [-.866, .5], [0, -1]], 1 / 2), [1 / 3, 1 / 3, 1 / 3]]; }, {}], 8: [function (require, module, exports) { 'use strict'; var _theDom = require('the-dom'); var _chaos = require('./chaos'); var _ifs = require('./ifs'); function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; }return arr2; } else { return Array.from(arr); } } var _html = (0, _theDom.html)(document); var body = _html.body; var content = body.find('#content'); var plotting = body.find('#plotting').node; var ctx = plotting.getContext('2d'); var dragging = false; var center = undefined, zoom = 200; var width = undefined, height = undefined; var points = [[0, 0]]; /** * Re-render the scene from scratch * * @return {null} */ var render = function render() { plotting.width = width; plotting.height = height; // do not plot (very) small sizes if (width < 1) { return; } // do the chaos game var image = ctx.getImageData(0, 0, width, height); var length = points.length; var color = [0, 0, 0]; for (var i = 50; i < length; i += 1) { var x = Math.floor(points[i][0] * zoom + center[0]); var y = height - Math.floor(points[i][1] * zoom + center[1]); if (x >= 0 && x < width && y >= 0 && y < height) { var index = (y * width + x) * 4; image.data[index] = color[0]; image.data[index + 1] = color[1]; image.data[index + 2] = color[2]; image.data[index + 3] = 255; } } ctx.putImageData(image, 0, 0); }; /** * Update the scene when the window has been resized * * @return {null} */ var resize = function resize() { width = content.node.clientWidth; height = content.node.clientHeight; center = [Math.floor(width / 2), Math.floor(height / 2)]; render(); }; /** * Zoom on the cursor position when using mouse wheel */ content.on('wheel', function (event) { var delta = event.deltaMode === 0 ? event.deltaY / 53 : event.deltaY; var newZoom = zoom * Math.max(0, 1 - delta * .035); // which (unprojected) point does the mouse point on? var mouse = [(event.offsetX - center[0]) / zoom, (height - event.offsetY - center[1]) / zoom]; // we need to set the center so that `mouse` stays at // the same position on screen, i.e (vectorially): // mouse * newZoom + newCenter = mouse * zoom + center // => newCenter = mouse * zoom - mouse * newZoom + center center = [mouse[0] * zoom - mouse[0] * newZoom + center[0], mouse[1] * zoom - mouse[1] * newZoom + center[1]]; zoom = newZoom; render(); event.preventDefault(); }); /** * Pan the content with click-drag action */ content.on('mousedown', function (event) { return dragging = [event.offsetX, event.offsetY]; }); content.on('mouseup', function () { return dragging = false; }); content.on('mousemove', function (event) { if (dragging !== false) { var newMouse = [event.offsetX, event.offsetY]; var movement = [newMouse[0] - dragging[0], newMouse[1] - dragging[1]]; center[0] += movement[0]; center[1] -= movement[1]; render(); dragging = newMouse; event.preventDefault(); } }); _chaos.applyChaos.apply(undefined, [points, 200000].concat(_toConsumableArray(_ifs.barnsley))); window.onresize = resize; resize(); }, { "./chaos": 6, "./ifs": 7, "the-dom": 1 }] }, {}, [8]);