UNPKG

dat.gui

Version:

A lightweight graphical user interface for changing variables in JavaScript.

293 lines (260 loc) 6.78 kB
/** * dat-gui JavaScript Controller Library * https://github.com/dataarts/dat.gui * * Copyright 2011 Data Arts Team, Google Creative Lab * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 */ import common from '../utils/common'; const EVENT_MAP = { HTMLEvents: ['change'], MouseEvents: ['click', 'mousemove', 'mousedown', 'mouseup', 'mouseover'], KeyboardEvents: ['keydown'] }; const EVENT_MAP_INV = {}; common.each(EVENT_MAP, function(v, k) { common.each(v, function(e) { EVENT_MAP_INV[e] = k; }); }); const CSS_VALUE_PIXELS = /(\d+(\.\d+)?)px/; function cssValueToPixels(val) { if (val === '0' || common.isUndefined(val)) { return 0; } const match = val.match(CSS_VALUE_PIXELS); if (!common.isNull(match)) { return parseFloat(match[1]); } // TODO ...ems? %? return 0; } /** * @namespace * @member dat.dom */ const dom = { /** * * @param elem * @param selectable */ makeSelectable: function(elem, selectable) { if (elem === undefined || elem.style === undefined) return; elem.onselectstart = selectable ? function() { return false; } : function() { }; elem.style.MozUserSelect = selectable ? 'auto' : 'none'; elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none'; elem.unselectable = selectable ? 'on' : 'off'; }, /** * * @param elem * @param horizontal * @param vert */ makeFullscreen: function(elem, hor, vert) { let vertical = vert; let horizontal = hor; if (common.isUndefined(horizontal)) { horizontal = true; } if (common.isUndefined(vertical)) { vertical = true; } elem.style.position = 'absolute'; if (horizontal) { elem.style.left = 0; elem.style.right = 0; } if (vertical) { elem.style.top = 0; elem.style.bottom = 0; } }, /** * * @param elem * @param eventType * @param params */ fakeEvent: function(elem, eventType, pars, aux) { const params = pars || {}; const className = EVENT_MAP_INV[eventType]; if (!className) { throw new Error('Event type ' + eventType + ' not supported.'); } const evt = document.createEvent(className); switch (className) { case 'MouseEvents': { const clientX = params.x || params.clientX || 0; const clientY = params.y || params.clientY || 0; evt.initMouseEvent(eventType, params.bubbles || false, params.cancelable || true, window, params.clickCount || 1, 0, // screen X 0, // screen Y clientX, // client X clientY, // client Y false, false, false, false, 0, null); break; } case 'KeyboardEvents': { const init = evt.initKeyboardEvent || evt.initKeyEvent; // webkit || moz common.defaults(params, { cancelable: true, ctrlKey: false, altKey: false, shiftKey: false, metaKey: false, keyCode: undefined, charCode: undefined }); init(eventType, params.bubbles || false, params.cancelable, window, params.ctrlKey, params.altKey, params.shiftKey, params.metaKey, params.keyCode, params.charCode); break; } default: { evt.initEvent(eventType, params.bubbles || false, params.cancelable || true); break; } } common.defaults(evt, aux); elem.dispatchEvent(evt); }, /** * * @param elem * @param event * @param func * @param bool */ bind: function(elem, event, func, newBool) { const bool = newBool || false; if (elem.addEventListener) { elem.addEventListener(event, func, bool); } else if (elem.attachEvent) { elem.attachEvent('on' + event, func); } return dom; }, /** * * @param elem * @param event * @param func * @param bool */ unbind: function(elem, event, func, newBool) { const bool = newBool || false; if (elem.removeEventListener) { elem.removeEventListener(event, func, bool); } else if (elem.detachEvent) { elem.detachEvent('on' + event, func); } return dom; }, /** * * @param elem * @param className */ addClass: function(elem, className) { if (elem.className === undefined) { elem.className = className; } else if (elem.className !== className) { const classes = elem.className.split(/ +/); if (classes.indexOf(className) === -1) { classes.push(className); elem.className = classes.join(' ').replace(/^\s+/, '').replace(/\s+$/, ''); } } return dom; }, /** * * @param elem * @param className */ removeClass: function(elem, className) { if (className) { if (elem.className === className) { elem.removeAttribute('class'); } else { const classes = elem.className.split(/ +/); const index = classes.indexOf(className); if (index !== -1) { classes.splice(index, 1); elem.className = classes.join(' '); } } } else { elem.className = undefined; } return dom; }, hasClass: function(elem, className) { return new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)').test(elem.className) || false; }, /** * * @param elem */ getWidth: function(elem) { const style = getComputedStyle(elem); return cssValueToPixels(style['border-left-width']) + cssValueToPixels(style['border-right-width']) + cssValueToPixels(style['padding-left']) + cssValueToPixels(style['padding-right']) + cssValueToPixels(style.width); }, /** * * @param elem */ getHeight: function(elem) { const style = getComputedStyle(elem); return cssValueToPixels(style['border-top-width']) + cssValueToPixels(style['border-bottom-width']) + cssValueToPixels(style['padding-top']) + cssValueToPixels(style['padding-bottom']) + cssValueToPixels(style.height); }, /** * * @param el */ getOffset: function(el) { let elem = el; const offset = { left: 0, top: 0 }; if (elem.offsetParent) { do { offset.left += elem.offsetLeft; offset.top += elem.offsetTop; elem = elem.offsetParent; } while (elem); } return offset; }, // http://stackoverflow.com/posts/2684561/revisions /** * * @param elem */ isActive: function(elem) { return elem === document.activeElement && (elem.type || elem.href); } }; export default dom;