import {forEach, mapObj} from './funky.js'; export function noop() {}; // hypotenuse factor of isoscelese right triangle export const sqrt2 = Math.sqrt(2); // short width factor given the lenght of a hexagon's side // (2*S gives long width) export const sqrt3 = Math.sqrt(3); //export function throttleEvent(type, name, obj) { // obj = obj || window; // let running = false; // // let throttle = () => { // if (!running) { // running = true; // // requestAnimationFrame(() => { // obj.dispatchEvent(new CustomEvent(name)); // running = false; // }); // } // } // // obj.addEventListener(type, throttle); //} // //throttleEvent('resize', 'optimizedResize'); export function clone(obj) { return JSON.parse(JSON.stringify(obj)); } export function has(obj, prop) { return obj && obj.hasOwnProperty(prop); } export function hypotenuse(a, b) { if (b == null) b = a; return Math.sqrt(a*a + b*b); } export function isObject (obj) { return obj && (typeof obj === 'object') && !Array.isArray(obj) ? true : false; } export function random(min, max) { if (Array.isArray(min)) { return min[random(min.length - 1)]; } if (typeof min === 'object') { return min[random(Object.keys(min))]; } if (max == null) { max = min; min = 0; } return min + Math.floor(Math.random() * (max - min + 1)); } export function range (start, end) { if (end == null) { end = start; start = 0; } if (start > end) { const swap = start; start = end; end = swap; } return Array.from(Array(Math.abs(end - start)), (_value, index) => index + start); } export function rangeInclusive(start, end) { if (end == null) { end = start; start = 0; } return range(Math.min(start, end), Math.max(start, end)+1); } export function getQueryStringParameters (queryString = document.location.search, separator = '&', assignment = '=') { let parameters = {}; queryString .replace(/(^\?)/,'') .split(separator) .forEach(pair => { pair = pair.split(assignment); parameters[pair[0]] = pair[1]; }); return parameters; } export function getQueryStringObj (queryString = document.location.search, separator = '&', assignment = '=') { return mapObj(getQueryStringParameters(queryString, separator, assignment), parseString); } const braced = /^{.*}$/; const bracketed = /^\[.*\]$/; export function parseString (str) { return typeof str !== 'string' ? str : str.toLowerCase() === 'true' ? true : str.toLowerCase() === 'false' ? false : str.toLowerCase() === 'null' ? null : str.toLowerCase() === 'undefined' ? undefined : !isNaN(Number(str)) ? Number(str) : braced.test(str) || bracketed.test(str) ? JSON.parse(decodeURIComponent(str)) : str; } export function toFixed(number, precision = 3, fallback = NaN) { return typeof number === 'number' && !isNaN(number) ? Number(number.toFixed(precision)) : fallback; } export function getColor ({red, green, blue, alpha}) { return alpha != null ? `rgba(${ red }, ${ green }, ${ blue }, ${ alpha })` : `rgb(${ red }, ${ green }, ${ blue })`; } const GRAY_FACTOR = { red: 0.299, green: 0.587, blue: 0.114, }; // grayscale accounting for luminosity export function grayscale ({red, green, blue}) { return GRAY_FACTOR.red * red + GRAY_FACTOR.green * green + GRAY_FACTOR.blue * blue; } export function extend (obj, ...sources) { const extended = Object.assign({}, obj); sources.forEach(src => { forEach(src, (value, key) => { if (has(src, key)) { if (isObject(value) && isObject(extended[key])) { extended[key] = extendDeep(extended[key], value); } else { extended[key] = value; } } }); }); return extended; }