From 2d400a18ec0057d8816583136981523cc32ed1db Mon Sep 17 00:00:00 2001 From: Sebastian Kupke Date: Thu, 18 Jul 2019 12:26:39 +0200 Subject: [PATCH] Prettified all files. --- dist/iwmlib.js | 3632 ++++++++------ dist/iwmlib.pixi.js | 4178 ++++++++++------- doc/out/AbstractPopup.html | 10 +- doc/out/Badge.html | 10 +- doc/out/BlurFilter.html | 4 +- doc/out/Button.html | 12 +- doc/out/ButtonGroup.html | 10 +- doc/out/DeepZoomImage.html | 2 +- doc/out/DeepZoomInfo.html | 2 +- doc/out/Flippable.html | 6 +- doc/out/FontInfo.html | 4 +- doc/out/Hypenate.html | 6 +- doc/out/InteractivePopup.html | 10 +- ...beledGraphics.exports.LabeledGraphics.html | 4 +- doc/out/LabeledGraphics.html | 16 +- doc/out/List.html | 12 +- doc/out/Message.html | 8 +- doc/out/MessageInteractivePopup.html | 4 +- doc/out/MessageMessageInteractivePopup.html | 4 +- doc/out/Modal.html | 10 +- doc/out/ModalInteractivePopup.html | 4 +- doc/out/ModalModalInteractivePopup.html | 4 +- doc/out/PIXIApp.html | 40 +- doc/out/Popup.html | 10 +- doc/out/PopupInteractivePopup.html | 4 +- doc/out/PopupMenu.html | 10 +- doc/out/PopupMenuPopupInteractivePopup.html | 4 +- ...pupMenuPopupMenuPopupInteractivePopup.html | 4 +- ...nuPopupMenuPopupPopupInteractivePopup.html | 4 +- .../PopupMenuPopupPopupInteractivePopup.html | 4 +- doc/out/PopupPopupInteractivePopup.html | 4 +- doc/out/Progress.html | 10 +- doc/out/Scrollview.html | 6 +- doc/out/Slider.html | 10 +- doc/out/Switch.html | 10 +- doc/out/TextLabel.TextLabel.html | 4 +- doc/out/Theme.html | 6 +- doc/out/ThemeDark.html | 4 +- doc/out/ThemeLight.html | 4 +- doc/out/ThemeRed.html | 4 +- doc/out/TileQuadNode.html | 2 +- doc/out/Tooltip.html | 10 +- doc/out/UITest.html | 18 +- doc/out/Volatile.html | 6 +- doc/out/global.html | 2 +- doc/out/index.html | 2 +- doc/out/pixi_abstractpopup.js.html | 145 +- doc/out/pixi_app.js.html | 198 +- doc/out/pixi_badge.js.html | 57 +- doc/out/pixi_blurfilter.js.html | 66 +- doc/out/pixi_button.js.html | 306 +- doc/out/pixi_buttongroup.js.html | 176 +- doc/out/pixi_deepzoom_image.js.html | 2 +- doc/out/pixi_flippable.js.html | 137 +- doc/out/pixi_labeledgraphics.js.html | 119 +- doc/out/pixi_list.js.html | 136 +- doc/out/pixi_message.js.html | 58 +- doc/out/pixi_modal.js.html | 73 +- doc/out/pixi_popup.js.html | 82 +- doc/out/pixi_popupmenu.js.html | 51 +- doc/out/pixi_progress.js.html | 161 +- doc/out/pixi_scrollview.js.html | 20 +- doc/out/pixi_slider.js.html | 201 +- doc/out/pixi_switch.js.html | 265 +- doc/out/pixi_theme.js.html | 136 +- doc/out/pixi_tooltip.js.html | 53 +- doc/out/pixi_volatile.js.html | 57 +- doc/out/uitest.js.html | 745 +-- gulpfile.js | 25 + lib/bootstrap.babel.js | 400 +- lib/bootstrap.js | 69 +- lib/bundle.js | 51 +- lib/capabilities.js | 59 +- lib/card/card.js | 862 ++-- lib/card/highlight.js | 87 +- lib/card/plugin.js | 292 +- lib/card/scatter.js | 70 +- lib/card/theme.js | 9 +- lib/card/wrapper.js | 96 +- lib/doctest.js | 62 +- lib/errors.js | 64 +- lib/events.js | 49 +- lib/flippable.js | 47 +- lib/frames.js | 100 +- lib/imageloader.js | 13 +- lib/index.js | 28 +- lib/inspect.js | 3 +- lib/interaction.js | 231 +- lib/interface.js | 13 +- lib/logging.js | 23 +- lib/pixi/abstractpopup.js | 143 +- lib/pixi/app.js | 196 +- lib/pixi/blurfilter.js | 64 +- lib/pixi/bundle.js | 10 +- lib/pixi/button.js | 304 +- lib/pixi/buttongroup.js | 174 +- lib/pixi/flipeffect.js | 118 +- lib/pixi/flippable.js | 135 +- lib/pixi/labeledgraphics.js | 115 +- lib/pixi/list.js | 134 +- lib/pixi/message.js | 56 +- lib/pixi/modal.js | 71 +- lib/pixi/popover.js | 68 +- lib/pixi/popup.js | 80 +- lib/pixi/popupmenu.js | 49 +- lib/pixi/progress.js | 159 +- lib/pixi/scatter.js | 144 +- lib/pixi/scrollbox.js | 424 +- lib/pixi/scrollview.js | 18 +- lib/pixi/slider.js | 199 +- lib/pixi/stylus.js | 104 +- lib/pixi/switch.js | 263 +- lib/pixi/test.js | 55 +- lib/pixi/theme.js | 134 +- lib/pixi/timeline.js | 290 +- lib/pixi/tooltip.js | 51 +- lib/pixi/volatile.js | 55 +- lib/poppable.js | 27 +- lib/popup.js | 375 +- lib/popupmenu.js | 169 +- lib/scatter.js | 177 +- lib/uitest.js | 743 +-- lib/utils.js | 88 +- package-lock.json | 105 +- package.json | 10 +- 125 files changed, 11184 insertions(+), 8154 deletions(-) diff --git a/dist/iwmlib.js b/dist/iwmlib.js index 45d7992..4b7f239 100644 --- a/dist/iwmlib.js +++ b/dist/iwmlib.js @@ -10,11 +10,10 @@ static implementationError(klass) { let interfaceKeys = Reflect.ownKeys(this.prototype); let classKeys = Reflect.ownKeys(klass.prototype); - for(let key of interfaceKeys) { + for (let key of interfaceKeys) { let interfaceDesc = this.prototype[key]; let classDesc = klass.prototype[key]; - if (typeof(classDesc) == 'undefined') - return 'Missing ' + key + if (typeof classDesc == 'undefined') return 'Missing ' + key } return null } @@ -26,10 +25,10 @@ return error == null } - // TODO: Specify optional methods - // static optionalMethods() { - // return [this.onMouseWheel] - // } + // TODO: Specify optional methods + // static optionalMethods() { + // return [this.onMouseWheel] + // } } /** Basic Application object to be used as a singleton. @@ -100,12 +99,15 @@ var docTestLogMessages = []; Array.prototype.equals = function(array) { - return this.length == array.length && - this.every( function(this_i,i) { return this_i == array[i] } ) + return ( + this.length == array.length && + this.every(function(this_i, i) { + return this_i == array[i] + }) + ) }; class Doctest { - static assert(value) { if (!value) { throw new Error('Assertion violated') @@ -113,34 +115,42 @@ } static pprint(obj) { - if (obj === null) - return 'null' + if (obj === null) return 'null' let stringified = obj.toString(); - if (stringified == '[object Object]') - return JSON.stringify(obj) + if (stringified == '[object Object]') return JSON.stringify(obj) return stringified } static expect(expr, value) { if (this.pprint(expr) != this.pprint(value)) { //throw new Error("got `" + expr + "` but expected `" + value + "`.") - throw new Error('got `' + this.pprint(expr) + '` but expected `' + this.pprint(value) + '`.') + throw new Error( + 'got `' + + this.pprint(expr) + + '` but expected `' + + this.pprint(value) + + '`.' + ) } } static expectError(error, message) { let index = error.toString().indexOf(message); if (index < 0) { - throw new Error('got `' + message + '` but expected `' + error + '`.') + throw new Error( + 'got `' + message + '` but expected `' + error + '`.' + ) } } static expectLog(...messages) { - // if (!docTestLogMessages.equals(messages)) { - docTestLogMessages.forEach((msg, i) => { - if (msg != messages[i]) - throw new Error('Unexpected log message: `' + messages[i] + '`.') - }); + // if (!docTestLogMessages.equals(messages)) { + docTestLogMessages.forEach((msg, i) => { + if (msg != messages[i]) + throw new Error( + 'Unexpected log message: `' + messages[i] + '`.' + ) + }); // throw new Error('Uups') //} } @@ -150,37 +160,35 @@ } static highlight(code) { - if (typeof(hljs) == 'undefined') - return code + if (typeof hljs == 'undefined') return code return hljs.highlight('javascript', code) } static stripLeadingLines(code) { let result = []; let informative = false; - for(let line of code.split('\n')) { + for (let line of code.split('\n')) { if (line.trim().length > 0) { informative = true; } - if (informative) - result.push(line); + if (informative) result.push(line); } return result.join('\n') } - static event(type='mouse', {clientX = 0, clientY = 0} = {}) { + static event(type = 'mouse', { clientX = 0, clientY = 0 } = {}) { if (type.startsWith('mouse')) { return new MouseEvent(type, { clientX, clientY }) } return { type, clientX, clientY } } - static run(replaceExpect=false) { - if (typeof(hljs) != 'undefined') { + static run(replaceExpect = false) { + if (typeof hljs != 'undefined') { hljs.initHighlighting(); } let doctests = document.querySelectorAll('.doctest'); - for(let i=0; i>> ').trim(); if (line.endsWith(')') || line.endsWith(',')) { line = line.slice(0, -1); @@ -210,17 +221,16 @@ var recordedErrors = new Map(); class Errors { - static countErrors() { let total = 0; - for(let error of recordedErrors.keys()) { + for (let error of recordedErrors.keys()) { total += recordedErrors.get(error).size; } return total } static setStyle(element, styles) { - for(let key in styles) { + for (let key in styles) { element.style[key] = styles[key]; } } @@ -229,8 +239,7 @@ if (recordedErrors.has(error)) { let sources = recordedErrors.get(error); sources.add(source); - } - else { + } else { recordedErrors.set(error, new Set([source])); } } @@ -246,16 +255,19 @@ this.setStyle(document.body, { border: '2px solid red' }); - this.setStyle(errors, {position: 'absolute', + this.setStyle(errors, { + position: 'absolute', top: '0px', padding: '8px', width: '100%', background: 'red', - color: 'white'}); + color: 'white' + }); document.body.appendChild(errors); let counter = document.createElement('div'); counter.setAttribute('id', 'runtime-errors-counter'); - this.setStyle(counter, {borderRadius: '50%', + this.setStyle(counter, { + borderRadius: '50%', width: '32px', height: '32px', background: 'white', @@ -263,16 +275,19 @@ fontSize: '18px', textAlign: 'center', lineHeight: '32px', - verticalAlign: 'middle'}); + verticalAlign: 'middle' + }); counter.innerHTML = '1'; errors.appendChild(counter); let header = document.createElement('div'); - this.setStyle(header, {position: 'absolute', + this.setStyle(header, { + position: 'absolute', top: '6px', left: '48px', height: '44px', - fontSize: '32px'}); + fontSize: '32px' + }); header.innerHTML = 'Runtime Errors'; errors.appendChild(header); errors.addEventListener('click', this.toggleErrors.bind(this)); @@ -283,9 +298,9 @@ static expandErrors() { let errors = document.getElementById('runtime-errors'); - for(let error of recordedErrors.keys()) { - for(var source of recordedErrors.get(error)) { - if (typeof(source) == 'undefined') { + for (let error of recordedErrors.keys()) { + for (var source of recordedErrors.get(error)) { + if (typeof source == 'undefined') { source = 'See console for details'; return } @@ -302,9 +317,8 @@ let errors = document.getElementById('runtime-errors'); let infos = errors.querySelectorAll('.info'); if (infos.length > 0) { - infos.forEach((info) => errors.removeChild(info)); - } - else { + infos.forEach(info => errors.removeChild(info)); + } else { this.expandErrors(); } } @@ -320,26 +334,29 @@ static registerGlobalErrorHandler() { // Register more informative error handler - window.addEventListener('error', (event) => { - // if (typeof(event.error) == 'undefined') { - // console.info("Catched undefined error", event) - // } - this.appendError(event.error, event.filename); - }, true); + window.addEventListener( + 'error', + event => { + // if (typeof(event.error) == 'undefined') { + // console.info("Catched undefined error", event) + // } + this.appendError(event.error, event.filename); + }, + true + ); - document.addEventListener('DOMContentLoaded', (event) => { + document.addEventListener('DOMContentLoaded', event => { this.showErrors(); }); } static registerFrameAwaitErrors() { let iframes = document.getElementsByTagName('iframe'); - for(let i=0; i { - this.appendError('Cannot load iframe', target.src);}, - frameErrorTimeout); + target.iframeTimeout = setTimeout(() => { + this.appendError('Cannot load iframe', target.src); + }, frameErrorTimeout); target.onload = () => { clearTimeout(target.iframeTimeout); }; @@ -350,7 +367,6 @@ Errors.registerGlobalErrorHandler(); class Events { - static stop(event) { event.preventDefault(); event.stopPropagation(); @@ -370,8 +386,7 @@ } static isCaptured(event) { - if (event.__capturedBy) - return true + if (event.__capturedBy) return true return false } @@ -380,7 +395,7 @@ } static isPointerDown(event) { - // According to + // According to // https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events // pointer events use the buttons feature to represent pressed buttons return event.buttons @@ -427,8 +442,15 @@ for (let i = 0; i < targets.length; i++) { let t = targets[i]; let touchTarget = document.elementFromPoint(t.pageX, t.pageY); - let touch = new Touch(undefined, touchTarget, t.identifier, - t.pageX, t.pageY, t.screenX, t.screenY); + let touch = new Touch( + undefined, + touchTarget, + t.identifier, + t.pageX, + t.pageY, + t.screenX, + t.screenY + ); touches.push(touch); } return new TouchList(...touches) @@ -518,8 +540,7 @@ for (let key of keys) { try { result += ' ' + key + ':' + event[key]; - } - catch (e) { + } catch (e) { console.log('Invalid key: ' + key); } } @@ -528,10 +549,14 @@ static compareExtractedWithSimulated() { if (this.extracted.length != this.simulated.length) { - alert('Unequal length of extracted [' + this.extracted.length + - '] and simulated events [' + this.simulated.length + '].'); - } - else { + alert( + 'Unequal length of extracted [' + + this.extracted.length + + '] and simulated events [' + + this.simulated.length + + '].' + ); + } else { for (let i = 0; i < this.extracted.length; i++) { var extracted = this.extracted[i]; var simulated = this.simulated[i]; @@ -585,8 +610,10 @@ div.innerHTML = line; this.popup.appendChild(div); } - Elements.setStyle(this.popup, - { left: event.clientX + 'px', top: event.clientY + 'px' }); + Elements.setStyle(this.popup, { + left: event.clientX + 'px', + top: event.clientY + 'px' + }); } } @@ -597,7 +624,6 @@ Events.simulationRunning = false; class EventRecorder { - constructor() { this.recording = []; this.recorded = []; @@ -609,8 +635,7 @@ if (length == 0) { this.startTime = event.timeStamp; Events.reset(); - } - else { + } else { let last = this.recording[length - 1]; if (event.timeStamp < last.time) { console.log('warning: wrong temporal order'); @@ -638,7 +663,7 @@ if (this.step < this.recorded.length) { let { type, time, constructor, data } = this.recorded[this.step]; Events.simulateEvent(type, constructor, data); - + this.step += 1; let dt = 0; if (this.step < this.recorded.length) { @@ -652,8 +677,7 @@ let delta = Math.round(dt); setTimeout(() => this.replay(whileCondition, onComplete), delta); } - } - else { + } else { console.log('Played ' + this.step + ' events' + onComplete); Events.simulationRunning = false; if (onComplete != null) { @@ -683,7 +707,6 @@ return amt * (stop - start) + start } - // Returns a function, that, as long as it continues to be invoked, will not // be triggered. The function will be called after it stops being called for // N milliseconds. If `immediate` is passed, trigger the function on the @@ -691,10 +714,10 @@ // Taken from: https://davidwalsh.name/essential-javascript-functions function debounce(func, wait, immediate) { let timeout; - return function () { + return function() { let context = this, args = arguments; - let later = function () { + let later = function() { timeout = null; if (!immediate) func.apply(context, args); }; @@ -723,7 +746,6 @@ } class Dates { - static create(fullYear, month, day) { return new Date(Date.UTC(fullYear, month, day)) } @@ -733,7 +755,9 @@ } static startYearRange(date) { - return new Date(Date.UTC(date.getFullYear() - 1, 11, 31, 23, 59, 59, 999)) + return new Date( + Date.UTC(date.getFullYear() - 1, 11, 31, 23, 59, 59, 999) + ) } static endYearRange(date) { @@ -1021,7 +1045,6 @@ * @class Sets */ class Sets { - /** * Returns the intersection of all sets * https://stackoverflow.com/questions/31930894/javascript-set-data-structure-intersect @@ -1032,12 +1055,10 @@ */ static intersect(...sets) { if (!sets.length) return new Set() - const i = sets.reduce((m, s, i) => s.size < sets[m].size ? i : m, 0); + const i = sets.reduce((m, s, i) => (s.size < sets[m].size ? i : m), 0); const [smallest] = sets.splice(i, 1); const res = new Set(); - for (let val of smallest) - if (sets.every(s => s.has(val))) - res.add(val); + for (let val of smallest) if (sets.every(s => s.has(val))) res.add(val); return res } @@ -1085,7 +1106,6 @@ /** Static methods to compute angles. */ class Angle { - static normalize(angle) { let TAU = Math.PI * 2.0; while (angle > Math.PI) { @@ -1132,11 +1152,11 @@ } static degree2radian(degree) { - return Math.PI * degree / 180.0 + return (Math.PI * degree) / 180.0 } static radian2degree(rad) { - return 180.0 / Math.PI * rad + return (180.0 / Math.PI) * rad } } @@ -1330,10 +1350,9 @@ if ( verty[i] > testy != verty[j] > testy && testx < - (vertx[j] - vertx[i]) * - (testy - verty[i]) / - (verty[j] - verty[i]) + - vertx[i] + ((vertx[j] - vertx[i]) * (testy - verty[i])) / + (verty[j] - verty[i]) + + vertx[i] ) c = !c; } @@ -1497,13 +1516,10 @@ } } - /** * Util functions to deal with DOMRects. */ class Rect$1 { - - /** * Test if a given point is contained by the provided Rect. * @@ -1514,12 +1530,14 @@ * @memberof Rect */ static contains(rect, point) { - return (point.x > rect.left && - point.x < rect.x + rect.right - && point.y > rect.top && point.y < rect.bottom) + return ( + point.x > rect.left && + point.x < rect.x + rect.right && + point.y > rect.top && + point.y < rect.bottom + ) } - /** *Returns the position of an rect as point object. * @@ -1536,7 +1554,6 @@ /** String utility functions */ class Strings { - static toUpperCaseFirstChar(str) { return str.substr(0, 1).toUpperCase() + str.substr(1) } @@ -1546,19 +1563,22 @@ } static toUpperCaseEachWord(str, delim = ' ') { - return str.split(delim).map((v) => v.toUpperCaseFirstChar()).join(delim) + return str + .split(delim) + .map(v => v.toUpperCaseFirstChar()) + .join(delim) } static toLowerCaseEachWord(str, delim = ' ') { - return str.split(delim).map((v) => v.toLowerCaseFirstChar()).join(delim) + return str + .split(delim) + .map(v => v.toLowerCaseFirstChar()) + .join(delim) } - } - class LowPassFilter { - - constructor(smoothing = 0.5, bufferMaxSize=10) { + constructor(smoothing = 0.5, bufferMaxSize = 10) { this.smoothing = smoothing; // must be smaller than 1 this.buffer = []; // FIFO queue this.bufferMaxSize = bufferMaxSize; @@ -1566,7 +1586,7 @@ /** * Setup buffer with array of values - * + * * @param {array} values * @returns {array} * @access public @@ -1595,9 +1615,8 @@ * @access private */ __push(value) { - let removed = (this.buffer.length === this.bufferMaxSize) - ? this.buffer.shift() - : 0; + let removed = + this.buffer.length === this.bufferMaxSize ? this.buffer.shift() : 0; this.buffer.push(value); return removed @@ -1611,7 +1630,6 @@ * @access public */ next(nextValue) { - // push new value to the end, and remove oldest one let removed = this.__push(nextValue); // smooth value using all values from buffer @@ -1663,15 +1681,14 @@ /** Basic class for app specific logging requirements. * Can be used to implement persistent logging in electron apps. - * Uses a logMessage cache to prevent error overflows. This is + * Uses a logMessage cache to prevent error overflows. This is * needed since errors may occur very frequently * (e.g. display update loops at 60fps, programmatic loops, ...). - * + * * The logging handlers can be overwritten by calling the static * setup method. */ class Logging$1 { - /** Static log function. * @param {*} message */ @@ -1680,9 +1697,9 @@ } /** - * Static warn function. + * Static warn function. * Emits each warning only once per session. - * @param {*} message + * @param {*} message */ static warn(message) { if (!logMessages.has(message)) { @@ -1692,10 +1709,10 @@ } /** - * Static error function. - * Emits each error message only once per session. - * @param {*} message - */ + * Static error function. + * Emits each error message only once per session. + * @param {*} message + */ static error(message) { if (!logMessages.has(message)) { logMessages.add(message); @@ -1703,7 +1720,11 @@ } } - static setup({log=console.log, warn=console.warn, error=console.error} = {}) { + static setup({ + log = console.log, + warn = console.warn, + error = console.error + } = {}) { logHandlers.log = log; logHandlers.warn = warn; logHandlers.error = error; @@ -1718,16 +1739,15 @@ */ class IInteractionTarget extends Interface { - capture(event) { return typeof true } - onStart(event, interaction) { } - onMove(event, interaction) { } - onEnd(event, interaction) { } + onStart(event, interaction) {} + onMove(event, interaction) {} + onEnd(event, interaction) {} - onMouseWheel(event) { } + onMouseWheel(event) {} } class IInteractionMapperTarget extends Interface { @@ -1935,14 +1955,32 @@ let currentAngle = Points$1.angle(c1, c2); let previousAngle = Points$1.angle(p1, p2); let alpha = this.diffAngle(currentAngle, previousAngle); - return new InteractionDelta(delta.x, delta.y, zoom, alpha, cm, csize) - } else if (csize == 1 && psize == 1 && this.current.firstKey() == this.previous.firstKey()) { + return new InteractionDelta( + delta.x, + delta.y, + zoom, + alpha, + cm, + csize + ) + } else if ( + csize == 1 && + psize == 1 && + this.current.firstKey() == this.previous.firstKey() + ) { // We need to ensure that the keys are the same, since single points with different keys // can jump let current = this.current.first(); let previous = this.previous.first(); let delta = Points$1.subtract(current, previous); - return new InteractionDelta(delta.x, delta.y, 1.0, 0.0, current, csize) + return new InteractionDelta( + delta.x, + delta.y, + 1.0, + 0.0, + current, + csize + ) } return null } @@ -2080,8 +2118,7 @@ if (this.tapCounts.has(key)) { let count = this.tapCounts.get(key); this.tapCounts.set(key, count + 1); - } - else { + } else { this.tapCounts.set(key, 1); } this.tapPositions.set(key, point); @@ -2123,7 +2160,10 @@ this.unregisterTap(key); } } - if (this.tapTimestamps.has(key) && performance.now() > this.tapTimestamps.get(key) + this.tapDuration) { + if ( + this.tapTimestamps.has(key) && + performance.now() > this.tapTimestamps.get(key) + this.tapDuration + ) { //console.log("tap too long") this.unregisterTap(key); } @@ -2131,8 +2171,7 @@ if (this.isTap(key)) { this.registerTap(key, ended); result = this.tapCounts.get(key) == 2; - } - else { + } else { this.unregisterTap(key); } //console.log("isDoubleTap", this.tapCounts.get(key), result) @@ -2199,7 +2238,13 @@ constructor( element, target, - { mouseWheelElement = null, useCapture = true, capturePointerEvents = true, cancelOnWindowOut = true, debug = false } = {} + { + mouseWheelElement = null, + useCapture = true, + capturePointerEvents = true, + cancelOnWindowOut = true, + debug = false + } = {} ) { this.debug = debug; this.interaction = new Interaction(); @@ -2254,7 +2299,8 @@ element.addEventListener( 'pointermove', e => { - if (this.debug) console.log('pointermove', e.pointerId, e.pointerType); + if (this.debug) + console.log('pointermove', e.pointerId, e.pointerType); if ( e.pointerType == 'touch' || @@ -2271,7 +2317,8 @@ element.addEventListener( 'pointerup', e => { - if (this.debug) console.log('pointerup', e.pointerId, e.pointerType); + if (this.debug) + console.log('pointerup', e.pointerId, e.pointerType); this.onEnd(e); if (this.capturePointerEvents) { try { @@ -2286,7 +2333,8 @@ element.addEventListener( 'pointercancel', e => { - if (this.debug) console.log('pointercancel', e.pointerId, e.pointerType); + if (this.debug) + console.log('pointercancel', e.pointerId, e.pointerType); this.onEnd(e); if (this.capturePointerEvents) element.releasePointerCapture(e.pointerId); @@ -2298,7 +2346,12 @@ element.addEventListener( 'pointerleave', e => { - if (this.debug) console.log('pointerleave', e.pointerId, e.pointerType); + if (this.debug) + console.log( + 'pointerleave', + e.pointerId, + e.pointerType + ); if (e.target == element) this.onEnd(e); }, useCapture @@ -2309,7 +2362,12 @@ element.addEventListener( 'pointerout', e => { - if (this.debug) console.log('pointerout', e.pointerId, e.pointerType); + if (this.debug) + console.log( + 'pointerout', + e.pointerId, + e.pointerType + ); if (e.target == element) this.onEnd(e); }, useCapture @@ -2320,14 +2378,20 @@ window.addEventListener( 'pointerout', e => { - if (this.debug) console.log('pointerout', e.pointerId, e.pointerType, e.target); + if (this.debug) + console.log( + 'pointerout', + e.pointerId, + e.pointerType, + e.target + ); if (e.target == element) { this.onEnd(e); } }, - useCapture); + useCapture + ); } - } else if (window.TouchEvent) { if (this.debug) console.log('Touch API'); element.addEventListener( @@ -2403,8 +2467,7 @@ // && Events.isMouseDown(e)) if (Events.isMouseDown(e)) { - if (this.debug) - console.log('mousemove', e); + if (this.debug) console.log('mousemove', e); this.onMove(e); } }, @@ -2425,7 +2488,9 @@ e => { if (e.target == element) { this.onEnd(e); - console.warn('Shouldn\'t happen: mouseout ends interaction'); + console.warn( + "Shouldn't happen: mouseout ends interaction" + ); } }, useCapture @@ -2439,7 +2504,8 @@ this.onEnd(e); } }, - useCapture); + useCapture + ); } } } @@ -2526,42 +2592,42 @@ // 'targetTouches' let result = {}; switch (event.constructor.name) { - case 'MouseEvent': { - let buttons = event.buttons || event.which; - if (buttons) result['mouse'] = this.getPosition(event); - break - } - case 'PointerEvent': { - result[event.pointerId.toString()] = this.getPosition(event); - break - } - case 'Touch': { - let id = + case 'MouseEvent': { + let buttons = event.buttons || event.which; + if (buttons) result['mouse'] = this.getPosition(event); + break + } + case 'PointerEvent': { + result[event.pointerId.toString()] = this.getPosition(event); + break + } + case 'Touch': { + let id = event.touchType === 'stylus' ? 'stylus' : event.identifier.toString(); - result[id] = this.getPosition(event); - break - } - // case 'TouchEvent': - // // Needs to be observed: Perhaps changedTouches are all we need. If so - // // we can remove the touchEventKey default parameter - // if (touchEventKey == 'all') { - // for(let t of event.targetTouches) { - // result[t.identifier.toString()] = this.getPosition(t) - // } - // for(let t of event.changedTouches) { - // result[t.identifier.toString()] = this.getPosition(t) - // } - // } - // else { - // for(let t of event.changedTouches) { - // result[t.identifier.toString()] = this.getPosition(t) - // } - // } - // break - default: - break + result[id] = this.getPosition(event); + break + } + // case 'TouchEvent': + // // Needs to be observed: Perhaps changedTouches are all we need. If so + // // we can remove the touchEventKey default parameter + // if (touchEventKey == 'all') { + // for(let t of event.targetTouches) { + // result[t.identifier.toString()] = this.getPosition(t) + // } + // for(let t of event.changedTouches) { + // result[t.identifier.toString()] = this.getPosition(t) + // } + // } + // else { + // for(let t of event.changedTouches) { + // result[t.identifier.toString()] = this.getPosition(t) + // } + // } + // break + default: + break } return result } @@ -2574,7 +2640,7 @@ // Callback: can be overwritten } - interactionFinished(event, key, point) { } + interactionFinished(event, key, point) {} startInteraction(event, extracted) { for (let key in extracted) { @@ -2589,7 +2655,10 @@ let point = extracted[key]; let updated = this.interaction.update(key, point); if (updated) { - console.warn('new pointer in updateInteraction shouldn\'t happen', key); + console.warn( + "new pointer in updateInteraction shouldn't happen", + key + ); this.interactionStarted(event, key, point); } } @@ -2627,13 +2696,23 @@ * @extends {InteractionDelegate} */ class InteractionMapper$1 extends InteractionDelegate { - constructor( element, target, - { tapDistance = 10, longPressTime = 500.0, useCapture = true, mouseWheelElement = null, logInteractionsAbove = 12 } = {} + { + tapDistance = 10, + longPressTime = 500.0, + useCapture = true, + mouseWheelElement = null, + logInteractionsAbove = 12 + } = {} ) { - super(element, target, { tapDistance, useCapture, longPressTime, mouseWheelElement }); + super(element, target, { + tapDistance, + useCapture, + longPressTime, + mouseWheelElement + }); this.logInteractionsAbove = logInteractionsAbove; } @@ -2740,10 +2819,7 @@ * @param {object} [opts] - An options object. See the hammer documentation for more details. */ static on(types, elements, cb, opts = {}) { - - opts = Object.assign({}, { - - }, opts); + opts = Object.assign({}, {}, opts); if (typeof Hammer === 'undefined') { console.error('Hammer.js not found!'); @@ -2752,23 +2828,25 @@ // convert to array types = Array.isArray(types) ? types : types.split(/\s/); - if (elements instanceof NodeList || elements instanceof HTMLCollection) { + if ( + elements instanceof NodeList || + elements instanceof HTMLCollection + ) { elements = Array.from(elements); } elements = Array.isArray(elements) ? elements : [elements]; for (let i = 0; i < types.length; i++) { - const type = types[i].toLowerCase(); // list of hammer events - const useHammer = /^(tap|doubletap|press|pan|swipe|pinch|rotate).*$/.test(type); + const useHammer = /^(tap|doubletap|press|pan|swipe|pinch|rotate).*$/.test( + type + ); // if it is a hammer event if (useHammer) { - for (let j = 0; j < elements.length; j++) { - // if(elements[j].tagName == "svg") return false; let hammer = new Hammer(elements[j], opts); @@ -2779,15 +2857,33 @@ // recognizers if (type.startsWith('pan')) { - hammer.get('pan').set(Object.assign({ direction: Hammer.DIRECTION_ALL }, opts)); + hammer + .get('pan') + .set( + Object.assign( + { direction: Hammer.DIRECTION_ALL }, + opts + ) + ); } else if (type.startsWith('pinch')) { - hammer.get('pinch').set(Object.assign({ enable: true }, opts)); + hammer + .get('pinch') + .set(Object.assign({ enable: true }, opts)); } else if (type.startsWith('press')) { hammer.get('press').set(opts); } else if (type.startsWith('rotate')) { - hammer.get('rotate').set(Object.assign({ enable: true }, opts)); + hammer + .get('rotate') + .set(Object.assign({ enable: true }, opts)); } else if (type.startsWith('swipe')) { - hammer.get('swipe').set(Object.assign({ direction: Hammer.DIRECTION_ALL }, opts)); + hammer + .get('swipe') + .set( + Object.assign( + { direction: Hammer.DIRECTION_ALL }, + opts + ) + ); } else if (type.startsWith('tap')) { hammer.get('tap').set(opts); } @@ -2796,9 +2892,7 @@ cb(event); }); } - } else { - for (let j = 0; j < elements.length; j++) { Hammer.on(elements[j], type, event => { cb(event); @@ -2816,7 +2910,6 @@ /** Report capabilities with guaranteed values. */ class Capabilities { - /** Returns the browser userAgent. @return {string} */ @@ -2829,7 +2922,7 @@ @return {boolean} */ static get isMobile() { - return (/Mobi/.test(navigator.userAgent)) + return /Mobi/.test(navigator.userAgent) } /** Tests whether the app is running on a iOS device. @@ -2837,7 +2930,7 @@ @return {boolean} */ static get isIOS() { - return (/iPad|iPhone|iPod/.test(navigator.userAgent)) && !window.MSStream + return /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream } /** Tests whether the app is running in a Safari environment. @@ -2846,28 +2939,44 @@ @return {boolean} */ static get isSafari() { - return navigator.vendor && navigator.vendor.indexOf('Apple') > -1 && navigator.userAgent && !navigator.userAgent.match('CriOS') + return ( + navigator.vendor && + navigator.vendor.indexOf('Apple') > -1 && + navigator.userAgent && + !navigator.userAgent.match('CriOS') + ) } /** * Distincts if the app is running inside electron or not. - * + * * source: https://github.com/cheton/is-electron */ static get isElectron() { - // Renderer process - if (typeof window !== 'undefined' && typeof window.process === 'object' && window.process.type === 'renderer') { + if ( + typeof window !== 'undefined' && + typeof window.process === 'object' && + window.process.type === 'renderer' + ) { return true } // Main process - if (typeof process !== 'undefined' && typeof process.versions === 'object' && !!process.versions.electron) { + if ( + typeof process !== 'undefined' && + typeof process.versions === 'object' && + !!process.versions.electron + ) { return true } // Detect the user agent when the `nodeIntegration` option is set to true - if (typeof navigator === 'object' && typeof navigator.userAgent === 'string' && navigator.userAgent.indexOf('Electron') >= 0) { + if ( + typeof navigator === 'object' && + typeof navigator.userAgent === 'string' && + navigator.userAgent.indexOf('Electron') >= 0 + ) { return true } @@ -2885,52 +2994,56 @@ @return {boolean} */ static get isMultiTouchTable() { - return Capabilities.devicePixelRatio > 2 && Capabilities.isMobile === false && /Windows/i.test(Capabilities.userAgent) + return ( + Capabilities.devicePixelRatio > 2 && + Capabilities.isMobile === false && + /Windows/i.test(Capabilities.userAgent) + ) } /** Returns true if mouse events are supported @return {boolean} */ static supportsMouseEvents() { - return typeof(window.MouseEvent) != 'undefined' + return typeof window.MouseEvent != 'undefined' } /** Returns true if touch events are supported @return {boolean} */ static supportsTouchEvents() { - return typeof(window.TouchEvent) != 'undefined' + return typeof window.TouchEvent != 'undefined' } /** Returns true if pointer events are supported @return {boolean} */ static supportsPointerEvents() { - return typeof(window.PointerEvent) != 'undefined' + return typeof window.PointerEvent != 'undefined' } /** Returns true if DOM templates are supported @return {boolean} */ static supportsTemplate() { - return 'content' in document.createElement('template'); + return 'content' in document.createElement('template') } } /** Basic tests for Capabilities. */ class CapabilitiesTests { - static testConfirm() { let bool = confirm('Please confirm'); - document.getElementById('demo').innerHTML = (bool) ? 'Confirmed' : 'Not confirmed'; + document.getElementById('demo').innerHTML = bool + ? 'Confirmed' + : 'Not confirmed'; } static testPrompt() { let person = prompt('Please enter your name', 'Harry Potter'); if (person != null) { - demo.innerHTML = - 'Hello ' + person + '! How are you today?'; + demo.innerHTML = 'Hello ' + person + '! How are you today?'; } } @@ -2945,7 +3058,9 @@ } static testMultiTouchTable() { - let value = 'Is the device a multi-touch table? ' + Capabilities.isMultiTouchTable; + let value = + 'Is the device a multi-touch table? ' + + Capabilities.isMultiTouchTable; multi_touch_table.innerHTML = value; } @@ -2979,16 +3094,11 @@ /** This interface allows scatters to delegate tap events to other objects. */ class ITapDelegate extends Interface { - /** This method must be defined by the delegate. It handles the tap event. */ - tap(event) { - - } + tap(event) {} /** Tells the delegate that it should handle standard click events. */ - handleClicks() { - - } + handleClicks() {} } /** @@ -3040,7 +3150,7 @@ toString() { return ( - 'Event(\'scatterTransformed\', scale: ' + + "Event('scatterTransformed', scale: " + this.scale + ' about: ' + this.about.x + @@ -3115,7 +3225,12 @@ // Avoid division by zero errors later on // and consider the number of involved pointers sind addVelocity will be called by the // onMove events - let velocity = { t: t, dt: dt, dx: delta.x / delta.number, dy: delta.y / delta.number }; + let velocity = { + t: t, + dt: dt, + dx: delta.x / delta.number, + dy: delta.y / delta.number + }; this.velocities.push(velocity); while (this.velocities.length > buffer) { this.velocities.shift(); @@ -3211,8 +3326,8 @@ // damping, collison detection, etc. here let next = Points$1.multiplyScalar(velocity, this.throwDamping); return { - x: (this.movableX) ? next.x : 0, - y: (this.movableY) ? next.y : 0 + x: this.movableX ? next.x : 0, + y: this.movableY ? next.y : 0 } } @@ -3253,7 +3368,7 @@ onClose = null, onThrowFinished = null, scaleAutoClose = false, - scaleCloseThreshold = 0.10, + scaleCloseThreshold = 0.1, scaleCloseBuffer = 0.05, maxRotation = Angle.degree2radian(5), useLowPassFilter = true @@ -3275,7 +3390,7 @@ }); /** - * Closes the card when the minScale is reached and the + * Closes the card when the minScale is reached and the * card is released. Card can be saved by scaling it up again. */ this.scaleAutoClose = scaleAutoClose; @@ -3357,7 +3472,7 @@ if (this.useLowPassFilter) { rotate = this.rotateLPF.next(rotate); zoom = this.zoomLPF.next(zoom); - // console.log({rotate, zoom}) + // console.log({rotate, zoom}) } this.transform(delta, zoom, rotate, delta.about); if (zoom != 1) this.interactionAnchor = delta.about; @@ -3365,8 +3480,8 @@ } get polygon() { - let w2 = this.width * this.scale / 2; - let h2 = this.height * this.scale / 2; + let w2 = (this.width * this.scale) / 2; + let h2 = (this.height * this.scale) / 2; let center = this.center; let polygon = new Polygon(center); polygon.addPoint({ x: -w2, y: -h2 }); @@ -3379,11 +3494,9 @@ isOutside() { let stagePolygon = this.containerPolygon; - if (stagePolygon == null) - return false + if (stagePolygon == null) return false let polygon = this.polygon; - if (polygon == null) - return false + if (polygon == null) return false let result = stagePolygon.intersectsWith(polygon); return result === false || result.overlap < this.throwVisibility } @@ -3426,7 +3539,7 @@ keepOnStage(velocity, collision = 0.5) { let stagePolygon = this.containerPolygon; - // UO: since keepOnStage is called in nextVelocity we need to + // UO: since keepOnStage is called in nextVelocity we need to // ensure a return value if (!stagePolygon) return { x: 0, y: 0 } let polygon = this.polygon; @@ -3468,10 +3581,18 @@ _checkAutoClose() { if (this.scaleAutoClose) - if (this.scale < this.minScale + this.scaleCloseThreshold - this.scaleCloseBuffer) { - this.zoom(this.minScale, { animate: 0.2, onComplete: this.close.bind(this) }); + if ( + this.scale < + this.minScale + this.scaleCloseThreshold - this.scaleCloseBuffer + ) { + this.zoom(this.minScale, { + animate: 0.2, + onComplete: this.close.bind(this) + }); } else if (this.scale < this.minScale + this.scaleCloseThreshold) { - this.zoom(this.minScale + this.scaleCloseThreshold, { animate: 0.4 }); + this.zoom(this.minScale + this.scaleCloseThreshold, { + animate: 0.4 + }); } } @@ -3570,7 +3691,7 @@ fast: false, type: UPDATE }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -3579,9 +3700,15 @@ let origin = this.rotationOrigin; let beta = Points$1.angle(origin, anchor); let distance = Points$1.distance(origin, anchor); - let { scale: newScale, zoom: thresholdedZoom } = this.calculateScale(zoom); + let { scale: newScale, zoom: thresholdedZoom } = this.calculateScale( + zoom + ); - let newOrigin = Points$1.arc(anchor, beta + rotate, distance * thresholdedZoom); + let newOrigin = Points$1.arc( + anchor, + beta + rotate, + distance * thresholdedZoom + ); let extra = Points$1.subtract(newOrigin, origin); let offset = Points$1.subtract(anchor, origin); this._move(offset); @@ -3601,7 +3728,7 @@ rotate: rotate, about: anchor }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -3613,7 +3740,7 @@ /** * For a given zoom, a new scale is calculated, taking * min and max scale into account. - * + * * @param {number} zoom - The zoom factor, to scale the object with. * @returns {object} - Returns an object containing the a value for a valid scale and the corrected zoom factor. */ @@ -3631,8 +3758,7 @@ zoom = scale / this.scale; } - if (this.scaleAutoClose) - this._updateTransparency(); + if (this.scaleAutoClose) this._updateTransparency(); return { zoom, scale } } @@ -3645,8 +3771,10 @@ } calculateScaleTransparency() { - let transparency = (this.scale - this.minScale) / this.scaleCloseThreshold; - transparency = (transparency > 1) ? 1 : (transparency < 0) ? 0 : transparency; + let transparency = + (this.scale - this.minScale) / this.scaleCloseThreshold; + transparency = + transparency > 1 ? 1 : transparency < 0 ? 0 : transparency; return transparency } @@ -3663,7 +3791,7 @@ animateZoomBounce(dt = 1) { if (this.zoomAnchor != null) { let zoom = 1; - let amount = Math.min(0.01, 0.3 * dt / 100000.0); + let amount = Math.min(0.01, (0.3 * dt) / 100000.0); if (this.scale < this.minScale) zoom = 1 + amount; if (this.scale > this.maxScale) zoom = 1 - amount; if (zoom != 1) { @@ -3704,8 +3832,8 @@ if (this.scaleAutoClose) { if (this.scale <= this.minScale + this.scaleCloseThreshold) { - - if (this.scaleAutoCloseTimeout) clearTimeout(this.scaleAutoCloseTimeout); + if (this.scaleAutoCloseTimeout) + clearTimeout(this.scaleAutoCloseTimeout); this.scaleAutoCloseTimeout = setTimeout(() => { this._checkAutoClose(); }, 600); @@ -3715,7 +3843,6 @@ } onStart(event, interaction) { - if (this.startGesture(interaction)) { this.dragging = true; this.interactionAnchor = null; @@ -3729,7 +3856,7 @@ fast: false, type: START }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -3764,7 +3891,7 @@ fast: false, type: END }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -3775,7 +3902,7 @@ } } - onTap(event, interaction, point) { } + onTap(event, interaction, point) {} onDragUpdate(delta) { if (this.onTransform != null) { @@ -3786,7 +3913,7 @@ about: this.currentAbout, type: null }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -3800,7 +3927,7 @@ fast: false, type: null }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -3814,7 +3941,7 @@ fast: true, type: null }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -3827,16 +3954,14 @@ fast: false, type: null }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } } onZoomed(about) { - - if (this.scaleAutoClose) - this._updateTransparency(); + if (this.scaleAutoClose) this._updateTransparency(); if (this.onTransform != null) { let event = new ScatterEvent(this, { @@ -3845,7 +3970,7 @@ fast: false, type: null }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -3871,7 +3996,13 @@ */ constructor( element, - { stopEvents = 'auto', claimEvents = true, useCapture = true, touchAction = 'none', debugCanvas = null } = {} + { + stopEvents = 'auto', + claimEvents = true, + useCapture = true, + touchAction = 'none', + debugCanvas = null + } = {} ) { this.onCapture = null; this.element = element; @@ -3985,7 +4116,10 @@ ***/ let found = document.elementFromPoint(global.x, global.y); for (let target of this.scatter.values()) { - if (target.interactive && this.isDescendant(target.element, found)) { + if ( + target.interactive && + this.isDescendant(target.element, found) + ) { if (this.stopEvents) Events.stop(event); if (this.claimEvents) event.claimedByScatter = target; return target @@ -4019,8 +4153,6 @@ } } - - class DOMScatter$1 extends AbstractScatter { constructor( element, @@ -4044,7 +4176,7 @@ x = 0, y = 0, width = null, // required - height = null, // required + height = null, // required resizable = false, tapDelegate = null, triggerSVGClicks = false, @@ -4057,7 +4189,7 @@ autoThrow = true, scaleAutoClose = false, onClose = null, - scaleCloseThreshold = 0.10, + scaleCloseThreshold = 0.1, scaleCloseBuffer = 0.05, useLowPassFilter = true, maxRotation = Angle.degree2radian(15) @@ -4117,7 +4249,7 @@ transformOrigin: transformOrigin }; this.tapNodes = new Map(); - + // For tweenlite we need initial values in _gsTransform TweenLite.set(element, this.initialValues); this.onResize = onResize; @@ -4136,15 +4268,15 @@ button.className = 'interactiveElement'; this.element.appendChild(button); - button.addEventListener('pointerdown', (e) => { + button.addEventListener('pointerdown', e => { this.startResize(e); }); - button.addEventListener('pointermove', (e) => { + button.addEventListener('pointermove', e => { this.resize(e); }); - button.addEventListener('pointerup', (e) => { + button.addEventListener('pointerup', e => { this.stopResize(e); }); this.resizeButton = button; @@ -4314,7 +4446,7 @@ onTap(event, interaction, point) { if (this.tapDelegate) { Events.stop(event); - this.tapDelegate.tap(event, "scatter"); + this.tapDelegate.tap(event, 'scatter'); } } @@ -4366,12 +4498,18 @@ e.preventDefault(); let event = new CustomEvent('resizeStarted'); - let oldPostition = { x: this.element.getBoundingClientRect().left, y: this.element.getBoundingClientRect().top }; + let oldPostition = { + x: this.element.getBoundingClientRect().left, + y: this.element.getBoundingClientRect().top + }; this.bringToFront(); this.element.style.transformOrigin = '0% 0%'; - let newPostition = { x: this.element.getBoundingClientRect().left, y: this.element.getBoundingClientRect().top }; + let newPostition = { + x: this.element.getBoundingClientRect().left, + y: this.element.getBoundingClientRect().top + }; let offset = Points$1.subtract(oldPostition, newPostition); @@ -4394,23 +4532,31 @@ rotation = (rotation + 360) % 360; let event = new CustomEvent('resized'); if (e.target.getAttribute('resizing') == 'true') { - - let deltaX = (e.clientX - this.oldX); - let deltaY = (e.clientY - this.oldY); + let deltaX = e.clientX - this.oldX; + let deltaY = e.clientY - this.oldY; let r = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2)); let phi = Angle.radian2degree(Math.atan2(deltaX, deltaY)); - phi = ((phi) + 630) % 360; - let rot = ((rotation + 90) + 630) % 360; + phi = (phi + 630) % 360; + let rot = (rotation + 90 + 630) % 360; - let diffAngle = ((0 + rot) + 360) % 360; + let diffAngle = (0 + rot + 360) % 360; let phiCorrected = (phi + diffAngle + 360) % 360; let resizeW = r * Math.cos(Angle.degree2radian(phiCorrected)); let resizeH = -r * Math.sin(Angle.degree2radian(phiCorrected)); - if ((this.element.offsetWidth + resizeW) / this.scale > this.width * 0.5 / this.scale && (this.element.offsetHeight + resizeH) / this.scale > this.height * 0.3 / this.scale) TweenLite.to(this.element, 0, { width: this.element.offsetWidth + resizeW / this.scale, height: this.element.offsetHeight + resizeH / this.scale }); + if ( + (this.element.offsetWidth + resizeW) / this.scale > + (this.width * 0.5) / this.scale && + (this.element.offsetHeight + resizeH) / this.scale > + (this.height * 0.3) / this.scale + ) + TweenLite.to(this.element, 0, { + width: this.element.offsetWidth + resizeW / this.scale, + height: this.element.offsetHeight + resizeH / this.scale + }); this.oldX = e.clientX; this.oldY = e.clientY; @@ -4424,9 +4570,15 @@ e.preventDefault(); let event = new CustomEvent('resizeEnded'); - let oldPostition = { x: this.element.getBoundingClientRect().left, y: this.element.getBoundingClientRect().top }; + let oldPostition = { + x: this.element.getBoundingClientRect().left, + y: this.element.getBoundingClientRect().top + }; this.element.style.transformOrigin = '50% 50%'; - let newPostition = { x: this.element.getBoundingClientRect().left, y: this.element.getBoundingClientRect().top }; + let newPostition = { + x: this.element.getBoundingClientRect().left, + y: this.element.getBoundingClientRect().top + }; let offset = Points$1.subtract(oldPostition, newPostition); TweenLite.to(this.element, 0, { css: { left: '+=' + offset.x + 'px' } }); @@ -4469,12 +4621,10 @@ this.maxHeight = maxHeight != null ? maxHeight : window.innerHeight; this.addedNode = null; console.log({ - width, height, maxWidth, - maxHeight, - + maxHeight }); } @@ -4590,11 +4740,13 @@ domNode.innerHTML = xhr.response; this.addedNode = domNode.firstElementChild; let { width, height } = this.size(this.addedNode); - console.log("HTMLLoader.load", { added: this.addedNode, width, height }); - if (width) - this.wantedWidth = width || this.wantedWidth; - if (height) - this.wantedHeight = height || this.wantedHeight; + console.log('HTMLLoader.load', { + added: this.addedNode, + width, + height + }); + if (width) this.wantedWidth = width || this.wantedWidth; + if (height) this.wantedHeight = height || this.wantedHeight; resolve(this); }; xhr.onerror = e => { @@ -4607,7 +4759,7 @@ /** * Tries to determine the size of the addedNode. * Checks for explicit width and height style attributes. - * + * * Overwrite this method if you want to extract values from other infos. * * @returns { width: int, height: int } @@ -4686,7 +4838,7 @@ this.cardWrapper = dom.querySelector('#' + this.id); let front = this.cardWrapper.querySelector('.front'); this.frontLoader.load(front).then(loader => { - this.frontLoaded(loader).then((obj) => { + this.frontLoaded(loader).then(obj => { if (this.onLoaded) this.onLoaded(); resolve(this); }); @@ -4713,7 +4865,9 @@ scalable: this.scalable, rotatable: this.rotatable, overdoScaling: this.overdoScaling, - tapDelegate: (this.tapDelegateFactory) ? this.tapDelegateFactory(this.cardWrapper) : null + tapDelegate: this.tapDelegateFactory + ? this.tapDelegateFactory(this.cardWrapper) + : null } ); @@ -4722,7 +4876,7 @@ } if (this.closeOnMinScale) { - const removeOnMinScale = function () { + const removeOnMinScale = function() { if (scatter.scale <= scatter.minScale) { this.flippable.close(); @@ -4732,7 +4886,9 @@ //Remove callback if (scatter.onTransform) { - let callbackIdx = scatter.onTransform.indexOf(removeOnMinScale); + let callbackIdx = scatter.onTransform.indexOf( + removeOnMinScale + ); scatter.onTransform.splice(callbackIdx, 1); } } @@ -4763,7 +4919,7 @@ } setupFlippable(flippable, loader) { - console.log("setupFlippable", loader.wantedWidth); + console.log('setupFlippable', loader.wantedWidth); flippable.wantedWidth = loader.wantedWidth; flippable.wantedHeight = loader.wantedHeight; flippable.wantedScale = loader.scale; @@ -4773,12 +4929,10 @@ } start({ targetCenter = null } = {}) { - console.log("DOMFlip.start", targetCenter); + console.log('DOMFlip.start', targetCenter); if (this.preloadBack) { - this.flippable.start({ duration: this.flipDuration, targetCenter }); - } - else { + } else { let back = this.cardWrapper.querySelector('.back'); let flippable = this.flippable; this.backLoader.load(back).then(loader => { @@ -4925,7 +5079,7 @@ clickInfo() { this.bringToFront(); - console.log("clickInfo"); + console.log('clickInfo'); this.infoBtn.click(); } @@ -5023,14 +5177,14 @@ let y = this.flipped ? yy : this.startY; let onUpdate = this.onUpdate !== null ? () => this.onUpdate(this) : null; - console.log("start", this.flipDuration); + console.log('start', this.flipDuration); TweenLite.to(this.card, this.flipDuration, { rotationY: targetY, ease: Power1.easeOut, transformOrigin: '50% 50%', onUpdate, onComplete: e => { - console.log("start end", this.flipDuration); + console.log('start end', this.flipDuration); if (this.flipped) { //this.hide(this.front) this.enable(this.backBtn); @@ -5040,7 +5194,6 @@ this.onFrontFlipped(this); } } else { - if (this.onBackFlipped == null) { this.enable(this.infoBtn, this.fadeDuration); this.enable(this.closeBtn, this.fadeDuration); @@ -5063,7 +5216,7 @@ force3D: true }); - console.log("start 2", this.wantedWidth, this.startWidth, {w, h}); + console.log('start 2', this.wantedWidth, this.startWidth, { w, h }); // See https://greensock.com/forums/topic/7997-rotate-the-shortest-way/ TweenLite.to(this.element, this.flipDuration / 2, { scale: targetScale, @@ -5088,15 +5241,14 @@ } class Index { - - constructor(template, pages, notfound='thumbnails/notfound.png') { + constructor(template, pages, notfound = 'thumbnails/notfound.png') { this.template = template; this.pages = pages; this.notfound = notfound; } setup() { - for(let pair of this.pages) { + for (let pair of this.pages) { let [title, src] = pair; let id = getId(); pair.push(id); @@ -5105,20 +5257,18 @@ wrapper.id = id; let clone = document.importNode(t.content, true); container.appendChild(clone); - wrapper = container.querySelector('#'+id); + wrapper = container.querySelector('#' + id); let icon = wrapper.querySelector('.icon'); - icon.onerror = (e) => { - if (this.notfound) - icon.src = this.notfound; + icon.onerror = e => { + if (this.notfound) icon.src = this.notfound; }; let iconSrc = src.replace('.html', '.png'); //console.log("iconSrc", iconSrc) if (iconSrc.endsWith('index.png')) { icon.src = iconSrc.replace('index.png', 'thumbnail.png'); - } - else { + } else { icon.src = 'thumbnails/' + iconSrc; } @@ -5131,8 +5281,7 @@ } frames() { - if (this.pages.length == 0) - return + if (this.pages.length == 0) return let [title, src, id] = this.pages.shift(); let iframe = document.createElement('iframe'); iframe.frameborder = 0; @@ -5140,7 +5289,7 @@ let icon = wrapper.querySelector('.icon'); icon.parentNode.replaceChild(iframe, icon); - iframe.onload = (e) => { + iframe.onload = e => { this.frames(); }; iframe.src = src + window.location.search; @@ -5148,14 +5297,12 @@ load() { this.setup(); - if (window.location.search.startsWith('?test')) - this.frames(); + if (window.location.search.startsWith('?test')) this.frames(); } loadAndTest() { this.setup(); - if (!Capabilities.isMobile) - this.frames(); + if (!Capabilities.isMobile) this.frames(); } } @@ -5163,9 +5310,8 @@ * shown. */ class Poppable { - /** Register the poppable element in a context. Closes previously registered ones. - * @param {*} context + * @param {*} context */ register(context) { let registered = Poppable.get(context); @@ -5177,7 +5323,7 @@ /** * Unregister object from context - * @param {*} context + * @param {*} context */ unregister(context) { Poppable.delete(context); @@ -5194,20 +5340,20 @@ return Poppable.registrations.get(context) } - /** Sets the poppable in the given context - * @static - * @param {*} context - * @param {*} poppable - * @returns - * @memberof Poppable - */ + /** Sets the poppable in the given context + * @static + * @param {*} context + * @param {*} poppable + * @returns + * @memberof Poppable + */ static set(context, poppable) { return Poppable.registrations.set(context, poppable) } /** Test whether a poppable exists in the given context - * - * @param {*} context + * + * @param {*} context */ static has(context) { return Poppable.registrations.has(context) @@ -5226,7 +5372,7 @@ /** All poppable must implement a close method. */ close() { - console.error("Must be implemented"); + console.error('Must be implemented'); } } @@ -5267,16 +5413,16 @@ parent = null, content = null, context = window, - fontSize = "1em", - fontFamily = "Arial", + fontSize = '1em', + fontFamily = 'Arial', padding = 16, notchSize = 10, switchPos = false, minWidth = null, maxWidth = 800, - backgroundColor = "#EEE", - normalColor = "#444", - notchPosition = "bottomCenter", + backgroundColor = '#EEE', + normalColor = '#444', + notchPosition = 'bottomCenter', zIndex = 0, keepWithin = null, autoClose = true, @@ -5291,7 +5437,7 @@ onResize = null, onMove = null, noStyle = false, - hideOnUp = true, + hideOnUp = true } = {}) { super(); this.context = context; @@ -5339,38 +5485,38 @@ //console.log("Popup.setup", this.draggable) this.content = content; this.items = {}; - this.element = document.createElement("div"); - this.element.classList.add("popup"); + this.element = document.createElement('div'); + this.element.classList.add('popup'); this.setAlpha(this.element, 0); // this.element.style.opacity = 0 - Elements$1.addClass(this.element, "unselectable"); - this.notch = document.createElement("div"); + Elements$1.addClass(this.element, 'unselectable'); + this.notch = document.createElement('div'); Elements$1.setStyle(this.notch, this.notchStyle()); - this.notch.className = "notch"; + this.notch.className = 'notch'; this.setupDraggable(); if (this.closeIcon) { - let img = document.createElement("img"); - img.setAttribute("draggable", false); + let img = document.createElement('img'); + img.setAttribute('draggable', false); img.src = this.closeIcon; - img.style.position = "absolute"; - img.style.right = "0px"; - img.style.top = "0px"; - img.style.width = "16px"; - img.style.height = "16px"; + img.style.position = 'absolute'; + img.style.right = '0px'; + img.style.top = '0px'; + img.style.width = '16px'; + img.style.height = '16px'; img.onclick = e => { this.close(); }; this.element.appendChild(img); } if (this.resizeIcon) { - let img = document.createElement("img"); - img.style.position = "absolute"; - img.style.right = "0px"; - img.style.bottom = "0px"; - img.style.width = "16px"; - img.style.height = "16px"; + let img = document.createElement('img'); + img.style.position = 'absolute'; + img.style.right = '0px'; + img.style.bottom = '0px'; + img.style.width = '16px'; + img.style.height = '16px'; img.src = this.resizeIcon; - img.setAttribute("draggable", true); + img.setAttribute('draggable', true); img.ondragstart = e => { this.currentPos = { x: e.clientX, y: e.clientY }; return true @@ -5378,27 +5524,27 @@ img.ondrag = e => { e.preventDefault(); - let target = this.element.querySelector("iframe") || this.element; + let target = + this.element.querySelector('iframe') || this.element; let delta = { x: e.clientX - this.currentPos.x, y: e.clientY - this.currentPos.y }; this.currentPos = { x: e.clientX, y: e.clientY }; - if (delta.x == 0 && delta.y == 0) - return + if (delta.x == 0 && delta.y == 0) return let rect = target.getBoundingClientRect(); let width = rect.width + delta.x; let height = rect.height + delta.y; - target.style.width = width + "px"; - target.style.height = height + "px"; + target.style.width = width + 'px'; + target.style.height = height + 'px'; switch (this.notchPosition) { - case "bottomLeft": - case "bottomCenter": + case 'bottomLeft': + case 'bottomCenter': let bottom = parseFloat(this.element.style.bottom); - this.element.style.bottom = bottom - delta.y + "px"; + this.element.style.bottom = bottom - delta.y + 'px'; break default: break @@ -5408,31 +5554,30 @@ this.onResize({ target, delta, width, height }); } }; - img.ondragend = e => { }; + img.ondragend = e => {}; this.element.appendChild(img); } - for (let key in content) { switch (key) { - case "selector": + case 'selector': break - case "text": - let text = document.createElement("span"); + case 'text': + let text = document.createElement('span'); this.element.appendChild(text); text.innerHTML = content[key]; Elements$1.setStyle(text, { color: this.normalColor }); - Elements$1.addClass(text, "unselectable"); - Elements$1.addClass(text, "PopupContent"); + Elements$1.addClass(text, 'unselectable'); + Elements$1.addClass(text, 'PopupContent'); this.insertedNode = text; this.loaded = true; break - case "img": - alert("img to be implemented"); + case 'img': + alert('img to be implemented'); break - case "iframe": - let iframe = document.createElement("iframe"); - iframe.setAttribute("frameBorder", 0); + case 'iframe': + let iframe = document.createElement('iframe'); + iframe.setAttribute('frameBorder', 0); iframe.src = content[key]; iframe.onload = e => { let body = iframe.contentWindow.document.body; @@ -5447,8 +5592,8 @@ }); let w = Math.max(body.scrollWidth, body.offsetWidth); let h = Math.max(body.scrollHeight, body.offsetHeight); - iframe.style.width = w + "px"; - iframe.style.height = h + "px"; + iframe.style.width = w + 'px'; + iframe.style.height = h + 'px'; this.layoutAfterInsert(); if (this.onload != null) { this.onload(); @@ -5456,13 +5601,13 @@ this.loaded = true; }; this.element.appendChild(iframe); - Elements$1.addClass(iframe, "PopupContent"); + Elements$1.addClass(iframe, 'PopupContent'); this.insertIntoDOM(); return - case "html": + case 'html': this.loaded = false; - let div = document.createElement("div"); - Elements$1.addClass(div, "PopupContent"); + let div = document.createElement('div'); + Elements$1.addClass(div, 'PopupContent'); this.element.appendChild(div); div.innerHTML = content.html; //console.log("insert", content) @@ -5473,8 +5618,7 @@ div.innerHTML = `

Popup content not found. Missing ${selector}

`; this.insertedNode = div.firstElementChild; } - } - else { + } else { this.insertedNode = div.firstElementChild || div; } this.setAlpha(this.insertedNode, 0); @@ -5483,9 +5627,12 @@ if (images.length > 0) { let count = 0; for (let image of images) { - if (!image.complete && !image.src.startsWith('data:')) { + if ( + !image.complete && + !image.src.startsWith('data:') + ) { total += 1; - console.log("image not complete", image.src); + console.log('image not complete', image.src); image.onload = e => { count += 1; if (count == total) { @@ -5502,15 +5649,15 @@ this.loaded = true; } break - case "node": + case 'node': this.loaded = true; - Elements$1.addClass(content.node, "PopupContent"); + Elements$1.addClass(content.node, 'PopupContent'); this.element.appendChild(content.node); this.insertedNode = content.node; this.setAlpha(this.insertedNode, 0); break default: - alert("Unexpected content type: " + key); + alert('Unexpected content type: ' + key); break } } @@ -5524,8 +5671,7 @@ let closing = this.closingEvent(e); if (closing) { this.close(); - } - else { + } else { this.setupCloseHandler(); } } @@ -5534,18 +5680,36 @@ let close = this.handleClose; if (this.hideOnUp) { if (window.PointerEvent) - this.parent.addEventListener("pointerup", close.bind(this), { capture: true, once: true }); + this.parent.addEventListener('pointerup', close.bind(this), { + capture: true, + once: true + }); else if (window.TouchEvent) - this.parent.addEventListener("touchend", close.bind(this), { capture: true, once: true }); + this.parent.addEventListener('touchend', close.bind(this), { + capture: true, + once: true + }); else - this.parent.addEventListener("mouseup", close.bind(this), { capture: true, once: true }); + this.parent.addEventListener('mouseup', close.bind(this), { + capture: true, + once: true + }); } else { if (window.PointerEvent) - this.parent.addEventListener("pointerdown", close.bind(this), { capture: true, once: true }); + this.parent.addEventListener('pointerdown', close.bind(this), { + capture: true, + once: true + }); else if (window.TouchEvent) - this.parent.addEventListener("touchstart", close.bind(this), { capture: true, once: true }); + this.parent.addEventListener('touchstart', close.bind(this), { + capture: true, + once: true + }); else - this.parent.addEventListener("mousedown", close.bind(this), { capture: true, once: true }); + this.parent.addEventListener('mousedown', close.bind(this), { + capture: true, + once: true + }); } } @@ -5557,7 +5721,7 @@ closingEvent(e) { if (this.interactive) { - let node = e.target.closest(".PopupContent"); + let node = e.target.closest('.PopupContent'); return node == null } return true @@ -5567,18 +5731,19 @@ let body = iframe.contentWindow.document.body; let w = Math.max(body.scrollWidth, body.offsetWidth); let h = Math.max(body.scrollHeight, body.offsetHeight); - iframe.style.width = w + "px"; - iframe.style.height = h + "px"; + iframe.style.width = w + 'px'; + iframe.style.height = h + 'px'; } setupDraggable() { if (this.draggable) { let target = this.element; - target.setAttribute("draggable", true); + target.setAttribute('draggable', true); target.ondragstart = e => { this.currentPos = { x: e.clientX, y: e.clientY }; var img = document.createElement('img'); - img.src = 'data:image/gifbase64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'; + img.src = + 'data:image/gifbase64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'; e.dataTransfer.setDragImage(img, 0, 0); }; target.ondrag = e => { @@ -5609,9 +5774,7 @@ } } - moveDragged(target) { - - } + moveDragged(target) {} insertIntoDOM(layout = true) { this.setAlpha(this.insertedNode, 0); @@ -5627,8 +5790,7 @@ /** Layout the menu items. Needed only in the subclass. */ - layout() { } - + layout() {} remove() { if (this.parent.contains(this.element)) @@ -5643,8 +5805,7 @@ this.unregister(this.context); if (this.closeCommand) { this.closeCommand(this, () => this.remove()); - } - else { + } else { this.remove(); } } @@ -5658,10 +5819,10 @@ * @memberof Popup */ setAlpha(targets, value) { - let objs = (targets instanceof Array) ? targets : [targets]; + let objs = targets instanceof Array ? targets : [targets]; for (let obj of objs) { if (value) { - obj.style.transition = "opacity 0.2s ease-in"; + obj.style.transition = 'opacity 0.2s ease-in'; } obj.style.opacity = value; } @@ -5690,12 +5851,11 @@ */ showAt(content, point) { this.setup(content); - console.log("showAt", this.loaded); + console.log('showAt', this.loaded); if (this.loaded) { this.placeAt(point); this.fadeIn(); - } - else { + } else { this.setAlpha([this.element, this.insertedNode], 0); this.onload = () => { this.layoutAfterInsert(); @@ -5714,7 +5874,7 @@ * @memberof Popup */ placeOrigin(x, y) { - Elements$1.setStyle(this.element, { left: x + "px", top: y + "px" }); + Elements$1.setStyle(this.element, { left: x + 'px', top: y + 'px' }); } /** @@ -5754,25 +5914,24 @@ * @memberof Popup */ notchPositionWithin(x, y) { - let horizontal = "Center"; - let vertical = "center"; + let horizontal = 'Center'; + let vertical = 'center'; let { width, height } = this.withinDimensions(); let local = this.localPointWithin(x, y, width, height); if (local.y < height * 0.33) { - vertical = "top"; + vertical = 'top'; } if (local.y > height * 0.66) { - vertical = "bottom"; + vertical = 'bottom'; } if (local.x < width * 0.33) { - horizontal = "Left"; + horizontal = 'Left'; } if (local.x > width * 0.66) { - horizontal = "Right"; + horizontal = 'Right'; } let result = vertical + horizontal; - if (result == "centerCenter") - return this.notchPosition + if (result == 'centerCenter') return this.notchPosition return result } @@ -5784,37 +5943,39 @@ notchPosition = this.notchPositionWithin(x, y); } Elements$1.setStyle(this.notch, this.notchStyle(notchPosition)); - this.notch.className = "notch " + notchPosition; + this.notch.className = 'notch ' + notchPosition; let { width, height } = this.localDimensions(); //if targetBoundingBox is set, popup is placed next to the rectangle if (this.targetBoundingBox) { let bbTop = this.targetBoundingBox.y; - let bbBottom = this.targetBoundingBox.y + this.targetBoundingBox.height; + let bbBottom = + this.targetBoundingBox.y + this.targetBoundingBox.height; let bbLeft = this.targetBoundingBox.x; - let bbRight = this.targetBoundingBox.x + this.targetBoundingBox.width; + let bbRight = + this.targetBoundingBox.x + this.targetBoundingBox.width; //console.log("place popup with bb set:", x, y, bbTop, bbBottom, bbLeft, bbRight) switch (notchPosition) { - case "bottomLeft": - case "bottomRight": - case "bottomCenter": + case 'bottomLeft': + case 'bottomRight': + case 'bottomCenter': y = bbTop; if (!this.useEventPosWithBoundingBox) x = (bbLeft + bbRight) / 2; break - case "topLeft": - case "topRight": - case "topCenter": + case 'topLeft': + case 'topRight': + case 'topCenter': y = bbBottom; if (!this.useEventPosWithBoundingBox) x = (bbLeft + bbRight) / 2; break - case "centerRight": + case 'centerRight': x = bbLeft; if (!this.useEventPosWithBoundingBox) y = (bbTop + bbBottom) / 2; break - case "centerLeft": + case 'centerLeft': x = bbRight; if (!this.useEventPosWithBoundingBox) y = (bbTop + bbBottom) / 2; @@ -5826,14 +5987,14 @@ //calculate position depending on several (optional) parameters switch (notchPosition) { - case "bottomLeft": + case 'bottomLeft': x -= this.padding; x -= this.notchSize; y -= height; y -= this.notchSize * 2; y -= this.posOffset; break - case "bottomRight": + case 'bottomRight': x -= width; x += this.padding; x += this.notchSize; @@ -5841,36 +6002,36 @@ y -= this.notchSize * 2; y -= this.posOffset; break - case "bottomCenter": + case 'bottomCenter': x -= width / 2; y -= height; y -= this.notchSize * 2; y -= this.posOffset; break - case "topLeft": + case 'topLeft': x -= this.padding; x -= this.notchSize; y += this.notchSize * 2; y += this.posOffset; break - case "topRight": + case 'topRight': x -= width; x += this.padding; x += this.notchSize; y += this.notchSize * 2; y += this.posOffset; break - case "topCenter": + case 'topCenter': x -= width / 2; y += this.notchSize * 2; y += this.posOffset; break - case "centerRight": + case 'centerRight': x -= width + this.notchSize * 2; x -= this.posOffset; y -= height / 2; break - case "centerLeft": + case 'centerLeft': //console.log("height", height) y -= height / 2; x += this.notchSize * 2; @@ -5898,23 +6059,23 @@ defaultStyle() { let padding = this.padding; let style = { - maxWidth: this.maxWidth + "px", + maxWidth: this.maxWidth + 'px', zIndex: this.zIndex, - position: "absolute", + position: 'absolute' }; if (this.minWidth) { - style.minWidth = this.minWidth + "px"; + style.minWidth = this.minWidth + 'px'; } if (!this.noStyle) { Object.assign(style, { - borderRadius: Math.round(this.padding / 2) + "px", + borderRadius: Math.round(this.padding / 2) + 'px', backgroundColor: this.backgroundColor, - padding: this.padding + "px", - boxShadow: "0 10px 15px rgba(0, 0, 0, 0.3)", + padding: this.padding + 'px', + boxShadow: '0 10px 15px rgba(0, 0, 0, 0.3)', fontFamily: this.fontFamily, fontSize: this.fontSize, - stroke: "black", - fill: "white" + stroke: 'black', + fill: 'white' }); } @@ -5931,56 +6092,56 @@ let height = 0; let left = this.padding; let size = this.localDimensions(); - if (notchPosition.endsWith("Right")) { + if (notchPosition.endsWith('Right')) { left = size.width - this.padding - this.notchSize * 2; } - if (notchPosition.endsWith("Center")) { + if (notchPosition.endsWith('Center')) { left = size.width / 2 - this.notchSize; } left = Math.round(left) + 'px'; - if (notchPosition.startsWith("bottom")) { + if (notchPosition.startsWith('bottom')) { if (this.noStyle) { return { width, height, left, - bottom: -this.notchSize + "px", - position: "absolute", - borderStyle: "solid", - borderTopWidth: this.notchSize + "px", - borderRight: this.notchSize + "px solid transparent", - borderLeft: this.notchSize + "px solid transparent", + bottom: -this.notchSize + 'px', + position: 'absolute', + borderStyle: 'solid', + borderTopWidth: this.notchSize + 'px', + borderRight: this.notchSize + 'px solid transparent', + borderLeft: this.notchSize + 'px solid transparent', borderBottom: 0 } - } else { return { width, height, left, - boxShadow: "0 12px 15px rgba(0, 0, 0, 0.1)", - bottom: -this.notchSize + "px", - position: "absolute", - borderTop: this.notchSize + "px solid " + this.backgroundColor, - borderRight: this.notchSize + "px solid transparent", - borderLeft: this.notchSize + "px solid transparent", + boxShadow: '0 12px 15px rgba(0, 0, 0, 0.1)', + bottom: -this.notchSize + 'px', + position: 'absolute', + borderTop: + this.notchSize + 'px solid ' + this.backgroundColor, + borderRight: this.notchSize + 'px solid transparent', + borderLeft: this.notchSize + 'px solid transparent', borderBottom: 0 } } } - if (notchPosition.startsWith("top")) { + if (notchPosition.startsWith('top')) { if (this.noStyle) { return { width, height, left, - top: -this.notchSize + "px", - position: "absolute", - borderStyle: "solid", - borderBottomWidth: this.notchSize + "px", - borderRight: this.notchSize + "px solid transparent", - borderLeft: this.notchSize + "px solid transparent", + top: -this.notchSize + 'px', + position: 'absolute', + borderStyle: 'solid', + borderBottomWidth: this.notchSize + 'px', + borderRight: this.notchSize + 'px solid transparent', + borderLeft: this.notchSize + 'px solid transparent', borderTop: 0 } } else { @@ -5988,31 +6149,29 @@ width, height, left, - top: -this.notchSize + "px", - position: "absolute", - borderBottom: this.notchSize + "px solid " + this.backgroundColor, - borderRight: this.notchSize + "px solid transparent", - borderLeft: this.notchSize + "px solid transparent", + top: -this.notchSize + 'px', + position: 'absolute', + borderBottom: + this.notchSize + 'px solid ' + this.backgroundColor, + borderRight: this.notchSize + 'px solid transparent', + borderLeft: this.notchSize + 'px solid transparent', borderTop: 0 } } } if (this.noStyle) { - - if (notchPosition.endsWith("Left")) { - left = -this.notchSize * 2 + "px"; + if (notchPosition.endsWith('Left')) { + left = -this.notchSize * 2 + 'px'; } - if (notchPosition.endsWith("Right")) { - left = size.width + "px"; + if (notchPosition.endsWith('Right')) { + left = size.width + 'px'; } - let top = size.height / 2 - this.notchSize; top = Math.round(top) + 'px'; - return { width, height, @@ -6020,29 +6179,30 @@ top, borderRightWidth: this.notchSize, borderLeftWidth: this.notchSize, - position: "absolute", - borderTop: this.notchSize + "px solid transparent", - borderBottom: this.notchSize + "px solid transparent" + position: 'absolute', + borderTop: this.notchSize + 'px solid transparent', + borderBottom: this.notchSize + 'px solid transparent' } - } else { - let borderRight = this.notchSize + "px solid transparent"; - let borderLeft = this.notchSize + "px solid transparent"; + let borderRight = this.notchSize + 'px solid transparent'; + let borderLeft = this.notchSize + 'px solid transparent'; let top = size.height / 2 - this.notchSize; - if (notchPosition.endsWith("Left")) { - left = -this.notchSize * 2 + "px"; - borderRight = this.notchSize + "px solid " + this.backgroundColor; - this.element.style.boxShadow = "15px 10px 15px rgba(0, 0, 0, 0.3)"; + if (notchPosition.endsWith('Left')) { + left = -this.notchSize * 2 + 'px'; + borderRight = + this.notchSize + 'px solid ' + this.backgroundColor; + this.element.style.boxShadow = + '15px 10px 15px rgba(0, 0, 0, 0.3)'; } - if (notchPosition.endsWith("Right")) { - left = size.width + "px"; - borderLeft = this.notchSize + "px solid " + this.backgroundColor; - this.element.style.boxShadow = "15px 5px 15px rgba(0, 0, 0, 0.3)"; + if (notchPosition.endsWith('Right')) { + left = size.width + 'px'; + borderLeft = this.notchSize + 'px solid ' + this.backgroundColor; + this.element.style.boxShadow = + '15px 5px 15px rgba(0, 0, 0, 0.3)'; } top = Math.round(top) + 'px'; - return { width, height, @@ -6051,9 +6211,9 @@ borderRight, borderLeft, // boxShadow, - position: "absolute", - borderTop: this.notchSize + "px solid transparent", - borderBottom: this.notchSize + "px solid transparent" + position: 'absolute', + borderTop: this.notchSize + 'px solid transparent', + borderBottom: this.notchSize + 'px solid transparent' } } } @@ -6071,16 +6231,16 @@ { parent = null, context = window, - fontSize = "1em", - fontFamily = "Arial", + fontSize = '1em', + fontFamily = 'Arial', padding = 16, notchSize = 10, switchPos = false, minWidth = null, maxWidth = 800, - backgroundColor = "#EEE", + backgroundColor = '#EEE', zIndex = 0, - normalColor = "#444", + normalColor = '#444', closeIcon = null, resizeIcon = null, closeCommand = null, @@ -6095,9 +6255,8 @@ onMove = null } = {} ) { - - - let notchPosition = (switchPos && point.y < 50) ? "topCenter" : "bottomCenter"; + let notchPosition = + switchPos && point.y < 50 ? 'topCenter' : 'bottomCenter'; let popup = new Popup$1({ parent, context, @@ -6199,21 +6358,22 @@ */ class PopupMenu extends Popup$1 { /** - * The constructor. - * @constructor - * @param {DOM Element} parent - The DOM parent element. - * @param {Object} commands - A dict object with command label strings as keys - * and command functions as values. - * @param {string} fontSize - Describes the font size as CSS value - * @param {number || string} padding - Describes the padding as CSS value - * @param {number || string} notchSize - Describes the size of the notch (callout) as CSS value - * @param {string} highlightColor - The color of highlighted menu items as CSS value - * @param {string} backgroundColor - The color of the background as CSS value - * @param {string} normalColor - The color of normal menu items as CSS value - * @param {DOM Element} keepWithin - The container to stay within - * @param {boolean} autoClose - Autoclose the menu after selecting an item - */ - constructor({ parent = null, + * The constructor. + * @constructor + * @param {DOM Element} parent - The DOM parent element. + * @param {Object} commands - A dict object with command label strings as keys + * and command functions as values. + * @param {string} fontSize - Describes the font size as CSS value + * @param {number || string} padding - Describes the padding as CSS value + * @param {number || string} notchSize - Describes the size of the notch (callout) as CSS value + * @param {string} highlightColor - The color of highlighted menu items as CSS value + * @param {string} backgroundColor - The color of the background as CSS value + * @param {string} normalColor - The color of normal menu items as CSS value + * @param {DOM Element} keepWithin - The container to stay within + * @param {boolean} autoClose - Autoclose the menu after selecting an item + */ + constructor({ + parent = null, commands = null, fontSize = '1em', fontFamily = 'Arial', @@ -6228,8 +6388,20 @@ highlightColor = 'black', notchPosition = 'bottomLeft', keepWithin = null, - autoClose = true } = {}) { - super({ parent, fontSize, fontFamily, padding, notchSize, notchPosition, backgroundColor, keepWithin, normalColor, autoClose }); + autoClose = true + } = {}) { + super({ + parent, + fontSize, + fontFamily, + padding, + notchSize, + notchPosition, + backgroundColor, + keepWithin, + normalColor, + autoClose + }); this.commands = commands; this.zIndex = zIndex; this.switchPos = switchPos; @@ -6243,7 +6415,6 @@ * @return {PopupMenu} this */ setup(commands) { - this.commands = commands; this.items = {}; this.element = document.createElement('div'); @@ -6256,14 +6427,25 @@ this.element.appendChild(item); item.innerHTML = key; item.style.paddingBottom = item.style.paddingTop = this.spacing; - Elements$1.setStyle(item, { color: this.normalColor, cursor: 'default' }); + Elements$1.setStyle(item, { + color: this.normalColor, + cursor: 'default' + }); Elements$1.addClass(item, 'unselectable'); Elements$1.addClass(item, 'popupMenuItem'); this.items[key] = item; - item.onclick = (event) => { this.perform(key); }; - item.ontap = (event) => { this.perform(key); }; - item.onmouseover = (event) => { this.over(event, key); }; - item.onmouseout = (event) => { this.out(event, key); }; + item.onclick = event => { + this.perform(key); + }; + item.ontap = event => { + this.perform(key); + }; + item.onmouseover = event => { + this.over(event, key); + }; + item.onmouseout = event => { + this.out(event, key); + }; } this.element.appendChild(this.notch); @@ -6293,7 +6475,7 @@ */ update(key, highlight = false) { let text = this.items[key]; - text.style.color = (highlight) ? this.highlightColor : this.normalColor; + text.style.color = highlight ? this.highlightColor : this.normalColor; } /** Mouse over handöer. @@ -6319,7 +6501,7 @@ * and command functions as values. * @param {Point} point - The position as x, y coordinates {px}. * @return {PopupMenu} this - */ + */ showAt(commands, point) { this.show(commands); this.placeAt(point); @@ -6339,44 +6521,71 @@ * @param {string} normalColor - The color of normal menu items as CSS value * @param {boolean} autoClose - Autoclose the menu after selecting an item */ - static open(commands, point, { parent = null, - context = window, - fontSize = '1em', - fontFamily = 'Arial', - padding = 16, - zIndex = 1, - spacing = '0px', - switchPos = false, - notchSize = 10, - maxWidth = 800, - keepWithin = null, - backgroundColor = '#EEE', - normalColor = '#444', - autoClose = true } = {}) { - + static open( + commands, + point, + { + parent = null, + context = window, + fontSize = '1em', + fontFamily = 'Arial', + padding = 16, + zIndex = 1, + spacing = '0px', + switchPos = false, + notchSize = 10, + maxWidth = 800, + keepWithin = null, + backgroundColor = '#EEE', + normalColor = '#444', + autoClose = true + } = {} + ) { let registered = Poppable.get(context); if (registered) { this.closePopup(); return } - console.log("open", point); - let notchPosition = (point.y < 50 && switchPos) ? 'topCenter' : 'bottomCenter'; + console.log('open', point); + let notchPosition = + point.y < 50 && switchPos ? 'topCenter' : 'bottomCenter'; let popup = new PopupMenu({ - parent, fontSize, padding, zIndex, spacing, switchPos, notchSize, + parent, + fontSize, + padding, + zIndex, + spacing, + switchPos, + notchSize, notchPosition, - maxWidth, backgroundColor, normalColor, - notchPosition, keepWithin, autoClose + maxWidth, + backgroundColor, + normalColor, + notchPosition, + keepWithin, + autoClose }); popup.showAt(commands, point); popup.register(context); - popup.closeEventListener = (e) => { - if (this.eventOutside(e)) - this.closePopup(context); + popup.closeEventListener = e => { + if (this.eventOutside(e)) this.closePopup(context); }; if (autoClose) { - context.addEventListener('mousedown', popup.closeEventListener, true); - context.addEventListener('touchstart', popup.closeEventListener, true); - context.addEventListener('pointerdown', popup.closeEventListener, true); + context.addEventListener( + 'mousedown', + popup.closeEventListener, + true + ); + context.addEventListener( + 'touchstart', + popup.closeEventListener, + true + ); + context.addEventListener( + 'pointerdown', + popup.closeEventListener, + true + ); } } @@ -6387,23 +6596,32 @@ /** Convenient static methods to close the PopupMenu implemented * as a class variable. */ - static closePopup(context=window) { + static closePopup(context = window) { let registered = Poppable.get(context); if (registered) { registered.close(); - context.removeEventListener('mousedown', registered.closeEventListener); - context.removeEventListener('touchstart', registered.closeEventListener); - context.removeEventListener('pointerdown', registered.closeEventListener); + context.removeEventListener( + 'mousedown', + registered.closeEventListener + ); + context.removeEventListener( + 'touchstart', + registered.closeEventListener + ); + context.removeEventListener( + 'pointerdown', + registered.closeEventListener + ); } } } class FrameContainer { - constructor(element) { this.element = element; - this.delegate = new InteractionMapper(element, this, - { mouseWheelElement: window}); + this.delegate = new InteractionMapper(element, this, { + mouseWheelElement: window + }); } capture(event) { @@ -6427,8 +6645,7 @@ } class FrameTarget { - - constructor(frame, target, debug=false) { + constructor(frame, target, debug = false) { this.frame = frame; this.target = target; this.debug = debug; @@ -6445,22 +6662,30 @@ bubbles: true, cancelable: true, clientX: p.x, - clientY: p.y}); + clientY: p.y + }); this.target.dispatchEvent(event); } createTouchList(pointMap) { let touches = []; let doc = this.frame.contentWindow.document; - for(let key of pointMap.keys()) { + for (let key of pointMap.keys()) { let point = pointMap.get(key); let p = Points$1.fromPageToNode(this.frame, point); let touchTarget = doc.elementFromPoint(p.x, p.y); - let touch = new Touch(undefined, touchTarget, key, - p.x, p.y, p.x, p.y); + let touch = new Touch( + undefined, + touchTarget, + key, + p.x, + p.y, + p.x, + p.y + ); touches.push(touch); } - return new TouchList(...touches) + return new TouchList(...touches) } simulateTouchEventChrome(type, point, pointMap) { @@ -6477,7 +6702,7 @@ radiusX: 2.5, radiusY: 2.5, rotationAngle: 10, - force: 0.5, + force: 0.5 }); const touchEvent = new TouchEvent(type, { @@ -6486,47 +6711,57 @@ touches: [touchObj], targetTouches: [touchObj], changedTouches: [touchObj], - shiftKey: false, + shiftKey: false }); - if (this.debug) console.log("simulateTouchEventChrome", touchEvent); + if (this.debug) console.log('simulateTouchEventChrome', touchEvent); this.target.dispatchEvent(touchEvent); } - simulateTouchEventSafari(type, point, pointMap, touchEventKey='targetTouches') { + simulateTouchEventSafari( + type, + point, + pointMap, + touchEventKey = 'targetTouches' + ) { let p = Points$1.fromPageToNode(this.frame, point); - let data = { view: this.frame.contentWindow, + let data = { + view: this.frame.contentWindow, bubbles: true, cancelable: true, clientX: p.x, - clientY: p.y}; + clientY: p.y + }; data[touchEventKey] = this.createTouchList(pointMap); let event = new TouchEvent(type, data); - if (this.debug) console.log("simulateTouchEventChrome", touchEvent); + if (this.debug) console.log('simulateTouchEventChrome', touchEvent); this.target.dispatchEvent(event); } - simulateTouchEvent(type, point, pointMap, touchEventKey='targetTouches') { + simulateTouchEvent(type, point, pointMap, touchEventKey = 'targetTouches') { if (Capabilities.isSafari) { this.simulateTouchEventSafari(type, point, pointMap, touchEventKey); - } - else { + } else { this.simulateTouchEventChrome(type, point, pointMap); } } isMouseLikeEvent(event) { - return event.type.startsWith('mouse') || event.type.startsWith('pointer') + return ( + event.type.startsWith('mouse') || event.type.startsWith('pointer') + ) } onStart(event, interaction) { if (this.debug) console.log('onStart', this.frame.parentNode); - for(let [key, point] of interaction.current.entries()) { + for (let [key, point] of interaction.current.entries()) { if (this.isMouseLikeEvent(event)) { this.simulateMouseEvent('mousedown', point); - } - else { - this.simulateTouchEvent('touchstart', point, - interaction.current); + } else { + this.simulateTouchEvent( + 'touchstart', + point, + interaction.current + ); return } } @@ -6534,13 +6769,11 @@ onMove(event, interaction) { if (this.debug) console.log('onMove'); - for(let [key, point] of interaction.current.entries()) { + for (let [key, point] of interaction.current.entries()) { if (this.isMouseLikeEvent(event)) { this.simulateMouseEvent('mousemove', point); - } - else { - this.simulateTouchEvent('touchmove', point, - interaction.current); + } else { + this.simulateTouchEvent('touchmove', point, interaction.current); return } } @@ -6548,13 +6781,16 @@ onEnd(event, interaction) { if (this.debug) console.log('onEnd'); - for(let [key, point] of interaction.current.entries()) { + for (let [key, point] of interaction.current.entries()) { if (this.isMouseLikeEvent(event)) { this.simulateMouseEvent('mouseend', point); - } - else { - this.simulateTouchEvent('touchend', point, - interaction.ended, 'changedTouches'); + } else { + this.simulateTouchEvent( + 'touchend', + point, + interaction.ended, + 'changedTouches' + ); return } } @@ -6564,8 +6800,7 @@ class Inspect { // Code inspection functions - static allScriptSources() - { + static allScriptSources() { let sources = []; let scripts = document.getElementsByTagName('script'); for (let i = 0; i < scripts.length; i++) { @@ -6594,7 +6829,7 @@ * * // Add an action to the test case * test.tap(button, {eventType: 'click'}) - * + * * // Start the test case * test.start() * @@ -6602,10 +6837,9 @@ * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/uitest.html|DocTest} */ class UITest { - /** * Creates an instance of an UITest. - * + * * In the background, the class UITest uses the Greensock TimelineMax class. The opts object is passed directly to the TimelineMax class, so it can use any key that uses the TimelineMax class. * * @constructor @@ -6616,19 +6850,28 @@ * @param {number} [opts.defaultInterval] - The interval used when no action is specified for an action. */ constructor(opts = {}) { - - this.opts = Object.assign({}, { - timeScale: 1, - eventType: 'auto', - debug: false, - defaultInterval: null - }, opts); + this.opts = Object.assign( + {}, + { + timeScale: 1, + eventType: 'auto', + debug: false, + defaultInterval: null + }, + opts + ); // timeline //-------------------- - this._timeline = new TimelineMax(Object.assign({}, { - paused: true - }, this.opts)); + this._timeline = new TimelineMax( + Object.assign( + {}, + { + paused: true + }, + this.opts + ) + ); this._timeline.timeScale(this.opts.timeScale); // eventType @@ -6696,7 +6939,7 @@ /** * Clears all instructions of the test case. - * + * * @return {UITest} A reference to the UITest for chaining. */ clear() { @@ -6706,7 +6949,7 @@ /** * Restarts the test case. - * + * * @return {UITest} A reference to the UITest for chaining. */ restart() { @@ -6716,7 +6959,7 @@ /** * Executes a tap event (pointerdown, pointerup) on a specific element. - * + * * @param {HTMLElement|string} element - The HTML element on which the event is to be executed, e.g. button, document, h2, canvas, etc. or an selector string. If a selector has been specified, it is evaluated immediately before the event is called using the querySelector method. * @param {number[]|object|PIXI.DisplayObject} [position=The center of the element.] - The local position of the event in the context of the specified HTML element. If no position is specified, the center of the HTML element is used. The position can be specified as an array of numbers, as an object with the two properties x and y, or as a PIXI.Display object. * @param {number} [timelinePosition=One second after the last action.] - The position in seconds when the event should be triggered, see shttps://greensock.com/docs/TimelineMax/addCallback(). @@ -6730,91 +6973,116 @@ * @param {boolean} [opts.cancelable=true] - Events' cancelable property indicates if the event can be canceled, and therefore prevented as if the event never happened. If the event is not cancelable, then its cancelable property will be false and the event listener cannot stop the event from occurring. */ tap(element, position, timelinePosition, opts = {}) { - - // arguments - //-------------------- - [position, timelinePosition, opts] = this.reorderArguments(arguments); + [position, timelinePosition, opts] = this.reorderArguments(arguments); this._timelinePositions.push(timelinePosition); // debug //-------------------- - if (this.opts.debug) console.log('tap params', {element, position, timelinePosition, opts}); + if (this.opts.debug) + console.log('tap params', { + element, + position, + timelinePosition, + opts + }); // opts //-------------------- - opts = Object.assign({}, { - onStart: null, - onComplete: null, - eventTypes: this.resolveEvents(['down', 'up']), - eventType: null, - context: window, - bubbles: true, - cancelable: true - }, opts); + opts = Object.assign( + {}, + { + onStart: null, + onComplete: null, + eventTypes: this.resolveEvents(['down', 'up']), + eventType: null, + context: window, + bubbles: true, + cancelable: true + }, + opts + ); if (opts.eventType) { opts.eventTypes = opts.eventType; } - opts.eventTypes = Array.isArray(opts.eventTypes) ? opts.eventTypes : [opts.eventTypes]; + opts.eventTypes = Array.isArray(opts.eventTypes) + ? opts.eventTypes + : [opts.eventTypes]; // timeline //-------------------- - this._timeline.addCallback(position => { + this._timeline.addCallback( + position => { + // element + //-------------------- + const elem = Util.extractElement(opts.context, element); - // element - //-------------------- - const elem = Util.extractElement(opts.context, element); + // position + //-------------------- + if (position === null) { + const rect = elem.getBoundingClientRect(); + position = [rect.width / 2, rect.height / 2]; + } - // position - //-------------------- - if (position === null) { - const rect = elem.getBoundingClientRect(); - position = [rect.width / 2, rect.height / 2]; - } + // coords + //-------------------- + const coords = Util.extractPosition(position); + if (this.opts.debug) console.log('local coords', coords); - // coords - //-------------------- - const coords = Util.extractPosition(position); - if (this.opts.debug) console.log('local coords', coords); + // eventTypes + //-------------------- + if (opts.eventTypes.length === 1) { + opts.eventTypes.unshift(null); + } - // eventTypes - //-------------------- - if (opts.eventTypes.length === 1) { - opts.eventTypes.unshift(null); - } + // event opts + //-------------------- + const eventOpts = { + bubbles: opts.bubbles, + cancelable: opts.cancelable + }; - // event opts - //-------------------- - const eventOpts = {bubbles: opts.bubbles, cancelable: opts.cancelable}; + if (opts.eventTypes[0]) { + // create and dispatch event + //-------------------- + const eventStart = Event$1.create( + elem, + coords, + opts.eventTypes[0], + eventOpts + ); + if (this.opts.debug) + console.log('dispatch event', eventStart); + elem.dispatchEvent(eventStart); - if (opts.eventTypes[0]) { + // onStart + //-------------------- + if (opts.onStart) { + opts.onStart.call(this, eventStart); + } + } // create and dispatch event //-------------------- - const eventStart = Event$1.create(elem, coords, opts.eventTypes[0], eventOpts); - if (this.opts.debug) console.log('dispatch event', eventStart); - elem.dispatchEvent(eventStart); + const eventComplete = Event$1.create( + elem, + coords, + opts.eventTypes[1], + eventOpts + ); + if (this.opts.debug) + console.log('dispatch event', eventComplete); + elem.dispatchEvent(eventComplete); - // onStart + // onComplete //-------------------- - if (opts.onStart) { - opts.onStart.call(this, eventStart); + if (opts.onComplete) { + opts.onComplete.call(this, eventComplete); } - } - - // create and dispatch event - //-------------------- - const eventComplete = Event$1.create(elem, coords, opts.eventTypes[1], eventOpts); - if (this.opts.debug) console.log('dispatch event', eventComplete); - elem.dispatchEvent(eventComplete); - - // onComplete - //-------------------- - if (opts.onComplete) { - opts.onComplete.call(this, eventComplete); - } - - }, timelinePosition, [position]); + }, + timelinePosition, + [position] + ); this._actions++; @@ -6823,7 +7091,7 @@ /** * Executes a pan event (pointerdown, pointermove, pointerup) on a specific element. - * + * * @param {HTMLElement|string} element - The HTML element on which the event is to be executed, e.g. button, document, h2, canvas, etc. or an selector string. If a selector has been specified, it is evaluated immediately before the event is called using the querySelector method. * @param {number[]|object|PIXI.DisplayObject} [position=The center of the element.] - The local position of the event in the context of the specified HTML element. If no position is specified, the center of the HTML element is used. The position can be specified as an array of numbers, as an object with the two properties x and y, or as a PIXI.Display object. * @param {number} [timelinePosition=One second after the last action.] - The position in seconds when the event should be triggered, see shttps://greensock.com/docs/TimelineMax/addCallback(). @@ -6840,104 +7108,131 @@ * @param {boolean} [opts.cancelable=true] - Events' cancelable property indicates if the event can be canceled, and therefore prevented as if the event never happened. If the event is not cancelable, then its cancelable property will be false and the event listener cannot stop the event from occurring. */ pan(element, position, timelinePosition, opts = {}) { - - // arguments - //-------------------- - [position, timelinePosition, opts] = this.reorderArguments(arguments); + [position, timelinePosition, opts] = this.reorderArguments(arguments); this._timelinePositions.push(timelinePosition); // debug //-------------------- - if (this.opts.debug) console.log('tap params', {element, position, timelinePosition, opts}); + if (this.opts.debug) + console.log('tap params', { + element, + position, + timelinePosition, + opts + }); // opts //-------------------- - opts = Object.assign({}, { - onStart: null, - onUpdate: null, - onComplete: null, - to: {x: 0, y: 0}, - duration: 1, - ease: Power0.easeNone, - eventTypes: this.resolveEvents(['down', 'move', 'up']), - context: window, - bubbles: true, - cancelable: true - }, opts); + opts = Object.assign( + {}, + { + onStart: null, + onUpdate: null, + onComplete: null, + to: { x: 0, y: 0 }, + duration: 1, + ease: Power0.easeNone, + eventTypes: this.resolveEvents(['down', 'move', 'up']), + context: window, + bubbles: true, + cancelable: true + }, + opts + ); // timeline //-------------------- - this._timeline.addCallback(position => { + this._timeline.addCallback( + position => { + // element + //-------------------- + const elem = Util.extractElement(opts.context, element); - // element - //-------------------- - const elem = Util.extractElement(opts.context, element); + // coords + //-------------------- + const from = Util.extractPosition(position); - // coords - //-------------------- - const from = Util.extractPosition(position); + // event opts + //-------------------- + const eventOpts = { + bubbles: opts.bubbles, + cancelable: opts.cancelable + }; - // event opts - //-------------------- - const eventOpts = {bubbles: opts.bubbles, cancelable: opts.cancelable}; + const gsOpts = { + ease: opts.ease, + onStart: () => { + // create and dispatch event + //-------------------- + const event = Event$1.create( + elem, + from, + opts.eventTypes[0], + eventOpts + ); + if (this.opts.debug) + console.log('dispatch event', event); + elem.dispatchEvent(event); - const gsOpts = { - ease: opts.ease, - onStart: () => { + // onStart + //-------------------- + if (opts.onStart) { + opts.onStart.call(this, event); + } + }, + onUpdate: () => { + // create and dispatch event + //-------------------- + const event = Event$1.create( + elem, + from, + opts.eventTypes[1], + eventOpts + ); + if (this.opts.debug) + console.log('dispatch event', event); + elem.dispatchEvent(event); - // create and dispatch event - //-------------------- - const event = Event$1.create(elem, from, opts.eventTypes[0], eventOpts); - if (this.opts.debug) console.log('dispatch event', event); - elem.dispatchEvent(event); + // onUpdate + //-------------------- + if (opts.onUpdate) { + opts.onUpdate.call(this, event); + } + }, + onComplete: () => { + // create and dispatch event + //-------------------- + const event = Event$1.create( + elem, + from, + opts.eventTypes[2], + eventOpts + ); + if (this.opts.debug) + console.log('dispatch event', event); + elem.dispatchEvent(event); - // onStart - //-------------------- - if (opts.onStart) { - opts.onStart.call(this, event); + // onComplete + //-------------------- + if (opts.onComplete) { + opts.onComplete.call(this, event); + } } - }, - onUpdate: () => { + }; - // create and dispatch event - //-------------------- - const event = Event$1.create(elem, from, opts.eventTypes[1], eventOpts); - if (this.opts.debug) console.log('dispatch event', event); - elem.dispatchEvent(event); + // to + //-------------------- + const object = Util.extractTo(opts); + Object.assign(gsOpts, object); - // onUpdate - //-------------------- - if (opts.onUpdate) { - opts.onUpdate.call(this, event); - } - }, - onComplete: () => { + // drag animation + //-------------------- + TweenLite.to(from, opts.duration, gsOpts); + }, + timelinePosition, + [position] + ); - // create and dispatch event - //-------------------- - const event = Event$1.create(elem, from, opts.eventTypes[2], eventOpts); - if (this.opts.debug) console.log('dispatch event', event); - elem.dispatchEvent(event); - - // onComplete - //-------------------- - if (opts.onComplete) { - opts.onComplete.call(this, event); - } - } - }; - - // to - //-------------------- - const object = Util.extractTo(opts); - Object.assign(gsOpts, object); - - // drag animation - //-------------------- - TweenLite.to(from, opts.duration, gsOpts); - - }, timelinePosition, [position]); - this._actions++; return this @@ -6945,7 +7240,7 @@ /** * Executes a pinch event (pointerdown, pointermove, pointerup) on a specific element with two "fingers" simultaneously. - * + * * @param {HTMLElement|string} element - The HTML element on which the event is to be executed, e.g. button, document, h2, canvas, etc. or an selector string. If a selector has been specified, it is evaluated immediately before the event is called using the querySelector method. * @param {number[]|object|PIXI.DisplayObject} [position=The center of the element.] - The local position of the event in the context of the specified HTML element. If no position is specified, the center of the HTML element is used. The position can be specified as an array of numbers, as an object with the two properties x and y, or as a PIXI.Display object. * @param {number} [timelinePosition=One second after the last action.] - The position in seconds when the event should be triggered, see shttps://greensock.com/docs/TimelineMax/addCallback(). @@ -6965,145 +7260,182 @@ * @param {boolean} [opts.cancelable=true] - Events' cancelable property indicates if the event can be canceled, and therefore prevented as if the event never happened. If the event is not cancelable, then its cancelable property will be false and the event listener cannot stop the event from occurring. */ pinch(element, position, timelinePosition, opts = {}) { - - // arguments - //-------------------- - [position, timelinePosition, opts] = this.reorderArguments(arguments); + [position, timelinePosition, opts] = this.reorderArguments(arguments); this._timelinePositions.push(timelinePosition); // debug //-------------------- - if (this.opts.debug) console.log('tap params', {element, position, timelinePosition, opts}); + if (this.opts.debug) + console.log('tap params', { + element, + position, + timelinePosition, + opts + }); // opts //-------------------- - opts = Object.assign({}, { - onStart: null, - onUpdate: null, - onComplete: null, - doubleCallbacks: false, - duration: 1, - distance: 100, - to: null, - bezier: null, - ease: Power0.easeNone, - eventTypes: this.resolveEvents(['down', 'move', 'up']), - context: window, - bubbles: true, - cancelable: true - }, opts); + opts = Object.assign( + {}, + { + onStart: null, + onUpdate: null, + onComplete: null, + doubleCallbacks: false, + duration: 1, + distance: 100, + to: null, + bezier: null, + ease: Power0.easeNone, + eventTypes: this.resolveEvents(['down', 'move', 'up']), + context: window, + bubbles: true, + cancelable: true + }, + opts + ); // timeline //-------------------- - this._timeline.addCallback(position => { - - // element - //-------------------- - const elem = Util.extractElement(opts.context, element); - - // from - //-------------------- - let from1 = null; - let from2 = null; - - if (Array.isArray(position) && !Util.isNumber(position[0])) { - from1 = Util.extractPosition(position[0]); - from2 = Util.extractPosition(position[1]); - } else { - from1 = Util.extractPosition(position); - from2 = {x: from1.x, y: from1.y}; - } - - // to - //-------------------- - let gsOpts1 = {}; - let gsOpts2 = {}; - - if (opts.to || opts.bezier) { - [gsOpts1, gsOpts2] = Util.extractMultiTo(opts); - } else { - const distance = opts.distance != null ? opts.distance : 100; - gsOpts1.x = from1.x - distance / 2; - gsOpts1.y = from1.y; - gsOpts2.x = from2.x + distance / 2; - gsOpts2.y = from2.y; - } - - // pointers - //-------------------- - const pointers = new Map(); - pointers.set(0, {element: from1, gsOpts: gsOpts1}); - pointers.set(1, {element: from2, gsOpts: gsOpts2}); - - // loop - //-------------------- - pointers.forEach((value, key) => { + this._timeline.addCallback( + position => { + // element + //-------------------- + const elem = Util.extractElement(opts.context, element); // from //-------------------- - const from = value.element; + let from1 = null; + let from2 = null; - // event opts - //-------------------- - const eventOpts = {bubbles: opts.bubbles, cancelable: opts.cancelable, pointerId: key, isPrimary: key === 0}; - - const gsOpts = { - ease: opts.ease, - onStart: () => { - - // create and dispatch event - //-------------------- - const event = Event$1.create(elem, from, opts.eventTypes[0], eventOpts); - if (this.opts.debug) console.log('dispatch event', event); - elem.dispatchEvent(event); - - // onStart - //-------------------- - if (opts.onStart && (opts.doubleCallbacks || key === 0)) { - opts.onStart.call(this, event); - } - }, - onUpdate: () => { - - // create and dispatch event - //-------------------- - const event = Event$1.create(elem, from, opts.eventTypes[1], eventOpts); - if (this.opts.debug) console.log('dispatch event', event); - elem.dispatchEvent(event); - - // onUpdate - //-------------------- - if (opts.onUpdate && (opts.doubleCallbacks || key === 0)) { - opts.onUpdate.call(this, event); - } - }, - onComplete: () => { - - // create and dispatch event - //-------------------- - const event = Event$1.create(elem, from, opts.eventTypes[2], eventOpts); - if (this.opts.debug) console.log('dispatch event', event); - elem.dispatchEvent(event); - - // onComplete - //-------------------- - if (opts.onComplete && (opts.doubleCallbacks || key === 0)) { - opts.onComplete.call(this, event); - } - } - }; + if (Array.isArray(position) && !Util.isNumber(position[0])) { + from1 = Util.extractPosition(position[0]); + from2 = Util.extractPosition(position[1]); + } else { + from1 = Util.extractPosition(position); + from2 = { x: from1.x, y: from1.y }; + } // to //-------------------- - Object.assign(gsOpts, value.gsOpts); + let gsOpts1 = {}; + let gsOpts2 = {}; - // drag animation + if (opts.to || opts.bezier) { + [gsOpts1, gsOpts2] = Util.extractMultiTo(opts); + } else { + const distance = opts.distance != null ? opts.distance : 100; + gsOpts1.x = from1.x - distance / 2; + gsOpts1.y = from1.y; + gsOpts2.x = from2.x + distance / 2; + gsOpts2.y = from2.y; + } + + // pointers //-------------------- - TweenLite.to(from, opts.duration, gsOpts); - }); + const pointers = new Map(); + pointers.set(0, { element: from1, gsOpts: gsOpts1 }); + pointers.set(1, { element: from2, gsOpts: gsOpts2 }); + + // loop + //-------------------- + pointers.forEach((value, key) => { + // from + //-------------------- + const from = value.element; + + // event opts + //-------------------- + const eventOpts = { + bubbles: opts.bubbles, + cancelable: opts.cancelable, + pointerId: key, + isPrimary: key === 0 + }; + + const gsOpts = { + ease: opts.ease, + onStart: () => { + // create and dispatch event + //-------------------- + const event = Event$1.create( + elem, + from, + opts.eventTypes[0], + eventOpts + ); + if (this.opts.debug) + console.log('dispatch event', event); + elem.dispatchEvent(event); + + // onStart + //-------------------- + if ( + opts.onStart && + (opts.doubleCallbacks || key === 0) + ) { + opts.onStart.call(this, event); + } + }, + onUpdate: () => { + // create and dispatch event + //-------------------- + const event = Event$1.create( + elem, + from, + opts.eventTypes[1], + eventOpts + ); + if (this.opts.debug) + console.log('dispatch event', event); + elem.dispatchEvent(event); + + // onUpdate + //-------------------- + if ( + opts.onUpdate && + (opts.doubleCallbacks || key === 0) + ) { + opts.onUpdate.call(this, event); + } + }, + onComplete: () => { + // create and dispatch event + //-------------------- + const event = Event$1.create( + elem, + from, + opts.eventTypes[2], + eventOpts + ); + if (this.opts.debug) + console.log('dispatch event', event); + elem.dispatchEvent(event); + + // onComplete + //-------------------- + if ( + opts.onComplete && + (opts.doubleCallbacks || key === 0) + ) { + opts.onComplete.call(this, event); + } + } + }; + + // to + //-------------------- + Object.assign(gsOpts, value.gsOpts); + + // drag animation + //-------------------- + TweenLite.to(from, opts.duration, gsOpts); + }); + }, + timelinePosition, + [position] + ); - }, timelinePosition, [position]); - this._actions++; return this @@ -7147,13 +7479,12 @@ /** * Sorts the parameters so that the second, third, and fourth parameters can be optional (and possibly slip forward). - * + * * @private * @param {arguments} params - The arguments which were passed to the function. * @returns {array} - Returns an array of the position, the timelinePosition and the opts object. */ reorderArguments(params) { - // first parameter //-------------------- const element = params[0]; @@ -7163,12 +7494,16 @@ let position = null; let timelinePosition = null; let opts = null; - + // second parameter //-------------------- if (Util.isNumber(params[1])) { timelinePosition = params[1]; - } else if (Util.isObject(params[1]) && !Util.isPixiDisplayObject(params[1]) && (params[1].x == null || params[1].y == null)) { + } else if ( + Util.isObject(params[1]) && + !Util.isPixiDisplayObject(params[1]) && + (params[1].x == null || params[1].y == null) + ) { opts = params[1]; } else if (params[1] != null) { position = params[1]; @@ -7190,9 +7525,13 @@ if (timelinePosition === null) { if (this.opts.defaultInterval === null && this._actions > 1) { - throw new Error('No execution time was specified for this action, and a default interval was not set in the class constructor!') + throw new Error( + 'No execution time was specified for this action, and a default interval was not set in the class constructor!' + ) } - timelinePosition = Math.max(...this._timelinePositions) + (this.opts.defaultInterval || 1); + timelinePosition = + Math.max(...this._timelinePositions) + + (this.opts.defaultInterval || 1); } if (opts === null) { @@ -7204,12 +7543,11 @@ /** * Converts event type shortcuts to real event names. - * + * * @private * @param {string[]} events - An array of event types. */ resolveEvents(events) { - const data = []; if (this.opts.eventType === 'pointer') { @@ -7260,34 +7598,35 @@ * @class */ class Util { - /** * Resolves the element from a specific context. - * + * * @static * @param {Window|Frame} context - The context within which the optionally specified element selector should be executed. * @return {HTMLElement|string} element - The HTML element on which the event is to be executed, e.g. button, document, h2, canvas, etc. or an selector string. If a selector has been specified, it is evaluated immediately before the event is called using the querySelector method. */ static extractElement(context, element) { - - const cont = Util.isFrame(context) ? context.contentDocument : context.document; - const elem = Util.isString(element) ? cont.querySelector(element) : element; + const cont = Util.isFrame(context) + ? context.contentDocument + : context.document; + const elem = Util.isString(element) + ? cont.querySelector(element) + : element; return elem } /** * Extracts the position of the second parameter. - * + * * @static * @param {object} object - Something were the coords should be extracted. * @return {object} - Returns an object with the keys x and y. */ static extractPosition(object) { - // event coords //-------------------- - const position = {x: 0, y: 0}; + const position = { x: 0, y: 0 }; // get the position //-------------------- @@ -7311,17 +7650,15 @@ /** * Extracts the to or bezier key. - * + * * @static * @param {object} opts - An options object where to or bezier should be extracted. * @return {object} - Returns an object with the to or bezier keys. */ static extractTo(opts) { - const object = {}; if (opts.bezier) { - let bezier = null; if (Array.isArray(opts.bezier)) { @@ -7330,7 +7667,9 @@ type: 'thru' }; } else { - opts.bezier.values = opts.bezier.values.map(it => Util.extractPosition(it)); + opts.bezier.values = opts.bezier.values.map(it => + Util.extractPosition(it) + ); bezier = opts.bezier; } @@ -7346,19 +7685,16 @@ /** * Extracts multiple to or bezier keys. - * + * * @static * @param {object} opts - An options object where to or bezier should be extracted. * @return {object[]} - Returns an array of objects with the keys x and y. */ static extractMultiTo(opts) { - const objects = []; if (opts.bezier) { - opts.bezier.forEach(it => { - let bezier = null; if (Array.isArray(it)) { @@ -7375,9 +7711,7 @@ bezier }); }); - } else { - opts.to.forEach(it => { const to = Util.extractPosition(it); objects.push({ @@ -7392,7 +7726,7 @@ /** * Checks if a thing is a string. - * + * * @static * @param {object} object - The object to test for. * @return {boolean} - true if the thing is a string, otherwise false. @@ -7403,7 +7737,7 @@ /** * Checks if a thing is a number. - * + * * @static * @param {object} object - The object to test for. * @return {boolean} - true if the thing is a number, otherwise false. @@ -7414,7 +7748,7 @@ /** * Checks if a thing is an object. - * + * * @static * @param {object} object - The object to test for. * @return {boolean} - true if the thing is an object, otherwise false. @@ -7425,18 +7759,22 @@ /** * Checks if a thing is an PIXI.DisplayObject. - * + * * @static * @param {object} object - The object to test for. * @return {boolean} - true if the thing is a PIXI.DisplayObject, otherwise false. */ static isPixiDisplayObject(object) { - return typeof object.getBounds === 'function' && typeof object.renderWebGL === 'function' && typeof object.setTransform === 'function' + return ( + typeof object.getBounds === 'function' && + typeof object.renderWebGL === 'function' && + typeof object.setTransform === 'function' + ) } /** * Checks if a thing is a frame. - * + * * @static * @param {object} object - The object to test for. * @return {boolean} - true if the thing is a frame, otherwise false. @@ -7458,19 +7796,25 @@ * @class */ class Event$1 { - /** * Creates an event object. - * + * * @static * @param {HTMLElement} target - The element on which the event should be executed. * @param {object} position - The local position of the event in relation to the target. The object must have the keys x and y. * @param {string} type - The type of the event, see https://developer.mozilla.org/de/docs/Web/Events * @param {object} opts - An options object. Every paramter of the event object can be overridden, see e.g. https://developer.mozilla.org/de/docs/Web/API/MouseEvent for all the properties. */ - static create(target, position = {x: 0, y: 0}, type = 'pointerup', opts = {}) { - - const rect = typeof target.getBoundingClientRect === 'function' ? target.getBoundingClientRect() : {x: 0, y: 0}; + static create( + target, + position = { x: 0, y: 0 }, + type = 'pointerup', + opts = {} + ) { + const rect = + typeof target.getBoundingClientRect === 'function' + ? target.getBoundingClientRect() + : { x: 0, y: 0 }; // EventInit const eventOpts = { @@ -7527,15 +7871,33 @@ }; if (type.startsWith('pointer')) { - return new PointerEvent(type, Object.assign({}, eventOpts, uiEventOpts, mouseEventOpts, pointerEventOpts, opts)) + return new PointerEvent( + type, + Object.assign( + {}, + eventOpts, + uiEventOpts, + mouseEventOpts, + pointerEventOpts, + opts + ) + ) } else if (type.startsWith('touch')) { - return new TouchEvent(type, Object.assign({}, eventOpts, uiEventOpts, touchEventOpts, opts)) + return new TouchEvent( + type, + Object.assign({}, eventOpts, uiEventOpts, touchEventOpts, opts) + ) } else { - return new MouseEvent(type, Object.assign({}, eventOpts, uiEventOpts, mouseEventOpts, opts)) + return new MouseEvent( + type, + Object.assign({}, eventOpts, uiEventOpts, mouseEventOpts, opts) + ) } } } + /** To avoid problems with relative URL paths, we use inline data URI to load svg icons. */ + /** * A class that collects static methods to maintain the states and parts of * EyeVisit like cards. @@ -7543,9 +7905,8 @@ * The class is used as a namespace and should never called with new. */ class Card { - static setup(context, modules = []) { - console.log("Setup Card...", modules); + console.log('Setup Card...', modules); context.modules = []; modules.forEach(module => { if (module.apply(context)) @@ -7566,7 +7927,7 @@ if (context.onClose) { context.onClose(event); } else context.parentNode.removeChild(context); - } else console.error("Could not find context!", event.target); + } else console.error('Could not find context!', event.target); } /** @@ -7581,7 +7942,6 @@ static _replaceAttributes(html, attribute, replaceFunc) { let clickables = html.querySelectorAll(`[${attribute}]`); clickables.forEach(element => { - let attributeVal = element.getAttribute(attribute); element.removeAttribute(attribute); replaceFunc.call(this, element, attributeVal); @@ -7589,33 +7949,33 @@ } /** - * Replaces the onClick callback of the element with an - * Interaction mapper event. - * - * @static - * @param {*} element - * @param {*} attributeVal - * @returns - * @memberof Card - */ + * Replaces the onClick callback of the element with an + * Interaction mapper event. + * + * @static + * @param {*} element + * @param {*} attributeVal + * @returns + * @memberof Card + */ static _replaceCallback(element, attributeVal) { - - if (element.tagName == "A") { - element.addEventListener("click", event => { event.preventDefault(); }); + if (element.tagName == 'A') { + element.addEventListener('click', event => { + event.preventDefault(); + }); } - - let callbackParts = attributeVal.split("("); + let callbackParts = attributeVal.split('('); let funcPart = callbackParts[0].trim(); let trimmedArgs = callbackParts[1].trim(); //Remove the closing ')' trimmedArgs = trimmedArgs.substring(0, trimmedArgs.length - 1); - - let callParts = funcPart.split("."); - let argsStrings = trimmedArgs.split(",").filter(entry => { return entry.trim() != "" }); - + let callParts = funcPart.split('.'); + let argsStrings = trimmedArgs.split(',').filter(entry => { + return entry.trim() != '' + }); let callStack = window; do { @@ -7628,28 +7988,24 @@ //Remove the events on the circle. // These are 'hardcoded' inside the convert.js. - if (element.tagName == "circle") return false - - - InteractionMapper.on(interactionType, element, (event) => { + if (element.tagName == 'circle') return false + InteractionMapper.on(interactionType, element, event => { /** * Replaces the strings from the listener with the cooresponding variables. */ let args = []; argsStrings.forEach(arg => { arg = arg.trim(); - if (arg == "this") - args.push(event.target); - else if (arg == "event") - args.push(event); + if (arg == 'this') args.push(event.target); + else if (arg == 'event') args.push(event); else { const firstCharacter = arg[0]; - if (firstCharacter == "\"" || firstCharacter == "'") { + if (firstCharacter == '"' || firstCharacter == "'") { arg = arg.substring(1); } const lastCharacter = arg[arg.length - 1]; - if (lastCharacter == "\"" || lastCharacter == "'") { + if (lastCharacter == '"' || lastCharacter == "'") { arg = arg.substring(0, arg.length - 1); } @@ -7657,15 +8013,16 @@ } }); event.stopPropagation(); - if (callStack) - callStack.call(that, ...args); + if (callStack) callStack.call(that, ...args); else { - console.error("Could not call callback function " + attributeVal, ...args); + console.error( + 'Could not call callback function ' + attributeVal, + ...args + ); } }); } - /** * Transform the relative links to absolute ones. * @@ -7684,23 +8041,27 @@ This RegEx finds all requested tags[1], and all requested attributes[3] and replaces the relative path [4] with the absolute one. while all other attributes [2],[5] are preserved. */ - return html.replace(/<\s*(a|video|img|image|circle)\s(.*?)(xlink:href|href|src)\s*=\s*["'](\..*?)["']\s*(.*?)>/g, function (data) { - let path = that._getRelativePath(arguments[4]); - const tag = `<${arguments[1]} ${arguments[2]} ${arguments[3]}="${path}" ${arguments[5]}>`; - /* if (that.debug) */ console.log("Adjusted: ", tag); - return tag - }) + return html.replace( + /<\s*(a|video|img|image|circle)\s(.*?)(xlink:href|href|src)\s*=\s*["'](\..*?)["']\s*(.*?)>/g, + function(data) { + let path = that._getRelativePath(arguments[4]); + const tag = `<${arguments[1]} ${arguments[2]} ${ + arguments[3] + }="${path}" ${arguments[5]}>`; + /* if (that.debug) */ console.log('Adjusted: ', tag); + return tag + } + ) } /** * Concats the given path with the relative path specified in the Card (as static variable). */ static _getRelativePath(src) { - let path = (this.relativePath != "") ? this.relativePath + "/" + src : src; + let path = this.relativePath != '' ? this.relativePath + '/' + src : src; return path } - /** * Loads the card text using an ajax request. * @@ -7713,7 +8074,7 @@ return new Promise((resolve, reject) => { let request = new XMLHttpRequest(); - request.onreadystatechange = function () { + request.onreadystatechange = function() { if (this.readyState == 4) { if (this.status == 200 || Card._isLocal()) { try { @@ -7721,11 +8082,14 @@ } catch (e) { reject(e); } - } else reject(`Request failed '${path}'. Returned status ${this.status} and ready state ${this.readyState}.`); + } else + reject( + `Request failed '${path}'. Returned status ${this.status} and ready state ${this.readyState}.` + ); } }; - request.open("GET", path, true); + request.open('GET', path, true); request.send(); }) } @@ -7734,7 +8098,7 @@ * TODO: Maybe put this in a utility script. */ static _isLocal() { - return (window.location.protocol == "file:") + return window.location.protocol == 'file:' } /** @@ -7759,8 +8123,7 @@ */ static closestWithClass(node, klass) { if (node && node.classList) { - if (node.classList.contains(klass)) - return node + if (node.classList.contains(klass)) return node return this.closestWithClass(node.parentNode, klass) } return null @@ -7797,10 +8160,10 @@ * @param {string} [effectAllowed="all"] * @memberof Card */ - static dragStart(event, type = "card", effectAllowed = 'all') { + static dragStart(event, type = 'card', effectAllowed = 'all') { event.dataTransfer.effectAllowed = effectAllowed; let html = event.target.outerHTML; - event.dataTransfer.setData("text/html", html); + event.dataTransfer.setData('text/html', html); // https://stackoverflow.com/questions/11065803/determine-what-is-being-dragged-from-dragenter-dragover-events event.dataTransfer.setData('iwmbrowser/' + type, ''); } @@ -7816,11 +8179,11 @@ * @memberof Card */ static _openPopup(context, src, position, content, options = {}) { - if (this.debug) console.log("Card._openPopup", position); + if (this.debug) console.log('Card._openPopup', position); //logging if (src) { - let strparts = src.split("/"); + let strparts = src.split('/'); let cardID = strparts[strparts.length - 2]; let cardName = strparts[strparts.length - 1]; //console.log('open popup:',cardID,cardName,context,content) @@ -7835,38 +8198,41 @@ delete options.highlight; } - this._createPopup(context, position, content, options).then((popup) => { - if ( - //Test if meanwhile another popup was registered... - this._getPopup(context) || - // Or if an highlight was loaded, if the highlight already was closed. - highlight !== null && !this._isHighlightActive(context, highlight) - ) { - //.. if so remove the create popup instantly. - popup.remove(); - } else { - // Otherwise set the popup regularly. - let popupParagraphs = popup.element.querySelectorAll(".popupContent > *"); + this._createPopup(context, position, content, options) + .then(popup => { + if ( + //Test if meanwhile another popup was registered... + this._getPopup(context) || + // Or if an highlight was loaded, if the highlight already was closed. + (highlight !== null && + !this._isHighlightActive(context, highlight)) + ) { + //.. if so remove the create popup instantly. + popup.remove(); + } else { + // Otherwise set the popup regularly. + let popupParagraphs = popup.element.querySelectorAll( + '.popupContent > *' + ); - // Remove a design error of naming two adjacent elements popup. - // Todo: fix this properly and remove this code. - // let unnecessaryPopupElement = popup.element.querySelector(".popupContent > .popup") - // unnecessaryPopupElement.classList.remove("popup") + // Remove a design error of naming two adjacent elements popup. + // Todo: fix this properly and remove this code. + // let unnecessaryPopupElement = popup.element.querySelector(".popupContent > .popup") + // unnecessaryPopupElement.classList.remove("popup") - popupParagraphs.forEach(popupParagraph => { - popupParagraph.setAttribute("draggable", false); - popupParagraph.addEventListener("mousedown", (event) => { - event.preventDefault(); + popupParagraphs.forEach(popupParagraph => { + popupParagraph.setAttribute('draggable', false); + popupParagraph.addEventListener('mousedown', event => { + event.preventDefault(); + }); }); - }); - - this._setPopup(context, popup, src); - } - }).catch(e => console.error(e)); + this._setPopup(context, popup, src); + } + }) + .catch(e => console.error(e)); } - /** * Closes a provided popup and unsets it on the context. * @@ -7877,12 +8243,12 @@ */ static closePopup(context, popup) { if (popup) { - if (this.debug) console.log("Close Popup.", context, popup); + if (this.debug) console.log('Close Popup.', context, popup); window.popup = popup; popup.close(); this._unsetPopup(context); } else { - console.error("Requested to close popup, but popup was not found."); + console.error('Requested to close popup, but popup was not found.'); } } @@ -7898,27 +8264,33 @@ * @memberof Card */ static _createPopup(context, position, content, options = {}) { - - if (this.debug) console.log("Create Popup.", context, position, content, options); - let popup = new Popup(Object.assign({ - parent: context, - content - }, Object.assign({ - noStyle: true, - // TODO: Remove offset when positioning according to element position - // is working. - posOffset: 10 - }, options))); + if (this.debug) + console.log('Create Popup.', context, position, content, options); + let popup = new Popup( + Object.assign( + { + parent: context, + content + }, + Object.assign( + { + noStyle: true, + // TODO: Remove offset when positioning according to element position + // is working. + posOffset: 10 + }, + options + ) + ) + ); // Placing the popup when it required loading, // it resulted in flahing up at the default position. // We manually prevent this here. - popup.element.style.display = "none"; + popup.element.style.display = 'none'; - - let promise = new Promise((resolve) => { - if (popup.loaded) - resolve(popup); + let promise = new Promise(resolve => { + if (popup.loaded) resolve(popup); else { popup.onload = () => { resolve(popup); @@ -7926,10 +8298,9 @@ } }); - promise.then((popup) => { - - popup.element.style.display = "block"; - popup.element.style.visibility = "hidden"; + promise.then(popup => { + popup.element.style.display = 'block'; + popup.element.style.visibility = 'hidden'; popup.element.style.opacity = 0; popup.placeAt(position); @@ -7946,15 +8317,12 @@ autoAlpha: 1, ease: Power2.easeIn }); - }); return promise } - static _overlayCleanup(context, overlay) { - /** * The cleanup functionality is now covered by the _cleanup function. * It cleans up zoomables, popups and open image highlights. @@ -7963,7 +8331,8 @@ */ if (overlay) { TweenLite.to(overlay, 0.2, { - autoAlpha: 0, onComplete: () => { + autoAlpha: 0, + onComplete: () => { popup.remove(); //this._cleanup(context) //overlay.parentNode.removeChild(overlay) @@ -7981,7 +8350,6 @@ * @memberof Card */ static loadPopup(event, context = null, node = null, local = null) { - let editable = Card.isEditable(); if (context == null) { context = this.getContext(event.target); @@ -7990,33 +8358,33 @@ node = event.target; } if (local == null) { - let globalClick = (event.center) ? event.center : { x: event.x, y: event.y }; + let globalClick = event.center + ? event.center + : { x: event.x, y: event.y }; local = Points.fromPageToNode(context, globalClick); } - if (this.debug) console.log("loadPopup", event); + if (this.debug) console.log('loadPopup', event); // Prevents loading the link in the current tab. // Prevents loading the link in the current tab. - if (event.type != "Follow") - event.preventDefault(); + if (event.type != 'Follow') event.preventDefault(); if (editable && event.type == 'click') { return false } let overlay = document.createElement('div'); - let src = node.getAttribute("href"); + let src = node.getAttribute('href'); let parentArticle = node.closest('article'); const that = this; let xhr = new XMLHttpRequest(); xhr.open('get', src, true); xhr.onreadystatechange = () => { - - if (this.debug) console.log("Popup Source: ", src); + if (this.debug) console.log('Popup Source: ', src); if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0)) { if (editable) { - if (this.debug) console.log("Append overlay.", context); + if (this.debug) console.log('Append overlay.', context); overlay.classList.add('overlay'); TweenLite.set(overlay, { autoAlpha: 0 }); context.appendChild(overlay); @@ -8025,11 +8393,17 @@ // Extract the body from the Popup site. let parser = new DOMParser(); - let popupPage = parser.parseFromString(xhr.responseText, "text/html"); + let popupPage = parser.parseFromString( + xhr.responseText, + 'text/html' + ); //Fix the relative path of loaded images in the popup. - popupPage.querySelectorAll("img").forEach(node => { - node.setAttribute("src", that._getRelativePath(node.getAttribute("src"))); + popupPage.querySelectorAll('img').forEach(node => { + node.setAttribute( + 'src', + that._getRelativePath(node.getAttribute('src')) + ); }); let html = popupPage.body.innerHTML; /** @@ -8047,17 +8421,22 @@ let selector = Card.popupHtmlSelector; let content = { html, selector }; - let isSame = Card._checkForActiveSource(context, src); Card._cleanup(context); - if (!isSame) { - Card._activateCorrespondingHighlights(context, node, parentArticle); - + Card._activateCorrespondingHighlights( + context, + node, + parentArticle + ); let callback = (popup, callback) => { - if (this.debug) console.log("Close popup (Editable = " + editable + ").", popup); + if (this.debug) + console.log( + 'Close popup (Editable = ' + editable + ').', + popup + ); if (editable) { let isDirty = mainController.askSaveNode(); if (isDirty) @@ -8075,9 +8454,8 @@ this._overlayCleanup(context, overlay); } mainController.popController(); - } - /** This may be in conflice with the cleanup method. */ - else { + } else { + /** This may be in conflice with the cleanup method. */ //this._overlayCleanup(context, overlay) popup.remove(); } @@ -8090,12 +8468,12 @@ } overlay.onclick = e => { - if (editable) - e.preventDefault(); + if (editable) e.preventDefault(); }; //console.log("onreadystatechange", editable) if (editable) { - if (this.debug) console.log("pushController", src, popup.insertedNode); + if (this.debug) + console.log('pushController', src, popup.insertedNode); mainController.pushController(popup.insertedNode, src); } }; @@ -8104,15 +8482,15 @@ } /** - * When an highlight link is clicked, this method activates all - * corresponding highlights. - * - * @static - * @param {DomElement} context - The context of the element. - * @param {DomElement} node - The node that (may) contain a highlightId. - * @param {DomElement} parent - The parent element that may contain more highlightIds. - * @memberof Card - */ + * When an highlight link is clicked, this method activates all + * corresponding highlights. + * + * @static + * @param {DomElement} context - The context of the element. + * @param {DomElement} node - The node that (may) contain a highlightId. + * @param {DomElement} parent - The parent element that may contain more highlightIds. + * @memberof Card + */ static _activateCorrespondingHighlights(context, node, parent) { let highlightId = node.getAttribute('data-highlight-id'); // console.log("Request Highlight: " + highlightId) @@ -8125,8 +8503,13 @@ } if (correspondingHighlights.length > 0) { for (let highlight of correspondingHighlights) { - if (highlight.parentNode && highlight.parentNode.nodeName.toLowerCase() == 'g') { - Highlight.openHighlight(highlight, { animation: Card.highlightAnimation }); + if ( + highlight.parentNode && + highlight.parentNode.nodeName.toLowerCase() == 'g' + ) { + Highlight.openHighlight(highlight, { + animation: Card.highlightAnimation + }); this._addHighlight(context, highlight); } } @@ -8135,16 +8518,15 @@ } /** - * Tests if any open item already contains the requested Source. - * - * @static - * @param {DomElement} context - Dom context we are in. - * @param {string} src - Source as dataUrl. - * @returns {boolean} - True if source is already active, false otherwise. - * @memberof Card - */ + * Tests if any open item already contains the requested Source. + * + * @static + * @param {DomElement} context - Dom context we are in. + * @param {string} src - Source as dataUrl. + * @returns {boolean} - True if source is already active, false otherwise. + * @memberof Card + */ static _checkForActiveSource(context, src) { - let requestedSame = false; let activePopup = Card._getPopup(context); let activeHighlights = Card._getHighlights(context); @@ -8178,8 +8560,7 @@ * @memberof Card */ static loadHighlightPopup(event) { - - if (this.debug) console.log("Load Highlight Popup: ", event); + if (this.debug) console.log('Load Highlight Popup: ', event); let node; if (event.firstTarget) { node = event.firstTarget; @@ -8190,10 +8571,10 @@ event.stopPropagation(); /** - * This node is the documents body, as events wont work - * on svg elements properly. We need a workaround for that. - */ - let src = node.getAttribute("xlink:href"); + * This node is the documents body, as events wont work + * on svg elements properly. We need a workaround for that. + */ + let src = node.getAttribute('xlink:href'); let isSame = this._checkForActiveSource(context, src); this._cleanup(context); @@ -8204,11 +8585,11 @@ animation: Card.highlightAnimation, onExpanded: () => { // We assume it's always a circle. This may break, when other svg shapes are used. - let x = node.getAttribute("cx"); - let y = node.getAttribute("cy"); + let x = node.getAttribute('cx'); + let y = node.getAttribute('cy'); let position = { x, y }; - let radius = parseFloat(node.getAttribute("r")); + let radius = parseFloat(node.getAttribute('r')); /* As the popup is appended directly to the card. We have to @@ -8216,7 +8597,7 @@ card space. */ - let svgRoot = node.closest("svg"); + let svgRoot = node.closest('svg'); let svgPoint = svgRoot.createSVGPoint(); svgPoint.x = position.x; @@ -8224,7 +8605,10 @@ let matrix = node.getCTM(); let point = svgPoint.matrixTransform(matrix); - let global = Points.fromNodeToPage(node.closest("div"), point); + let global = Points.fromNodeToPage( + node.closest('div'), + point + ); let local = Points.fromPageToNode(context, global); let overlay = document.createElement('div'); @@ -8246,35 +8630,40 @@ } }); }) - .catch(err => { console.error(err); }); + .catch(err => { + console.error(err); + }); } }); } } /** - * Loads the popup from a provided source. - * - * @static - * @private - * @param {string} source - Url to a popup file. - * @returns {Promise} - Returns a promise, that's resolved when the data is loaded. - * @memberof Card - */ + * Loads the popup from a provided source. + * + * @static + * @private + * @param {string} source - Url to a popup file. + * @returns {Promise} - Returns a promise, that's resolved when the data is loaded. + * @memberof Card + */ static _loadPopupContent(source) { return new Promise((resolve, reject) => { let xhr = new XMLHttpRequest(); xhr.open('get', source, true); xhr.onreadystatechange = () => { if (xhr.readyState == 4) { - - if ((xhr.status == 200 || xhr.status == 0)) { - let html = this.postProcessResponseText(xhr.responseText); + if (xhr.status == 200 || xhr.status == 0) { + let html = this.postProcessResponseText( + xhr.responseText + ); let selector = Card.popupHtmlSelector; let content = { html: html.body.innerHTML, selector }; resolve(content); } else { - reject(` Popup request failed (Code: ${xhr.status}): Could not load resource: ${src}`); + reject( + ` Popup request failed (Code: ${xhr.status}): Could not load resource: ${src}` + ); } } }; @@ -8283,7 +8672,6 @@ } static openZoomable(event) { - let node = event.target; //console.log("Open zoomable: ", node, node.classList) @@ -8297,7 +8685,6 @@ this._openZoomable(event); } - /** * Retrieve a Rectangle object from the a given zoomable. * @@ -8308,8 +8695,6 @@ * @memberof Card */ static zoomableCurrentGeometry(zoomable, wrapper) { - - /* I don't think it's wise, that the zoomable calculation relies on some icon that may or may not be present. When the same calculation can be @@ -8318,12 +8703,12 @@ */ //The div is cloned and animated, therefore we need it's style! - let actuallyZoomedItem = zoomable.querySelector("div"); + let actuallyZoomedItem = zoomable.querySelector('div'); let zoomableStyle = window.getComputedStyle(actuallyZoomedItem); - let svgElement = zoomable.querySelector("svg"); - let videoElement = zoomable.querySelector("video"); + let svgElement = zoomable.querySelector('svg'); + let videoElement = zoomable.querySelector('video'); let curStyle = null; if (svgElement) { curStyle = window.getComputedStyle(svgElement); @@ -8343,21 +8728,29 @@ globalBottomRight = Points.fromNodeToPage(zoomable, globalBottomRight); let globalFigurePos = Points.fromNodeToPage(zoomable, { x: 0, y: 0 }); let localFigurePos = Points.fromPageToNode(wrapper, globalFigurePos); - let relativeBottomRight = Points.fromPageToNode(zoomable, globalBottomRight); + let relativeBottomRight = Points.fromPageToNode( + zoomable, + globalBottomRight + ); - let width = relativeBottomRight.x + parseFloat(zoomableStyle.borderLeftWidth) + parseFloat(zoomableStyle.borderRightWidth);/*+ zoomIconRight*/ - let height = relativeBottomRight.y + parseFloat(zoomableStyle.borderTopWidth) + parseFloat(zoomableStyle.borderBottomWidth); /*+ zoomIconRight*/ + let width = + relativeBottomRight.x + + parseFloat(zoomableStyle.borderLeftWidth) + + parseFloat(zoomableStyle.borderRightWidth); /*+ zoomIconRight*/ + let height = + relativeBottomRight.y + + parseFloat(zoomableStyle.borderTopWidth) + + parseFloat(zoomableStyle.borderBottomWidth); /*+ zoomIconRight*/ return { x: localFigurePos.x, y: localFigurePos.y, width, height } } - /** - * Opens a zoomable object, which can be a figure containing an image or video or an image group - * - * @static - * @param {any} event - The trigger event, typically a click event - * @memberof Card - */ + * Opens a zoomable object, which can be a figure containing an image or video or an image group + * + * @static + * @param {any} event - The trigger event, typically a click event + * @memberof Card + */ static _openZoomable(event, editable = false) { event.stopPropagation(); let node = event.target; @@ -8378,7 +8771,7 @@ // Clone the zoomable and create a clone that is zoomed instead. let current = this.zoomableCurrentGeometry(zoomable, wrapper); let zoomedFig = zoomable.cloneNode(true); - let caption = zoomedFig.querySelector("figcaption.cap"); + let caption = zoomedFig.querySelector('figcaption.cap'); caption.parentNode.removeChild(caption); this._toggleNextIcon(zoomedFig); this._setZoomable(wrapper, zoomable, zoomedFig); @@ -8390,9 +8783,9 @@ * -SO */ let zoomContainer = document.createElement('div'); - zoomContainer.classList.add("zoomable-wrapper"); + zoomContainer.classList.add('zoomable-wrapper'); Object.assign(zoomContainer.style, { - position: "absolute", + position: 'absolute', top: 0, left: 0, zIndex: 200 @@ -8404,8 +8797,7 @@ zoomedFig.className = 'zoomed-figure'; zoomedFig.style.zIndex = this.zIndices.zoomedFigure; let zoomedG = zoomedFig.querySelector('g'); - if (zoomedG && !editable) - zoomedG.parentNode.removeChild(zoomedG); + if (zoomedG && !editable) zoomedG.parentNode.removeChild(zoomedG); zoomContainer.appendChild(zoomedFig); let zoomedImg = zoomedFig.querySelector('.mainimg'); @@ -8416,18 +8808,18 @@ zoomedFig.zoomableGeometry = current; //play video - let videoElement = zoomedFig.querySelector("video"); + let videoElement = zoomedFig.querySelector('video'); if (videoElement) { videoElement.play(); } //logging - let imgElt = zoomedFig.querySelector("image"); - let videoElt = zoomedFig.querySelector("video"); + let imgElt = zoomedFig.querySelector('image'); + let videoElt = zoomedFig.querySelector('video'); //console.log('open zoomable:',imgElt,videoElt) if (imgElt) { let imgSrc = imgElt.getAttribute('xlink:href'); - let strparts = imgSrc.split("/"); + let strparts = imgSrc.split('/'); let cardID = strparts[strparts.length - 2]; let cardName = strparts[strparts.length - 1]; let msg = 'ShowImage: ' + cardID + '/' + cardName; @@ -8436,7 +8828,7 @@ } if (videoElt) { let videoSrc = videoElt.getAttribute('src'); - let strparts = videoSrc.split("/"); + let strparts = videoSrc.split('/'); let cardID = strparts[strparts.length - 2]; let cardName = strparts[strparts.length - 1]; let msg = 'ShowVideo: ' + cardID + '/' + cardName; @@ -8448,14 +8840,17 @@ // It's just an indicator that an action is possible. The click must be // captured from the whole subcard. - InteractionMapper.on(this.interactionType, zoomedFig, (event) => { + InteractionMapper.on(this.interactionType, zoomedFig, event => { this._cleanup(wrapper); }); let zoomedFigStyle = window.getComputedStyle(zoomedFig); - let borderX = parseFloat(zoomedFigStyle.borderLeftWidth) + parseFloat(zoomedFigStyle.borderRightWidth); - let borderY = parseFloat(zoomedFigStyle.borderBottomWidth) + parseFloat(zoomedFigStyle.borderTopWidth); - + let borderX = + parseFloat(zoomedFigStyle.borderLeftWidth) + + parseFloat(zoomedFigStyle.borderRightWidth); + let borderY = + parseFloat(zoomedFigStyle.borderBottomWidth) + + parseFloat(zoomedFigStyle.borderTopWidth); const scaleFactor = 2; const transformOrigin = 'bottom right'; @@ -8469,49 +8864,66 @@ }); TweenLite.set(zoomable, { opacity: 0 }); - let icon = zoomedFig.querySelector(".icon"); + let icon = zoomedFig.querySelector('.icon'); TweenLite.set(icon, { transformOrigin }); - zoomedFig.style.transformOrigin = "calc(100% - " + parseFloat(zoomedFigStyle.borderRightWidth) + "px) calc(100% - " + parseFloat(zoomedFigStyle.borderBottomWidth) + "px)"; - + zoomedFig.style.transformOrigin = + 'calc(100% - ' + + parseFloat(zoomedFigStyle.borderRightWidth) + + 'px) calc(100% - ' + + parseFloat(zoomedFigStyle.borderBottomWidth) + + 'px)'; let tl = new TimelineLite(); - let zoomCaption = zoomedFig.querySelector(".zoomcap"); + let zoomCaption = zoomedFig.querySelector('.zoomcap'); - tl.to(zoomedFig, Card.animation.zoomable, { - ease: Power2.easeIn, - css: { - scaleX: scaleFactor, - scaleY: scaleFactor - } - }, 0).set(zoomCaption, { - css: { - display: "block", - opacity: 0, - x: -parseFloat(zoomedFigStyle.borderLeftWidth), - width: current.width + borderX - } - }).to(zoomCaption, this.animation.fade, { - autoAlpha: 1 - }); - - } else this._openZoomableEditorBehaviour(wrapper, img, zoomable, zoomedFig, current); + tl.to( + zoomedFig, + Card.animation.zoomable, + { + ease: Power2.easeIn, + css: { + scaleX: scaleFactor, + scaleY: scaleFactor + } + }, + 0 + ) + .set(zoomCaption, { + css: { + display: 'block', + opacity: 0, + x: -parseFloat(zoomedFigStyle.borderLeftWidth), + width: current.width + borderX + } + }) + .to(zoomCaption, this.animation.fade, { + autoAlpha: 1 + }); + } else + this._openZoomableEditorBehaviour( + wrapper, + img, + zoomable, + zoomedFig, + current + ); } /** - * Selects and transforms the zoomicon from a zoomicon to a closeicon - * or the other way around. - * - * @static - * @param {DomElement} parent - Parent to be searched for an zoomicon. - * @memberof Card - */ + * Selects and transforms the zoomicon from a zoomicon to a closeicon + * or the other way around. + * + * @static + * @param {DomElement} parent - Parent to be searched for an zoomicon. + * @memberof Card + */ static _toggleNextIcon(parent) { let zoomIcon = Card._findNextIcon(parent); - const closeClass = "close"; - const zoomClass = "zoom"; + const closeClass = 'close'; + const zoomClass = 'zoom'; if (zoomIcon.classList.contains(closeClass)) { zoomIcon.classList.remove(closeClass); @@ -8520,7 +8932,9 @@ zoomIcon.classList.remove(zoomClass); zoomIcon.classList.add(closeClass); } else { - console.error(`Error Toggleing Zoomicon: It did neither contain a class named ${closeClass} or ${zoomClass}.`); + console.error( + `Error Toggleing Zoomicon: It did neither contain a class named ${closeClass} or ${zoomClass}.` + ); } } @@ -8528,9 +8942,13 @@ return parent.querySelector('.icon') } - - static _openZoomableEditorBehaviour(wrapper, img, zoomable, zoomedFig, current) { - + static _openZoomableEditorBehaviour( + wrapper, + img, + zoomable, + zoomedFig, + current + ) { let zoomContainer = document.createElement('div'); let zoomIcon = zoomable.querySelector('.zoom-icon'); zoomContainer.style.position = 'relative'; @@ -8540,7 +8958,12 @@ zoomParent.appendChild(zoomedFig); zoomedFig.style.opacity = 0.5; zoomContainer.appendChild(zoomable); - TweenLite.set(zoomable, { x: current.x, y: current.y, width: current.width, height: current.height }); + TweenLite.set(zoomable, { + x: current.x, + y: current.y, + width: current.width, + height: current.height + }); let editor = mainController.topController().ensureEditor(img); let savedDisplay = zoomIcon.style.display; let iconClone = zoomIcon.cloneNode(true); @@ -8578,7 +9001,10 @@ event.preventDefault(); let dx = event.pageX - zoomable.dragStartPos.x; let dy = event.pageY - zoomable.dragStartPos.y; - TweenLite.set([zoomable, iconClone], { x: '+=' + dx, y: '+=' + dy }); + TweenLite.set([zoomable, iconClone], { + x: '+=' + dx, + y: '+=' + dy + }); zoomable.dragStartPos = { x: event.pageX, y: event.pageY }; if (editor) { editor.showControls(); @@ -8605,7 +9031,6 @@ return } - /** * Closes a zoomable object with animation * @@ -8617,19 +9042,18 @@ * @memberof Card */ static closeZoomable(context, zoomable, zoomedFig) { - - if (this.debug) console.log("Close Zoomable", context, zoomable, zoomedFig); + if (this.debug) + console.log('Close Zoomable', context, zoomable, zoomedFig); if (zoomable) { this._unsetZoomable(context); - let caption = zoomable.querySelector("figcaption.cap"); + let caption = zoomable.querySelector('figcaption.cap'); zoomable.removeChild(caption); zoomable.appendChild(caption); - let zoomedCaption = zoomedFig.querySelector("figcaption.zoomcap"); - + let zoomedCaption = zoomedFig.querySelector('figcaption.zoomcap'); TweenLite.to(zoomedCaption, this.animation.fade, { - autoAlpha: 0, + autoAlpha: 0 }); TweenLite.to(zoomedFig, this.animation.zoomable, { @@ -8643,8 +9067,7 @@ }); let div = zoomedFig.parentNode; let videoElement = div.querySelector('video'); - if (videoElement) - videoElement.pause(); + if (videoElement) videoElement.pause(); div.parentNode.removeChild(div); } }); @@ -8671,7 +9094,13 @@ * @param {*} src - The src of the expanded element * @param {*} callback - A callback that is called when the expanded element is closed */ - static expandIndexCard(card, html, tagName = 'article', src = null, callback = null) { + static expandIndexCard( + card, + html, + tagName = 'article', + src = null, + callback = null + ) { let editable = Card.isEditable(); let context = this.getContext(card); @@ -8679,35 +9108,35 @@ this._cleanup(context); - let angle = 0; // UO: out of context, to be computed from the scatter let clone = card.cloneNode(true); - /** * We have to reorder the clone, as it still contains the * preview text image. And the new html is * inserted before everything else. */ - let cloneWrapper = clone.querySelector(".wrapper"); - const article = html.body.querySelector("article"); + let cloneWrapper = clone.querySelector('.wrapper'); + const article = html.body.querySelector('article'); - let subcardContent = clone.querySelector(".subcard-content"); + let subcardContent = clone.querySelector('.subcard-content'); subcardContent.appendChild(article); cloneWrapper.parentNode.removeChild(cloneWrapper); /* Removes the 'default' cleanup on the card */ - clone.removeAttribute("onclick"); - InteractionMapper.on(this.interactionType, clone, (event) => { + clone.removeAttribute('onclick'); + InteractionMapper.on(this.interactionType, clone, event => { this._cleanup(context); }); let articleClone = clone.querySelector(tagName); - let globalPreviewRect = Card._getGlobalRect(card); let globalIndexCardRect = Card._getGlobalRect(indexbox); - let localOrigin = Points.fromPageToNode(indexbox, Rect.getPosition(globalPreviewRect)); + let localOrigin = Points.fromPageToNode( + indexbox, + Rect.getPosition(globalPreviewRect) + ); let scaleX = globalPreviewRect.width / globalIndexCardRect.width; let scaleY = globalPreviewRect.height / globalIndexCardRect.height; @@ -8737,12 +9166,12 @@ scaleX, scaleY, transformOrigin: '0% 0%', - rotation: angle, + rotation: angle }); indexbox.prepend(clone); - let titlebar = clone.querySelector(".titlebar"); - let title = titlebar.querySelector("h2"); + let titlebar = clone.querySelector('.titlebar'); + let title = titlebar.querySelector('h2'); let titlebarStyle = window.getComputedStyle(titlebar); let start = { height: parseInt(titlebarStyle.height) @@ -8751,7 +9180,7 @@ if (this.dynamicHeight) { let targetHeight = subcardContent.offsetHeight; console.log(targetHeight); - subcardContent.classList.add("dynamic-height"); + subcardContent.classList.add('dynamic-height'); /** * Scale the content from 100% to it's target size. */ @@ -8764,23 +9193,29 @@ } //jquery hyphenate below - if (typeof($) != 'undefined') { - $('.column').not('.overview').children('p').hyphenate('de'); + if (typeof $ != 'undefined') { + $('.column') + .not('.overview') + .children('p') + .hyphenate('de'); } //logging if (src) { - let strparts = src.split("/"); + let strparts = src.split('/'); let cardID = strparts[strparts.length - 2]; let cardName = strparts[strparts.length - 1]; - strparts = card.className.split(" "); + strparts = card.className.split(' '); let cardType = strparts[1]; - let msg = 'Card: ' + cardID + ': openTopic: ' + cardType + ', ' + cardName; + let msg = + 'Card: ' + cardID + ': openTopic: ' + cardType + ', ' + cardName; console.log('Logging:', msg); Logging.log(msg); } - let desiredBorderBottomWidth = parseInt(window.getComputedStyle(titlebar).borderBottomWidth); + let desiredBorderBottomWidth = parseInt( + window.getComputedStyle(titlebar).borderBottomWidth + ); TweenLite.to(clone, Card.animation.articleTransition, { x: -padding, y: -padding, @@ -8788,20 +9223,21 @@ scale: 1, rotation: 0, onComplete: () => { - card.classList.add("visited"); + card.classList.add('visited'); }, onUpdateParams: ['{self}'], - onUpdate: (self) => { + onUpdate: self => { let transform = self.target._gsTransform; TweenLite.set(title, { scale: 1 / transform.scaleX }); TweenLite.set(titlebar, { - height: start.height * 1 / transform.scaleY + height: (start.height * 1) / transform.scaleY }); // Retain the border at same visual thickness. - titlebar.style.borderBottomWidth = desiredBorderBottomWidth / transform.scaleY + "px"; + titlebar.style.borderBottomWidth = + desiredBorderBottomWidth / transform.scaleY + 'px'; } }); @@ -8819,12 +9255,18 @@ const closeAnimation = () => { //logging if (src) { - let strparts = src.split("/"); + let strparts = src.split('/'); let cardID = strparts[strparts.length - 2]; let cardName = strparts[strparts.length - 1]; - strparts = card.className.split(" "); + strparts = card.className.split(' '); let cardType = strparts[1]; - let msg = 'Card: ' + cardID + ': closeTopic: ' + cardType + ', ' + cardName; + let msg = + 'Card: ' + + cardID + + ': closeTopic: ' + + cardType + + ', ' + + cardName; console.log('Logging:', msg); Logging.log(msg); } @@ -8834,9 +9276,9 @@ this._enableCardCloseButton(context); - let previewTitlebar = card.querySelector(".titlebar"); + let previewTitlebar = card.querySelector('.titlebar'); let titlebarStyle = window.getComputedStyle(previewTitlebar); - let titlebar = clone.querySelector(".titlebar"); + let titlebar = clone.querySelector('.titlebar'); TweenLite.to(titlebar, this.animation.articleTransition, { height: parseInt(titlebarStyle.height) @@ -8846,14 +9288,14 @@ autoAlpha: 0 }); - let title = titlebar.querySelector("h2"); + let title = titlebar.querySelector('h2'); let original = { height: parseInt(titlebarStyle.height) }; if (this.dynamicHeight) { TweenLite.to(subcardContent, this.animation.articleTransition, { - height: "100%" + height: '100%' }); } @@ -8867,21 +9309,19 @@ rotation: angle, onComplete: () => { // article.remove() - TweenLite.to(clone, this.animation.fade, - { - //delay: 0.2, - autoAlpha: 0, - onComplete: - () => { - if (editable) { - mainController.popController(); - } - clone.remove(); - } - }); + TweenLite.to(clone, this.animation.fade, { + //delay: 0.2, + autoAlpha: 0, + onComplete: () => { + if (editable) { + mainController.popController(); + } + clone.remove(); + } + }); }, - onUpdateParams: ["{self}"], - onUpdate: function (self) { + onUpdateParams: ['{self}'], + onUpdate: function(self) { let transform = self.target._gsTransform; TweenLite.set(title, { @@ -8889,11 +9329,12 @@ }); TweenLite.set(titlebar, { - height: original.height * 1 / transform.scaleY + height: (original.height * 1) / transform.scaleY }); // Retain the border at same visual thickness. - titlebar.style.borderBottomWidth = desiredBorderBottomWidth / transform.scaleY + "px"; + titlebar.style.borderBottomWidth = + desiredBorderBottomWidth / transform.scaleY + 'px'; } }); }; @@ -8902,16 +9343,22 @@ let iconClone = clone.querySelector('.card-icon'); if (iconClone == null) { - iconClone = clone.querySelector(".cardicon"); - console.warn("Legacy selector. Change it to 'card-icon' and find a more suitable name."); + iconClone = clone.querySelector('.cardicon'); + console.warn( + "Legacy selector. Change it to 'card-icon' and find a more suitable name." + ); } - if (iconClone.tagName == "img") { + if (iconClone.tagName == 'img') { iconClone.src = iconClone.src.replace('info.svg', 'close.svg'); } //console.log("ICON: ", iconClone) - iconClone.classList.remove("info"); - iconClone.classList.add("close", "view-button", "transparent-background"); + iconClone.classList.remove('info'); + iconClone.classList.add( + 'close', + 'view-button', + 'transparent-background' + ); // We append the icon clone to the subcard-content. // Then it's always on the content and not on the background @@ -8922,7 +9369,7 @@ // Use the 'tap' event for closing. // Otherwise the subcard cannot be closed, // when another subcard is touched. - InteractionMapper.on("tap", iconClone, () => { + InteractionMapper.on('tap', iconClone, () => { if (editable) { let isDirty = mainController.askSaveNode(); if (isDirty) { @@ -8930,12 +9377,10 @@ callback(url); closeAnimation(); }); - } - else { + } else { closeAnimation(); } - } - else { + } else { closeAnimation(); } }); @@ -8971,23 +9416,22 @@ static openIndexCard(event, src) { //console.log("openIndexCard", src) /* - * Called by the expandIndexCard(...) - */ + * Called by the expandIndexCard(...) + */ let target = event.target; - const saveCallback = (url) => { + const saveCallback = url => { let handler = `Card.openIndexCard(event, '${url}')`; - console.log("File has changed", target, handler); + console.log('File has changed', target, handler); //TODO If this is required, it should be accessing the interaction type. - target.setAttribute("onclick", handler); + target.setAttribute('onclick', handler); }; let context = this.getContext(target); let subcard = this._getSubcard(context); //console.log("openIndexCard", { context, subcard }) //Dont proceeed if a subcard is active - if (subcard != null) - return + if (subcard != null) return // In edit mode we only accept icon clicks let editable = Card.isEditable(); @@ -9011,7 +9455,13 @@ // card.insertAdjacentElement('afterbegin', article) // TweenLite.set(article, { autoAlpha: 0 }) - Card.expandIndexCard(card, parsedHTML, 'article', relativeSource, saveCallback); + Card.expandIndexCard( + card, + parsedHTML, + 'article', + relativeSource, + saveCallback + ); } }; xhr.onerror = () => { @@ -9020,24 +9470,22 @@ xhr.send(); } - static _selectCardCloseButton(context) { - return context.querySelector(".mainview > .button.close") + return context.querySelector('.mainview > .button.close') } static _enableCardCloseButton(context) { //console.log("ENABLE") let btn = this._selectCardCloseButton(context); //console.log(btn) - btn.classList.remove("disabled"); + btn.classList.remove('disabled'); } static _disableCardCloseButton(context) { let btn = this._selectCardCloseButton(context); - btn.classList.add("disabled"); + btn.classList.add('disabled'); } - /** * Provides the nearest info-card of the provided item. * @@ -9047,10 +9495,12 @@ * @memberof Card */ static getContext(child) { - let dom = child.closest(".info-card"); + let dom = child.closest('.info-card'); if (!dom) { - dom = child.querySelector(".wrapper"); - console.warn("Change the 'wrapper' class to 'info-card' it's more suitable."); + dom = child.querySelector('.wrapper'); + console.warn( + "Change the 'wrapper' class to 'info-card' it's more suitable." + ); } return dom // (dom == null) ? document.body : dom } @@ -9063,7 +9513,6 @@ * @memberof Card */ static _cleanup(context) { - let [zoomable, zoomedFig] = this._getZoomable(context); if (zoomable && zoomedFig) { this.closeZoomable(context, zoomable, zoomedFig); @@ -9076,14 +9525,14 @@ let highlights = this._getHighlights(context); highlights.forEach(highlight => { - Highlight.closeHighlight(highlight, { animation: Card.highlightAnimation }); + Highlight.closeHighlight(highlight, { + animation: Card.highlightAnimation + }); }); this._unsetHighlights(context); } - - /** * Retrieves an Rectangle for an element in the local space of a provided context. * @@ -9097,7 +9546,10 @@ */ static _getContextRect(context, element) { let global = this._getGlobalRect(element); - let localPosition = Points.fromPageToNode(context, { x: global.x, y: global.y }); + let localPosition = Points.fromPageToNode(context, { + x: global.x, + y: global.y + }); return DOMRectReadOnly.fromRect({ x: localPosition.x, y: localPosition.y, @@ -9106,7 +9558,6 @@ }) } - /** * Gets a rectangle in global space for a provided element. * @@ -9131,37 +9582,37 @@ } /** - * Adjusts all links - * - * @static - * @param {*} htmlString - * @returns - * @memberof Card - */ + * Adjusts all links + * + * @static + * @param {*} htmlString + * @returns + * @memberof Card + */ static postProcessResponseText(htmlString) { let editable = this.isEditable(); htmlString = this._adjustRelativeLinks(htmlString); //console.log(htmlString) let parser = new DOMParser(); - let html = parser.parseFromString(htmlString, "text/html"); + let html = parser.parseFromString(htmlString, 'text/html'); if (!editable) { - this._replaceAttributes(html, "onclick", this._replaceCallback); + this._replaceAttributes(html, 'onclick', this._replaceCallback); } - let zoomableWrappers = html.querySelectorAll(".svg-wrapper"); + let zoomableWrappers = html.querySelectorAll('.svg-wrapper'); zoomableWrappers.forEach(wrapper => { - let svg = wrapper.querySelector("svg"); + let svg = wrapper.querySelector('svg'); Object.assign(wrapper.style, { - width: svg.getAttribute("width") + "px", - height: svg.getAttribute("height") + "px" + width: svg.getAttribute('width') + 'px', + height: svg.getAttribute('height') + 'px' }); }); - let zoomableVideoWrappers = html.querySelectorAll(".video-wrapper"); + let zoomableVideoWrappers = html.querySelectorAll('.video-wrapper'); zoomableVideoWrappers.forEach(wrapper => { - let video = wrapper.querySelector("video"); + let video = wrapper.querySelector('video'); Object.assign(wrapper.style, { - width: video.getAttribute("width") + "px", - height: video.getAttribute("height") + "px" + width: video.getAttribute('width') + 'px', + height: video.getAttribute('height') + 'px' }); }); @@ -9176,7 +9627,7 @@ */ static openPopupOrZoomable(event) { let target = this._preferFirstTarget(event); - if (target.tagName == "circle") { + if (target.tagName == 'circle') { Card.loadHighlightPopup(event); event.stopPropagation(); } else { @@ -9194,16 +9645,29 @@ if (event.target) { //let column = event.target.closest(".column") let indexbox = this.closestWithClass(card, 'mainview'); - if (indexbox != null) { // column != null || - let links = Array.from(indexbox.getElementsByTagName("a")); - let globalClick = (event.center) ? event.center : { x: event.x, y: event.y }; + if (indexbox != null) { + // column != null || + let links = Array.from(indexbox.getElementsByTagName('a')); + let globalClick = event.center + ? event.center + : { x: event.x, y: event.y }; let localClick = Points.fromPageToNode(indexbox, globalClick); let linkRects = links.map(link => { let rect = link.getBoundingClientRect(); let topLeft = Points.fromPageToNode(indexbox, rect); - let center = Points.fromPageToNode(indexbox, { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 }); - return { x: topLeft.x, y: topLeft.y, width: rect.width, height: rect.height, center, link } + let center = Points.fromPageToNode(indexbox, { + x: rect.x + rect.width / 2, + y: rect.y + rect.height / 2 + }); + return { + x: topLeft.x, + y: topLeft.y, + width: rect.width, + height: rect.height, + center, + link + } }); let distances = []; @@ -9221,9 +9685,16 @@ let closestLinkIndex = distances.indexOf(Math.min(...distances)); let closestLink = links[closestLinkIndex]; - console.log("finding closest links", closestLink, closestLink.getClientRects()); + console.log( + 'finding closest links', + closestLink, + closestLink.getClientRects() + ); - if (distances[closestLinkIndex] < 44 && closestLink.getAttribute("href")) { + if ( + distances[closestLinkIndex] < 44 && + closestLink.getAttribute('href') + ) { // Adapt context and local position let context = this.getContext(closestLink); let local = Points.fromPageToNode(context, globalClick); @@ -9236,16 +9707,14 @@ } } - /** * Evaluates an event, if it has a first target. If so it returns the first target, * otherwise it returns the target. */ static _preferFirstTarget(event) { - return (event.firstTarget) ? event.firstTarget : event.target + return event.firstTarget ? event.firstTarget : event.target } - /** * Getter, Setter and 'Unsetter' for the properties hooked onto the context element. */ @@ -9258,7 +9727,7 @@ this._setPopupSource(popup, source); context.popup = popup; - if (typeof($) != 'undefined') { + if (typeof $ != 'undefined') { //jquery hyphenate below console.log('hyphenated popup:', $('span').hyphenate('de')); } @@ -9269,11 +9738,11 @@ } static _setPopupSource(popup, source) { - popup.element.setAttribute("data-src", source); + popup.element.setAttribute('data-src', source); } static _getPopupSource(popup) { - return popup.element.getAttribute("data-src") + return popup.element.getAttribute('data-src') } static _unsetZoomable(context) { @@ -9285,20 +9754,20 @@ } static _getZoomable(context) { - return (context.zoomable) ? context.zoomable : [] + return context.zoomable ? context.zoomable : [] } /** - * Helper function to determine if a proided element is still - * an active highlight. - */ + * Helper function to determine if a proided element is still + * an active highlight. + */ static _isHighlightActive(context, element) { let highlights = this._getHighlights(context); - return (highlights.indexOf(element) != -1) + return highlights.indexOf(element) != -1 } static _getHighlights(context) { - return (context.highlights) ? context.highlights : [] + return context.highlights ? context.highlights : [] } static _addHighlight(context, highlight) { @@ -9311,11 +9780,11 @@ } static _getHighlightSource(highlight) { - return highlight.getAttribute("xlink:href") + return highlight.getAttribute('xlink:href') } static _getActiveSubcard(context) { - return context.querySelector(".mainview > .subcard") + return context.querySelector('.mainview > .subcard') } static _setSubcard(context, subcard) { @@ -9337,7 +9806,7 @@ } static getZIndex(context) { - return (context.zIndex || 0) + return context.zIndex || 0 } /** @@ -9357,14 +9826,13 @@ static get relativePath() { return Card._relativePath } - } Card.debug = true; - Card._relativePath = ""; + Card._relativePath = ''; Card.scatterContainer = null; - Card.interactionType = "tap"; - Card.popupHtmlSelector = ".popupHtml"; + Card.interactionType = 'tap'; + Card.popupHtmlSelector = '.popupHtml'; Card.dynamicHeight = false; Card.popupYOffset = -15; @@ -9387,8 +9855,10 @@ /* eslint-disable no-console */ class CardWrapper extends Object { - - constructor(domNode, { triggerSVGClicks = true, allowClickDistance = 44 } = {}) { + constructor( + domNode, + { triggerSVGClicks = true, allowClickDistance = 44 } = {} + ) { super(); this.domNode = domNode; this.triggerSVGClicks = triggerSVGClicks; @@ -9398,42 +9868,43 @@ } handleClicks() { - this.domNode.addEventListener('click', event => { - if (event.isTrusted) { - Events.stop(event); - if (this.triggerSVGClicks && this.isSVGNode(event.target)) { - this.tap(event, "triggerSVGClicks"); + this.domNode.addEventListener( + 'click', + event => { + if (event.isTrusted) { + Events.stop(event); + if (this.triggerSVGClicks && this.isSVGNode(event.target)) { + this.tap(event, 'triggerSVGClicks'); + } } - } - - }, true); + }, + true + ); } handleClicksAsTaps() { - this.domNode.addEventListener('click', event => { - if (event.isTrusted) { - Events.stop(event); - - } - this.tap(event); - }, true); + this.domNode.addEventListener( + 'click', + event => { + if (event.isTrusted) { + Events.stop(event); + } + this.tap(event); + }, + true + ); } isClickable(node) { - if (node == null) - return false - if (node.tagName == 'A' && node.hasAttribute("href")) - return true - if (node.hasAttribute("onclick")) - return true + if (node == null) return false + if (node.tagName == 'A' && node.hasAttribute('href')) return true + if (node.hasAttribute('onclick')) return true return false } hasClickHandler(node) { - if (node == null) - return false - if (this.tapNodes.has(node)) - return true + if (node == null) return false + if (this.tapNodes.has(node)) return true for (let [selector, handler] of this.tapHandler.entries()) { for (let obj of this.domNode.querySelectorAll(selector)) { if (node == obj) { @@ -9450,15 +9921,13 @@ * See https://stackoverflow.com/questions/11455515/how-to-check-whether-dynamically-attached-event-listener-exists-or-not * Therefore we can only detect the following standard cases: * I. All clickable objects like activeNodes - * II. Objects that have been attached a click handler by the scatter itself via + * II. Objects that have been attached a click handler by the scatter itself via */ activeNodes() { let result = []; - for (let node of this.domNode.querySelectorAll("*")) { - if (this.isClickable(node)) - result.push(node); - if (this.hasClickHandler(node)) - result.push(node); + for (let node of this.domNode.querySelectorAll('*')) { + if (this.isClickable(node)) result.push(node); + if (this.hasClickHandler(node)) result.push(node); } return result } @@ -9466,14 +9935,26 @@ nearestActive(event) { let element = this.domNode; let activeNodes = this.activeNodes(); - let globalClick = (event.center) ? event.center : { x: event.x, y: event.y }; + let globalClick = event.center + ? event.center + : { x: event.x, y: event.y }; let localClick = Points$1.fromPageToNode(element, globalClick); let clickRects = activeNodes.map(link => { let rect = link.getBoundingClientRect(); let topLeft = Points$1.fromPageToNode(element, rect); - let center = Points$1.fromPageToNode(element, { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 }); - return { x: topLeft.x, y: topLeft.y, width: rect.width, height: rect.height, center, link } + let center = Points$1.fromPageToNode(element, { + x: rect.x + rect.width / 2, + y: rect.y + rect.height / 2 + }); + return { + x: topLeft.x, + y: topLeft.y, + width: rect.width, + height: rect.height, + center, + link + } }); let distances = []; @@ -9529,12 +10010,12 @@ return false } - tap(event, calledBy='unknown') { + tap(event, calledBy = 'unknown') { if (event.isTrusted) { let node = this.nearestActive(event); this.nodeTapped(node, event); - /* let node = document.elementFromPoint(event.clientX, event.clientY) + /* let node = document.elementFromPoint(event.clientX, event.clientY) if (!this.nodeTapped(node, event)) { node = this.nearestActive(event) this.nodeTapped(node, event) @@ -9543,15 +10024,12 @@ } onTap(objOrSelector, handler) { - if (typeof (objOrSelector) == 'string') { + if (typeof objOrSelector == 'string') { this.tapHandler.set(objOrSelector, handler); - } - else { + } else { this.tapNodes.set(objOrSelector, handler); } - } - } /* eslint-disable no-console */ @@ -9560,17 +10038,15 @@ let _HighlightEnabled = true; let _CircleIds = 0; - /** Helper method to round values with one digit precision */ function round(value) { return Math.round(parseFloat(value) * 10) / 10 } - /** * A namespace with static functions to expand and shrink highlighted image regions. * Assumes an SVG image with the following structure: - * + * * * * @@ -9579,15 +10055,14 @@ * * * - * + * * The SVG root element should use a viewbox with 0 0 100 100 to ensure that the positions and size of the * circles can be represnted in percent. - * + * * @class Highlight * @extends {Object} */ class Highlight$1 extends Object { - static disableAnimations() { _HighlightEnabled = false; let expanded = document.querySelectorAll('.expanded'); @@ -9620,7 +10095,10 @@ if (circle.classList.length == 0) { circle.removeAttribute('class'); } - if (circle.hasAttribute('id') && circle.getAttribute('id').startsWith('@@')) { + if ( + circle.hasAttribute('id') && + circle.getAttribute('id').startsWith('@@') + ) { circle.removeAttribute('id'); } circle.removeAttribute('data-svg-origin'); @@ -9635,9 +10113,11 @@ } } - static expand(obj, { scale = 2, duration = 3, stroke = 2, onComplete = null } = {}) { - if (obj == null) - return + static expand( + obj, + { scale = 2, duration = 3, stroke = 2, onComplete = null } = {} + ) { + if (obj == null) return //console.log("expand") obj.classList.add('zooming'); TweenLite.to(obj, duration, { @@ -9658,8 +10138,7 @@ static shrink(obj, { duration = 0.5, stroke = 2 } = {}) { //console.log("shrink") - if (obj == null) - return + if (obj == null) return obj.classList.add('zooming'); TweenLite.to(obj, duration, { scale: 1, @@ -9697,7 +10176,6 @@ let circleGroup = circle.parentNode; let image = svgRoot.querySelector('image'); - let stroke = parseFloat(circleGroup.getAttribute('stroke-width') || 6); let defs = svgRoot.querySelector('defs'); @@ -9716,15 +10194,16 @@ this.shrink(maskImage, { stroke }); return } - //console.log("animate called while zooming out -> expand") - } - else if (circle.classList.contains('zooming')) { + //console.log("animate called while zooming out -> expand") + } else if (circle.classList.contains('zooming')) { //console.log("animate called while zooming in -> shrink") this.shrink(circle, { stroke }); this.shrink(maskImage, { stroke }); return } - let circles = Array.from(circleGroup.children).filter(e => e.tagName == 'circle'); + let circles = Array.from(circleGroup.children).filter( + e => e.tagName == 'circle' + ); for (let c of circles) { //console.log("shrinking all circles") this.shrink(c, { stroke }); @@ -9744,11 +10223,10 @@ return false } - static openHighlight(target, { - animation = 0.5, - scale = 2, - onExpanded = null - } = {}) { + static openHighlight( + target, + { animation = 0.5, scale = 2, onExpanded = null } = {} + ) { if (Highlight$1._isExpanded(target)) { console.log('Target is already expanded!'); return @@ -9762,7 +10240,10 @@ let image = parent.querySelector(imageId); if (image) { this._bringToFront(image); - } else console.error('Could not find corresponding image element.'); + } else + console.error( + 'Could not find corresponding image element.' + ); } else console.log('Element was no parent:', target); } this._bringToFront(target); @@ -9771,10 +10252,15 @@ let image = svgRoot.querySelector('image'); // eslint-disable-next-line no-unused-vars - let [mask, maskImage] = Highlight$1._getSVGMask(target, { svgRoot, image }); + let [mask, maskImage] = Highlight$1._getSVGMask(target, { + svgRoot, + image + }); let center = Highlight$1._calculateCenterRelativeTo(target, image); - TweenLite.set(maskImage, { transformOrigin: `${center.x}% ${center.y}%` }); + TweenLite.set(maskImage, { + transformOrigin: `${center.x}% ${center.y}%` + }); TweenLite.set(target, { transformOrigin: '50% 50%' }); TweenLite.to([target, maskImage], animation, { @@ -9789,8 +10275,7 @@ static toggleHighlight(node) { if (Highlight$1._isExpanded(node)) { Highlight$1.closeHighlight(node); - } - else { + } else { Highlight$1.openHighlight(node); } } @@ -9800,7 +10285,12 @@ if (target && parent) { parent.removeChild(target); parent.appendChild(target); - } else console.error('Could not bring to front. Either no target or no parent.', target, parent); + } else + console.error( + 'Could not bring to front. Either no target or no parent.', + target, + parent + ); } static _getSVGMask(circle, { svgRoot = null, image = null } = {}) { @@ -9814,13 +10304,15 @@ let maskImage = svgRoot.getElementById(maskImageId); if (!mask || !maskImage) - [mask, maskImage] = Highlight$1._createSVGMask(circle, { svgRoot, image, id }); + [mask, maskImage] = Highlight$1._createSVGMask(circle, { + svgRoot, + image, + id + }); return [mask, maskImage] } - - /** * Creates an SVG mask for a provided svgElement. * @@ -9833,8 +10325,10 @@ * @returns * @memberof Highlight */ - static _createSVGMask(element, { svgRoot = null, image = null, id = null } = {}) { - + static _createSVGMask( + element, + { svgRoot = null, image = null, id = null } = {} + ) { // We can fetch these values here, but it's more efficient to // simply pass them in, as it's likely they were already retrieved beforehand. if (svgRoot == null) svgRoot = element.closest('svg'); @@ -9872,7 +10366,6 @@ let height = bbox.height; if (maskImage == null) { - maskImage = document.createElementNS(svg, 'image'); maskImage.style.pointerEvents = 'none'; maskImage.setAttribute('id', maskImageId); @@ -9925,8 +10418,7 @@ } static animate(event) { - if (!_HighlightEnabled) - return + if (!_HighlightEnabled) return event.stopPropagation(); Highlight$1.animateCircle(event.target); @@ -9957,8 +10449,6 @@ * @class ScatterCard */ class ScatterCard extends Card { - - /** * TODO: Find a more suitable name. * Adjusts the HTML to work in the new context. @@ -9970,32 +10460,27 @@ * @param {*} [opts={}] * @memberof Card */ - static setup(context, htmlString, { - basePath = "./", - modules = [] - } = {}) { - context.classList.add("info-card"); + static setup(context, htmlString, { basePath = './', modules = [] } = {}) { + context.classList.add('info-card'); this.relativePath = basePath; htmlString = this._adjustRelativeLinks(htmlString); let parser = new DOMParser(); - let html = parser.parseFromString(htmlString, "text/html"); + let html = parser.parseFromString(htmlString, 'text/html'); /** * Conflicts with the FindTarget method of the Abstract scatter. */ - this._replaceAttributes(html, "onclick", this._replaceCallback); + this._replaceAttributes(html, 'onclick', this._replaceCallback); - - let content = html.querySelector(".mainview"); + let content = html.querySelector('.mainview'); context.appendChild(content); super.setup(context, modules); return context } - /** * Appends a close listener to the scatter element. * @@ -10010,7 +10495,6 @@ } } - /** * Creates a scatter for the card and applies the card to it, * @@ -10022,11 +10506,12 @@ * @returns * @memberof Card */ - static createCardScatter(html, scatterContainer, { - basePath = "./", - modules = [] - } = {}) { - let element = document.createElement("div"); + static createCardScatter( + html, + scatterContainer, + { basePath = './', modules = [] } = {} + ) { + let element = document.createElement('div'); scatterContainer.element.appendChild(element); new DOMScatter(element, scatterContainer, { @@ -10041,8 +10526,6 @@ return element } - - /** *Utility function to create a fully functional card scatter. * @@ -10054,24 +10537,27 @@ * @returns * @memberof CardScatter */ - static loadAndCreateScatterCard(scatterContainer, item, { - basePath = "../", - modules = [], - onClose = null - } = {}) { + static loadAndCreateScatterCard( + scatterContainer, + item, + { basePath = '../', modules = [], onClose = null } = {} + ) { console.log(basePath); return new Promise((resolve, reject) => { - let url = basePath + "/" + item + "/index.html"; - console.log("Loading", url); + let url = basePath + '/' + item + '/index.html'; + console.log('Loading', url); this.loadHTML(url) .then(html => { - console.log("Received", html); - let element = this.createCardScatter(html, scatterContainer, { - basePath, - modules - }); - if (onClose) - this.addOnCloseListener(element, onClose); + console.log('Received', html); + let element = this.createCardScatter( + html, + scatterContainer, + { + basePath, + modules + } + ); + if (onClose) this.addOnCloseListener(element, onClose); resolve(element); }) .catch(e => reject(e)); @@ -10085,27 +10571,25 @@ static _getLanguage(context) { return context.language } - } ScatterCard.selectedLanguage = 0; - ScatterCard.languages = ["Deutsch", "English"]; + ScatterCard.languages = ['Deutsch', 'English']; ScatterCard.languageTags = { - Deutsch: "de", - English: "en" + Deutsch: 'de', + English: 'en' }; ScatterCard.scatterContainer = null; var CardPlugin = CardPlugin || {}; class CardPluginBase { - apply(context) { if (this.verify(context)) { this.append(context); - console.log("Plugin " + this.name + " was verified successfully."); + console.log('Plugin ' + this.name + ' was verified successfully.'); return true - } else console.error("Could not verify module " + this.name + "."); + } else console.error('Could not verify module ' + this.name + '.'); return false } @@ -10130,19 +10614,20 @@ missing.push(selector); } } - const valid = (missing.length == 0); - if (!valid) console.error("Elements were missing: ", missing.join(", ")); + const valid = missing.length == 0; + if (!valid) console.error('Elements were missing: ', missing.join(', ')); return valid } - /** * Appends the Plugin to the context. * * @memberof CardPlugin */ append(context) { - console.error("Call of abstract method CardPlugin.prototype.append(context). Plugins need to overwrite the append method!"); + console.error( + 'Call of abstract method CardPlugin.prototype.append(context). Plugins need to overwrite the append method!' + ); } _getVerificationFunctions(context) { @@ -10154,7 +10639,7 @@ _verifyContext(context) { if (!(context instanceof HTMLElement)) { - console.error("Context is not of type HTML Element.", context); + console.error('Context is not of type HTML Element.', context); return false } else return true } @@ -10169,13 +10654,18 @@ } }); - const valid = (missing.length == 0); - if (!valid) console.error("Could not apply module '" + this.name + "'. Following modules are required but were missing: " + missing.join(",")); - else console.log("All requirements were met! Well done!"); + const valid = missing.length == 0; + if (!valid) + console.error( + "Could not apply module '" + + this.name + + "'. Following modules are required but were missing: " + + missing.join(',') + ); + else console.log('All requirements were met! Well done!'); return valid } - _collectAllRequirements() { let requirements = []; let klass = this.__proto__; @@ -10189,9 +10679,6 @@ } } - - - CardPlugin.LightBox = class LightBox extends CardPluginBase { constructor(className, style = {}) { super(); @@ -10200,27 +10687,30 @@ } append(context) { - let wrapper = document.createElement("div"); + let wrapper = document.createElement('div'); wrapper.className = this.className; - Object.assign(wrapper.style, { - zIndex: 1000, - // backgroundColor: "black", - top: 0, - left: 0, - width: "100%", - height: "100%" - }, this.style, { - display: "none", - position: "absolute", - }); + Object.assign( + wrapper.style, + { + zIndex: 1000, + // backgroundColor: "black", + top: 0, + left: 0, + width: '100%', + height: '100%' + }, + this.style, + { + display: 'none', + position: 'absolute' + } + ); context.appendChild(wrapper); } - }; - /** * The Enlargeable Overlay module allows the user to click on the thumbnail image, * and the images gets enlarged inside the card. @@ -10229,12 +10719,15 @@ * @extends {CardPlugin} */ CardPlugin.EnlargeableThumbnail = class EnlargeableThumbnail extends CardPluginBase { - - constructor(wrapperSelector, overlaySelector = null, { - zoomAnimationDuration = 0.4, - fadeAnimationDuration = 0.4, - interactionType = "tap" - } = {}) { + constructor( + wrapperSelector, + overlaySelector = null, + { + zoomAnimationDuration = 0.4, + fadeAnimationDuration = 0.4, + interactionType = 'tap' + } = {} + ) { super(); this.wrapperSelector = wrapperSelector; this.overlaySelector = overlaySelector; @@ -10245,15 +10738,18 @@ } get require() { - return [ - CardPlugin.LightBox - ] + return [CardPlugin.LightBox] } _getVerificationFunctions(context) { let arr = super._getVerificationFunctions(context); let funcs = [ - this._verifyElementsExist.bind(this, context, this.wrapperSelector, this.overlaySelector) + this._verifyElementsExist.bind( + this, + context, + this.wrapperSelector, + this.overlaySelector + ) ]; return arr.concat(funcs) } @@ -10263,7 +10759,6 @@ this.setupEnlargeableThumbnail(context, source); } - /** * Get the preview image. * @@ -10275,26 +10770,25 @@ * @memberof EnlargeableThumbnail */ _retrieveSource(context) { - let img = context.querySelector(this.wrapperSelector + " img"); - let src = img.getAttribute("src"); - let parts = src.split("/"); + let img = context.querySelector(this.wrapperSelector + ' img'); + let src = img.getAttribute('src'); + let parts = src.split('/'); parts.pop(); parts.push(parts[parts.length - 1]); - let imagePath = parts.join("/") + ".jpg"; + let imagePath = parts.join('/') + '.jpg'; return imagePath } - setupEnlargeableThumbnail(context, src) { let wrapper = context.querySelector(this.wrapperSelector); let overlay = context.querySelector(this.overlaySelector); - let icon = document.createElement("div"); - icon.className = "button corner-button bottom-right icon zoom"; + let icon = document.createElement('div'); + icon.className = 'button corner-button bottom-right icon zoom'; wrapper.appendChild(icon); Object.assign(wrapper.style, { - cursor: "pointer" + cursor: 'pointer' }); InteractionMapper.on(this.interactionType, wrapper, () => { @@ -10307,28 +10801,28 @@ } openThumbnailDetail(context, src) { - let overlay = context.querySelector(".img-overlay"); - overlay.innerHTML = ""; + let overlay = context.querySelector('.img-overlay'); + overlay.innerHTML = ''; let source = context.querySelector(this.wrapperSelector); let sourceStyle = window.getComputedStyle(source); let imageWrapper = source.cloneNode(true); - let image = imageWrapper.querySelector("img"); + let image = imageWrapper.querySelector('img'); Object.assign(imageWrapper.style, { - maxWidth: "none", - maxHeight: "none" + maxWidth: 'none', + maxHeight: 'none' }); Object.assign(image.style, { - width: "100%", - height: "100%", - objectFit: "cover" + width: '100%', + height: '100%', + objectFit: 'cover' }); this._replaceIcon(imageWrapper); image.onload = () => { - let header = context.querySelector("header"); + let header = context.querySelector('header'); let headerStlye = window.getComputedStyle(header); /** @@ -10340,20 +10834,20 @@ /** * The minor side should not exceed the height of the context window. */ - const maxMinorSize = context.offsetHeight - 2 * parseInt(headerStlye.paddingTop) - 2 * parseInt(headerStlye.marginTop); - - + const maxMinorSize = + context.offsetHeight - + 2 * parseInt(headerStlye.paddingTop) - + 2 * parseInt(headerStlye.marginTop); const max = { width: context.offsetWidth * maxFillRatio, height: context.offsetHeight * maxFillRatio }; - let majorSide; let minorSide; - const _width = { name: "width", axis: "x" }; - const _height = { name: "height", axis: "y" }; + const _width = { name: 'width', axis: 'x' }; + const _height = { name: 'height', axis: 'y' }; if (image.naturalHeight > image.naturalWidth) { majorSide = _height; minorSide = _width; @@ -10366,14 +10860,17 @@ return string.charAt(0).toUpperCase() + string.slice(1) } function getImageSize(side) { - return image["natural" + capitalize(side.name)] + return image['natural' + capitalize(side.name)] } const majorImageSize = getImageSize(majorSide); // const minorImageSize = getImageSize(minorSide) let ratio = getImageSize(minorSide) / getImageSize(majorSide); - let size = (majorImageSize > max[majorSide.name]) ? max[majorSide.name] : majorImageSize; + let size = + majorImageSize > max[majorSide.name] + ? max[majorSide.name] + : majorImageSize; if (size * ratio > maxMinorSize) { size = maxMinorSize / ratio; @@ -10384,8 +10881,10 @@ height: 0 }; - - let position = Points.fromPageToNode(context, Points.fromNodeToPage(source, { x: 0, y: 0 })); + let position = Points.fromPageToNode( + context, + Points.fromNodeToPage(source, { x: 0, y: 0 }) + ); let targetOffset = { x: 0, @@ -10395,8 +10894,14 @@ targetDimensions[majorSide.name] = size; targetDimensions[minorSide.name] = size * ratio; - targetOffset[majorSide.axis] = (context["offset" + capitalize(majorSide.name)] - targetDimensions[majorSide.name]) / 2; - targetOffset[minorSide.axis] = (context["offset" + capitalize(minorSide.name)] - targetDimensions[minorSide.name]) / 2; + targetOffset[majorSide.axis] = + (context['offset' + capitalize(majorSide.name)] - + targetDimensions[majorSide.name]) / + 2; + targetOffset[minorSide.axis] = + (context['offset' + capitalize(minorSide.name)] - + targetDimensions[minorSide.name]) / + 2; overlay.appendChild(imageWrapper); @@ -10405,14 +10910,13 @@ top: 0, x: position.x, y: position.y, - position: "absolute", + position: 'absolute', width: parseInt(sourceStyle.width), height: parseInt(sourceStyle.height) }); - TweenMax.set(overlay, { - display: "flex", + display: 'flex', autoAlpha: 0 }); @@ -10420,7 +10924,7 @@ x: targetOffset.x, y: targetOffset.y, width: targetDimensions.width, - height: targetDimensions.height, + height: targetDimensions.height }); TweenMax.to(overlay, this.fadeAnimationTime, { autoAlpha: 1 @@ -10431,35 +10935,40 @@ } _replaceIcon(clone) { - let zoomIcon = clone.querySelector(".icon.zoom"); - zoomIcon.classList.remove("zoom"); - zoomIcon.classList.add("close"); + let zoomIcon = clone.querySelector('.icon.zoom'); + zoomIcon.classList.remove('zoom'); + zoomIcon.classList.add('close'); } getBorderHeight(style) { - const borderWidth = parseInt(style.borderTopWidth) + parseInt(style.borderBottomWidth); - const padding = parseInt(style.paddingTop) + parseInt(style.paddingBottom); + const borderWidth = + parseInt(style.borderTopWidth) + parseInt(style.borderBottomWidth); + const padding = + parseInt(style.paddingTop) + parseInt(style.paddingBottom); return parseInt(style.width) + borderWidth + padding } getBorderWidth(style) { - const borderWidth = parseInt(style.borderLeftWidth) + parseInt(style.borderRightWidth); - const padding = parseInt(style.paddingLeft) + parseInt(style.paddingRight); + const borderWidth = + parseInt(style.borderLeftWidth) + parseInt(style.borderRightWidth); + const padding = + parseInt(style.paddingLeft) + parseInt(style.paddingRight); return parseInt(style.width) + borderWidth + padding } closeThumnailDetail(context) { - let overlay = context.querySelector(".img-overlay"); + let overlay = context.querySelector('.img-overlay'); let timeline = new TimelineLite(); - timeline.to(overlay, this.fadeAnimationDuration, { - autoAlpha: 0 - }).set(overlay, { - display: "none" - }); + timeline + .to(overlay, this.fadeAnimationDuration, { + autoAlpha: 0 + }) + .set(overlay, { + display: 'none' + }); } - }; CardPlugin.Ui = class UiPlugin extends CardPluginBase { @@ -10471,56 +10980,52 @@ _getVerificationFunctions(context) { let arr = super._getVerificationFunctions(context); - let func = [ - this._doesParentExist.bind(this, context, this.parent) - ]; + let func = [this._doesParentExist.bind(this, context, this.parent)]; return arr.concat(func) } _doesParentExist(context, parent) { if (parent == null) return true - let valid = (context.querySelector(parent) != null); - if (!valid) console.error("Could not find parent on context.", context, parent); + let valid = context.querySelector(parent) != null; + if (!valid) + console.error('Could not find parent on context.', context, parent); return valid } append(context) { - parent = (this.parent == null) ? context : context.querySelector(this.parent).appendChild(container); - let container = document.createElement("div"); + parent = + this.parent == null + ? context + : context.querySelector(this.parent).appendChild(container); + let container = document.createElement('div'); container.className = this.className; parent.appendChild(container); } - }; CardPlugin.Speech = class SpeechPlugin extends CardPluginBase { - - constructor(parentSelector, className, interactionType = "tap") { + constructor(parentSelector, className, interactionType = 'tap') { super(); this.className = className; this.parentSelector = parentSelector; this.interactionType = interactionType; - } get require() { - return [ - CardPlugin.Ui - ] + return [CardPlugin.Ui] } append(context) { let container = context.querySelector(this.parentSelector); - this.button = document.createElement("div"); - this.button.className = "icon button " + this.className; + this.button = document.createElement('div'); + this.button.className = 'icon button ' + this.className; container.appendChild(this.button); InteractionMapper.on(this.interactionType, this.button, () => { - let subcard = context.querySelector(".mainview > .subcard"); - let target = (subcard) ? subcard : context; + let subcard = context.querySelector('.mainview > .subcard'); + let target = subcard ? subcard : context; this.speak(target); - }); } @@ -10531,8 +11036,7 @@ } _activateButton() { - if (this.button) - this.button.classList.add("active"); + if (this.button) this.button.classList.add('active'); } _deactivate() { @@ -10540,36 +11044,32 @@ } _deactivateButton() { - if (this.button) - this.button.classList.remove("active"); + if (this.button) this.button.classList.remove('active'); } _isSameNode(node) { //console.log(this.currentText, node.innerText) - return (this.currentText == node.innerText) + return this.currentText == node.innerText } speak(node) { - console.log(this._isSameNode(node)); if (!window.speechSynthesis.speaking) { - console.log("Noone talking!"); + console.log('Noone talking!'); this._start(node); } else if (this._isSameNode(node)) { - console.log("Requested same!"); + console.log('Requested same!'); this._stop(); - } else { - console.log("Requested Different!"); + console.log('Requested Different!'); this._stop(); this._start(node); } - } _disableActive() { - console.log("disableActive:", this.active); + console.log('disableActive:', this.active); if (this.active) { this.active._deactivate(); } @@ -10581,28 +11081,40 @@ let voices = window.speechSynthesis.getVoices(); console.log(voices); - let voice = voices.filter((val) => { + let voice = voices.filter(val => { //console.log(val) - return val.name == "Microsoft Hedda Desktop - German" + return val.name == 'Microsoft Hedda Desktop - German' })[0]; //console.log(voice) utterance.voice = voice; - console.log("TALK: ", utterance); + console.log('TALK: ', utterance); window.speechSynthesis.speak(utterance); this._activate(); window.speechSynthesis.resume(); - - utterance.onboundary = () => { console.log("onboundary", node.innerText); if (this.currentText.substring(0, 5) != node.innerText.substring(0, 5)) { console.log("text for speech synth changed!", this.currentText, node.innerText); this._stop(); } }; - utterance.onend = () => console.log("onend", node.innerText); - utterance.onerror = () => console.log("onerror", node.innerText); - utterance.onmark = () => console.log("onmark", node.innerText); - utterance.onpause = () => console.log("onpause", node.innerText); - utterance.onresume = () => console.log("onresume", node.innerText); - utterance.onstart = () => console.log("onstart", node.innerText); - utterance.onerror = () => console.log("onerror", node.innerText); + utterance.onboundary = () => { + console.log('onboundary', node.innerText); + if ( + this.currentText.substring(0, 5) != + node.innerText.substring(0, 5) + ) { + console.log( + 'text for speech synth changed!', + this.currentText, + node.innerText + ); + this._stop(); + } + }; + utterance.onend = () => console.log('onend', node.innerText); + utterance.onerror = () => console.log('onerror', node.innerText); + utterance.onmark = () => console.log('onmark', node.innerText); + utterance.onpause = () => console.log('onpause', node.innerText); + utterance.onresume = () => console.log('onresume', node.innerText); + utterance.onstart = () => console.log('onstart', node.innerText); + utterance.onerror = () => console.log('onerror', node.innerText); } _stop() { @@ -10615,7 +11127,9 @@ return this.constructor.active } - set active(val) { this.constructor.active = val; } + set active(val) { + this.constructor.active = val; + } get currentText() { return this.constructor.text @@ -10624,7 +11138,6 @@ set currentText(val) { this.constructor.text = val; } - }; /* eslint-disable no-unused-vars */ @@ -10636,7 +11149,6 @@ * @class Theme */ class Theme { - /** * Loads a config file and parses it to JSON. * @@ -10647,17 +11159,15 @@ */ static loadConfig(path = null) { return new Promise((resolve, reject) => { - path = (path) ? path : './config.json'; + path = path ? path : './config.json'; let xhttp = new XMLHttpRequest(); - xhttp.onreadystatechange = function () { + xhttp.onreadystatechange = function() { if (this.readyState == 4) { - if (this.status == 200 || Theme._isLocal()) { try { const json = JSON.parse(this.responseText); resolve(json); - } catch (e) { reject(e); } @@ -10670,7 +11180,7 @@ } static _isLocal() { - return (window.location.protocol == 'file:') + return window.location.protocol == 'file:' } } diff --git a/dist/iwmlib.pixi.js b/dist/iwmlib.pixi.js index ec6b2ba..e151e3b 100644 --- a/dist/iwmlib.pixi.js +++ b/dist/iwmlib.pixi.js @@ -34,7 +34,6 @@ * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/theme.html|DocTest} */ class Theme { - /** * Creates an instance of a Theme. * @@ -84,52 +83,86 @@ * is used for large actived text. */ constructor(opts = {}) { + const colorPrimary = + opts.primaryColor != null ? opts.primaryColor : 0x5ec7f8; // blue + const color1 = opts.color1 != null ? opts.color1 : 0x282828; // black + const color2 = opts.color2 != null ? opts.color2 : 0xf6f6f6; // white - const colorPrimary = opts.primaryColor != null ? opts.primaryColor : 0x5ec7f8; // blue - const color1 = opts.color1 != null ? opts.color1 : 0x282828; // black - const color2 = opts.color2 != null ? opts.color2 : 0xf6f6f6; // white - - this.opts = Object.assign({}, { - margin: 12, - padding: 12, - radius: 4, - fast: .25, - normal: .5, - slow: 1, - primaryColor: colorPrimary, - color1: color1, - color2: color2, - fill: color1, - fillAlpha: 1, - fillActive: color1, - fillActiveAlpha: 1, - stroke: color2, - strokeWidth: .6, - strokeAlpha: 1, - strokeActive: color2, - strokeActiveWidth: .6, - strokeActiveAlpha: 1, - iconColor: color2, - iconColorActive: colorPrimary, - background: color1 - }, opts); + this.opts = Object.assign( + {}, + { + margin: 12, + padding: 12, + radius: 4, + fast: 0.25, + normal: 0.5, + slow: 1, + primaryColor: colorPrimary, + color1: color1, + color2: color2, + fill: color1, + fillAlpha: 1, + fillActive: color1, + fillActiveAlpha: 1, + stroke: color2, + strokeWidth: 0.6, + strokeAlpha: 1, + strokeActive: color2, + strokeActiveWidth: 0.6, + strokeActiveAlpha: 1, + iconColor: color2, + iconColorActive: colorPrimary, + background: color1 + }, + opts + ); // Set textStyle and variants - this.opts.textStyle = Object.assign({}, { - fontFamily: '"Avenir Next", "Open Sans", "Segoe UI", "Roboto", "Helvetica Neue", -apple-system, system-ui, BlinkMacSystemFont, Arial, sans-serif !default', - fontWeight: '500', - fontSize: 18, - fill: color2, - stroke: color1, - strokeThickness: 0, - miterLimit: 1, - lineJoin: 'round' - }, this.opts.textStyle); - this.opts.textStyleSmall = Object.assign({}, this.opts.textStyle, {fontSize: this.opts.textStyle.fontSize - 3}, this.opts.textStyleSmall); - this.opts.textStyleLarge = Object.assign({}, this.opts.textStyle, {fontSize: this.opts.textStyle.fontSize + 3}, this.opts.textStyleLarge); - this.opts.textStyleActive = Object.assign({}, this.opts.textStyle, {fill: this.opts.primaryColor}, this.opts.textStyleActive); - this.opts.textStyleSmallActive = Object.assign({}, this.opts.textStyleSmall, {fill: this.opts.primaryColor}, this.opts.textStyleSmallActive); - this.opts.textStyleLargeActive = Object.assign({}, this.opts.textStyleLarge, {fill: this.opts.primaryColor}, this.opts.textStyleLargeActive); + this.opts.textStyle = Object.assign( + {}, + { + fontFamily: + '"Avenir Next", "Open Sans", "Segoe UI", "Roboto", "Helvetica Neue", -apple-system, system-ui, BlinkMacSystemFont, Arial, sans-serif !default', + fontWeight: '500', + fontSize: 18, + fill: color2, + stroke: color1, + strokeThickness: 0, + miterLimit: 1, + lineJoin: 'round' + }, + this.opts.textStyle + ); + this.opts.textStyleSmall = Object.assign( + {}, + this.opts.textStyle, + { fontSize: this.opts.textStyle.fontSize - 3 }, + this.opts.textStyleSmall + ); + this.opts.textStyleLarge = Object.assign( + {}, + this.opts.textStyle, + { fontSize: this.opts.textStyle.fontSize + 3 }, + this.opts.textStyleLarge + ); + this.opts.textStyleActive = Object.assign( + {}, + this.opts.textStyle, + { fill: this.opts.primaryColor }, + this.opts.textStyleActive + ); + this.opts.textStyleSmallActive = Object.assign( + {}, + this.opts.textStyleSmall, + { fill: this.opts.primaryColor }, + this.opts.textStyleSmallActive + ); + this.opts.textStyleLargeActive = Object.assign( + {}, + this.opts.textStyleLarge, + { fill: this.opts.primaryColor }, + this.opts.textStyleLargeActive + ); Object.assign(this, this.opts); } @@ -142,7 +175,6 @@ * @return {Theme} Returns a newly created Theme object. */ static fromString(theme) { - if (theme && typeof theme === 'object') { return theme } @@ -174,9 +206,7 @@ * @extends Theme * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/theme.html|DocTest} */ - class ThemeDark extends Theme { - - } + class ThemeDark extends Theme {} /** * Class that represents a PixiJS ThemeLight. @@ -196,15 +226,13 @@ * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/theme.html|DocTest} */ class ThemeLight extends Theme { - /** * Creates an instance of a ThemeLight. * * @constructor */ constructor() { - - super({color1: 0xf6f6f6, color2: 0x282828}); + super({ color1: 0xf6f6f6, color2: 0x282828 }); } } @@ -226,21 +254,19 @@ * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/theme.html|DocTest} */ class ThemeRed extends Theme { - /** * Creates an instance of a ThemeRed. * * @constructor */ constructor() { - - super({primaryColor: 0xd92f31}); + super({ primaryColor: 0xd92f31 }); } } /** * Class that represents a PixiJS Progress. - * + * * @example * // Create the progress * const progress = new Progress({ @@ -256,10 +282,9 @@ * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/progress.html|DocTest} */ class Progress extends PIXI.Container { - /** * Creates an instance of a Progress. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the progress. * @param {number} [opts.id=auto generated] - The id of the progress. @@ -291,36 +316,39 @@ * @param {boolean} [opts.visible=true] - Is the progress initially visible (property visible)? */ constructor(opts = {}) { - super(); - + const theme = Theme.fromString(opts.theme); this.theme = theme; - this.opts = Object.assign({}, { - id: PIXI.utils.uid(), - app: window.app, - width: null, - height: 2, - margin: 100, - padding: 0, - fill: theme.fill, - fillAlpha: theme.fillAlpha, - fillActive: theme.primaryColor, - fillActiveAlpha: theme.fillActiveAlpha, - stroke: theme.stroke, - strokeWidth: 0, - strokeAlpha: theme.strokeAlpha, - strokeActive: theme.strokeActive, - strokeActiveWidth: 0, - strokeActiveAlpha: theme.strokeActiveAlpha, - background: false, - backgroundFill: theme.background, - backgroundFillAlpha: 1, - radius: theme.radius, - destroyOnComplete: true, - visible: true - }, opts); + this.opts = Object.assign( + {}, + { + id: PIXI.utils.uid(), + app: window.app, + width: null, + height: 2, + margin: 100, + padding: 0, + fill: theme.fill, + fillAlpha: theme.fillAlpha, + fillActive: theme.primaryColor, + fillActiveAlpha: theme.fillActiveAlpha, + stroke: theme.stroke, + strokeWidth: 0, + strokeAlpha: theme.strokeAlpha, + strokeActive: theme.strokeActive, + strokeActiveWidth: 0, + strokeActiveAlpha: theme.strokeActiveAlpha, + background: false, + backgroundFill: theme.background, + backgroundFillAlpha: 1, + radius: theme.radius, + destroyOnComplete: true, + visible: true + }, + opts + ); this.id = this.opts.id; @@ -329,7 +357,7 @@ this.barActive = null; this.alpha = 0; - + this.visible = this.opts.visible; this._progress = 0; @@ -342,15 +370,14 @@ //----------------- this.layout(); } - + /** * Creates children and instantiates everything. - * + * * @private * @return {Progress} A reference to the progress for chaining. */ setup() { - // interaction //----------------- this.on('added', e => { @@ -377,14 +404,13 @@ return this } - + /** * Should be called to refresh the layout of the progress. Can be used after resizing. - * + * * @return {Progress} A reference to the progress for chaining. */ layout() { - const width = this.opts.app.size.width; const height = this.opts.app.size.height; @@ -392,7 +418,10 @@ //----------------- if (this.opts.background) { this.background.clear(); - this.background.beginFill(this.opts.backgroundFill, this.opts.backgroundFillAlpha); + this.background.beginFill( + this.opts.backgroundFill, + this.opts.backgroundFillAlpha + ); this.background.drawRect(0, 0, width, height); this.background.endFill(); } @@ -401,15 +430,14 @@ return this } - + /** * Draws the canvas. - * + * * @private * @return {Progress} A reference to the progress for chaining. */ draw() { - this.bar.clear(); this.barActive.clear(); @@ -418,59 +446,80 @@ return this } - + /** * Draws the bar. - * + * * @private * @return {Progress} A reference to the progress for chaining. */ drawBar() { - const width = this.opts.app.size.width; const height = this.opts.app.size.height; this.radius = this.opts.radius; - if ((this.radius * 2) > this.opts.height) { + if (this.radius * 2 > this.opts.height) { this.radius = this.opts.height / 2; } - const wantedWidth = this.opts.width || (width - (2 * this.opts.margin)); + const wantedWidth = this.opts.width || width - 2 * this.opts.margin; const wantedHeight = this.opts.height; - this.bar.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha); + this.bar.lineStyle( + this.opts.strokeWidth, + this.opts.stroke, + this.opts.strokeAlpha + ); this.bar.beginFill(this.opts.fill, this.opts.fillAlpha); if (this.radius > 1) { - this.bar.drawRoundedRect(0, 0, wantedWidth, wantedHeight, this.radius); + this.bar.drawRoundedRect( + 0, + 0, + wantedWidth, + wantedHeight, + this.radius + ); } else { this.bar.drawRect(0, 0, wantedWidth, wantedHeight); } this.bar.endFill(); - + this.bar.x = width / 2 - this.bar.width / 2; this.bar.y = height / 2 - this.bar.height / 2; return this } - + /** * Draws the active bar. - * + * * @private * @return {Progress} A reference to the progress for chaining. */ drawBarActive() { + const wantedWidth = this.bar.width - 2 * this.opts.padding; + const wantedHeight = this.bar.height - 2 * this.opts.padding; - const wantedWidth = this.bar.width - (2 * this.opts.padding); - const wantedHeight = this.bar.height - (2 * this.opts.padding); - - const barActiveWidth = wantedWidth * this._progress / 100; + const barActiveWidth = (wantedWidth * this._progress) / 100; - this.barActive.lineStyle(this.opts.strokeActiveWidth, this.opts.strokeActive, this.opts.strokeActiveAlpha); - this.barActive.beginFill(this.opts.fillActive, this.opts.fillActiveAlpha); + this.barActive.lineStyle( + this.opts.strokeActiveWidth, + this.opts.strokeActive, + this.opts.strokeActiveAlpha + ); + this.barActive.beginFill( + this.opts.fillActive, + this.opts.fillActiveAlpha + ); if (barActiveWidth > 0) { if (this.radius > 1) { - this.barActive.drawRoundedRect(0, 0, barActiveWidth, wantedHeight, this.radius); + this.barActive.drawRoundedRect( + 0, + 0, + barActiveWidth, + wantedHeight, + this.radius + ); } else { this.barActive.drawRect(0, 0, barActiveWidth, wantedHeight); } @@ -482,39 +531,41 @@ return this } - + /** * Shows the progress (sets his alpha values to 1). - * + * * @return {Progress} A reference to the progress for chaining. */ show() { - TweenLite.to(this, this.theme.fast, {alpha: 1}); + TweenLite.to(this, this.theme.fast, { alpha: 1 }); return this } - + /** * Hides the progress (sets his alpha values to 1). - * + * * @return {Progress} A reference to the progress for chaining. */ hide() { - TweenLite.to(this, this.theme.fast, {alpha: 0, onComplete: () => this.visible = false}); + TweenLite.to(this, this.theme.fast, { + alpha: 0, + onComplete: () => (this.visible = false) + }); return this } - + /** * Gets or sets the progress. Has to be a number between 0 and 100. - * + * * @member {number} */ get progress() { return this._progress } set progress(value) { - value = Math.round(value); if (value < 0) { @@ -532,7 +583,7 @@ if (value === 100 && this.opts.destroyOnComplete) { TweenLite.to(this, this.theme.fast, { alpha: 0, - onComplete: () => this.destroy({children: true}) + onComplete: () => this.destroy({ children: true }) }); } } @@ -551,10 +602,9 @@ * @see {@link http://pixijs.download/dev/docs/PIXI.Graphics.html|PIXI.Graphics} */ class AbstractPopup extends PIXI.Graphics { - /** * Creates an instance of an AbstractPopup (only for internal use). - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the popup. * @param {number} [opts.id=auto generated] - The id of the popup. @@ -585,34 +635,37 @@ * to landscape, the popup cannot be displayed in portrait mode. */ constructor(opts = {}) { - super(); - + const theme = Theme.fromString(opts.theme); this.theme = theme; - this.opts = Object.assign({}, { - id: PIXI.utils.uid(), - x: 0, - y: 0, - header: null, // null or null - content: null, // null or String or PIXI.DisplayObject - minWidth: 320, - minHeight: 130, - maxWidth: null, - padding: theme.padding, - fill: theme.fill, - fillAlpha: theme.fillAlpha, - stroke: theme.stroke, - strokeWidth: theme.strokeWidth, - strokeAlpha: theme.strokeAlpha, - headerStyle: theme.textStyleLarge, - textStyle: theme.textStyleSmall, - radius: theme.radius, - onHidden: null, - visible: true, - orientation: null - }, opts); + this.opts = Object.assign( + {}, + { + id: PIXI.utils.uid(), + x: 0, + y: 0, + header: null, // null or null + content: null, // null or String or PIXI.DisplayObject + minWidth: 320, + minHeight: 130, + maxWidth: null, + padding: theme.padding, + fill: theme.fill, + fillAlpha: theme.fillAlpha, + stroke: theme.stroke, + strokeWidth: theme.strokeWidth, + strokeAlpha: theme.strokeAlpha, + headerStyle: theme.textStyleLarge, + textStyle: theme.textStyleSmall, + radius: theme.radius, + onHidden: null, + visible: true, + orientation: null + }, + opts + ); this.id = this.opts.id; @@ -621,10 +674,12 @@ if (this.opts.maxWidth) { this.headerStyle.wordWrap = true; - this.headerStyle.wordWrapWidth = this.opts.maxWidth - (2 * this.opts.padding); + this.headerStyle.wordWrapWidth = + this.opts.maxWidth - 2 * this.opts.padding; this.textStyle.wordWrap = true; - this.textStyle.wordWrapWidth = this.opts.maxWidth - (2 * this.opts.padding); + this.textStyle.wordWrapWidth = + this.opts.maxWidth - 2 * this.opts.padding; } this.alpha = 0; @@ -639,7 +694,7 @@ // padding this.innerPadding = this.opts.padding * 1.5; - + // interaction //----------------- this.interactive = true; @@ -647,15 +702,14 @@ this.show(); }); } - + /** * Creates the framework and instantiates everything. - * + * * @private * @return {AbstractPopup} A reference to the popup for chaining. */ setup() { - // position //----------------- this.sy = this.opts.padding; @@ -663,15 +717,17 @@ // header //----------------- if (this.opts.header != null) { - let header = null; if (this.opts.header instanceof PIXI.Text) { header = this.opts.header; } else if (typeof this.opts.header === 'number') { - header = new PIXI.Text(this.opts.header.toString(), this.headerStyle); + header = new PIXI.Text( + this.opts.header.toString(), + this.headerStyle + ); } else { - header = new PIXI.Text(this.opts.header, this.headerStyle); + header = new PIXI.Text(this.opts.header, this.headerStyle); } header.x = this.opts.padding; @@ -691,13 +747,15 @@ // content //----------------- if (this.opts.content != null) { - let content = null; if (typeof this.opts.content === 'string') { content = new PIXI.Text(this.opts.content, this.textStyle); } else if (typeof this.opts.content === 'number') { - content = new PIXI.Text(this.opts.content.toString(), this.textStyle); + content = new PIXI.Text( + this.opts.content.toString(), + this.textStyle + ); } else { content = this.opts.content; } @@ -714,24 +772,23 @@ return this } - + /** * Should be called to refresh the layout of the popup. Can be used after resizing. - * + * * @return {AbstractPopup} A reference to the popup for chaining. */ layout() { - // wanted width & wanted height //----------------- const padding = this.opts.padding; const size = this.getInnerSize(); - const width = size.width + (2 * padding); - const height = size.height + (2 * padding); + const width = size.width + 2 * padding; + const height = size.height + 2 * padding; this.wantedWidth = Math.max(width, this.opts.minWidth); this.wantedHeight = Math.max(height, this.opts.minHeight); - + if (this.opts.maxWidth) { this.wantedWidth = Math.min(this.wantedWidth, this.opts.maxWidth); } @@ -761,41 +818,54 @@ return this } - + /** * Draws the canvas. - * + * * @private * @return {AbstractPopup} A reference to the popup for chaining. */ draw() { - - const square = Math.round(this.wantedWidth) === Math.round(this.wantedHeight); + const square = + Math.round(this.wantedWidth) === Math.round(this.wantedHeight); const diameter = Math.round(this.opts.radius * 2); this.clear(); - this.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha); + this.lineStyle( + this.opts.strokeWidth, + this.opts.stroke, + this.opts.strokeAlpha + ); this.beginFill(this.opts.fill, this.opts.fillAlpha); if (square && diameter === this.wantedWidth) { - this.drawCircle(this.wantedWidth / 2, this.wantedHeight / 2, this.opts.radius); + this.drawCircle( + this.wantedWidth / 2, + this.wantedHeight / 2, + this.opts.radius + ); } else { - this.drawRoundedRect(0, 0, this.wantedWidth, this.wantedHeight, this.opts.radius); + this.drawRoundedRect( + 0, + 0, + this.wantedWidth, + this.wantedHeight, + this.opts.radius + ); } this.endFill(); return this } - + /** * Calculates the size of the children of the AbstractPopup. * Cannot use getBounds() because it is not updated when children * are removed. - * + * * @private * @returns {object} An JavaScript object width the keys width and height. */ getInnerSize() { - let width = 0; let height = 0; @@ -813,17 +883,16 @@ height += this._content.height; } - return {width, height} + return { width, height } } - + /** * Shows the popup (sets his alpha values to 1). - * + * * @param {callback} [cb] - Executed when show animation was completed. * @return {AbstractPopup} A reference to the popup for chaining. */ show(cb) { - TweenLite.to(this, this.theme.fast, { alpha: 1, onComplete: () => { @@ -835,15 +904,14 @@ return this } - + /** * Hides the popup (sets his alpha values to 0). - * + * * @param {callback} [cb] - Executed when hide animation was completed. * @return {AbstractPopup} A reference to the popup for chaining. */ hide(cb) { - TweenLite.to(this, this.theme.fast, { alpha: 0, onComplete: () => { @@ -864,7 +932,7 @@ /** * Sets or gets the header. The getter always returns a PIXI.Text object. The setter can receive * a string, a number or a PIXI.Text object. - * + * * @member {string|number|PIXI.Text} */ get header() { @@ -877,11 +945,11 @@ this.opts.header = value; this.setup().layout(); } - + /** * Sets or gets the content. The getter always returns an PIXI.DisplayObject. The setter can receive * a string, a number or a PIXI.DisplayObject. - * + * * @member {string|number|PIXI.DisplayObject} */ get content() { @@ -898,7 +966,7 @@ /** * Class that represents a PixiJS Tooltip. - * + * * @example * // Create the app * const app = new PIXIApp({ @@ -906,13 +974,13 @@ * width: 900, * height: 250 * }).setup().run() - * + * * // Add an DisplayObject to the app * const circle = new PIXI.Graphics() * circle.beginFill(0x5251a3) * circle.drawCircle(50, 50, 40) * app.scene.addChild(circle) - * + * * const tooltip = new Tooltip({ * object: circle, * container: app.scene, @@ -924,10 +992,9 @@ * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/tooltip.html|DocTest} */ class Tooltip extends AbstractPopup { - /** * Creates an instance of a Tooltip. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the tooltip. * @param {number} [opts.minWidth=0] - The minimum width of the tooltip. @@ -940,19 +1007,22 @@ * @param {number} [opts.delay=0] - A delay, after which the tooltip should be opened. */ constructor(opts = {}) { - const theme = Theme.fromString(opts.theme); - - opts = Object.assign({}, { - minWidth: 0, - minHeight: 0, - padding: theme.padding / 2, - object: null, - container: null, - offsetLeft: 8, - offsetTop: -8, - delay: 0 - }, opts); + + opts = Object.assign( + {}, + { + minWidth: 0, + minHeight: 0, + padding: theme.padding / 2, + object: null, + container: null, + offsetLeft: 8, + offsetTop: -8, + delay: 0 + }, + opts + ); opts.container = opts.container || opts.object; @@ -966,15 +1036,14 @@ //----------------- this.layout(); } - + /** * Creates children and instantiates everything. - * + * * @private * @return {Tooltip} A reference to the tooltip for chaining. */ setup() { - super.setup(); // bind events this @@ -982,7 +1051,7 @@ this.interactive = true; let mouseoverTooltip = false; - + this.on('mouseover', e => { mouseoverTooltip = true; }); @@ -995,7 +1064,7 @@ }); } }); - + // bind events object //----------------- const object = this.opts.object; @@ -1004,7 +1073,6 @@ let mouseoverObject = false; object.on('mouseover', e => { - this.timeout = window.setTimeout(() => { mouseoverObject = true; this.visible = true; @@ -1031,15 +1099,14 @@ return this } - + /** * Calculates and sets the position of the tooltip. - * + * * @private * @return {Tooltip} A reference to the tooltip for chaining. */ setPosition(e) { - const position = e.data.getLocalPosition(this.opts.container); this.x = position.x + this.opts.offsetLeft; @@ -1051,7 +1118,7 @@ /** * Class that represents a PixiJS Badge. - * + * * @example * // Create the app * const app = new PIXIApp({ @@ -1059,13 +1126,13 @@ * width: 900, * height: 250 * }).setup().run() - * + * * // Add an DisplayObject to the app * const circle = new PIXI.Graphics() * circle.beginFill(0x5251a3) * circle.drawCircle(50, 50, 40) * app.scene.addChild(circle) - * + * * const badge1 = new Badge({ * object: circle, * container: app.scene, @@ -1077,10 +1144,9 @@ * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/badge.html|DocTest} */ class Badge extends AbstractPopup { - /** * Creates an instance of a Badge. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the badge. * @param {number} [opts.minWidth=0] - The minimum width of the badge. @@ -1090,15 +1156,18 @@ * to display. */ constructor(opts = {}) { - const theme = Theme.fromString(opts.theme); - - opts = Object.assign({}, { - minWidth: 0, - minHeight: 0, - padding: theme.padding / 2, - tooltip: null - }, opts); + + opts = Object.assign( + {}, + { + minWidth: 0, + minHeight: 0, + padding: theme.padding / 2, + tooltip: null + }, + opts + ); super(opts); @@ -1112,7 +1181,7 @@ //----------------- this.layout(); } - + /** * Creates children and instantiates everything. * @@ -1121,42 +1190,50 @@ * @return {Badge} A reference to the badge for chaining. */ setup() { - super.setup(); // tooltip //----------------- if (this.opts.tooltip) { if (typeof this.opts.tooltip === 'string') { - this.tooltip = new Tooltip({object: this, content: this.opts.tooltip}); + this.tooltip = new Tooltip({ + object: this, + content: this.opts.tooltip + }); } else { - this.opts.tooltip = Object.assign({}, {object: this}, this.opts.tooltip); + this.opts.tooltip = Object.assign( + {}, + { object: this }, + this.opts.tooltip + ); this.tooltip = new Tooltip(this.opts.tooltip); } } return this } - + /** * Should be called to refresh the layout of the badge. Can be used after resizing. - * + * * @override * @return {Badge} A reference to the badge for chaining. */ layout() { - super.layout(); - this.content.x = this.width / 2 - this.content.width / 2 - this.opts.strokeWidth / 2; - this.content.y = this.height / 2 - this.content.height / 2 - this.opts.strokeWidth / 2; + this.content.x = + this.width / 2 - this.content.width / 2 - this.opts.strokeWidth / 2; + this.content.y = + this.height / 2 - + this.content.height / 2 - + this.opts.strokeWidth / 2; return this } } class Events$1 { - static stop(event) { event.preventDefault(); event.stopPropagation(); @@ -1176,8 +1253,7 @@ } static isCaptured(event) { - if (event.__capturedBy) - return true + if (event.__capturedBy) return true return false } @@ -1186,7 +1262,7 @@ } static isPointerDown(event) { - // According to + // According to // https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events // pointer events use the buttons feature to represent pressed buttons return event.buttons @@ -1233,8 +1309,15 @@ for (let i = 0; i < targets.length; i++) { let t = targets[i]; let touchTarget = document.elementFromPoint(t.pageX, t.pageY); - let touch = new Touch(undefined, touchTarget, t.identifier, - t.pageX, t.pageY, t.screenX, t.screenY); + let touch = new Touch( + undefined, + touchTarget, + t.identifier, + t.pageX, + t.pageY, + t.screenX, + t.screenY + ); touches.push(touch); } return new TouchList(...touches) @@ -1324,8 +1407,7 @@ for (let key of keys) { try { result += ' ' + key + ':' + event[key]; - } - catch (e) { + } catch (e) { console.log('Invalid key: ' + key); } } @@ -1334,10 +1416,14 @@ static compareExtractedWithSimulated() { if (this.extracted.length != this.simulated.length) { - alert('Unequal length of extracted [' + this.extracted.length + - '] and simulated events [' + this.simulated.length + '].'); - } - else { + alert( + 'Unequal length of extracted [' + + this.extracted.length + + '] and simulated events [' + + this.simulated.length + + '].' + ); + } else { for (let i = 0; i < this.extracted.length; i++) { var extracted = this.extracted[i]; var simulated = this.simulated[i]; @@ -1391,8 +1477,10 @@ div.innerHTML = line; this.popup.appendChild(div); } - Elements.setStyle(this.popup, - { left: event.clientX + 'px', top: event.clientY + 'px' }); + Elements.setStyle(this.popup, { + left: event.clientX + 'px', + top: event.clientY + 'px' + }); } } @@ -1447,7 +1535,6 @@ * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/button.html|DocTest} */ class Button extends PIXI.Container { - /** * Creates an instance of a Button. * @@ -1506,62 +1593,76 @@ * @param {boolean} [opts.visible=true] - Is the button initially visible (property visible)? */ constructor(opts = {}) { - super(); const theme = Theme.fromString(opts.theme); this.theme = theme; - this.opts = Object.assign({}, { - id: PIXI.utils.uid(), - label: null, - x: 0, - y: 0, - minWidth: 44, - minHeight: 44, - padding: theme.padding, - icon: undefined, - iconActive: undefined, - iconPosition: 'left', - iconColor: theme.iconColor, - iconColorActive: theme.iconColorActive, - fill: theme.fill, - fillAlpha: theme.fillAlpha, - fillActive: theme.fillActive, - fillActiveAlpha: theme.fillActiveAlpha, - stroke: theme.stroke, - strokeWidth: theme.strokeWidth, - strokeAlpha: theme.strokeAlpha, - strokeActive: theme.strokeActive, - strokeActiveWidth: theme.strokeActiveWidth, - strokeActiveAlpha: theme.strokeActiveAlpha, - textStyle: theme.textStyle, - textStyleActive: theme.textStyleActive, - style: 'default', - radius: theme.radius, - disabled: false, - active: false, - action: null, - beforeAction: null, - afterAction: null, - type: 'default', - align: 'center', - verticalAlign: 'middle', - tooltip: null, - badge: null, - visible: true - }, opts); + this.opts = Object.assign( + {}, + { + id: PIXI.utils.uid(), + label: null, + x: 0, + y: 0, + minWidth: 44, + minHeight: 44, + padding: theme.padding, + icon: undefined, + iconActive: undefined, + iconPosition: 'left', + iconColor: theme.iconColor, + iconColorActive: theme.iconColorActive, + fill: theme.fill, + fillAlpha: theme.fillAlpha, + fillActive: theme.fillActive, + fillActiveAlpha: theme.fillActiveAlpha, + stroke: theme.stroke, + strokeWidth: theme.strokeWidth, + strokeAlpha: theme.strokeAlpha, + strokeActive: theme.strokeActive, + strokeActiveWidth: theme.strokeActiveWidth, + strokeActiveAlpha: theme.strokeActiveAlpha, + textStyle: theme.textStyle, + textStyleActive: theme.textStyleActive, + style: 'default', + radius: theme.radius, + disabled: false, + active: false, + action: null, + beforeAction: null, + afterAction: null, + type: 'default', + align: 'center', + verticalAlign: 'middle', + tooltip: null, + badge: null, + visible: true + }, + opts + ); this.id = this.opts.id; - if (typeof this.opts.icon === 'undefined' && typeof this.opts.iconActive !== 'undefined') { + if ( + typeof this.opts.icon === 'undefined' && + typeof this.opts.iconActive !== 'undefined' + ) { this.opts.icon = this.opts.iconActive; - } else if (typeof this.opts.icon !== 'undefined' && typeof this.opts.iconActive === 'undefined') { + } else if ( + typeof this.opts.icon !== 'undefined' && + typeof this.opts.iconActive === 'undefined' + ) { this.opts.iconActive = this.opts.icon; } if (this.opts.style === 'link') { - Object.assign(this.opts, { strokeAlpha: 0, strokeActiveAlpha: 0, fillAlpha: 0, fillActiveAlpha: 0 }); + Object.assign(this.opts, { + strokeAlpha: 0, + strokeActiveAlpha: 0, + fillAlpha: 0, + fillActiveAlpha: 0 + }); } this._active = null; @@ -1600,7 +1701,6 @@ * @return {Button} A reference to the button for chaining. */ setup() { - // Button //----------------- let button = new PIXI.Graphics(); @@ -1622,18 +1722,27 @@ // Icon //----------------- if (this.opts.icon) { - this.iconInactive = this.loadIcon(this.opts.icon, this.opts.iconColor); + this.iconInactive = this.loadIcon( + this.opts.icon, + this.opts.iconColor + ); } if (this.opts.iconActive) { - this.iconActive = this.loadIcon(this.opts.iconActive, this.opts.iconColorActive); + this.iconActive = this.loadIcon( + this.opts.iconActive, + this.opts.iconColorActive + ); } // interaction //----------------- this.button.on('pointerover', e => { this.capture(e); - TweenLite.to([this.button, this.content], this.theme.fast, { alpha: .83, overwrite: 'none' }); + TweenLite.to([this.button, this.content], this.theme.fast, { + alpha: 0.83, + overwrite: 'none' + }); }); this.button.on('pointermove', e => { @@ -1642,13 +1751,19 @@ this.button.on('pointerout', e => { this.capture(e); - TweenLite.to([this.button, this.content], this.theme.fast, { alpha: 1, overwrite: 'none' }); + TweenLite.to([this.button, this.content], this.theme.fast, { + alpha: 1, + overwrite: 'none' + }); }); // eslint-disable-next-line no-unused-vars this.button.on('pointerdown', e => { //this.capture(e) - TweenLite.to([this.button, this.content], this.theme.fast, { alpha: .7, overwrite: 'none' }); + TweenLite.to([this.button, this.content], this.theme.fast, { + alpha: 0.7, + overwrite: 'none' + }); }); this.button.on('pointerup', e => { @@ -1661,7 +1776,10 @@ this.opts.action.call(this, e, this); } - TweenLite.to([this.button, this.content], this.theme.fast, { alpha: .83, overwrite: 'none' }); + TweenLite.to([this.button, this.content], this.theme.fast, { + alpha: 0.83, + overwrite: 'none' + }); if (this.opts.type === 'checkbox') { this.active = !this.active; @@ -1678,15 +1796,22 @@ // active //----------------- - this.active = this.opts.active; // calls .layout() + this.active = this.opts.active; // calls .layout() // tooltip //----------------- if (this.opts.tooltip) { if (typeof this.opts.tooltip === 'string') { - this.tooltip = new Tooltip({ object: this, content: this.opts.tooltip }); + this.tooltip = new Tooltip({ + object: this, + content: this.opts.tooltip + }); } else { - this.opts.tooltip = Object.assign({}, { object: this }, this.opts.tooltip); + this.opts.tooltip = Object.assign( + {}, + { object: this }, + this.opts.tooltip + ); this.tooltip = new Tooltip(this.opts.tooltip); } } @@ -1694,12 +1819,15 @@ // badge //----------------- if (this.opts.badge) { - let opts = Object.assign({}, { - align: 'right', - verticalAlign: 'top', - offsetLeft: 0, - offsetTop: 0 - }); + let opts = Object.assign( + {}, + { + align: 'right', + verticalAlign: 'top', + offsetLeft: 0, + offsetTop: 0 + } + ); if (typeof this.opts.badge === 'string') { opts = Object.assign(opts, { content: this.opts.badge }); } else { @@ -1709,25 +1837,35 @@ const badge = new Badge(opts); switch (opts.align) { - case 'left': - badge.x = this.x - badge.width / 2 + opts.offsetLeft; - break - case 'center': - badge.x = this.x + this.width / 2 - badge.width / 2 + opts.offsetLeft; - break - case 'right': - badge.x = this.x + this.width - badge.width / 2 + opts.offsetLeft; + case 'left': + badge.x = this.x - badge.width / 2 + opts.offsetLeft; + break + case 'center': + badge.x = + this.x + + this.width / 2 - + badge.width / 2 + + opts.offsetLeft; + break + case 'right': + badge.x = + this.x + this.width - badge.width / 2 + opts.offsetLeft; } switch (opts.verticalAlign) { - case 'top': - badge.y = this.y - badge.height / 2 + opts.offsetTop; - break - case 'middle': - badge.y = this.y + this.height / 2 - badge.height / 2 + opts.offsetTop; - break - case 'bottom': - badge.y = this.y + this.height - badge.height / 2 + opts.offsetTop; + case 'top': + badge.y = this.y - badge.height / 2 + opts.offsetTop; + break + case 'middle': + badge.y = + this.y + + this.height / 2 - + badge.height / 2 + + opts.offsetTop; + break + case 'bottom': + badge.y = + this.y + this.height - badge.height / 2 + opts.offsetTop; } this.addChild(badge); @@ -1748,7 +1886,6 @@ * @return {Button} A reference to the button for chaining. */ layout() { - // Clear content //----------------- this.removeChild(this.content); @@ -1834,18 +1971,17 @@ * @return {Button} A reference to the button for chaining. */ layoutInnerContent() { - for (let child of this.content.children) { switch (this.opts.verticalAlign) { - case 'top': - child.y = 0; - break - case 'middle': - child.y = this.content.height / 2 - child.height / 2; - break - case 'bottom': - child.y = this.content.height - child.height; - break + case 'top': + child.y = 0; + break + case 'middle': + child.y = this.content.height / 2 - child.height / 2; + break + case 'bottom': + child.y = this.content.height - child.height; + break } } @@ -1860,29 +1996,30 @@ * @return {Button} A reference to the button for chaining. */ layoutContent() { - switch (this.opts.align) { - case 'left': - this.content.x = this.opts.padding; - break - case 'center': - this.content.x = ((this._width - this.content.width) / 2); - break - case 'right': - this.content.x = this._width - this.opts.padding - this.content.width; - break + case 'left': + this.content.x = this.opts.padding; + break + case 'center': + this.content.x = (this._width - this.content.width) / 2; + break + case 'right': + this.content.x = + this._width - this.opts.padding - this.content.width; + break } switch (this.opts.verticalAlign) { - case 'top': - this.content.y = this.opts.padding; - break - case 'middle': - this.content.y = (this._height - this.content.height) / 2; - break - case 'bottom': - this.content.y = this._height - this.opts.padding - this.content.height; - break + case 'top': + this.content.y = this.opts.padding; + break + case 'middle': + this.content.y = (this._height - this.content.height) / 2; + break + case 'bottom': + this.content.y = + this._height - this.opts.padding - this.content.height; + break } return this @@ -1895,16 +2032,32 @@ * @return {Button} A reference to the button for chaining. */ draw() { - this.button.clear(); if (this.active) { - this.button.lineStyle(this.opts.strokeActiveWidth, this.opts.strokeActive, this.opts.strokeActiveAlpha); - this.button.beginFill(this.opts.fillActive, this.opts.fillActiveAlpha); + this.button.lineStyle( + this.opts.strokeActiveWidth, + this.opts.strokeActive, + this.opts.strokeActiveAlpha + ); + this.button.beginFill( + this.opts.fillActive, + this.opts.fillActiveAlpha + ); } else { - this.button.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha); + this.button.lineStyle( + this.opts.strokeWidth, + this.opts.stroke, + this.opts.strokeAlpha + ); this.button.beginFill(this.opts.fill, this.opts.fillAlpha); } - this.button.drawRoundedRect(0, 0, this._width, this._height, this.opts.radius); + this.button.drawRoundedRect( + 0, + 0, + this._width, + this._height, + this.opts.radius + ); this.button.endFill(); return this @@ -1919,7 +2072,6 @@ return this._active } set active(value) { - this._active = value; if (this._active) { @@ -1944,18 +2096,17 @@ return this._disabled } set disabled(value) { - this._disabled = value; if (this._disabled) { this.button.interactive = false; this.button.buttonMode = false; - this.button.alpha = .5; + this.button.alpha = 0.5; if (this.icon) { - this.icon.alpha = .5; + this.icon.alpha = 0.5; } if (this.text) { - this.text.alpha = .5; + this.text.alpha = 0.5; } } else { this.button.interactive = true; @@ -1976,7 +2127,6 @@ * @return {Button} A reference to the button for chaining. */ show() { - this.opts.strokeAlpha = 1; this.opts.strokeActiveAlpha = 1; this.opts.fillAlpha = 1; @@ -1993,7 +2143,6 @@ * @return {Button} A reference to the button for chaining. */ hide() { - this.opts.strokeAlpha = 0; this.opts.strokeActiveAlpha = 0; this.opts.fillAlpha = 0; @@ -2013,7 +2162,6 @@ * @return {PIXI.DisplayObject} Return the icon as an PIXI.DisplayObject. */ loadIcon(icon, color) { - let displayObject = null; if (icon instanceof PIXI.DisplayObject) { @@ -2023,10 +2171,12 @@ if (this.text) { size = this.text.height; } else if (this.opts.minHeight) { - size = this.opts.minHeight - (2 * this.opts.padding); + size = this.opts.minHeight - 2 * this.opts.padding; } - const url = Button.iconIsUrl(icon) ? icon : `../../assets/icons/${icon}.png`; + const url = Button.iconIsUrl(icon) + ? icon + : `../../assets/icons/${icon}.png`; const iconTexture = PIXI.Texture.fromImage(url, true); const sprite = new PIXI.Sprite(iconTexture); @@ -2070,7 +2220,7 @@ /** * Class that represents a PixiJS ButtonGroup. - * + * * @example * // Create the button group * const buttonGroup = new ButtonGroup({ @@ -2091,10 +2241,9 @@ * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/buttongroup.html|DocTest} */ class ButtonGroup extends PIXI.Graphics { - /** * Creates an instance of a ButtonGroup. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the button group. * @param {number} [opts.id=auto generated] - The id of the button group. @@ -2141,50 +2290,53 @@ * @param {boolean} [opts.visible=true] - Is the button group initially visible (property visible)? */ constructor(opts = {}) { - super(); - + const theme = Theme.fromString(opts.theme); this.theme = theme; - this.opts = Object.assign({}, { - id: PIXI.utils.uid(), - x: 0, - y: 0, - buttons: [], - minWidth: 44, - minHeight: 44, - padding: theme.padding, - margin: theme.margin, - iconPosition: 'left', // left, right - iconColor: theme.iconColor, - iconColorActive: theme.iconColorActive, - fill: theme.fill, - fillAlpha: theme.fillAlpha, - fillActive: theme.fillActive, - fillActiveAlpha: theme.fillActiveAlpha, - stroke: theme.stroke, - strokeWidth: theme.strokeWidth, - strokeAlpha: theme.strokeAlpha, - strokeActive: theme.strokeActive, - strokeActiveWidth: theme.strokeActiveWidth, - strokeActiveAlpha: theme.strokeActiveAlpha, - textStyle: theme.textStyle, - textStyleActive: theme.textStyleActive, - style: 'default', - radius: theme.radius, - disabled: null, - type: 'default', // default, checkbox, radio - orientation: 'horizontal', - align: 'center', // left, center, right - verticalAlign: 'middle', // top, middle, bottom - visible: true - }, opts); + this.opts = Object.assign( + {}, + { + id: PIXI.utils.uid(), + x: 0, + y: 0, + buttons: [], + minWidth: 44, + minHeight: 44, + padding: theme.padding, + margin: theme.margin, + iconPosition: 'left', // left, right + iconColor: theme.iconColor, + iconColorActive: theme.iconColorActive, + fill: theme.fill, + fillAlpha: theme.fillAlpha, + fillActive: theme.fillActive, + fillActiveAlpha: theme.fillActiveAlpha, + stroke: theme.stroke, + strokeWidth: theme.strokeWidth, + strokeAlpha: theme.strokeAlpha, + strokeActive: theme.strokeActive, + strokeActiveWidth: theme.strokeActiveWidth, + strokeActiveAlpha: theme.strokeActiveAlpha, + textStyle: theme.textStyle, + textStyleActive: theme.textStyleActive, + style: 'default', + radius: theme.radius, + disabled: null, + type: 'default', // default, checkbox, radio + orientation: 'horizontal', + align: 'center', // left, center, right + verticalAlign: 'middle', // top, middle, bottom + visible: true + }, + opts + ); this.buttons = []; this._disabled = null; - + this.visible = this.opts.visible; // setup @@ -2195,21 +2347,19 @@ //----------------- this.layout(); } - + /** * Creates children and instantiates everything. - * + * * @private * @return {ButtonGroup} A reference to the button group for chaining. */ setup() { - // Buttons //----------------- let position = 0; for (let it of this.opts.buttons) { - delete it.x; delete it.y; @@ -2231,11 +2381,19 @@ it.fillActive = it.fillActive || this.opts.fillActive; it.fillActiveAlpha = it.fillActiveAlpha || this.opts.fillActiveAlpha; it.stroke = it.stroke || this.opts.stroke; - it.strokeWidth = it.strokeWidth != null ? it.strokeWidth : this.opts.strokeWidth; - it.strokeAlpha = it.strokeAlpha != null ? it.strokeAlpha : this.opts.strokeAlpha; + it.strokeWidth = + it.strokeWidth != null ? it.strokeWidth : this.opts.strokeWidth; + it.strokeAlpha = + it.strokeAlpha != null ? it.strokeAlpha : this.opts.strokeAlpha; it.strokeActive = it.strokeActive || this.opts.strokeActive; - it.strokeActiveWidth = it.strokeActiveWidth != null ? it.strokeActiveWidth : this.opts.strokeActiveWidth; - it.strokeActiveAlpha = it.strokeActiveAlpha != null ? it.strokeActiveAlpha : this.opts.strokeActiveAlpha; + it.strokeActiveWidth = + it.strokeActiveWidth != null + ? it.strokeActiveWidth + : this.opts.strokeActiveWidth; + it.strokeActiveAlpha = + it.strokeActiveAlpha != null + ? it.strokeActiveAlpha + : this.opts.strokeActiveAlpha; it.textStyle = it.textStyle || this.opts.textStyle; it.textStyleActive = it.textStyleActive || this.opts.textStyleActive; it.style = it.style || this.opts.style; @@ -2254,7 +2412,10 @@ it.align = it.align || this.opts.align; it.verticalAlign = it.verticalAlign || this.opts.verticalAlign; it.afterAction = (event, button) => { - if (this.opts.type === 'radio' && button.opts.type === 'default') { + if ( + this.opts.type === 'radio' && + button.opts.type === 'default' + ) { this.buttons.forEach(it => { if (it.opts.type === 'default') { it.active = false; @@ -2269,18 +2430,25 @@ if (it.tooltip) { if (typeof it.tooltip === 'string') { - it.tooltip = {content: it.tooltip, container: this}; + it.tooltip = { content: it.tooltip, container: this }; } else { - it.tooltip = Object.assign({}, {container: this}, it.tooltip); + it.tooltip = Object.assign( + {}, + { container: this }, + it.tooltip + ); } } - + let button = new Button(it); this.addChild(button); this.buttons.push(button); - position += (this.opts.orientation === 'horizontal' ? button.width : button.height) + this.opts.margin; + position += + (this.opts.orientation === 'horizontal' + ? button.width + : button.height) + this.opts.margin; } if (this.opts.orientation === 'vertical') { @@ -2300,14 +2468,13 @@ return this } - + /** * Should be called to refresh the layout of the button group. Can be used after resizing. - * + * * @return {ButtonGroup} A reference to the button group for chaining. */ layout() { - // set position //----------------- this.position.set(this.opts.x, this.opts.y); @@ -2318,26 +2485,38 @@ return this } - + /** * Draws the canvas. - * + * * @private * @return {ButtonGroup} A reference to the button group for chaining. */ draw() { - if (this.opts.margin === 0) { - this.buttons.forEach(it => it.hide()); this.clear(); - this.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha); + this.lineStyle( + this.opts.strokeWidth, + this.opts.stroke, + this.opts.strokeAlpha + ); this.beginFill(this.opts.fill, this.opts.fillAlpha); - this.drawRoundedRect(0, 0, this.width, this.height, this.opts.radius); + this.drawRoundedRect( + 0, + 0, + this.width, + this.height, + this.opts.radius + ); // Draw borders - this.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha / 2); + this.lineStyle( + this.opts.strokeWidth, + this.opts.stroke, + this.opts.strokeAlpha / 2 + ); this.buttons.forEach((it, i) => { if (i > 0) { @@ -2348,7 +2527,6 @@ } else { this.lineTo(it.width, it.y); } - } }); @@ -2357,10 +2535,10 @@ return this } - + /** * Gets or sets the disabled state. When disabled, no button of the button group can be clicked. - * + * * @member {boolean} */ get disabled() { @@ -2368,32 +2546,29 @@ } set disabled(value) { - this._disabled = value; - this.buttons.forEach(it => it.disabled = value); + this.buttons.forEach(it => (it.disabled = value)); } - + /** * Searches all buttons of the button group and returns the maximum width of one button. - * + * * @private * @return {number} The maximum with of a button of the button group. */ getMaxButtonWidth() { - let widths = this.buttons.map(it => it.width); return Math.max(...widths) } - + /** * Shows the button group (sets his alpha value to 1). - * + * * @return {ButtonGroup} A reference to the button group for chaining. */ show() { - this.alpha = 1; return this @@ -2401,11 +2576,10 @@ /** * Hides the button group (sets his alpha value to 0). - * + * * @return {ButtonGroup} A reference to the button group for chaining. */ hide() { - this.alpha = 0; return this @@ -2422,7 +2596,6 @@ * @extends AbstractPopup */ class InteractivePopup extends AbstractPopup { - /** * Creates an instance of an InteractivePopup (only for internal use). * @@ -2434,13 +2607,16 @@ * @param {object} [opts.buttonGroup] - A ButtonGroup object to be displayed on the lower right corner. */ constructor(opts = {}) { - - opts = Object.assign({}, { - closeOnPopup: false, - closeButton: true, - button: null, - buttonGroup: null - }, opts); + opts = Object.assign( + {}, + { + closeOnPopup: false, + closeButton: true, + button: null, + buttonGroup: null + }, + opts + ); super(opts); @@ -2466,7 +2642,6 @@ * @return {AbstractPopup} A reference to the popup for chaining. */ setup() { - super.setup(); // interaction @@ -2482,7 +2657,10 @@ // closeButton //----------------- if (this.opts.closeButton) { - let closeButton = PIXI.Sprite.fromImage('../../assets/icons/close.png', true); + let closeButton = PIXI.Sprite.fromImage( + '../../assets/icons/close.png', + true + ); closeButton.width = this.headerStyle.fontSize; closeButton.height = closeButton.width; closeButton.tint = this.theme.color2; @@ -2505,7 +2683,11 @@ // maxWidth is set and a closeButton should be displayed //----------------- if (this.opts.maxWidth) { - const wordWrapWidth = this.opts.maxWidth - (2 * this.opts.padding) - this.smallPadding - this._closeButton.width; + const wordWrapWidth = + this.opts.maxWidth - + 2 * this.opts.padding - + this.smallPadding - + this._closeButton.width; if (this._header) { this.headerStyle.wordWrapWidth = wordWrapWidth; } else if (this._content) { @@ -2518,9 +2700,19 @@ //----------------- if (this.opts.button || this.opts.buttonGroup) { if (this.opts.button) { - this._buttons = new Button(Object.assign({textStyle: this.theme.textStyleSmall}, this.opts.button)); + this._buttons = new Button( + Object.assign( + { textStyle: this.theme.textStyleSmall }, + this.opts.button + ) + ); } else { - this._buttons = new ButtonGroup(Object.assign({textStyle: this.theme.textStyleSmall}, this.opts.buttonGroup)); + this._buttons = new ButtonGroup( + Object.assign( + { textStyle: this.theme.textStyleSmall }, + this.opts.buttonGroup + ) + ); } this.addChild(this._buttons); @@ -2536,21 +2728,23 @@ * @return {AbstractPopup} A reference to the popup for chaining. */ layout() { - super.layout(); - + // closeButton //----------------- if (this.opts.closeButton) { - this._closeButton.x = this.wantedWidth - this.smallPadding - this._closeButton.width; + this._closeButton.x = + this.wantedWidth - this.smallPadding - this._closeButton.width; this._closeButton.y = this.smallPadding; } // buttons //----------------- if (this._buttons) { - this._buttons.x = this.wantedWidth - this.opts.padding - this._buttons.width; - this._buttons.y = this.wantedHeight - this.opts.padding - this._buttons.height; + this._buttons.x = + this.wantedWidth - this.opts.padding - this._buttons.width; + this._buttons.y = + this.wantedHeight - this.opts.padding - this._buttons.height; } return this @@ -2560,13 +2754,12 @@ * Calculates the size of the children of the AbstractPopup. * Cannot use getBounds() because it is not updated when children * are removed. - * + * * @private * @override * @returns {object} An JavaScript object width the keys width and height. */ getInnerSize() { - let size = super.getInnerSize(); if (this._closeButton) { @@ -2574,7 +2767,10 @@ } if (this._buttons) { - size.width = Math.max(size.width, this._buttons.x + this._buttons.width); + size.width = Math.max( + size.width, + this._buttons.x + this._buttons.width + ); size.height += this.innerPadding + this._buttons.height; } @@ -2600,7 +2796,6 @@ * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/popup.html|DocTest} */ class Popup extends InteractivePopup { - /** * Creates an instance of a Popup. * @@ -2611,12 +2806,15 @@ * @param {number} [opts.minHeight=0] - The minimum height of the popup. */ constructor(opts = {}) { - - opts = Object.assign({}, { - closeButton: false, - minWidth: 0, - minHeight: 0 - }, opts); + opts = Object.assign( + {}, + { + closeButton: false, + minWidth: 0, + minHeight: 0 + }, + opts + ); super(opts); } @@ -2624,7 +2822,7 @@ /** * Class that represents a PixiJS Modal. - * + * * @example * // Create the button and the modal when clicked * const button = new Button({ @@ -2649,10 +2847,9 @@ * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/modal.html|DocTest} */ class Modal extends PIXI.Container { - /** * Creates an instance of a Modal. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the modal. * @param {number} [opts.id=auto generated] - The id of the modal. @@ -2664,20 +2861,23 @@ * @param {boolean} [opts.visible=true] - Is the modal initially visible (property visible)? */ constructor(opts = {}) { - super(); - + const theme = Theme.fromString(opts.theme); this.theme = theme; - this.opts = Object.assign({}, { - id: PIXI.utils.uid(), - app: window.app, - backgroundFill: theme.background, - backgroundFillAlpha: .6, - closeOnBackground: true, - visible: true - }, opts); + this.opts = Object.assign( + {}, + { + id: PIXI.utils.uid(), + app: window.app, + backgroundFill: theme.background, + backgroundFillAlpha: 0.6, + closeOnBackground: true, + visible: true + }, + opts + ); this.id = this.opts.id; @@ -2695,15 +2895,14 @@ //----------------- this.layout(); } - + /** * Creates children and instantiates everything. - * + * * @private * @return {Modal} A reference to the modal for chaining. */ setup() { - // interaction //----------------- this.interactive = true; @@ -2741,21 +2940,23 @@ return this } - + /** * Should be called to refresh the layout of the modal. Can be used after resizing. - * + * * @return {Modal} A reference to the modal for chaining. */ layout() { - const width = this.opts.app.size.width; const height = this.opts.app.size.height; // background //----------------- this.background.clear(); - this.background.beginFill(this.opts.backgroundFill, this.opts.backgroundFillAlpha); + this.background.beginFill( + this.opts.backgroundFill, + this.opts.backgroundFillAlpha + ); this.background.drawRect(0, 0, width, height); this.background.endFill(); @@ -2765,33 +2966,39 @@ return this } - + /** * Shows the modal (sets his alpha values to 1). - * + * * @return {Modal} A reference to the modal for chaining. */ show() { - TweenLite.to(this, this.theme.fast, {alpha: 1, onStart: () => this.visible = true}); + TweenLite.to(this, this.theme.fast, { + alpha: 1, + onStart: () => (this.visible = true) + }); return this } - + /** * Hides the modal (sets his alpha values to 0). - * + * * @return {Modal} A reference to the modal for chaining. */ hide() { - TweenLite.to(this, this.theme.fast, {alpha: 0, onComplete: () => this.visible = false}); + TweenLite.to(this, this.theme.fast, { + alpha: 0, + onComplete: () => (this.visible = false) + }); return this } - + /** * Sets or gets the header. The getter always returns a PIXI.Text object. The setter can receive * a string or a PIXI.Text object. - * + * * @member {string|PIXI.Text} */ get header() { @@ -2803,11 +3010,11 @@ this.popup.destroy(); this.setup().layout(); } - + /** * Sets or gets the content. The getter always returns an PIXI.DisplayObject. The setter can receive * a string or a PIXI.DisplayObject. - * + * * @member {string|PIXI.DisplayObject} */ get content() { @@ -2823,7 +3030,7 @@ /** * Class that represents a Message. A message pops up and disappears after a specific amount of time. - * + * * @example * // Create the PixiJS App * const app = new PIXIApp({ @@ -2831,7 +3038,7 @@ * width: 900, * height: 250 * }).setup().run() - * + * * // Create a button * let button = new Button({ * label: 'Click me', @@ -2844,7 +3051,7 @@ * app.scene.addChild(message) * } * }) - * + * * // Add the button to the scene * app.scene.addChild(button) * @@ -2853,10 +3060,9 @@ * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/message.html|DocTest} */ class Message extends InteractivePopup { - /** * Creates an instance of a Message. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the message. * @param {PIXIApp} [opts.app=window.app] - The PIXIApp where this message belongs to. @@ -2873,32 +3079,34 @@ * @param {number} [opts.closeDuration=Theme.fast] - The duration in seconds of the closing of the message box. */ constructor(opts = {}) { - const theme = Theme.fromString(opts.theme); - opts = Object.assign({}, { - app: window.app, - closeButton: false, - minWidth: 280, - minHeight: 100, - margin: theme.margin, - align: 'right', // left, center, right - verticalAlign: 'top', // top, middle, bottom - duration: 5, - autoClose: true, - closeDuration: theme.fast - }, opts); + opts = Object.assign( + {}, + { + app: window.app, + closeButton: false, + minWidth: 280, + minHeight: 100, + margin: theme.margin, + align: 'right', // left, center, right + verticalAlign: 'top', // top, middle, bottom + duration: 5, + autoClose: true, + closeDuration: theme.fast + }, + opts + ); super(opts); } /** * Relayouts the position of the message box. - * + * * @return {Message} Returns the message box for chaining. */ layout() { - super.layout(); // horizontal @@ -2907,10 +3115,11 @@ this.x = this.opts.margin; break case 'center': - this.x = (this.opts.app.size.width / 2) - (this.width / 2); + this.x = this.opts.app.size.width / 2 - this.width / 2; break case 'right': - this.x = this.opts.app.size.width - this.opts.margin - this.width; + this.x = + this.opts.app.size.width - this.opts.margin - this.width; break } @@ -2920,21 +3129,21 @@ this.y = this.opts.margin; break case 'middle': - this.y = (this.opts.app.size.height / 2) - (this.height / 2); + this.y = this.opts.app.size.height / 2 - this.height / 2; break case 'bottom': - this.y = this.opts.app.size.height - this.opts.margin - this.height; + this.y = + this.opts.app.size.height - this.opts.margin - this.height; break } } /** * Shows the message box. - * + * * @private */ show() { - super.show(); if (this.opts.autoClose) { @@ -2964,7 +3173,6 @@ return amt * (stop - start) + start } - // Returns a function, that, as long as it continues to be invoked, will not // be triggered. The function will be called after it stops being called for // N milliseconds. If `immediate` is passed, trigger the function on the @@ -2972,10 +3180,10 @@ // Taken from: https://davidwalsh.name/essential-javascript-functions function debounce(func, wait, immediate) { let timeout; - return function () { + return function() { let context = this, args = arguments; - let later = function () { + let later = function() { timeout = null; if (!immediate) func.apply(context, args); }; @@ -2996,7 +3204,6 @@ } class Dates { - static create(fullYear, month, day) { return new Date(Date.UTC(fullYear, month, day)) } @@ -3006,7 +3213,9 @@ } static startYearRange(date) { - return new Date(Date.UTC(date.getFullYear() - 1, 11, 31, 23, 59, 59, 999)) + return new Date( + Date.UTC(date.getFullYear() - 1, 11, 31, 23, 59, 59, 999) + ) } static endYearRange(date) { @@ -3290,7 +3499,6 @@ /** Static methods to compute angles. */ class Angle { - static normalize(angle) { let TAU = Math.PI * 2.0; while (angle > Math.PI) { @@ -3337,11 +3545,11 @@ } static degree2radian(degree) { - return Math.PI * degree / 180.0 + return (Math.PI * degree) / 180.0 } static radian2degree(rad) { - return 180.0 / Math.PI * rad + return (180.0 / Math.PI) * rad } } @@ -3535,10 +3743,9 @@ if ( verty[i] > testy != verty[j] > testy && testx < - (vertx[j] - vertx[i]) * - (testy - verty[i]) / - (verty[j] - verty[i]) + - vertx[i] + ((vertx[j] - vertx[i]) * (testy - verty[i])) / + (verty[j] - verty[i]) + + vertx[i] ) c = !c; } @@ -3702,10 +3909,8 @@ } } - class LowPassFilter { - - constructor(smoothing = 0.5, bufferMaxSize=10) { + constructor(smoothing = 0.5, bufferMaxSize = 10) { this.smoothing = smoothing; // must be smaller than 1 this.buffer = []; // FIFO queue this.bufferMaxSize = bufferMaxSize; @@ -3713,7 +3918,7 @@ /** * Setup buffer with array of values - * + * * @param {array} values * @returns {array} * @access public @@ -3742,9 +3947,8 @@ * @access private */ __push(value) { - let removed = (this.buffer.length === this.bufferMaxSize) - ? this.buffer.shift() - : 0; + let removed = + this.buffer.length === this.bufferMaxSize ? this.buffer.shift() : 0; this.buffer.push(value); return removed @@ -3758,7 +3962,6 @@ * @access public */ next(nextValue) { - // push new value to the end, and remove oldest one let removed = this.__push(nextValue); // smooth value using all values from buffer @@ -3805,7 +4008,6 @@ * @see {@link https://stackoverflow.com/questions/29710696/webgl-drawing-buffer-size-does-not-equal-canvas-size} */ class FullscreenInteractionManager extends PIXI.interaction.InteractionManager { - mapPositionToPoint(point, x, y) { let resolution = this.renderer.resolution; let extendWidth = 1.0; @@ -3813,8 +4015,10 @@ let dy = 0; let canvas = this.renderer.view; let context = canvas.getContext('webgl'); - if (context.drawingBufferWidth < canvas.width || - context.drawingBufferHeight < canvas.height) { + if ( + context.drawingBufferWidth < canvas.width || + context.drawingBufferHeight < canvas.height + ) { extendWidth = context.drawingBufferWidth / canvas.width; extendHeight = context.drawingBufferHeight / canvas.height; //dx = wantedWidth - context.drawingBufferWidth @@ -3847,7 +4051,6 @@ * @see {@link http://pixijs.download/dev/docs/PIXI.Application.html|PIXI.Application} */ class PIXIApp extends PIXI.Application { - /** * Creates an instance of a PixiApp. * @@ -3870,12 +4073,23 @@ * @param {boolean} [opts.adaptive=true] - Adds Graphics adaptive calculation of quadratic curve and arc subdivision. */ constructor({ - width = null, height = null, view = null, - transparent = true, backgroundColor = 0x282828, theme = 'dark', - antialias = true, resolution = window.devicePixelRatio || 1, autoResize = true, - fpsLogging = false, progress = {}, forceCanvas = false, roundPixels = true, monkeyPatchMapping = true, adaptive = true, - graphql = false }) { - + width = null, + height = null, + view = null, + transparent = true, + backgroundColor = 0x282828, + theme = 'dark', + antialias = true, + resolution = window.devicePixelRatio || 1, + autoResize = true, + fpsLogging = false, + progress = {}, + forceCanvas = false, + roundPixels = true, + monkeyPatchMapping = true, + adaptive = true, + graphql = false + }) { const fullScreen = !width || !height; if (fullScreen) { @@ -3893,7 +4107,7 @@ autoResize, backgroundColor, forceCanvas, - roundPixels // not needed for PixiJS >= 5 + roundPixels // not needed for PixiJS >= 5 }); this.width = width; @@ -3916,7 +4130,10 @@ console.log('App is in fullScreen mode or autoResize mode'); const resizeDebounced = debounce(event => this.resize(event), 50); window.addEventListener('resize', resizeDebounced); - document.body.addEventListener('orientationchange', this.checkOrientation.bind(this)); + document.body.addEventListener( + 'orientationchange', + this.checkOrientation.bind(this) + ); } if (monkeyPatchMapping) { console.log('Using monkey patched coordinate mapping'); @@ -3943,15 +4160,17 @@ // GraphQL if (this.graphql && typeof apollo !== 'undefined') { - const networkInterface = apollo.createNetworkInterface({ uri: '/graphql' }); - const wsClient = new subscriptions.SubscriptionClient(`wss://${location.hostname}/subscriptions`, { - reconnect: true, - connectionParams: {} - }); + const wsClient = new subscriptions.SubscriptionClient( + `wss://${location.hostname}/subscriptions`, + { + reconnect: true, + connectionParams: {} + } + ); const networkInterfaceWithSubscriptions = subscriptions.addGraphQLSubscriptions( networkInterface, @@ -3964,7 +4183,11 @@ } // progress - this._progress = new Progress(Object.assign({ theme: this.theme }, this.progressOpts, { app: this })); + this._progress = new Progress( + Object.assign({ theme: this.theme }, this.progressOpts, { + app: this + }) + ); this._progress.visible = false; this.stage.addChild(this._progress); @@ -3989,9 +4212,12 @@ checkOrientation(event) { var value = this.orientation(); if (value != this.orient) { - setTimeout(100, function () { - this.orientationChanged(true); - }.bind(this)); + setTimeout( + 100, + function() { + this.orientationChanged(true); + }.bind(this) + ); this.orient = value; } } @@ -4014,9 +4240,7 @@ * @param {number} [width] - The width of the app. * @param {number} [height] - The height of the app. */ - layout(width, height) { - - } + layout(width, height) {} /** * Draws the display tree of the app. Typically this can be delegated @@ -4087,7 +4311,10 @@ * @param {number} [opts.height=window.innerHeight] - The height of the app to resize to. * @return {PIXIApp} - Returns the PIXIApp for chaining. */ - resize(event, { width = window.innerWidth, height = window.innerHeight } = {}) { + resize( + event, + { width = window.innerWidth, height = window.innerHeight } = {} + ) { this.width = width; this.height = height; this.expandRenderer(); @@ -4108,7 +4335,8 @@ monkeyPatchPixiMapping() { if (this.originalMapPositionToPoint === null) { let interactionManager = this.renderer.plugins.interaction; - this.originalMapPositionToPoint = interactionManager.mapPositionToPoint; + this.originalMapPositionToPoint = + interactionManager.mapPositionToPoint; interactionManager.mapPositionToPoint = (point, x, y) => { return this.fixedMapPositionToPoint(point, x, y) }; @@ -4116,7 +4344,7 @@ } /** - * In some browsers the canvas is distorted if the screen resolution and + * In some browsers the canvas is distorted if the screen resolution and * overall size of the canvas exceeds the internal limits (e.g. 4096 x 4096 pixels). * To compensate these distortions we need to fix the mapping to the actual * drawing buffer coordinates. @@ -4135,8 +4363,11 @@ let canvas = this.renderer.view; let context = canvas.getContext('webgl'); - if (context !== null && (context.drawingBufferWidth < canvas.width || - context.drawingBufferHeight < canvas.height)) { + if ( + context !== null && + (context.drawingBufferWidth < canvas.width || + context.drawingBufferHeight < canvas.height) + ) { extendWidth = context.drawingBufferWidth / canvas.width; extendHeight = context.drawingBufferHeight / canvas.height; //dx = wantedWidth - context.drawingBufferWidth @@ -4144,7 +4375,12 @@ } x *= extendWidth; y *= extendHeight; - return this.originalMapPositionToPoint.call(interactionManager, local, x, y + dy) + return this.originalMapPositionToPoint.call( + interactionManager, + local, + x, + y + dy + ) } /** @@ -4178,7 +4414,6 @@ * called without a parameter. */ progress(value) { - if (typeof value === 'undefined') { return this._progress } @@ -4196,8 +4431,9 @@ * @return {Modal} Returns the Modal object. */ modal(opts = {}) { - - let modal = new Modal(Object.assign({ theme: this.theme }, opts, { app: this })); + let modal = new Modal( + Object.assign({ theme: this.theme }, opts, { app: this }) + ); this.scene.addChild(modal); return modal @@ -4210,8 +4446,9 @@ * @return {Message} Returns the Message object. */ message(opts = {}) { - - let message = new Message(Object.assign({ theme: this.theme }, opts, { app: this })); + let message = new Message( + Object.assign({ theme: this.theme }, opts, { app: this }) + ); this.scene.addChild(message); return message @@ -4230,21 +4467,26 @@ * @param {boolean} [opts.progress=false] - Should a progress bar display the loading status? * @return {PIXIApp} The PIXIApp object for chaining. */ - loadSprites(resources, loaded = null, { resolutionDependent = true, progress = false } = {}) { + loadSprites( + resources, + loaded = null, + { resolutionDependent = true, progress = false } = {} + ) { + this.loadTextures( + resources, + textures => { + let sprites = new Map(); - this.loadTextures(resources, textures => { + for (let [key, texture] of textures) { + sprites.set(key, new PIXI.Sprite(texture)); + } - let sprites = new Map(); - - for (let [key, texture] of textures) { - sprites.set(key, new PIXI.Sprite(texture)); - } - - if (loaded) { - loaded.call(this, sprites); - } - - }, { resolutionDependent, progress }); + if (loaded) { + loaded.call(this, sprites); + } + }, + { resolutionDependent, progress } + ); return this } @@ -4262,8 +4504,11 @@ * @param {boolean} [opts.progress=false] - Should a progress bar display the loading status? * @return {PIXIApp} The PIXIApp object for chaining. */ - loadTextures(resources, loaded = null, { resolutionDependent = true, progress = false } = {}) { - + loadTextures( + resources, + loaded = null, + { resolutionDependent = true, progress = false } = {} + ) { if (!Array.isArray(resources)) { resources = [resources]; } @@ -4271,17 +4516,21 @@ const loader = this.loader; for (let resource of resources) { - if (!loader.resources[resource]) { - if (resolutionDependent) { let resolution = Math.round(this.renderer.resolution); switch (resolution) { case 2: - loader.add(resource, resource.replace(/\.([^.]*)$/, '@2x.$1')); + loader.add( + resource, + resource.replace(/\.([^.]*)$/, '@2x.$1') + ); break case 3: - loader.add(resource, resource.replace(/\.([^.]*)$/, '@3x.$1')); + loader.add( + resource, + resource.replace(/\.([^.]*)$/, '@3x.$1') + ); break default: loader.add(resource); @@ -4324,7 +4573,6 @@ * rejected with an error. */ query(query, opts = {}) { - if (typeof query === 'string') { opts = Object.assign({}, opts, { query }); } else { @@ -4356,7 +4604,6 @@ * rejected with an error. */ mutate(mutation, opts = {}) { - if (typeof mutation === 'string') { opts = Object.assign({}, opts, { mutation }); } else { @@ -4388,7 +4635,6 @@ * rejected with an error. */ subscribe(subscription, opts = {}) { - if (typeof subscription === 'string') { opts = Object.assign({}, opts, { subscription }); } else { @@ -4419,13 +4665,13 @@ * @param {DisplayObject} displayObject - The PIXI displayObject. * @param {number} x - The x coordinate. * @param {number} y - The y coordinate. - * + * * @return {PIXI.Point} Returns a PIXI.Point. */ convertPointFromPageToNode(displayObject, x, y) { let resolution = this.renderer.resolution; - console.log("resolution", resolution); + console.log('resolution', resolution); let pixiGlobal = window.convertPointFromPageToNode(app.view, x, y); pixiGlobal.x /= resolution; pixiGlobal.y /= resolution; @@ -4439,7 +4685,7 @@ * @param {DisplayObject} displayObject - The PIXI displayObject. * @param {number} x - The x coordinate. * @param {number} y - The y coordinate. - * + * * @return {Point} Returns a DOM Point. */ @@ -4449,7 +4695,11 @@ pixiGlobal.x *= resolution; pixiGlobal.y *= resolution; // console.log("app.convertPointFromNodeToPage", pixiGlobal) - return window.convertPointFromNodeToPage(app.view, pixiGlobal.x, pixiGlobal.y) + return window.convertPointFromNodeToPage( + app.view, + pixiGlobal.x, + pixiGlobal.y + ) } } @@ -4463,7 +4713,6 @@ * @see {@link http://pixijs.download/dev/docs/PIXI.Graphics.html|PIXI.Graphics} */ class FpsDisplay extends PIXI.Graphics { - /** * Creates an instance of a FpsDisplay. * @@ -4471,25 +4720,27 @@ * @param {PIXIApp} app - The PIXIApp where the frames per second should be displayed. */ constructor(app) { - super(); this.app = app; this.lineStyle(3, 0x434f4f, 1) - .beginFill(0x434f4f, .6) + .beginFill(0x434f4f, 0.6) .drawRoundedRect(0, 0, 68, 32, 5) .endFill() .position.set(20, 20); - this.text = new PIXI.Text(this.fps, new PIXI.TextStyle({ - fontFamily: 'Arial', - fontSize: 14, - fontWeight: 'bold', - fill: '#f6f6f6', - stroke: '#434f4f', - strokeThickness: 3 - })); + this.text = new PIXI.Text( + this.fps, + new PIXI.TextStyle({ + fontFamily: 'Arial', + fontSize: 14, + fontWeight: 'bold', + fill: '#f6f6f6', + stroke: '#434f4f', + strokeThickness: 3 + }) + ); this.text.position.set(6, 6); this.addChild(this.text); @@ -4505,7 +4756,7 @@ * @return {PIXIApp} Returns the PIXIApp object for chaining. */ refreshFps() { - this.text.text = `${(this.app.ticker.FPS).toFixed(1)} fps`; + this.text.text = `${this.app.ticker.FPS.toFixed(1)} fps`; return this } @@ -4526,17 +4777,17 @@ * height: 270, * transparent: false * }).setup().run() - * + * * // Add a video sprite * const sprite = new PIXI.Sprite(PIXI.Texture.fromVideo("assets/blurfilter.mp4")) * sprite.width = app.size.width * sprite.height = app.size.height * app.scene.addChild(sprite) - * + * * // Create the filter and assign it to the scene * const blurFilter = new BlurFilter(new PIXI.Rectangle(20, 20, 80, 60)) * app.scene.filters = [blurFilter] - * + * * @class * @extends PIXI.Filter * @param {PIXI.Rectangle|PIXI.Circle|PIXI.DisplayObject} shape The area where the blur effect should be applied to. Relative to the @@ -4544,7 +4795,6 @@ * @param {number} [blur=50] The strength of the blur. */ class BlurFilter extends PIXI.Filter { - constructor(shape, blur = 50) { super(); @@ -4572,7 +4822,7 @@ set blur(value) { this.tiltShiftXFilter.blur = this.tiltShiftYFilter.blur = value; } - + /** * The blur shape. * @@ -4582,26 +4832,39 @@ return this.tiltShiftXFilter.shape } set shape(value) { - this.tiltShiftXFilter.shape = this.tiltShiftYFilter.shape = this.normalize(value); + this.tiltShiftXFilter.shape = this.tiltShiftYFilter.shape = this.normalize( + value + ); } /** - * + * * @private * @param {PIXI.Rectangle|PIXI.Circle|PIXI.DisplayObject} value * @returns {Object} */ normalize(value) { - let shape = null; if (value instanceof PIXI.Circle) { - shape = {type: 'circle', x: value.x, y: value.y, r: value.radius}; + shape = { type: 'circle', x: value.x, y: value.y, r: value.radius }; } else if (value instanceof PIXI.Rectangle) { - shape = {type: 'rectangle', x: value.x, y: value.y, width: value.width, height: value.height}; + shape = { + type: 'rectangle', + x: value.x, + y: value.y, + width: value.width, + height: value.height + }; } else { const bounds = value.getBounds(); - shape = {type: 'rectangle', x: bounds.x, y: bounds.y, width: bounds.width, height: bounds.height}; + shape = { + type: 'rectangle', + x: bounds.x, + y: bounds.y, + width: bounds.width, + height: bounds.height + }; } return shape @@ -4617,9 +4880,7 @@ * @private */ class TiltShiftAxisFilter extends PIXI.Filter { - - constructor(shape, blur){ - + constructor(shape, blur) { const vertex = ` attribute vec2 aVertexPosition; attribute vec2 aTextureCoord; @@ -4686,13 +4947,18 @@ `; super(vertex, fragment); - + if (shape.type === 'circle') { this.uniforms.shape = 1; this.uniforms.circle = [shape.x, shape.y, shape.r]; } else { this.uniforms.shape = 2; - this.uniforms.rectangle = [shape.x, shape.y, shape.x + shape.width, shape.y + shape.height]; + this.uniforms.rectangle = [ + shape.x, + shape.y, + shape.x + shape.width, + shape.y + shape.height + ]; } this.uniforms.blur = blur; this.uniforms.delta = new PIXI.Point(0, 0); @@ -4713,7 +4979,7 @@ set blur(value) { this.uniforms.blur = value; } - + /** * The blur shape. * @@ -4726,7 +4992,12 @@ return new PIXI.Circle(circle[0], circle[1], circle[2]) } else { const rectangle = this.uniforms.rectangle; - return new PIXI.Rectangle(rectangle[0], rectangle[1], rectangle[2], rectangle[3]) + return new PIXI.Rectangle( + rectangle[0], + rectangle[1], + rectangle[2], + rectangle[3] + ) } } set shape(value) { @@ -4735,7 +5006,12 @@ this.uniforms.circle = [value.x, value.y, value.r]; } else { this.uniforms.shape = 2; - this.uniforms.rectangle = [value.x, value.y, value.x + value.width, value.y + value.height]; + this.uniforms.rectangle = [ + value.x, + value.y, + value.x + value.width, + value.y + value.height + ]; } } } @@ -4783,11 +5059,10 @@ static implementationError(klass) { let interfaceKeys = Reflect.ownKeys(this.prototype); let classKeys = Reflect.ownKeys(klass.prototype); - for(let key of interfaceKeys) { + for (let key of interfaceKeys) { let interfaceDesc = this.prototype[key]; let classDesc = klass.prototype[key]; - if (typeof(classDesc) == 'undefined') - return 'Missing ' + key + if (typeof classDesc == 'undefined') return 'Missing ' + key } return null } @@ -4799,10 +5074,10 @@ return error == null } - // TODO: Specify optional methods - // static optionalMethods() { - // return [this.onMouseWheel] - // } + // TODO: Specify optional methods + // static optionalMethods() { + // return [this.onMouseWheel] + // } } /* eslint-disable no-undef */ @@ -4827,15 +5102,14 @@ /** Basic class for app specific logging requirements. * Can be used to implement persistent logging in electron apps. - * Uses a logMessage cache to prevent error overflows. This is + * Uses a logMessage cache to prevent error overflows. This is * needed since errors may occur very frequently * (e.g. display update loops at 60fps, programmatic loops, ...). - * + * * The logging handlers can be overwritten by calling the static * setup method. */ class Logging$1 { - /** Static log function. * @param {*} message */ @@ -4844,9 +5118,9 @@ } /** - * Static warn function. + * Static warn function. * Emits each warning only once per session. - * @param {*} message + * @param {*} message */ static warn(message) { if (!logMessages.has(message)) { @@ -4856,10 +5130,10 @@ } /** - * Static error function. - * Emits each error message only once per session. - * @param {*} message - */ + * Static error function. + * Emits each error message only once per session. + * @param {*} message + */ static error(message) { if (!logMessages.has(message)) { logMessages.add(message); @@ -4867,7 +5141,11 @@ } } - static setup({log=console.log, warn=console.warn, error=console.error} = {}) { + static setup({ + log = console.log, + warn = console.warn, + error = console.error + } = {}) { logHandlers.log = log; logHandlers.warn = warn; logHandlers.error = error; @@ -4882,16 +5160,15 @@ */ class IInteractionTarget extends Interface { - capture(event) { return typeof true } - onStart(event, interaction) { } - onMove(event, interaction) { } - onEnd(event, interaction) { } + onStart(event, interaction) {} + onMove(event, interaction) {} + onEnd(event, interaction) {} - onMouseWheel(event) { } + onMouseWheel(event) {} } class IInteractionMapperTarget extends Interface { @@ -5099,14 +5376,32 @@ let currentAngle = Points.angle(c1, c2); let previousAngle = Points.angle(p1, p2); let alpha = this.diffAngle(currentAngle, previousAngle); - return new InteractionDelta(delta.x, delta.y, zoom, alpha, cm, csize) - } else if (csize == 1 && psize == 1 && this.current.firstKey() == this.previous.firstKey()) { + return new InteractionDelta( + delta.x, + delta.y, + zoom, + alpha, + cm, + csize + ) + } else if ( + csize == 1 && + psize == 1 && + this.current.firstKey() == this.previous.firstKey() + ) { // We need to ensure that the keys are the same, since single points with different keys // can jump let current = this.current.first(); let previous = this.previous.first(); let delta = Points.subtract(current, previous); - return new InteractionDelta(delta.x, delta.y, 1.0, 0.0, current, csize) + return new InteractionDelta( + delta.x, + delta.y, + 1.0, + 0.0, + current, + csize + ) } return null } @@ -5244,8 +5539,7 @@ if (this.tapCounts.has(key)) { let count = this.tapCounts.get(key); this.tapCounts.set(key, count + 1); - } - else { + } else { this.tapCounts.set(key, 1); } this.tapPositions.set(key, point); @@ -5287,7 +5581,10 @@ this.unregisterTap(key); } } - if (this.tapTimestamps.has(key) && performance.now() > this.tapTimestamps.get(key) + this.tapDuration) { + if ( + this.tapTimestamps.has(key) && + performance.now() > this.tapTimestamps.get(key) + this.tapDuration + ) { //console.log("tap too long") this.unregisterTap(key); } @@ -5295,8 +5592,7 @@ if (this.isTap(key)) { this.registerTap(key, ended); result = this.tapCounts.get(key) == 2; - } - else { + } else { this.unregisterTap(key); } //console.log("isDoubleTap", this.tapCounts.get(key), result) @@ -5363,7 +5659,13 @@ constructor( element, target, - { mouseWheelElement = null, useCapture = true, capturePointerEvents = true, cancelOnWindowOut = true, debug = false } = {} + { + mouseWheelElement = null, + useCapture = true, + capturePointerEvents = true, + cancelOnWindowOut = true, + debug = false + } = {} ) { this.debug = debug; this.interaction = new Interaction(); @@ -5418,7 +5720,8 @@ element.addEventListener( 'pointermove', e => { - if (this.debug) console.log('pointermove', e.pointerId, e.pointerType); + if (this.debug) + console.log('pointermove', e.pointerId, e.pointerType); if ( e.pointerType == 'touch' || @@ -5435,7 +5738,8 @@ element.addEventListener( 'pointerup', e => { - if (this.debug) console.log('pointerup', e.pointerId, e.pointerType); + if (this.debug) + console.log('pointerup', e.pointerId, e.pointerType); this.onEnd(e); if (this.capturePointerEvents) { try { @@ -5450,7 +5754,8 @@ element.addEventListener( 'pointercancel', e => { - if (this.debug) console.log('pointercancel', e.pointerId, e.pointerType); + if (this.debug) + console.log('pointercancel', e.pointerId, e.pointerType); this.onEnd(e); if (this.capturePointerEvents) element.releasePointerCapture(e.pointerId); @@ -5462,7 +5767,12 @@ element.addEventListener( 'pointerleave', e => { - if (this.debug) console.log('pointerleave', e.pointerId, e.pointerType); + if (this.debug) + console.log( + 'pointerleave', + e.pointerId, + e.pointerType + ); if (e.target == element) this.onEnd(e); }, useCapture @@ -5473,7 +5783,12 @@ element.addEventListener( 'pointerout', e => { - if (this.debug) console.log('pointerout', e.pointerId, e.pointerType); + if (this.debug) + console.log( + 'pointerout', + e.pointerId, + e.pointerType + ); if (e.target == element) this.onEnd(e); }, useCapture @@ -5484,14 +5799,20 @@ window.addEventListener( 'pointerout', e => { - if (this.debug) console.log('pointerout', e.pointerId, e.pointerType, e.target); + if (this.debug) + console.log( + 'pointerout', + e.pointerId, + e.pointerType, + e.target + ); if (e.target == element) { this.onEnd(e); } }, - useCapture); + useCapture + ); } - } else if (window.TouchEvent) { if (this.debug) console.log('Touch API'); element.addEventListener( @@ -5567,8 +5888,7 @@ // && Events.isMouseDown(e)) if (Events$1.isMouseDown(e)) { - if (this.debug) - console.log('mousemove', e); + if (this.debug) console.log('mousemove', e); this.onMove(e); } }, @@ -5589,7 +5909,9 @@ e => { if (e.target == element) { this.onEnd(e); - console.warn('Shouldn\'t happen: mouseout ends interaction'); + console.warn( + "Shouldn't happen: mouseout ends interaction" + ); } }, useCapture @@ -5603,7 +5925,8 @@ this.onEnd(e); } }, - useCapture); + useCapture + ); } } } @@ -5690,42 +6013,42 @@ // 'targetTouches' let result = {}; switch (event.constructor.name) { - case 'MouseEvent': { - let buttons = event.buttons || event.which; - if (buttons) result['mouse'] = this.getPosition(event); - break - } - case 'PointerEvent': { - result[event.pointerId.toString()] = this.getPosition(event); - break - } - case 'Touch': { - let id = + case 'MouseEvent': { + let buttons = event.buttons || event.which; + if (buttons) result['mouse'] = this.getPosition(event); + break + } + case 'PointerEvent': { + result[event.pointerId.toString()] = this.getPosition(event); + break + } + case 'Touch': { + let id = event.touchType === 'stylus' ? 'stylus' : event.identifier.toString(); - result[id] = this.getPosition(event); - break - } - // case 'TouchEvent': - // // Needs to be observed: Perhaps changedTouches are all we need. If so - // // we can remove the touchEventKey default parameter - // if (touchEventKey == 'all') { - // for(let t of event.targetTouches) { - // result[t.identifier.toString()] = this.getPosition(t) - // } - // for(let t of event.changedTouches) { - // result[t.identifier.toString()] = this.getPosition(t) - // } - // } - // else { - // for(let t of event.changedTouches) { - // result[t.identifier.toString()] = this.getPosition(t) - // } - // } - // break - default: - break + result[id] = this.getPosition(event); + break + } + // case 'TouchEvent': + // // Needs to be observed: Perhaps changedTouches are all we need. If so + // // we can remove the touchEventKey default parameter + // if (touchEventKey == 'all') { + // for(let t of event.targetTouches) { + // result[t.identifier.toString()] = this.getPosition(t) + // } + // for(let t of event.changedTouches) { + // result[t.identifier.toString()] = this.getPosition(t) + // } + // } + // else { + // for(let t of event.changedTouches) { + // result[t.identifier.toString()] = this.getPosition(t) + // } + // } + // break + default: + break } return result } @@ -5738,7 +6061,7 @@ // Callback: can be overwritten } - interactionFinished(event, key, point) { } + interactionFinished(event, key, point) {} startInteraction(event, extracted) { for (let key in extracted) { @@ -5753,7 +6076,10 @@ let point = extracted[key]; let updated = this.interaction.update(key, point); if (updated) { - console.warn('new pointer in updateInteraction shouldn\'t happen', key); + console.warn( + "new pointer in updateInteraction shouldn't happen", + key + ); this.interactionStarted(event, key, point); } } @@ -5791,13 +6117,23 @@ * @extends {InteractionDelegate} */ class InteractionMapper$1 extends InteractionDelegate { - constructor( element, target, - { tapDistance = 10, longPressTime = 500.0, useCapture = true, mouseWheelElement = null, logInteractionsAbove = 12 } = {} + { + tapDistance = 10, + longPressTime = 500.0, + useCapture = true, + mouseWheelElement = null, + logInteractionsAbove = 12 + } = {} ) { - super(element, target, { tapDistance, useCapture, longPressTime, mouseWheelElement }); + super(element, target, { + tapDistance, + useCapture, + longPressTime, + mouseWheelElement + }); this.logInteractionsAbove = logInteractionsAbove; } @@ -5904,10 +6240,7 @@ * @param {object} [opts] - An options object. See the hammer documentation for more details. */ static on(types, elements, cb, opts = {}) { - - opts = Object.assign({}, { - - }, opts); + opts = Object.assign({}, {}, opts); if (typeof Hammer === 'undefined') { console.error('Hammer.js not found!'); @@ -5916,23 +6249,25 @@ // convert to array types = Array.isArray(types) ? types : types.split(/\s/); - if (elements instanceof NodeList || elements instanceof HTMLCollection) { + if ( + elements instanceof NodeList || + elements instanceof HTMLCollection + ) { elements = Array.from(elements); } elements = Array.isArray(elements) ? elements : [elements]; for (let i = 0; i < types.length; i++) { - const type = types[i].toLowerCase(); // list of hammer events - const useHammer = /^(tap|doubletap|press|pan|swipe|pinch|rotate).*$/.test(type); + const useHammer = /^(tap|doubletap|press|pan|swipe|pinch|rotate).*$/.test( + type + ); // if it is a hammer event if (useHammer) { - for (let j = 0; j < elements.length; j++) { - // if(elements[j].tagName == "svg") return false; let hammer = new Hammer(elements[j], opts); @@ -5943,15 +6278,33 @@ // recognizers if (type.startsWith('pan')) { - hammer.get('pan').set(Object.assign({ direction: Hammer.DIRECTION_ALL }, opts)); + hammer + .get('pan') + .set( + Object.assign( + { direction: Hammer.DIRECTION_ALL }, + opts + ) + ); } else if (type.startsWith('pinch')) { - hammer.get('pinch').set(Object.assign({ enable: true }, opts)); + hammer + .get('pinch') + .set(Object.assign({ enable: true }, opts)); } else if (type.startsWith('press')) { hammer.get('press').set(opts); } else if (type.startsWith('rotate')) { - hammer.get('rotate').set(Object.assign({ enable: true }, opts)); + hammer + .get('rotate') + .set(Object.assign({ enable: true }, opts)); } else if (type.startsWith('swipe')) { - hammer.get('swipe').set(Object.assign({ direction: Hammer.DIRECTION_ALL }, opts)); + hammer + .get('swipe') + .set( + Object.assign( + { direction: Hammer.DIRECTION_ALL }, + opts + ) + ); } else if (type.startsWith('tap')) { hammer.get('tap').set(opts); } @@ -5960,9 +6313,7 @@ cb(event); }); } - } else { - for (let j = 0; j < elements.length; j++) { Hammer.on(elements[j], type, event => { cb(event); @@ -5980,7 +6331,6 @@ /** Report capabilities with guaranteed values. */ class Capabilities { - /** Returns the browser userAgent. @return {string} */ @@ -5993,7 +6343,7 @@ @return {boolean} */ static get isMobile() { - return (/Mobi/.test(navigator.userAgent)) + return /Mobi/.test(navigator.userAgent) } /** Tests whether the app is running on a iOS device. @@ -6001,7 +6351,7 @@ @return {boolean} */ static get isIOS() { - return (/iPad|iPhone|iPod/.test(navigator.userAgent)) && !window.MSStream + return /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream } /** Tests whether the app is running in a Safari environment. @@ -6010,28 +6360,44 @@ @return {boolean} */ static get isSafari() { - return navigator.vendor && navigator.vendor.indexOf('Apple') > -1 && navigator.userAgent && !navigator.userAgent.match('CriOS') + return ( + navigator.vendor && + navigator.vendor.indexOf('Apple') > -1 && + navigator.userAgent && + !navigator.userAgent.match('CriOS') + ) } /** * Distincts if the app is running inside electron or not. - * + * * source: https://github.com/cheton/is-electron */ static get isElectron() { - // Renderer process - if (typeof window !== 'undefined' && typeof window.process === 'object' && window.process.type === 'renderer') { + if ( + typeof window !== 'undefined' && + typeof window.process === 'object' && + window.process.type === 'renderer' + ) { return true } // Main process - if (typeof process !== 'undefined' && typeof process.versions === 'object' && !!process.versions.electron) { + if ( + typeof process !== 'undefined' && + typeof process.versions === 'object' && + !!process.versions.electron + ) { return true } // Detect the user agent when the `nodeIntegration` option is set to true - if (typeof navigator === 'object' && typeof navigator.userAgent === 'string' && navigator.userAgent.indexOf('Electron') >= 0) { + if ( + typeof navigator === 'object' && + typeof navigator.userAgent === 'string' && + navigator.userAgent.indexOf('Electron') >= 0 + ) { return true } @@ -6049,52 +6415,56 @@ @return {boolean} */ static get isMultiTouchTable() { - return Capabilities.devicePixelRatio > 2 && Capabilities.isMobile === false && /Windows/i.test(Capabilities.userAgent) + return ( + Capabilities.devicePixelRatio > 2 && + Capabilities.isMobile === false && + /Windows/i.test(Capabilities.userAgent) + ) } /** Returns true if mouse events are supported @return {boolean} */ static supportsMouseEvents() { - return typeof(window.MouseEvent) != 'undefined' + return typeof window.MouseEvent != 'undefined' } /** Returns true if touch events are supported @return {boolean} */ static supportsTouchEvents() { - return typeof(window.TouchEvent) != 'undefined' + return typeof window.TouchEvent != 'undefined' } /** Returns true if pointer events are supported @return {boolean} */ static supportsPointerEvents() { - return typeof(window.PointerEvent) != 'undefined' + return typeof window.PointerEvent != 'undefined' } /** Returns true if DOM templates are supported @return {boolean} */ static supportsTemplate() { - return 'content' in document.createElement('template'); + return 'content' in document.createElement('template') } } /** Basic tests for Capabilities. */ class CapabilitiesTests { - static testConfirm() { let bool = confirm('Please confirm'); - document.getElementById('demo').innerHTML = (bool) ? 'Confirmed' : 'Not confirmed'; + document.getElementById('demo').innerHTML = bool + ? 'Confirmed' + : 'Not confirmed'; } static testPrompt() { let person = prompt('Please enter your name', 'Harry Potter'); if (person != null) { - demo.innerHTML = - 'Hello ' + person + '! How are you today?'; + demo.innerHTML = 'Hello ' + person + '! How are you today?'; } } @@ -6109,7 +6479,9 @@ } static testMultiTouchTable() { - let value = 'Is the device a multi-touch table? ' + Capabilities.isMultiTouchTable; + let value = + 'Is the device a multi-touch table? ' + + Capabilities.isMultiTouchTable; multi_touch_table.innerHTML = value; } @@ -6190,7 +6562,7 @@ toString() { return ( - 'Event(\'scatterTransformed\', scale: ' + + "Event('scatterTransformed', scale: " + this.scale + ' about: ' + this.about.x + @@ -6265,7 +6637,12 @@ // Avoid division by zero errors later on // and consider the number of involved pointers sind addVelocity will be called by the // onMove events - let velocity = { t: t, dt: dt, dx: delta.x / delta.number, dy: delta.y / delta.number }; + let velocity = { + t: t, + dt: dt, + dx: delta.x / delta.number, + dy: delta.y / delta.number + }; this.velocities.push(velocity); while (this.velocities.length > buffer) { this.velocities.shift(); @@ -6361,8 +6738,8 @@ // damping, collison detection, etc. here let next = Points.multiplyScalar(velocity, this.throwDamping); return { - x: (this.movableX) ? next.x : 0, - y: (this.movableY) ? next.y : 0 + x: this.movableX ? next.x : 0, + y: this.movableY ? next.y : 0 } } @@ -6403,7 +6780,7 @@ onClose = null, onThrowFinished = null, scaleAutoClose = false, - scaleCloseThreshold = 0.10, + scaleCloseThreshold = 0.1, scaleCloseBuffer = 0.05, maxRotation = Angle.degree2radian(5), useLowPassFilter = true @@ -6425,7 +6802,7 @@ }); /** - * Closes the card when the minScale is reached and the + * Closes the card when the minScale is reached and the * card is released. Card can be saved by scaling it up again. */ this.scaleAutoClose = scaleAutoClose; @@ -6507,7 +6884,7 @@ if (this.useLowPassFilter) { rotate = this.rotateLPF.next(rotate); zoom = this.zoomLPF.next(zoom); - // console.log({rotate, zoom}) + // console.log({rotate, zoom}) } this.transform(delta, zoom, rotate, delta.about); if (zoom != 1) this.interactionAnchor = delta.about; @@ -6515,8 +6892,8 @@ } get polygon() { - let w2 = this.width * this.scale / 2; - let h2 = this.height * this.scale / 2; + let w2 = (this.width * this.scale) / 2; + let h2 = (this.height * this.scale) / 2; let center = this.center; let polygon = new Polygon(center); polygon.addPoint({ x: -w2, y: -h2 }); @@ -6529,11 +6906,9 @@ isOutside() { let stagePolygon = this.containerPolygon; - if (stagePolygon == null) - return false + if (stagePolygon == null) return false let polygon = this.polygon; - if (polygon == null) - return false + if (polygon == null) return false let result = stagePolygon.intersectsWith(polygon); return result === false || result.overlap < this.throwVisibility } @@ -6576,7 +6951,7 @@ keepOnStage(velocity, collision = 0.5) { let stagePolygon = this.containerPolygon; - // UO: since keepOnStage is called in nextVelocity we need to + // UO: since keepOnStage is called in nextVelocity we need to // ensure a return value if (!stagePolygon) return { x: 0, y: 0 } let polygon = this.polygon; @@ -6618,10 +6993,18 @@ _checkAutoClose() { if (this.scaleAutoClose) - if (this.scale < this.minScale + this.scaleCloseThreshold - this.scaleCloseBuffer) { - this.zoom(this.minScale, { animate: 0.2, onComplete: this.close.bind(this) }); + if ( + this.scale < + this.minScale + this.scaleCloseThreshold - this.scaleCloseBuffer + ) { + this.zoom(this.minScale, { + animate: 0.2, + onComplete: this.close.bind(this) + }); } else if (this.scale < this.minScale + this.scaleCloseThreshold) { - this.zoom(this.minScale + this.scaleCloseThreshold, { animate: 0.4 }); + this.zoom(this.minScale + this.scaleCloseThreshold, { + animate: 0.4 + }); } } @@ -6720,7 +7103,7 @@ fast: false, type: UPDATE }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -6729,9 +7112,15 @@ let origin = this.rotationOrigin; let beta = Points.angle(origin, anchor); let distance = Points.distance(origin, anchor); - let { scale: newScale, zoom: thresholdedZoom } = this.calculateScale(zoom); + let { scale: newScale, zoom: thresholdedZoom } = this.calculateScale( + zoom + ); - let newOrigin = Points.arc(anchor, beta + rotate, distance * thresholdedZoom); + let newOrigin = Points.arc( + anchor, + beta + rotate, + distance * thresholdedZoom + ); let extra = Points.subtract(newOrigin, origin); let offset = Points.subtract(anchor, origin); this._move(offset); @@ -6751,7 +7140,7 @@ rotate: rotate, about: anchor }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -6763,7 +7152,7 @@ /** * For a given zoom, a new scale is calculated, taking * min and max scale into account. - * + * * @param {number} zoom - The zoom factor, to scale the object with. * @returns {object} - Returns an object containing the a value for a valid scale and the corrected zoom factor. */ @@ -6781,8 +7170,7 @@ zoom = scale / this.scale; } - if (this.scaleAutoClose) - this._updateTransparency(); + if (this.scaleAutoClose) this._updateTransparency(); return { zoom, scale } } @@ -6795,8 +7183,10 @@ } calculateScaleTransparency() { - let transparency = (this.scale - this.minScale) / this.scaleCloseThreshold; - transparency = (transparency > 1) ? 1 : (transparency < 0) ? 0 : transparency; + let transparency = + (this.scale - this.minScale) / this.scaleCloseThreshold; + transparency = + transparency > 1 ? 1 : transparency < 0 ? 0 : transparency; return transparency } @@ -6813,7 +7203,7 @@ animateZoomBounce(dt = 1) { if (this.zoomAnchor != null) { let zoom = 1; - let amount = Math.min(0.01, 0.3 * dt / 100000.0); + let amount = Math.min(0.01, (0.3 * dt) / 100000.0); if (this.scale < this.minScale) zoom = 1 + amount; if (this.scale > this.maxScale) zoom = 1 - amount; if (zoom != 1) { @@ -6854,8 +7244,8 @@ if (this.scaleAutoClose) { if (this.scale <= this.minScale + this.scaleCloseThreshold) { - - if (this.scaleAutoCloseTimeout) clearTimeout(this.scaleAutoCloseTimeout); + if (this.scaleAutoCloseTimeout) + clearTimeout(this.scaleAutoCloseTimeout); this.scaleAutoCloseTimeout = setTimeout(() => { this._checkAutoClose(); }, 600); @@ -6865,7 +7255,6 @@ } onStart(event, interaction) { - if (this.startGesture(interaction)) { this.dragging = true; this.interactionAnchor = null; @@ -6879,7 +7268,7 @@ fast: false, type: START }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -6914,7 +7303,7 @@ fast: false, type: END }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -6925,7 +7314,7 @@ } } - onTap(event, interaction, point) { } + onTap(event, interaction, point) {} onDragUpdate(delta) { if (this.onTransform != null) { @@ -6936,7 +7325,7 @@ about: this.currentAbout, type: null }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -6950,7 +7339,7 @@ fast: false, type: null }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -6964,7 +7353,7 @@ fast: true, type: null }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -6977,16 +7366,14 @@ fast: false, type: null }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } } onZoomed(about) { - - if (this.scaleAutoClose) - this._updateTransparency(); + if (this.scaleAutoClose) this._updateTransparency(); if (this.onTransform != null) { let event = new ScatterEvent(this, { @@ -6995,15 +7382,13 @@ fast: false, type: null }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } } } - - class DOMScatter extends AbstractScatter { constructor( element, @@ -7027,7 +7412,7 @@ x = 0, y = 0, width = null, // required - height = null, // required + height = null, // required resizable = false, tapDelegate = null, triggerSVGClicks = false, @@ -7040,7 +7425,7 @@ autoThrow = true, scaleAutoClose = false, onClose = null, - scaleCloseThreshold = 0.10, + scaleCloseThreshold = 0.1, scaleCloseBuffer = 0.05, useLowPassFilter = true, maxRotation = Angle.degree2radian(15) @@ -7100,7 +7485,7 @@ transformOrigin: transformOrigin }; this.tapNodes = new Map(); - + // For tweenlite we need initial values in _gsTransform TweenLite.set(element, this.initialValues); this.onResize = onResize; @@ -7119,15 +7504,15 @@ button.className = 'interactiveElement'; this.element.appendChild(button); - button.addEventListener('pointerdown', (e) => { + button.addEventListener('pointerdown', e => { this.startResize(e); }); - button.addEventListener('pointermove', (e) => { + button.addEventListener('pointermove', e => { this.resize(e); }); - button.addEventListener('pointerup', (e) => { + button.addEventListener('pointerup', e => { this.stopResize(e); }); this.resizeButton = button; @@ -7297,7 +7682,7 @@ onTap(event, interaction, point) { if (this.tapDelegate) { Events$1.stop(event); - this.tapDelegate.tap(event, "scatter"); + this.tapDelegate.tap(event, 'scatter'); } } @@ -7349,12 +7734,18 @@ e.preventDefault(); let event = new CustomEvent('resizeStarted'); - let oldPostition = { x: this.element.getBoundingClientRect().left, y: this.element.getBoundingClientRect().top }; + let oldPostition = { + x: this.element.getBoundingClientRect().left, + y: this.element.getBoundingClientRect().top + }; this.bringToFront(); this.element.style.transformOrigin = '0% 0%'; - let newPostition = { x: this.element.getBoundingClientRect().left, y: this.element.getBoundingClientRect().top }; + let newPostition = { + x: this.element.getBoundingClientRect().left, + y: this.element.getBoundingClientRect().top + }; let offset = Points.subtract(oldPostition, newPostition); @@ -7377,23 +7768,31 @@ rotation = (rotation + 360) % 360; let event = new CustomEvent('resized'); if (e.target.getAttribute('resizing') == 'true') { - - let deltaX = (e.clientX - this.oldX); - let deltaY = (e.clientY - this.oldY); + let deltaX = e.clientX - this.oldX; + let deltaY = e.clientY - this.oldY; let r = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2)); let phi = Angle.radian2degree(Math.atan2(deltaX, deltaY)); - phi = ((phi) + 630) % 360; - let rot = ((rotation + 90) + 630) % 360; + phi = (phi + 630) % 360; + let rot = (rotation + 90 + 630) % 360; - let diffAngle = ((0 + rot) + 360) % 360; + let diffAngle = (0 + rot + 360) % 360; let phiCorrected = (phi + diffAngle + 360) % 360; let resizeW = r * Math.cos(Angle.degree2radian(phiCorrected)); let resizeH = -r * Math.sin(Angle.degree2radian(phiCorrected)); - if ((this.element.offsetWidth + resizeW) / this.scale > this.width * 0.5 / this.scale && (this.element.offsetHeight + resizeH) / this.scale > this.height * 0.3 / this.scale) TweenLite.to(this.element, 0, { width: this.element.offsetWidth + resizeW / this.scale, height: this.element.offsetHeight + resizeH / this.scale }); + if ( + (this.element.offsetWidth + resizeW) / this.scale > + (this.width * 0.5) / this.scale && + (this.element.offsetHeight + resizeH) / this.scale > + (this.height * 0.3) / this.scale + ) + TweenLite.to(this.element, 0, { + width: this.element.offsetWidth + resizeW / this.scale, + height: this.element.offsetHeight + resizeH / this.scale + }); this.oldX = e.clientX; this.oldY = e.clientY; @@ -7407,9 +7806,15 @@ e.preventDefault(); let event = new CustomEvent('resizeEnded'); - let oldPostition = { x: this.element.getBoundingClientRect().left, y: this.element.getBoundingClientRect().top }; + let oldPostition = { + x: this.element.getBoundingClientRect().left, + y: this.element.getBoundingClientRect().top + }; this.element.style.transformOrigin = '50% 50%'; - let newPostition = { x: this.element.getBoundingClientRect().left, y: this.element.getBoundingClientRect().top }; + let newPostition = { + x: this.element.getBoundingClientRect().left, + y: this.element.getBoundingClientRect().top + }; let offset = Points.subtract(oldPostition, newPostition); TweenLite.to(this.element, 0, { css: { left: '+=' + offset.x + 'px' } }); @@ -7452,12 +7857,10 @@ this.maxHeight = maxHeight != null ? maxHeight : window.innerHeight; this.addedNode = null; console.log({ - width, height, maxWidth, - maxHeight, - + maxHeight }); } @@ -7535,7 +7938,7 @@ this.cardWrapper = dom.querySelector('#' + this.id); let front = this.cardWrapper.querySelector('.front'); this.frontLoader.load(front).then(loader => { - this.frontLoaded(loader).then((obj) => { + this.frontLoaded(loader).then(obj => { if (this.onLoaded) this.onLoaded(); resolve(this); }); @@ -7562,7 +7965,9 @@ scalable: this.scalable, rotatable: this.rotatable, overdoScaling: this.overdoScaling, - tapDelegate: (this.tapDelegateFactory) ? this.tapDelegateFactory(this.cardWrapper) : null + tapDelegate: this.tapDelegateFactory + ? this.tapDelegateFactory(this.cardWrapper) + : null } ); @@ -7571,7 +7976,7 @@ } if (this.closeOnMinScale) { - const removeOnMinScale = function () { + const removeOnMinScale = function() { if (scatter.scale <= scatter.minScale) { this.flippable.close(); @@ -7581,7 +7986,9 @@ //Remove callback if (scatter.onTransform) { - let callbackIdx = scatter.onTransform.indexOf(removeOnMinScale); + let callbackIdx = scatter.onTransform.indexOf( + removeOnMinScale + ); scatter.onTransform.splice(callbackIdx, 1); } } @@ -7612,7 +8019,7 @@ } setupFlippable(flippable, loader) { - console.log("setupFlippable", loader.wantedWidth); + console.log('setupFlippable', loader.wantedWidth); flippable.wantedWidth = loader.wantedWidth; flippable.wantedHeight = loader.wantedHeight; flippable.wantedScale = loader.scale; @@ -7622,12 +8029,10 @@ } start({ targetCenter = null } = {}) { - console.log("DOMFlip.start", targetCenter); + console.log('DOMFlip.start', targetCenter); if (this.preloadBack) { - this.flippable.start({ duration: this.flipDuration, targetCenter }); - } - else { + } else { let back = this.cardWrapper.querySelector('.back'); let flippable = this.flippable; this.backLoader.load(back).then(loader => { @@ -7774,7 +8179,7 @@ clickInfo() { this.bringToFront(); - console.log("clickInfo"); + console.log('clickInfo'); this.infoBtn.click(); } @@ -7872,14 +8277,14 @@ let y = this.flipped ? yy : this.startY; let onUpdate = this.onUpdate !== null ? () => this.onUpdate(this) : null; - console.log("start", this.flipDuration); + console.log('start', this.flipDuration); TweenLite.to(this.card, this.flipDuration, { rotationY: targetY, ease: Power1.easeOut, transformOrigin: '50% 50%', onUpdate, onComplete: e => { - console.log("start end", this.flipDuration); + console.log('start end', this.flipDuration); if (this.flipped) { //this.hide(this.front) this.enable(this.backBtn); @@ -7889,7 +8294,6 @@ this.onFrontFlipped(this); } } else { - if (this.onBackFlipped == null) { this.enable(this.infoBtn, this.fadeDuration); this.enable(this.closeBtn, this.fadeDuration); @@ -7912,7 +8316,7 @@ force3D: true }); - console.log("start 2", this.wantedWidth, this.startWidth, {w, h}); + console.log('start 2', this.wantedWidth, this.startWidth, { w, h }); // See https://greensock.com/forums/topic/7997-rotate-the-shortest-way/ TweenLite.to(this.element, this.flipDuration / 2, { scale: targetScale, @@ -9885,7 +10289,6 @@ let globalScatterLoaderCanvas = null; class ScatterLoader extends CardLoader { - get scatter() { return this.src } @@ -9913,8 +10316,7 @@ if (isSprite) { w = this.scatter.displayObject.texture.width; h = this.scatter.displayObject.texture.height; - } - else if (isDeepZoom) { + } else if (isDeepZoom) { let [ww, hh] = this.scatter.displayObject.baseSize; w = ww; h = hh; @@ -9926,8 +10328,9 @@ canvas.width = w; canvas.height = h; let renderer = new PIXI.WebGLRenderer(w, h, { - view: canvas, - resolution: resolution}); + view: canvas, + resolution: resolution + }); let displayObject = this.scatter.displayObject; let x = displayObject.x; @@ -9942,8 +10345,7 @@ if (Capabilities.isSafari) { displayObject.y = h; displayObject.scale.set(1, -1); // sx, -sy) - } - else { + } else { displayObject.y = 0; displayObject.scale.set(1, 1); } @@ -9965,12 +10367,11 @@ return new Promise((resolve, reject) => { let isImage = domNode instanceof HTMLImageElement; let isSprite = this.scatter.displayObject instanceof PIXI.Sprite; - let image = (isImage) ? domNode : document.createElement("img"); + let image = isImage ? domNode : document.createElement('img'); let [x, y, w, h, cloneURL] = this.cloneScatterImage(); let [ww, hh] = this.unscaledSize(); - image.onload = (e) => { - if (!isImage) - domNode.appendChild(image); + image.onload = e => { + if (!isImage) domNode.appendChild(image); this.x = x; this.y = y; this.wantedWidth = ww; @@ -9979,40 +10380,42 @@ this.rotation = this.scatter.rotation; resolve(this); }; - image.onerror = (e) => { + image.onerror = e => { reject(this); }; image.src = cloneURL; - }) + }) } - } class FlipEffect { - constructor(scatter, domScatterContainer, flipTemplate, backLoader) { this.flipped = false; this.scatter = scatter; this.backLoader = backLoader; this.scatterLoader = new ScatterLoader(scatter); - this.domFlip = new DOMFlip(domScatterContainer, flipTemplate, - this.scatterLoader, - backLoader, { - onBack: this.backCardClosed.bind(this) - }); + this.domFlip = new DOMFlip( + domScatterContainer, + flipTemplate, + this.scatterLoader, + backLoader, + { + onBack: this.backCardClosed.bind(this) + } + ); this.setupInfoButton(); } startFlip() { let center = this.flipCenter(); let loader = this.backLoader; - this.domFlip.load().then((domFlip) => { + this.domFlip.load().then(domFlip => { this.scatter.displayObject.visible = false; domFlip.centerAt(center); domFlip.zoom(this.scatter.scale); let target = this.constraintFlipCenter(center, loader); - console.log("FlipEffect.startFlip", target, loader); - domFlip.start({targetCenter: target}); + console.log('FlipEffect.startFlip', target, loader); + domFlip.start({ targetCenter: target }); }); } @@ -10022,13 +10425,15 @@ flipCenter() { let isSprite = this.scatter.displayObject instanceof PIXI.Sprite; - let resolution = (isSprite) ? app.renderer.resolution : 1; + let resolution = isSprite ? app.renderer.resolution : 1; let center = this.scatter.center; let canvas = app.renderer.view; let domNode = this.domFlip.domScatterContainer.element; - let page = window.convertPointFromNodeToPage(canvas, - center.x*resolution, - center.y*resolution); + let page = window.convertPointFromNodeToPage( + canvas, + center.x * resolution, + center.y * resolution + ); let local = window.convertPointFromPageToNode(domNode, page.x, page.y); return local } @@ -10036,18 +10441,14 @@ constraintFlipCenter(center, loader) { let w = loader.wantedWidth; let h = loader.wantedHeight; - console.log("constraintFlipCenter", w, h); + console.log('constraintFlipCenter', w, h); let canvas = app.renderer.view; let x = center.x; let y = center.y; - if (x < w/2) - x = w/2; - if (y < h/2) - y = h/2; - if (x > canvas.width) - x = canvas.width - w/2; - if (y > canvas.height) - y = canvas.height - h/2; + if (x < w / 2) x = w / 2; + if (y < h / 2) y = h / 2; + if (x > canvas.width) x = canvas.width - w / 2; + if (y > canvas.height) y = canvas.height - h / 2; return { x, y } } @@ -10055,22 +10456,26 @@ let iscale = 1.0 / this.scatter.scale; this.infoBtn = new PIXI.Graphics(); this.infoBtn.beginFill(0x333333); - this.infoBtn.lineStyle(4, 0xFFFFFF); + this.infoBtn.lineStyle(4, 0xffffff); this.infoBtn.drawCircle(0, 0, 22); this.infoBtn.endFill(); - this.infoBtn.beginFill(0xFFFFFF); + this.infoBtn.beginFill(0xffffff); this.infoBtn.lineStyle(0); this.infoBtn.drawCircle(0, -8, 4); this.infoBtn.endFill(); - this.infoBtn.lineStyle(6, 0xFFFFFF); + this.infoBtn.lineStyle(6, 0xffffff); this.infoBtn.moveTo(0, -2); this.infoBtn.lineTo(0, 14); this.infoBtn.endFill(); - this.infoBtn.on('click', (e) => { this.infoSelected(); }); - this.infoBtn.on('tap', (e) => { this.infoSelected(); }); + this.infoBtn.on('click', e => { + this.infoSelected(); + }); + this.infoBtn.on('tap', e => { + this.infoSelected(); + }); this.infoBtn.interactive = true; this.infoBtn.width = 44; @@ -10085,8 +10490,7 @@ this.infoBtn.scale.x = iscale; this.infoBtn.scale.y = iscale; displayObject.foreground.addChild(this.infoBtn); - } - else { + } else { displayObject.addChild(this.infoBtn); } @@ -10109,15 +10513,15 @@ canvas.height = 44 * 4; svgImage.onload = e => { let displayObject = this.scatter.displayObject; - canvas.getContext ('2d').drawImage(svgImage, 0, 0, - canvas.width, canvas.height); + canvas + .getContext('2d') + .drawImage(svgImage, 0, 0, canvas.width, canvas.height); let texure = new PIXI.Texture(new PIXI.BaseTexture(canvas)); this.infoBtn = new PIXI.Sprite(texure); this.infoBtn.anchor.set(0.5, 0.5); if (displayObject.foreground) { displayObject.foreground.addChild(this.infoBtn); - } - else { + } else { displayObject.addChild(this.infoBtn); } this.infoBtn.scale.set(0.5, 0.5); @@ -10126,8 +10530,12 @@ this.infoBtn.position = new PIXI.Point(w, h); this.infoBtn.interactive = true; this.infoBtn.updateTransform(); - this.infoBtn.on('click', (e) => { this.infoSelected(); }); - this.infoBtn.on('tap', (e) => { this.infoSelected(); }); + this.infoBtn.on('click', e => { + this.infoSelected(); + }); + this.infoBtn.on('tap', e => { + this.infoSelected(); + }); }; svgImage.src = url; } @@ -10153,10 +10561,9 @@ let ortho = 90; let rest = alpha % ortho; let delta = 0.0; - if (rest > (ortho / 2.0)) { + if (rest > ortho / 2.0) { delta = ortho - rest; - } - else { + } else { delta = -rest; } return delta @@ -10194,10 +10601,10 @@ * const front = PIXI.Sprite.fromImage('./assets/front.jpg') * const back = PIXI.Sprite.fromImage('./assets/back.jpg') * app.scene.addChild(front) - * + * * // Create the flippable * const flippable = new Flippable(front, back, app.renderer) - * + * * front.interactive = true * front.on('click', event => flippable.toggle()) * @@ -10207,7 +10614,6 @@ * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/flippable.html|DocTest} */ class Flippable extends PIXI.projection.Camera3d { - /** * Creates an instance of a Flippable. * @@ -10233,30 +10639,38 @@ * @param {function} [opts.onComplete=null] - A callback executed when the flip animation is finished. */ constructor(front, back, renderer, opts = {}) { - super(); - this.opts = Object.assign({}, { - front, - back, - renderer, - duration: 1, - ease: Power2.easeOut, - shadow: false, - eulerX: 0, - eulerY: 0, - eulerEase: Power1.easeOut, - useBackTransforms: false, - transformEase: Power2.easeOut, - focus: 800, - near: 10, - far: 10000, - orthographic: false - }, opts); + this.opts = Object.assign( + {}, + { + front, + back, + renderer, + duration: 1, + ease: Power2.easeOut, + shadow: false, + eulerX: 0, + eulerY: 0, + eulerEase: Power1.easeOut, + useBackTransforms: false, + transformEase: Power2.easeOut, + focus: 800, + near: 10, + far: 10000, + orthographic: false + }, + opts + ); // planes //-------------------- - this.setPlanes(this.opts.focus, this.opts.near, this.opts.far, this.opts.orthographic); + this.setPlanes( + this.opts.focus, + this.opts.near, + this.opts.far, + this.opts.orthographic + ); // flipped //-------------------- @@ -10278,8 +10692,7 @@ * @return {Flippable} A reference to the flippable for chaining. */ setup() { - - const scale = .5; + const scale = 0.5; // filters //-------------------- @@ -10296,16 +10709,18 @@ // shadow //-------------------- - const shadow = new PIXI.projection.Sprite3d(PIXI.Texture.fromImage('../../assets/images/shadow.png')); + const shadow = new PIXI.projection.Sprite3d( + PIXI.Texture.fromImage('../../assets/images/shadow.png') + ); shadow.renderable = false; shadow.anchor.set(0.5); - shadow.scale3d.set(.98); + shadow.scale3d.set(0.98); shadow.alpha = 0.7; shadow.filters = [blurFilter]; shadow.visible = this.opts.shadow; outer.addChild(shadow); this.objects.shadow = shadow; - + // inner //-------------------- const inner = new PIXI.projection.Container3d(); @@ -10318,7 +10733,7 @@ const front = new PIXI.projection.Sprite3d(PIXI.Texture.EMPTY); front.scale.set(-1 / scale, 1 / scale); front.renderable = true; - front.anchor.set(.5); + front.anchor.set(0.5); inner.addChild(front); this.objects.front = front; @@ -10327,7 +10742,7 @@ const back = new PIXI.projection.Sprite3d(PIXI.Texture.EMPTY); back.scale.set(1 / scale, 1 / scale); back.renderable = false; - back.anchor.set(.5); + back.anchor.set(0.5); inner.addChild(back); this.objects.back = back; @@ -10343,7 +10758,6 @@ return this._flipped } set flipped(toBack) { - this._flipped = toBack; // references @@ -10364,7 +10778,7 @@ //-------------------- front.texture = this.generateTexture(this.opts.front); back.texture = this.generateTexture(this.opts.back); - + // switch objects and set params for virtual objects //-------------------- const fromCenter = this.anchorToCenter(fromObject); @@ -10389,11 +10803,21 @@ y: this.opts.useBackTransforms ? toCenter.y : fromCenter.y, anchorX: this.opts.useBackTransforms ? toObject.x : fromObject.x, anchorY: this.opts.useBackTransforms ? toObject.y : fromObject.y, - width: this.opts.useBackTransforms ? toObject.width * 2 : fromObject.width * 2, - height: this.opts.useBackTransforms ? toObject.height * 2 : fromObject.height * 2, - rotation: this.opts.useBackTransforms ? toObject.rotation : fromObject.rotation, - skewX: this.opts.useBackTransforms ? toObject.skew.x : fromObject.skew.x, - skewY: this.opts.useBackTransforms ? toObject.skew.y : fromObject.skew.y + width: this.opts.useBackTransforms + ? toObject.width * 2 + : fromObject.width * 2, + height: this.opts.useBackTransforms + ? toObject.height * 2 + : fromObject.height * 2, + rotation: this.opts.useBackTransforms + ? toObject.rotation + : fromObject.rotation, + skewX: this.opts.useBackTransforms + ? toObject.skew.x + : fromObject.skew.x, + skewY: this.opts.useBackTransforms + ? toObject.skew.y + : fromObject.skew.y }; // set toObject end values @@ -10470,20 +10894,24 @@ // camera //-------------------- new TimelineMax() - .to(this.euler, half, {x: this.opts.eulerX, y: this.opts.eulerY, ease}) - .to(this.euler, half, {x: 0, y: 0, ease}); + .to(this.euler, half, { + x: this.opts.eulerX, + y: this.opts.eulerY, + ease + }) + .to(this.euler, half, { x: 0, y: 0, ease }); // shadow //-------------------- new TimelineMax() - .to(shadow, half, {alpha: .3, ease}) - .to(shadow, half, {alpha: .7, ease}); - + .to(shadow, half, { alpha: 0.3, ease }) + .to(shadow, half, { alpha: 0.7, ease }); + // blurfilter //-------------------- new TimelineMax() - .to(blurFilter, half, {blur: 6, ease}) - .to(blurFilter, half, {blur: .2, ease}); + .to(blurFilter, half, { blur: 6, ease }) + .to(blurFilter, half, { blur: 0.2, ease }); } /** @@ -10492,18 +10920,18 @@ * @return {Flippable} A reference to the flippable for chaining. */ layout() { - const front = this.objects.front; const back = this.objects.back; const shadow = this.objects.shadow; const inner = this.objects.inner; - - inner.position3d.z = -Math.sin(inner.euler.y) * front.texture.baseTexture.width * 2; + + inner.position3d.z = + -Math.sin(inner.euler.y) * front.texture.baseTexture.width * 2; //this.objects.shadow.euler = this.objects.inner.euler shadow.euler.x = -inner.euler.x; shadow.euler.y = -inner.euler.y; - + if (this.frontSideInFront) { front.renderable = true; back.renderable = false; @@ -10563,13 +10991,25 @@ * @return {PIXI.Texture} The generated PIXI.Texture. */ generateTexture(displayObject) { - // renderTexture //-------------------- - const renderTexture = PIXI.RenderTexture.create(displayObject.width, displayObject.height); + const renderTexture = PIXI.RenderTexture.create( + displayObject.width, + displayObject.height + ); // save position - const transform = [displayObject.x, displayObject.y, displayObject.scale.x, displayObject.scale.y, displayObject.rotation, displayObject.skew.x, displayObject.skew.y, displayObject.pivot.x, displayObject.pivot.y]; + const transform = [ + displayObject.x, + displayObject.y, + displayObject.scale.x, + displayObject.scale.y, + displayObject.rotation, + displayObject.skew.x, + displayObject.skew.y, + displayObject.pivot.x, + displayObject.pivot.y + ]; displayObject.position.set(0, 0); displayObject.skew.set(0, 0); @@ -10578,7 +11018,7 @@ // render //-------------------- this.opts.renderer.render(displayObject, renderTexture); - + // restore position displayObject.setTransform(...transform); @@ -10606,15 +11046,32 @@ } /** - * + * */ class Popover extends PIXI.Graphics { - - constructor({title = null, text = null, x = 0, y = 0, placement = 'top', width = 250, titleStyle = {}, textStyle = {fontSize: '1.6em'}} = {}) { + constructor({ + title = null, + text = null, + x = 0, + y = 0, + placement = 'top', + width = 250, + titleStyle = {}, + textStyle = { fontSize: '1.6em' } + } = {}) { super(); - this.opts = {title, text, x, y, placement, width, titleStyle, textStyle}; - + this.opts = { + title, + text, + x, + y, + placement, + width, + titleStyle, + textStyle + }; + this.padding = 12; let style = { @@ -10623,12 +11080,16 @@ stroke: '#f6f6f6', strokeThickness: 3, wordWrap: true, - wordWrapWidth: width - (this.padding * 2) + wordWrapWidth: width - this.padding * 2 }; - this.titleTextStyle = new PIXI.TextStyle(Object.assign({}, style, titleStyle)); - this.textTextStyle = new PIXI.TextStyle(Object.assign({}, style, textStyle)); - + this.titleTextStyle = new PIXI.TextStyle( + Object.assign({}, style, titleStyle) + ); + this.textTextStyle = new PIXI.TextStyle( + Object.assign({}, style, textStyle) + ); + if (title || text) { this.setup(); this.draw(); @@ -10650,7 +11111,10 @@ if (this.opts.text) { this.textText = new PIXI.Text(this.opts.text, this.textTextStyle); - this.textText.position.set(this.padding, this.titleY + this.titleHeight + this.padding); + this.textText.position.set( + this.padding, + this.titleY + this.titleHeight + this.padding + ); this.addChild(this.textText); } @@ -10665,7 +11129,7 @@ draw() { this.clear(); this.beginFill(0xffffff, 1); - this.lineStyle(1, 0x282828, .5); + this.lineStyle(1, 0x282828, 0.5); // Draw rounded rectangle const height = this.height + this.padding; @@ -10679,7 +11143,7 @@ this.lineStyle(0); this.beginFill(0xf7f7f7, 1); let x = 1; - let y = this.titleText.x + this.titleText.height + (this.padding / 2); + let y = this.titleText.x + this.titleText.height + this.padding / 2; this.moveTo(x, y); y = 9; this.lineTo(x, y); @@ -10689,7 +11153,7 @@ this.lineTo(x, y); this.quadraticCurveTo(x + 5, y, x + 5, y + 8); x += 5; - y += this.titleText.x + this.titleText.height + (this.padding / 2); + y += this.titleText.x + this.titleText.height + this.padding / 2; this.lineTo(x, y); if (this.opts.text) { x = 1; @@ -10707,7 +11171,6 @@ } drawAnchor(placement) { - let x = 0; let y = 0; @@ -10716,7 +11179,7 @@ if (this.opts.title) { this.beginFill(0xf7f7f7, 1); } - x = (this.width / 2) - 10; + x = this.width / 2 - 10; y = 1; this.moveTo(x, y); x += 10; @@ -10728,7 +11191,7 @@ break case 'right': x = 1; - y = (this.height / 2) - 10; + y = this.height / 2 - 10; if (this.titleY + this.titleHeight > y) { this.beginFill(0xf7f7f7, 1); } @@ -10742,7 +11205,7 @@ break case 'left': x = this.width - 2; - y = (this.height / 2) - 10; + y = this.height / 2 - 10; if (this.titleY + this.titleHeight > y) { this.beginFill(0xf7f7f7, 1); } @@ -10755,7 +11218,7 @@ this.lineTo(x, y); break default: - x = (this.width / 2) - 10; + x = this.width / 2 - 10; y = this.height - 2; this.moveTo(x, y); x += 10; @@ -10769,22 +11232,21 @@ } positioning() { - const x = this.opts.x; const y = this.opts.y; switch (this.opts.placement) { case 'bottom': - this.position.set(x - (this.width / 2), y + 10); + this.position.set(x - this.width / 2, y + 10); break case 'right': - this.position.set(x, y - (this.height / 2)); + this.position.set(x, y - this.height / 2); break case 'left': - this.position.set(x - this.width, y - (this.height / 2)); + this.position.set(x - this.width, y - this.height / 2); break default: - this.position.set(x - (this.width / 2), y - this.height); + this.position.set(x - this.width / 2, y - this.height); break } } @@ -10796,30 +11258,32 @@ * on the same level. */ class ScatterContainer extends PIXI.Graphics { - /** - * @constructor - * @param {PIXI.Renderer} renderer - PIXI renderer, needed for hit testing - * @param {Bool} stopEvents - Whether events should be stopped or propagated - * @param {Bool} claimEvents - Whether events should be marked as claimed - * if findTarget return as non-null value. - * @param {PIXI.Container} container - A container for the scatter - * @param {Bool} showBounds - Show bounds for debugging purposes. - * @param {Bool} showTouches - Show touches and pointer for debugging purposes. - * @param {Color} backgroundColor - Set background color if specified. - * @param {PIXIApp} app - Needed if showBounds is true to register - * update handler. - */ - constructor(renderer, { - stopEvents = true, - claimEvents = true, - container = null, - showBounds = false, - showPolygon = false, - showTouches = false, - backgroundColor = null, - app = window.app - } = {}) { + * @constructor + * @param {PIXI.Renderer} renderer - PIXI renderer, needed for hit testing + * @param {Bool} stopEvents - Whether events should be stopped or propagated + * @param {Bool} claimEvents - Whether events should be marked as claimed + * if findTarget return as non-null value. + * @param {PIXI.Container} container - A container for the scatter + * @param {Bool} showBounds - Show bounds for debugging purposes. + * @param {Bool} showTouches - Show touches and pointer for debugging purposes. + * @param {Color} backgroundColor - Set background color if specified. + * @param {PIXIApp} app - Needed if showBounds is true to register + * update handler. + */ + constructor( + renderer, + { + stopEvents = true, + claimEvents = true, + container = null, + showBounds = false, + showPolygon = false, + showTouches = false, + backgroundColor = null, + app = window.app + } = {} + ) { super(); this.container = container; if (this.container) @@ -10840,7 +11304,7 @@ this.backgroundColor = backgroundColor; if (showBounds || showTouches || showPolygon) { //console.log("Show TOUCHES!!!") - this.app.ticker.add((delta) => this.update(delta), this); + this.app.ticker.add(delta => this.update(delta), this); } if (backgroundColor) { this.updateBackground(); @@ -10864,8 +11328,12 @@ let y = 0; // @container: We need to call the constant values, as the container // gets resized, when a child moves outside the original boundaries. - let w = (this.container) ? this.containerDimensions.x : (this.backgroundWidth || this.app.width); - let h = (this.container) ? this.containerDimensions.y : (this.backgroundHeight || this.app.height); + let w = this.container + ? this.containerDimensions.x + : this.backgroundWidth || this.app.width; + let h = this.container + ? this.containerDimensions.y + : this.backgroundHeight || this.app.height; if (this.app.fullscreen && this.app.monkeyPatchMapping) { let fixed = this.mapPositionToPoint({ x: w, y: 0 }); @@ -10900,7 +11368,7 @@ update(dt) { this.clear(); - this.lineStyle(1, 0x0000FF); + this.lineStyle(1, 0x0000ff); if (this.showBounds) { for (let child of this.children) { if (child.scatter) { @@ -10912,11 +11380,11 @@ this.drawCircle(child.scatter.x, child.scatter.y, 4); } } - this.lineStyle(2, 0x0000FF); + this.lineStyle(2, 0x0000ff); this.drawShape(this.bounds); } if (this.showPolygon) { - this.lineStyle(2, 0xFF0000); + this.lineStyle(2, 0xff0000); for (let child of this.children) { if (child.scatter) { let polygon = child.scatter.polygon; @@ -10936,8 +11404,7 @@ } capture(event) { - if (this.stopEvents) - Events$1.stop(event); + if (this.stopEvents) Events$1.stop(event); return true } @@ -10949,8 +11416,14 @@ // if (hit) { // console.log("findHitScatter", displayObject) // } - if (hit && this.hitScatter === null && typeof (displayObject) != undefined) { - this.hitScatter = (displayObject.scatter) ? displayObject.scatter : null; + if ( + hit && + this.hitScatter === null && + typeof displayObject != undefined + ) { + this.hitScatter = displayObject.scatter + ? displayObject.scatter + : null; } } @@ -10960,7 +11433,10 @@ let local = new PIXI.Point(); let interactionManager = this.renderer.plugins.interaction; interactionManager.mapPositionToPoint(local, point.x, point.y); - if (element instanceof DisplayObjectScatter && element.displayObject.parent != null) { + if ( + element instanceof DisplayObjectScatter && + element.displayObject.parent != null + ) { return element.displayObject.parent.toLocal(local) } return local @@ -10977,11 +11453,13 @@ this.hitScatter = null; let interactionManager = this.renderer.plugins.interaction; let fakeEvent = this.fakeInteractionEvent(local); - interactionManager.processInteractive(fakeEvent, + interactionManager.processInteractive( + fakeEvent, this, - this.findHitScatter.bind(this), true); - if (this.claimEvents) - event.claimedByScatter = this.hitScatter; + this.findHitScatter.bind(this), + true + ); + if (this.claimEvents) event.claimedByScatter = this.hitScatter; return this.hitScatter } @@ -10996,19 +11474,13 @@ let displayObject = interactionManager.hitTest(local, this); if (displayObject != null && displayObject.scatter != null) this.hitScatter = displayObject.scatter; - if (this.claimEvents) - event.claimedByScatter = this.hitScatter; + if (this.claimEvents) event.claimedByScatter = this.hitScatter; return this.hitScatter } + onStart(event, interaction) {} - onStart(event, interaction) { - - } - - onMove(event, interaction) { - - } + onMove(event, interaction) {} onEnd(event, interaction) { for (let key of interaction.ended.keys()) { @@ -11040,7 +11512,6 @@ if (this.backgroundColor) { this.updateBackground(); } - } } @@ -11049,14 +11520,20 @@ * PIXI.DisplayObject can be wrapped. */ class DisplayObjectScatter extends AbstractScatter { - - constructor(displayObject, renderer, - { x = null, y = null, + constructor( + displayObject, + renderer, + { + x = null, + y = null, minScale = 0.1, maxScale = 1.0, startScale = 1.0, autoBringToFront = true, - translatable = true, scalable = true, rotatable = true, resizable = false, + translatable = true, + scalable = true, + rotatable = true, + resizable = false, movableX = true, movableY = true, throwVisibility = 44, @@ -11066,19 +11543,29 @@ rotation = null, overdoScaling = 1.5, onTransform = null, - onThrowFinished = null } = {}) { + onThrowFinished = null + } = {} + ) { // For the simulation of named parameters, // see: http://exploringjs.com/es6/ch_parameter-handling.html super({ overdoScaling, - minScale, maxScale, + minScale, + maxScale, startScale, autoBringToFront, - translatable, scalable, rotatable, resizable, - movableX, movableY, throwVisibility, throwDamping, + translatable, + scalable, + rotatable, + resizable, + movableX, + movableY, + throwVisibility, + throwDamping, autoThrow, onThrowFinished, - rotationDegrees, rotation, + rotationDegrees, + rotation, onTransform }); this.displayObject = displayObject; @@ -11245,7 +11732,10 @@ if (this.displayObject.parent instanceof ScatterContainer) { let scatterContainer = this.displayObject.parent; scatterContainer.bringToFront(this.displayObject); - } else if (this.displayObject.parent != null && this.displayObject.parent.scatter) { + } else if ( + this.displayObject.parent != null && + this.displayObject.parent.scatter + ) { this.displayObject.parent.scatter.toFront(this.displayObject); } } @@ -11278,12 +11768,11 @@ this.setup(); } - setup() { - } + setup() {} draw() { this.clear(); - var color = (this.selected) ? this.selectedColor : 0xFFFFFF; + var color = this.selected ? this.selectedColor : 0xffffff; this.lineStyle(0); this.beginFill(color, 1); this.drawShape(this.shape); @@ -11371,7 +11860,6 @@ } class RecorderTools extends PIXI.Container { - constructor(renderer) { super(renderer); this.renderer = renderer; @@ -11385,7 +11873,9 @@ setup(container) { // Since this delegate might shadow another delegate, we mus avoid // capturing PointerEvents. - this.delegate = new InteractionMapper(container, this, { capturePointerEvents: false }); + this.delegate = new InteractionMapper(container, this, { + capturePointerEvents: false + }); } findTarget(event, local, global) { @@ -11394,13 +11884,21 @@ setupToolbar() { this.toolbar = new PIXI.Graphics(); - this.record = new RecordCommand(this, 0xCC0000, new PIXI.Circle(0, 0, 16)); - this.play = new PlayCommand(this, 0x0000CC, new PIXI.Polygon(0, 16, - 32, 16 + 16, - 0, 16 + 32, - 0, 16)); - this.stop = new StopCommand(this, 0x0000CC, - new PIXI.Rectangle(0, 0, 32, 32)); + this.record = new RecordCommand( + this, + 0xcc0000, + new PIXI.Circle(0, 0, 16) + ); + this.play = new PlayCommand( + this, + 0x0000cc, + new PIXI.Polygon(0, 16, 32, 16 + 16, 0, 16 + 32, 0, 16) + ); + this.stop = new StopCommand( + this, + 0x0000cc, + new PIXI.Rectangle(0, 0, 32, 32) + ); this.toolbar.addChild(this.record).position.set(44, 48); this.toolbar.addChild(this.play).position.set(44 + 44, 16); this.toolbar.addChild(this.stop).position.set(44 + 44 + 44 + 16, 32); @@ -11412,7 +11910,7 @@ var graphics = this.toolbar; graphics.clear(); graphics.beginFill(0x000000, 0.5); - graphics.lineStyle(2, 0xFFFFFF, 1); + graphics.lineStyle(2, 0xffffff, 1); graphics.drawRoundedRect(16, 16, 44 * 4 + 8, 64, 8); graphics.endFill(); } @@ -11438,7 +11936,11 @@ mapPositionToPoint(point) { let local = new PIXI.Point(); - this.renderer.plugins.interaction.mapPositionToPoint(local, point.x, point.y); + this.renderer.plugins.interaction.mapPositionToPoint( + local, + point.x, + point.y + ); return local } @@ -11447,8 +11949,7 @@ } capture(event) { - if (typeof event.mouseDownSubstitute != 'undefined') - return false + if (typeof event.mouseDownSubstitute != 'undefined') return false return true } @@ -11489,8 +11990,7 @@ let local = this.extractLocal(event); if (this.toolbar.containsPoint(local)) { this.onPress(local); - } - else { + } else { this.recordEvent(event); this.updateTouchGraphics(interaction); } @@ -11507,9 +12007,9 @@ } let p = current.get(key); if (key == 'mouse') { - graphics.beginFill(0xCC0000, 0.5); + graphics.beginFill(0xcc0000, 0.5); } else { - graphics.beginFill(0xCCCCCC, 0.5); + graphics.beginFill(0xcccccc, 0.5); } graphics.drawCircle(p.x, p.y, 20); } @@ -11519,7 +12019,6 @@ } class AppTest extends PIXIApp { - constructor(canvas, container) { super({ view: canvas, backgroundColor: 0x000000 }); this.container = container; @@ -11545,7 +12044,6 @@ * Defines usefull default text styles. */ class FontInfo { - static get small() { return app.theme.textStyleSmall } @@ -11561,15 +12059,13 @@ /** * Static methods to support hyphenation of lines. - * + * * @class Hypenate */ class Hypenate { - static splitPart(part) { let parts = part.split('-'); - if (parts.length == 1) - return [part] + if (parts.length == 1) return [part] let result = []; let last = parts.pop(); for (let p of parts) { @@ -11580,7 +12076,7 @@ } static splitWord(word) { - if (typeof (language) == 'undefined') { + if (typeof language == 'undefined') { if (word.indexOf('-') > -1) { return word.split('-') } @@ -11597,13 +12093,13 @@ } static abbreviateLine(label, style, width) { - const pixiStyle = new PIXI.TextStyle(style); + const pixiStyle = new PIXI.TextStyle(style); let metrics = PIXI.TextMetrics.measureText(label, pixiStyle); - while(metrics.width > width && label.length > 3) { - label = label.slice(0, label.length-1); + while (metrics.width > width && label.length > 3) { + label = label.slice(0, label.length - 1); metrics = PIXI.TextMetrics.measureText(label, pixiStyle); } - label = label.slice(0, label.length-1); + label = label.slice(0, label.length - 1); return label + '…' } @@ -11619,17 +12115,21 @@ if (parts.length == 1) { newWord += '\n' + word + ' '; x = wordMetrics.width + space.width; - } - else { + } else { let first = true; let lastPart = ''; for (let part of parts) { - let partMetrics = PIXI.TextMetrics.measureText(part, pixiStyle); + let partMetrics = PIXI.TextMetrics.measureText( + part, + pixiStyle + ); if (x + partMetrics.width + space.width > width) { - newWord += ((first || lastPart.endsWith('-')) ? '\n' : '-\n') + part; + newWord += + (first || lastPart.endsWith('-') + ? '\n' + : '-\n') + part; x = partMetrics.width; - } - else { + } else { newWord += part; x += partMetrics.width; } @@ -11639,8 +12139,7 @@ x += space.width; } result += newWord + ' '; - } - else { + } else { result += word + ' '; x += wordMetrics.width + space.width; } @@ -11649,7 +12148,7 @@ } /** - * Main method and entry point for text hyphenation + * Main method and entry point for text hyphenation * * @static * @param {*} text @@ -11672,17 +12171,21 @@ } class TextLabel extends PIXI.Text { - /** *Creates an instance of TextLabel. * @param {string} text - The string that you would like the text to display - * @param {object|PIXI.TextStyle} [style] - The style parameters - * @param {canvas} + * @param {object|PIXI.TextStyle} [style] - The style parameters + * @param {canvas} * @memberof TextLabel */ - constructor(text, style=null, canvas=null, { minZoom = 0.1, maxZoom = 10} = {}) { - super(text, style, canvas ); - this.normFontSize = this.style.fontSize; + constructor( + text, + style = null, + canvas = null, + { minZoom = 0.1, maxZoom = 10 } = {} + ) { + super(text, style, canvas); + this.normFontSize = this.style.fontSize; this.minZoom = minZoom; this.maxZoom = maxZoom; } @@ -11721,10 +12224,9 @@ * @extends {PIXI.Graphics} */ class LabeledGraphics extends PIXI.Graphics { - /** * Creates an instance of LabeledGraphics and defines a local label cache. - * + * * @memberof LabeledGraphics */ constructor() { @@ -11736,14 +12238,13 @@ return new TextLabel(label, fontInfo) } - /** * Main additional method. Ensures that a text object is created that is cached * under the given key. * * @param {*} key - The cache key * @param {*} label - The label to show - * @param {*} [attrs={}] - Defines attributes of the text object. + * @param {*} [attrs={}] - Defines attributes of the text object. * align: 'right', 'left', or 'center' * justify: 'top', 'bottom', or 'center' * maxLines: {integer} truncates the text and adds ellipsis @@ -11754,11 +12255,9 @@ * @memberof LabeledGraphics */ ensureLabel(key, label, attrs = {}, fontInfo = FontInfo.normal) { - if (attrs.maxWidth && attrs.maxLines == 1) { label = Hypenate.abbreviateLine(label, fontInfo, attrs.maxWidth); - } - else { + } else { if (attrs.maxWidth) { label = Hypenate.splitLines(label, fontInfo, attrs.maxWidth); } @@ -11772,7 +12271,7 @@ label = this.truncateLabel(label, fontInfo, maxLines); } } - + if (!this.labels.has(key)) { let text = this._createText(label, fontInfo); this.labels.set(key, text); @@ -11782,8 +12281,7 @@ for (let k in attrs) { text[k] = attrs[k]; } - if (label != text.text) - text.text = label; + if (label != text.text) text.text = label; // We do not follow the flexbox jargon and use align for x and justify for y axis // This deviation is needed to ensure backward compatability switch (attrs.justify || null) { @@ -11834,17 +12332,30 @@ const truncatedLines = lines.slice(0, maxLines); const lastLine = truncatedLines[truncatedLines.length - 1]; const words = lastLine.split(' '); - const wordMetrics = PIXI.TextMetrics.measureText(`\u00A0\n...\n${words.join('\n')}`, pixiStyle); - const [spaceLength, dotsLength, ...wordLengths] = wordMetrics.lineWidths; - const { text: newLastLine } = wordLengths.reduce((data, wordLength, i) => { - if (data.length + wordLength + spaceLength >= wordWrapWidth) { - return { ...data, length: wordWrapWidth } - } - return { - text: `${data.text}${i > 0 ? ' ' : ''}${words[i]}`, - length: data.length + wordLength + spaceLength, - }; - }, { text: '', length: dotsLength }); + const wordMetrics = PIXI.TextMetrics.measureText( + `\u00A0\n...\n${words.join('\n')}`, + pixiStyle + ); + const [ + spaceLength, + dotsLength, + ...wordLengths + ] = wordMetrics.lineWidths; + const { text: newLastLine } = wordLengths.reduce( + (data, wordLength, i) => { + if ( + data.length + wordLength + spaceLength >= + wordWrapWidth + ) { + return { ...data, length: wordWrapWidth } + } + return { + text: `${data.text}${i > 0 ? ' ' : ''}${words[i]}`, + length: data.length + wordLength + spaceLength + } + }, + { text: '', length: dotsLength } + ); truncatedLines[truncatedLines.length - 1] = `${newLastLine}...`; newText = truncatedLines.join('\n'); } @@ -11862,7 +12373,7 @@ return this.labels.get(key) } - /** + /** * Hides the label with the given key. * @param {*} key * @memberof LabeledGraphics @@ -11874,7 +12385,7 @@ } } - /** + /** * Removes the label with the given key. * @param {*} key * @memberof LabeledGraphics @@ -11885,7 +12396,6 @@ label.destroy(); } - /** * Ensures that labels are hidden on clear. * @@ -11908,7 +12418,6 @@ } } - const labelCache = new Map(); function getTexture(label, fontInfo = FontInfo.normal) { @@ -11926,7 +12435,6 @@ } class SpriteLabel extends PIXI.Sprite { - constructor(label, fontInfo) { let texture = getTexture(label, fontInfo); super(texture); @@ -11946,16 +12454,13 @@ } class BitmapLabeledGraphics extends LabeledGraphics { - _createText(label, fontInfo) { let texture = getTexture(label, fontInfo); return new SpriteLabel(texture) } - } class Ticks { - get reservedPrefixes() { return ['decade', 'year', 'month', 'day', 'hour', 'minute', 'second'] } @@ -12021,15 +12526,19 @@ visibleLast = end; } } - if (first == null) - return info - return { start: first, end: last, visibleStart: visibleFirst, visibleEnd: visibleLast, units: units } + if (first == null) return info + return { + start: first, + end: last, + visibleStart: visibleFirst, + visibleEnd: visibleLast, + units: units + } } drawTick(timeline, x, y, date) { let visible = date > timeline.start && date < timeline.end; - if (!visible) - return false + if (!visible) return false timeline.drawTick(x); return true } @@ -12038,13 +12547,24 @@ return date.toLocaleDateString('de', format) } - draw(timeline, range, width, height, available, format, nextFormat, level, extraTicks=false) { + draw( + timeline, + range, + width, + height, + available, + format, + nextFormat, + level, + extraTicks = false + ) { let first = null; let last = null; - let keyedFormat = (format) ? format[this.formatKey] : null; - let keyedNextFormat = (nextFormat) ? nextFormat[this.formatKey] : null; - let redundant = (nextFormat) ? this.formatKey in nextFormat : false; - let fullyRedundant = keyedFormat != null && keyedFormat == keyedNextFormat; + let keyedFormat = format ? format[this.formatKey] : null; + let keyedNextFormat = nextFormat ? nextFormat[this.formatKey] : null; + let redundant = nextFormat ? this.formatKey in nextFormat : false; + let fullyRedundant = + keyedFormat != null && keyedFormat == keyedNextFormat; let y = timeline.getY(); for (let { start, end } of this.iterRanges(range)) { let x = timeline.toX(start); @@ -12061,31 +12581,29 @@ let nextX = timeline.toX(end) - 100; if (x < 0 && nextX > -100 && !redundant) { xx = Math.min(4, nextX); - } - else { + } else { xx -= 2; } - } - else if (level > 0) { + } else if (level > 0) { xx = x + available / 2; } - + if (!fullyRedundant) { - timeline.ensureLabel(key, text, + timeline.ensureLabel( + key, + text, { x: xx, y: yy, align }, - FontInfo.small); + FontInfo.small + ); } - if (extraTicks) - timeline.drawTick(x, -level); + if (extraTicks) timeline.drawTick(x, -level); } if (timeline.visibleRange(start, end)) { - if (first == null) - first = start; + if (first == null) first = start; last = end; } } - if (first == null) - return null + if (first == null) return null return { start: first, end: last } } @@ -12100,7 +12618,6 @@ } class DecadeTicks extends Ticks { - get milliseconds() { return 10 * 365 * 24 * 60 * 60 * 1000 } @@ -12133,14 +12650,12 @@ } class YearTicks extends Ticks { - get milliseconds() { return 365 * 24 * 60 * 60 * 1000 } format(available) { - if (available < 44) - return { year: '2-digit', timeZone: 'UTC' } + if (available < 44) return { year: '2-digit', timeZone: 'UTC' } return { year: 'numeric', timeZone: 'UTC' } } @@ -12162,17 +12677,14 @@ } class MonthTicks extends Ticks { - get milliseconds() { return (365 / 12) * 24 * 60 * 60 * 1000 } format(available) { let format = { month: 'narrow', timeZone: 'UTC' }; - if (available > 44) - format.month = 'short'; - if (available > 66) - format.year = '2-digit'; + if (available > 44) format.month = 'short'; + if (available > 66) format.year = '2-digit'; if (available > 100) { format.month = 'long'; format.year = 'numeric'; @@ -12202,15 +12714,13 @@ } class DayTicks extends Ticks { - get milliseconds() { return 24 * 60 * 60 * 1000 } format(available) { let format = { day: 'numeric', timeZone: 'UTC' }; - if (available > 44) - format.month = 'short'; + if (available > 44) format.month = 'short'; if (available > 100) { format.month = 'long'; format.year = '2-digit'; @@ -12234,7 +12744,11 @@ } iterStart(start) { - return Dates.create(start.getFullYear(), start.getMonth(), start.getDate()) + return Dates.create( + start.getFullYear(), + start.getMonth(), + start.getDate() + ) } next(date) { @@ -12243,7 +12757,6 @@ } class TimeTicks { - constructor(...ticks) { this.ticks = ticks; } @@ -12275,9 +12788,11 @@ let amount = ticks.milliseconds / duration; let available = amount * size; availables.set(ticks, available); - if (available < ticks.minWidth) - break - formats.set(ticks, (available < ticks.minLabelWidth) ? null : ticks.format(available)); + if (available < ticks.minWidth) break + formats.set( + ticks, + available < ticks.minLabelWidth ? null : ticks.format(available) + ); nextFormats.set(previous, formats.get(ticks)); previous = ticks; visible.push(ticks); @@ -12285,21 +12800,26 @@ let level = 0; let ranges = []; for (let ticks of visible) { - if (range == null) - continue - range = ticks.draw(timeline, range, width, height, + if (range == null) continue + range = ticks.draw( + timeline, + range, + width, + height, availables.get(ticks), formats.get(ticks), - nextFormats.get(ticks), level); + nextFormats.get(ticks), + level + ); if (range) { - ranges.push({ticks, range}); + ranges.push({ ticks, range }); } level += 1; } let extraLevel = ranges.length - 1; let extraStart = extraLevel; - for(let {ticks, range} of ranges) { + for (let { ticks, range } of ranges) { ticks.drawExtra(timeline, range, extraLevel); extraLevel -= 1; if (extraLevel <= 0) { @@ -12315,7 +12835,6 @@ } class ColorRanges { - constructor(label, color, ranges) { this.label = label; this.color = color; @@ -12342,9 +12861,16 @@ } class Timeline extends BitmapLabeledGraphics { - - constructor(width, height, { ticks = null, - baseLine = 0.5, showRange = true, throwDamping = 0.95 } = {}) { + constructor( + width, + height, + { + ticks = null, + baseLine = 0.5, + showRange = true, + throwDamping = 0.95 + } = {} + ) { super(); this.wantedWidth = width; this.wantedHeight = height; @@ -12361,10 +12887,12 @@ this.deltas = []; this.labelDates = []; this.colorRanges = []; - this.rangeColors = new Cycle(Colors.eminence, + this.rangeColors = new Cycle( + Colors.eminence, Colors.steelblue, Colors.ochre, - Colors.turquoise); + Colors.turquoise + ); this.callbacks = []; this.onTapCallbacks = []; this.onDoubleTapCallbacks = []; @@ -12376,18 +12904,21 @@ this.autoScroll = false; this.direction = -1; this.throwDamping = throwDamping; - this.timeticks = ticks || new TimeTicks(new DecadeTicks(), - new YearTicks(), - new MonthTicks(), - new DayTicks()); + this.timeticks = + ticks || + new TimeTicks( + new DecadeTicks(), + new YearTicks(), + new MonthTicks(), + new DayTicks() + ); this.labelPrefix = '__'; } updateSelection() { if (this.visibleDate(this.start) && this.visibleDate(this.end)) { this.selection = [this.start, this.end]; - } - else { + } else { this.timeticks.selectedRange(this); } @@ -12433,8 +12964,12 @@ let cr = this.colorRanges[i]; let label = cr.label; cr.draw(this, w, h); - let current = this.ensureLabel('colorRange:' + label, label, - { x: xx, y: yy, align: 'right' }, FontInfo.small); + let current = this.ensureLabel( + 'colorRange:' + label, + label, + { x: xx, y: yy, align: 'right' }, + FontInfo.small + ); let r = current.getBounds(); xx -= r.width + 16; @@ -12463,7 +12998,7 @@ this.prepareLabels(); this.updateColorRanges(w, h); - this.lineStyle(2, 0xFFFFFF); + this.lineStyle(2, 0xffffff); if (this.start != null && this.end != null) { this.moveTo(this.toX(this.start), y); this.lineTo(this.toX(this.end), y); @@ -12471,32 +13006,30 @@ this.updateSelection(); let selected = this.selection; if (selected[0] != this.start && selected[1] != this.end) { - if (this.showRange) - this.drawSelectedRamge(selected); + if (this.showRange) this.drawSelectedRamge(selected); } for (let callback of this.callbacks) { callback(this.scroll, this.zoom, this.selection); } - } - else { + } else { this.moveTo(this.inset, y); this.lineTo(w - this.inset, y); } if (this.progress != null && this.progress < 1) { - this.lineStyle(2, 0xCCCCFF); + this.lineStyle(2, 0xccccff); this.moveTo(this.inset, y); this.lineTo((w - this.inset) * this.progress, y); } } totalWidth(bounded = false) { - let w = this.wantedWidth - (2 * this.inset); + let w = this.wantedWidth - 2 * this.inset; return w * this.validZoom(this.zoom, bounded) } validZoom(zoom, bounded = true) { - let overshoot = (bounded) ? 1.0 : 2.0; + let overshoot = bounded ? 1.0 : 2.0; zoom = Math.max(zoom, this.minZoom / overshoot); zoom = Math.min(zoom, this.maxZoom * overshoot); return zoom @@ -12530,7 +13063,7 @@ y = this.getY(); } this.moveTo(x, y); - this.lineTo(x, y - (this.tickHeight * direction * this.direction)); + this.lineTo(x, y - this.tickHeight * direction * this.direction); } prepareLabels() { @@ -12550,24 +13083,22 @@ visibleDate(date, offset = 0) { if (date >= this.start && date <= this.end) { let x = this.toX(date) + offset; - return (x > 0 && x < this.wantedWidth) + return x > 0 && x < this.wantedWidth } return false } visibleRange(start, end) { let x = this.toX(start); - if (x > this.wantedWidth) - return false + if (x > this.wantedWidth) return false x = this.toX(end); - if (x < 0) - return false + if (x < 0) return false return true } tickLabelOffset(direction = 1, level = 0) { let fs = FontInfo.small.fontSize; - let dh = fs + (level * (fs + 2)); + let dh = fs + level * (fs + 2); return this.direction * direction * dh } @@ -12580,12 +13111,16 @@ let [label, date] = this.labelDates[i]; let align = 'center'; // (last == null) ? 'right' : 'left' let x = this.toX(date); - let current = this.ensureLabel(this.labelPrefix + label, label, + let current = this.ensureLabel( + this.labelPrefix + label, + label, { - x: x, y: y, + x: x, + y: y, align }, - FontInfo.small); + FontInfo.small + ); let r = current.getBounds(); current.visible = !(last != null && r.x + r.width > last.x); if (current.visible) { @@ -12593,12 +13128,26 @@ last = r; } } - } - else { - let start = this.start.toLocaleDateString('de', { year: 'numeric', month: 'numeric', day: 'numeric' }); - let end = this.end.toLocaleDateString('de', { year: 'numeric', month: 'numeric', day: 'numeric' }); - this.ensureLabel(this.labelPrefix + 'start', start, { x: this.toX(this.start), y: h2 }); - this.ensureLabel(this.labelPrefix + 'end', end, { x: this.toX(this.end), y: h2, align: 'right' }); + } else { + let start = this.start.toLocaleDateString('de', { + year: 'numeric', + month: 'numeric', + day: 'numeric' + }); + let end = this.end.toLocaleDateString('de', { + year: 'numeric', + month: 'numeric', + day: 'numeric' + }); + this.ensureLabel(this.labelPrefix + 'start', start, { + x: this.toX(this.start), + y: h2 + }); + this.ensureLabel(this.labelPrefix + 'end', end, { + x: this.toX(this.end), + y: h2, + align: 'right' + }); } } @@ -12614,7 +13163,7 @@ this.killTweens(); this.deltas = []; this.validScroll(); - if (typeof ThrowPropsPlugin != "undefined") { + if (typeof ThrowPropsPlugin != 'undefined') { ThrowPropsPlugin.track(this, 'delta'); } } @@ -12636,8 +13185,7 @@ } onEnd(event, interaction) { - - if (typeof ThrowPropsPlugin != "undefined") { + if (typeof ThrowPropsPlugin != 'undefined') { let vel = ThrowPropsPlugin.getVelocity(this, 'delta'); ThrowPropsPlugin.untrack(this); } @@ -12655,33 +13203,31 @@ let anchor = interaction.current.mean(); this.keepInBounds(delta, anchor); - for(let key of interaction.ended.keys()) { + for (let key of interaction.ended.keys()) { if (interaction.isDoubleTap(key)) { this.onDoubleTap(event, interaction, key); - } - else if (interaction.isTap(key)) { + } else if (interaction.isTap(key)) { this.onTap(event, interaction, key); - } - else if (interaction.isLongPress(key)) { + } else if (interaction.isLongPress(key)) { this.onLongPress(event, interaction, key); } } } onLongPress(event, interaction, key) { - for(let callback of this.onLongPressCallbacks) { + for (let callback of this.onLongPressCallbacks) { callback(event, interaction, key); } } onTap(event, interaction, key) { - for(let callback of this.onTapCallbacks) { + for (let callback of this.onTapCallbacks) { callback(event, interaction, key); } } onDoubleTap(event, interaction, key) { - for(let callback of this.onDoubleTapCallbacks) { + for (let callback of this.onDoubleTapCallbacks) { callback(event, interaction, key); } } @@ -12694,8 +13240,7 @@ _scrollMaximum(bounded) { let total = this.totalWidth(bounded); let limit = this.wantedWidth; - if (total > limit) - return 0 + if (total > limit) return 0 let w = limit - 2 * this.inset; return (w - total) / 2 } @@ -12713,7 +13258,6 @@ this.autoScroll = false; } - validScroll(bounded = true) { let minimum = this.scrollMinimum(bounded); let maximum = this.scrollMaximum(bounded); @@ -12738,8 +13282,7 @@ let newX = this.toX(date); tweens.scroll = this.scroll + anchor.x - newX; this.zoom = oldZoom; - } - else { + } else { if (this.zoom < this.minZoom) { tweens.zoom = this.minZoom; } @@ -12751,7 +13294,9 @@ } } if (!isEmpty(tweens)) { - tweens.onUpdate = () => { this.redraw(); }; + tweens.onUpdate = () => { + this.redraw(); + }; TweenLite.to(this, 0.5, tweens).delay(0.1); return } @@ -12768,15 +13313,14 @@ let direction = event.detail < 0 || event.wheelDelta > 0; let anchor = { x: event.clientX, y: event.clientY }; const zoomFactor = 1.5; - this.onZoom((direction) ? zoomFactor : 1 / zoomFactor, anchor); + this.onZoom(direction ? zoomFactor : 1 / zoomFactor, anchor); this.redraw(); this.keepInBounds(0, anchor); } - showRanges(ranges, label = "Untitled", color = null) { + showRanges(ranges, label = 'Untitled', color = null) { for (let cr of this.colorRanges) { - if (cr.label == label) - return + if (cr.label == label) return } while (this.colorRanges.length >= this.rangeColors.length) { this.colorRanges.shift(); @@ -12812,26 +13356,29 @@ * @param {number} [options.fadeWait=3000] time to wait before fading the scrollbar if options.fade is set * @param {(string|function)} [options.fadeEase=easeInOutSine] easing function to use for fading */ - constructor(options) - { + constructor(options) { super(); - this.options = Object.assign({}, { - boxWidth: 100, - boxHeight: 100, - scrollbarSize: 10, - scrollbarBackground: 14540253, - scrollbarBackgroundAlpha: 1, - scrollbarForeground: 8947848, - scrollbarForegroundAlpha: 1, - dragScroll: true, - stopPropagation: true, - scrollbarOffsetHorizontal: 0, - scrollbarOffsetVertical: 0, - underflow: 'top-left', - fadeScrollbar: false, - fadeWait: 3000, - fadeEase: 'easeInOutSine' - }, options); + this.options = Object.assign( + {}, + { + boxWidth: 100, + boxHeight: 100, + scrollbarSize: 10, + scrollbarBackground: 14540253, + scrollbarBackgroundAlpha: 1, + scrollbarForeground: 8947848, + scrollbarForegroundAlpha: 1, + dragScroll: true, + stopPropagation: true, + scrollbarOffsetHorizontal: 0, + scrollbarOffsetVertical: 0, + underflow: 'top-left', + fadeScrollbar: false, + fadeWait: 3000, + fadeEase: 'easeInOutSine' + }, + options + ); this.ease = new PIXI.extras.Ease.list(); this.on('added', event => { @@ -12843,10 +13390,15 @@ * you can use any function from pixi-viewport on content to manually move the content (see https://davidfig.github.io/pixi-viewport/jsdoc/) * @type {PIXI.extras.Viewport} */ - this.content = this.addChild(new PIXI.extras.Viewport({ passiveWheel: this.options.stopPropagation, stopPropagation: this.options.stopPropagation, screenWidth: this.options.boxWidth, screenHeight: this.options.boxHeight })); - this.content - .decelerate() - .on('moved', () => this._drawScrollbars()); + this.content = this.addChild( + new PIXI.extras.Viewport({ + passiveWheel: this.options.stopPropagation, + stopPropagation: this.options.stopPropagation, + screenWidth: this.options.boxWidth, + screenHeight: this.options.boxHeight + }) + ); + this.content.decelerate().on('moved', () => this._drawScrollbars()); /** * graphics element for drawing the scrollbars @@ -12868,12 +13420,10 @@ * offset of horizontal scrollbar (in pixels) * @type {number} */ - get scrollbarOffsetHorizontal() - { + get scrollbarOffsetHorizontal() { return this.options.scrollbarOffsetHorizontal } - set scrollbarOffsetHorizontal(value) - { + set scrollbarOffsetHorizontal(value) { this.options.scrollbarOffsetHorizontal = value; } @@ -12881,12 +13431,10 @@ * offset of vertical scrollbar (in pixels) * @type {number} */ - get scrollbarOffsetVertical() - { + get scrollbarOffsetVertical() { return this.options.scrollbarOffsetVertical } - set scrollbarOffsetVertical(value) - { + set scrollbarOffsetVertical(value) { this.options.scrollbarOffsetVertical = value; } @@ -12894,14 +13442,11 @@ * disable the scrollbox (if set to true this will also remove the mask) * @type {boolean} */ - get disable() - { + get disable() { return this._disabled } - set disable(value) - { - if (this._disabled !== value) - { + set disable(value) { + if (this._disabled !== value) { this._disabled = value; this.update(); } @@ -12911,12 +13456,10 @@ * call stopPropagation on any events that impact scrollbox * @type {boolean} */ - get stopPropagation() - { + get stopPropagation() { return this.options.stopPropagation } - set stopPropagation(value) - { + set stopPropagation(value) { this.options.stopPropagation = value; } @@ -12924,19 +13467,14 @@ * user may drag the content area to scroll content * @type {boolean} */ - get dragScroll() - { + get dragScroll() { return this.options.dragScroll } - set dragScroll(value) - { + set dragScroll(value) { this.options.dragScroll = value; - if (value) - { + if (value) { this.content.drag(); - } - else - { + } else { this.content.removePlugin('drag'); } this.update(); @@ -12946,12 +13484,10 @@ * width of scrollbox including the scrollbar (if visible)- this changes the size and not the scale of the box * @type {number} */ - get boxWidth() - { + get boxWidth() { return this.options.boxWidth } - set boxWidth(value) - { + set boxWidth(value) { this.options.boxWidth = value; this.content.screenWidth = value; this.update(); @@ -12964,12 +13500,10 @@ * auto = if content is larger than box size, then show scrollbar * @type {string} */ - get overflow() - { + get overflow() { return this.options.overflow } - set overflow(value) - { + set overflow(value) { this.options.overflow = value; this.options.overflowX = value; this.options.overflowY = value; @@ -12983,12 +13517,10 @@ * auto = if content is larger than box size, then show scrollbar * @type {string} */ - get overflowX() - { + get overflowX() { return this.options.overflowX } - set overflowX(value) - { + set overflowX(value) { this.options.overflowX = value; this.update(); } @@ -13000,12 +13532,10 @@ * auto = if content is larger than box size, then show scrollbar * @type {string} */ - get overflowY() - { + get overflowY() { return this.options.overflowY } - set overflowY(value) - { + set overflowY(value) { this.options.overflowY = value; this.update(); } @@ -13014,12 +13544,10 @@ * height of scrollbox including the scrollbar (if visible) - this changes the size and not the scale of the box * @type {number} */ - get boxHeight() - { + get boxHeight() { return this.options.boxHeight } - set boxHeight(value) - { + set boxHeight(value) { this.options.boxHeight = value; this.content.screenHeight = value; this.update(); @@ -13029,12 +13557,10 @@ * scrollbar size in pixels * @type {number} */ - get scrollbarSize() - { + get scrollbarSize() { return this.options.scrollbarSize } - set scrollbarSize(value) - { + set scrollbarSize(value) { this.options.scrollbarSize = value; } @@ -13043,9 +13569,11 @@ * @type {number} * @readonly */ - get contentWidth() - { - return this.options.boxWidth - (this.isScrollbarVertical ? this.options.scrollbarSize : 0) + get contentWidth() { + return ( + this.options.boxWidth - + (this.isScrollbarVertical ? this.options.scrollbarSize : 0) + ) } /** @@ -13053,9 +13581,11 @@ * @type {number} * @readonly */ - get contentHeight() - { - return this.options.boxHeight - (this.isScrollbarHorizontal ? this.options.scrollbarSize : 0) + get contentHeight() { + return ( + this.options.boxHeight - + (this.isScrollbarHorizontal ? this.options.scrollbarSize : 0) + ) } /** @@ -13063,8 +13593,7 @@ * @type {boolean} * @readonly */ - get isScrollbarVertical() - { + get isScrollbarVertical() { return this._isScrollbarVertical } @@ -13073,24 +13602,21 @@ * @type {boolean} * @readonly */ - get isScrollbarHorizontal() - { + get isScrollbarHorizontal() { return this._isScrollbarHorizontal } /** * top coordinate of scrollbar */ - get scrollTop() - { + get scrollTop() { return this.content.top } /** * left coordinate of scrollbar */ - get scrollLeft() - { + get scrollLeft() { return this.content.left } @@ -13098,12 +13624,10 @@ * width of content area * if not set then it uses content.width to calculate width */ - get scrollWidth() - { + get scrollWidth() { return this._scrollWidth || this.content.width } - set scrollWidth(value) - { + set scrollWidth(value) { this._scrollWidth = value; } @@ -13111,12 +13635,10 @@ * height of content area * if not set then it uses content.height to calculate height */ - get scrollHeight() - { + get scrollHeight() { return this._scrollHeight || this.content.height } - set scrollHeight(value) - { + set scrollHeight(value) { this._scrollHeight = value; } @@ -13124,52 +13646,111 @@ * draws scrollbars * @private */ - _drawScrollbars() - { - this._isScrollbarHorizontal = this.overflowX === 'scroll' ? true : ['hidden', 'none'].indexOf(this.overflowX) !== -1 ? false : this.scrollWidth > this.options.boxWidth; - this._isScrollbarVertical = this.overflowY === 'scroll' ? true : ['hidden', 'none'].indexOf(this.overflowY) !== -1 ? false : this.scrollHeight > this.options.boxHeight; + _drawScrollbars() { + this._isScrollbarHorizontal = + this.overflowX === 'scroll' + ? true + : ['hidden', 'none'].indexOf(this.overflowX) !== -1 + ? false + : this.scrollWidth > this.options.boxWidth; + this._isScrollbarVertical = + this.overflowY === 'scroll' + ? true + : ['hidden', 'none'].indexOf(this.overflowY) !== -1 + ? false + : this.scrollHeight > this.options.boxHeight; this.scrollbar.clear(); let options = {}; options.left = 0; - options.right = this.scrollWidth + (this._isScrollbarVertical ? this.options.scrollbarSize : 0); + options.right = + this.scrollWidth + + (this._isScrollbarVertical ? this.options.scrollbarSize : 0); options.top = 0; - options.bottom = this.scrollHeight + (this.isScrollbarHorizontal ? this.options.scrollbarSize : 0); - const width = this.scrollWidth + (this.isScrollbarVertical ? this.options.scrollbarSize : 0); - const height = this.scrollHeight + (this.isScrollbarHorizontal ? this.options.scrollbarSize : 0); + options.bottom = + this.scrollHeight + + (this.isScrollbarHorizontal ? this.options.scrollbarSize : 0); + const width = + this.scrollWidth + + (this.isScrollbarVertical ? this.options.scrollbarSize : 0); + const height = + this.scrollHeight + + (this.isScrollbarHorizontal ? this.options.scrollbarSize : 0); this.scrollbarTop = (this.content.top / height) * this.boxHeight; this.scrollbarTop = this.scrollbarTop < 0 ? 0 : this.scrollbarTop; this.scrollbarHeight = (this.boxHeight / height) * this.boxHeight; - this.scrollbarHeight = this.scrollbarTop + this.scrollbarHeight > this.boxHeight ? this.boxHeight - this.scrollbarTop : this.scrollbarHeight; + this.scrollbarHeight = + this.scrollbarTop + this.scrollbarHeight > this.boxHeight + ? this.boxHeight - this.scrollbarTop + : this.scrollbarHeight; this.scrollbarLeft = (this.content.left / width) * this.boxWidth; this.scrollbarLeft = this.scrollbarLeft < 0 ? 0 : this.scrollbarLeft; this.scrollbarWidth = (this.boxWidth / width) * this.boxWidth; - this.scrollbarWidth = this.scrollbarWidth + this.scrollbarLeft > this.boxWidth ? this.boxWidth - this.scrollbarLeft : this.scrollbarWidth; - if (this.isScrollbarVertical) - { + this.scrollbarWidth = + this.scrollbarWidth + this.scrollbarLeft > this.boxWidth + ? this.boxWidth - this.scrollbarLeft + : this.scrollbarWidth; + if (this.isScrollbarVertical) { this.scrollbar - .beginFill(this.options.scrollbarBackground, this.options.scrollbarBackgroundAlpha) - .drawRect(this.boxWidth - this.scrollbarSize + this.options.scrollbarOffsetVertical, 0, this.scrollbarSize, this.boxHeight) + .beginFill( + this.options.scrollbarBackground, + this.options.scrollbarBackgroundAlpha + ) + .drawRect( + this.boxWidth - + this.scrollbarSize + + this.options.scrollbarOffsetVertical, + 0, + this.scrollbarSize, + this.boxHeight + ) .endFill(); } - if (this.isScrollbarHorizontal) - { + if (this.isScrollbarHorizontal) { this.scrollbar - .beginFill(this.options.scrollbarBackground, this.options.scrollbarBackgroundAlpha) - .drawRect(0, this.boxHeight - this.scrollbarSize + this.options.scrollbarOffsetHorizontal, this.boxWidth, this.scrollbarSize) + .beginFill( + this.options.scrollbarBackground, + this.options.scrollbarBackgroundAlpha + ) + .drawRect( + 0, + this.boxHeight - + this.scrollbarSize + + this.options.scrollbarOffsetHorizontal, + this.boxWidth, + this.scrollbarSize + ) .endFill(); } - if (this.isScrollbarVertical) - { + if (this.isScrollbarVertical) { this.scrollbar - .beginFill(this.options.scrollbarForeground, this.options.scrollbarForegroundAlpha) - .drawRect(this.boxWidth - this.scrollbarSize + this.options.scrollbarOffsetVertical, this.scrollbarTop, this.scrollbarSize, this.scrollbarHeight) + .beginFill( + this.options.scrollbarForeground, + this.options.scrollbarForegroundAlpha + ) + .drawRect( + this.boxWidth - + this.scrollbarSize + + this.options.scrollbarOffsetVertical, + this.scrollbarTop, + this.scrollbarSize, + this.scrollbarHeight + ) .endFill(); } - if (this.isScrollbarHorizontal) - { + if (this.isScrollbarHorizontal) { this.scrollbar - .beginFill(this.options.scrollbarForeground, this.options.scrollbarForegroundAlpha) - .drawRect(this.scrollbarLeft, this.boxHeight - this.scrollbarSize + this.options.scrollbarOffsetHorizontal, this.scrollbarWidth, this.scrollbarSize) + .beginFill( + this.options.scrollbarForeground, + this.options.scrollbarForegroundAlpha + ) + .drawRect( + this.scrollbarLeft, + this.boxHeight - + this.scrollbarSize + + this.options.scrollbarOffsetHorizontal, + this.scrollbarWidth, + this.scrollbarSize + ) .endFill(); } // this.content.forceHitArea = new PIXI.Rectangle(0, 0 , this.boxWidth, this.boxHeight) @@ -13180,8 +13761,7 @@ * draws mask layer * @private */ - _drawMask() - { + _drawMask() { this._maskContent .beginFill(0) .drawRect(0, 0, this.boxWidth, this.boxHeight) @@ -13192,19 +13772,20 @@ /** * call when scrollbox content changes */ - update() - { + update() { this.content.mask = null; this._maskContent.clear(); - if (!this._disabled) - { + if (!this._disabled) { this._drawScrollbars(); this._drawMask(); - if (this.options.dragScroll) - { - const direction = this.isScrollbarHorizontal && this.isScrollbarVertical ? 'all' : this.isScrollbarHorizontal ? 'x' : 'y'; - if (direction !== null) - { + if (this.options.dragScroll) { + const direction = + this.isScrollbarHorizontal && this.isScrollbarVertical + ? 'all' + : this.isScrollbarHorizontal + ? 'x' + : 'y'; + if (direction !== null) { this.content .drag({ clampWheel: true, direction }) .clamp({ direction, underflow: this.options.underflow }); @@ -13216,18 +13797,18 @@ /** * show the scrollbar and restart the timer for fade if options.fade is set */ - activateFade() - { - if (this.options.fade) - { - if (this.fade) - { + activateFade() { + if (this.options.fade) { + if (this.fade) { this.ease.remove(this.fade); } this.scrollbar.alpha = 1; const time = this.options.fade === true ? 1000 : this.options.fade; - this.fade = this.ease.to(this.scrollbar, { alpha: 0 }, time, { wait: this.options.fadeWait, ease: this.options.fadeEase }); - this.fade.on('each', () => this.content.dirty = true); + this.fade = this.ease.to(this.scrollbar, { alpha: 0 }, time, { + wait: this.options.fadeWait, + ease: this.options.fadeEase + }); + this.fade.on('each', () => (this.content.dirty = true)); } } @@ -13236,60 +13817,47 @@ * @param {PIXI.interaction.InteractionEvent} e * @private */ - scrollbarDown(e) - { + scrollbarDown(e) { const local = this.toLocal(e.data.global); - if (this.isScrollbarHorizontal) - { - if (local.y > this.boxHeight - this.scrollbarSize) - { - if (local.x >= this.scrollbarLeft && local.x <= this.scrollbarLeft + this.scrollbarWidth) - { + if (this.isScrollbarHorizontal) { + if (local.y > this.boxHeight - this.scrollbarSize) { + if ( + local.x >= this.scrollbarLeft && + local.x <= this.scrollbarLeft + this.scrollbarWidth + ) { this.pointerDown = { type: 'horizontal', last: local }; - } - else - { - if (local.x > this.scrollbarLeft) - { + } else { + if (local.x > this.scrollbarLeft) { this.content.left += this.content.worldScreenWidth; this.update(); - } - else - { + } else { this.content.left -= this.content.worldScreenWidth; this.update(); } } - if (this.options.stopPropagation) - { + if (this.options.stopPropagation) { e.stopPropagation(); } return } } - if (this.isScrollbarVertical) - { - if (local.x > this.boxWidth - this.scrollbarSize) - { - if (local.y >= this.scrollbarTop && local.y <= this.scrollbarTop + this.scrollbarWidth) - { + if (this.isScrollbarVertical) { + if (local.x > this.boxWidth - this.scrollbarSize) { + if ( + local.y >= this.scrollbarTop && + local.y <= this.scrollbarTop + this.scrollbarWidth + ) { this.pointerDown = { type: 'vertical', last: local }; - } - else - { - if (local.y > this.scrollbarTop) - { + } else { + if (local.y > this.scrollbarTop) { this.content.top += this.content.worldScreenHeight; this.update(); - } - else - { + } else { this.content.top -= this.content.worldScreenHeight; this.update(); } } - if (this.options.stopPropagation) - { + if (this.options.stopPropagation) { e.stopPropagation(); } return @@ -13302,26 +13870,20 @@ * @param {PIXI.interaction.InteractionEvent} e * @private */ - scrollbarMove(e) - { - if (this.pointerDown) - { - if (this.pointerDown.type === 'horizontal') - { + scrollbarMove(e) { + if (this.pointerDown) { + if (this.pointerDown.type === 'horizontal') { const local = this.toLocal(e.data.global); this.content.left += local.x - this.pointerDown.last.x; this.pointerDown.last = local; this.update(); - } - else if (this.pointerDown.type === 'vertical') - { + } else if (this.pointerDown.type === 'vertical') { const local = this.toLocal(e.data.global); this.content.top += local.y - this.pointerDown.last.y; this.pointerDown.last = local; this.update(); } - if (this.options.stopPropagation) - { + if (this.options.stopPropagation) { e.stopPropagation(); } } @@ -13331,8 +13893,7 @@ * handle pointer down on scrollbar * @private */ - scrollbarUp() - { + scrollbarUp() { this.pointerDown = null; } @@ -13344,19 +13905,27 @@ * @param {number} [options.scrollWidth] set the width of the inside of the scrollbox (leave null to use content.width) * @param {number} [options.scrollHeight] set the height of the inside of the scrollbox (leave null to use content.height) */ - resize(options) - { - this.options.boxWidth = typeof options.boxWidth !== 'undefined' ? options.boxWidth : this.options.boxWidth; - this.options.boxHeight = typeof options.boxHeight !== 'undefined' ? options.boxHeight : this.options.boxHeight; - if (options.scrollWidth) - { + resize(options) { + this.options.boxWidth = + typeof options.boxWidth !== 'undefined' + ? options.boxWidth + : this.options.boxWidth; + this.options.boxHeight = + typeof options.boxHeight !== 'undefined' + ? options.boxHeight + : this.options.boxHeight; + if (options.scrollWidth) { this.scrollWidth = options.scrollWidth; } - if (options.scrollHeight) - { + if (options.scrollHeight) { this.scrollHeight = options.scrollHeight; } - this.content.resize(this.options.boxWidth, this.options.boxHeight, this.scrollWidth, this.scrollHeight); + this.content.resize( + this.options.boxWidth, + this.options.boxHeight, + this.scrollWidth, + this.scrollHeight + ); this.update(); } @@ -13367,8 +13936,7 @@ * @param {number} width * @param {number} height */ - ensureVisible(x, y, width, height) - { + ensureVisible(x, y, width, height) { this.content.ensureVisible(x, y, width, height); this._drawScrollbars(); } @@ -13376,7 +13944,7 @@ /** * Class that represents a PixiJS Scrollview. - * + * * @example * // Create the app * const app = new PIXIApp({ @@ -13384,7 +13952,7 @@ * width: 600, * height: 400 * }).setup().run() - * + * * // Create the Scrollview * app.loader * .add('elephant', './assets/elephant-1.jpg') @@ -13400,38 +13968,34 @@ * @see {@link https://davidfig.github.io/pixi-viewport/jsdoc/Viewport.html|Viewport} */ class Scrollview extends Scrollbox { - /** * Creates an instance of a Scrollview. - * + * * @constructor * @see https://davidfig.github.io/pixi-scrollbox/jsdoc/Scrollbox.html */ constructor(opts = {}) { - super(opts); this.opts = opts; } - + /** * Creates children and instantiates everything. - * + * * @private * @return {Scrollview} A reference to the Scrollview for chaining. */ setup() { - return this } - + /** * Should be called to refresh the layout of the Scrollview. Can be used after resizing. - * + * * @return {Scrollview} A reference to the Scrollview for chaining. */ layout() { - this.update(); return this @@ -13464,7 +14028,7 @@ /** * Class that represents a PixiJS Slider. - * + * * @example * // Create the app * const app = new PIXIApp({ @@ -13472,7 +14036,7 @@ * width: 900, * height: 250 * }).setup().run() - * + * * // Create the slider * const slider = new Slider({ * x: 10, @@ -13488,10 +14052,9 @@ * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/slider.html|DocTest} */ class Slider extends PIXI.Container { - /** * Creates an instance of a Slider. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the slider. * @param {number} [opts.id=auto generated] - The id of the slider. @@ -13519,46 +14082,49 @@ * @param {onUpdateCallback} [opts.onUpdate] - Executed when the slider control is moved. * @param {onCompleteCallback} [opts.onComplete] - Executed when the slider control was dropped. * @param {string|object} [opts.tooltip] - A string for the label of the tooltip or an object to configure the tooltip - * to display. + * to display. * @param {boolean} [opts.visible=true] - Is the slider initially visible (property visible)? */ constructor(opts = {}) { - super(); - + const theme = Theme.fromString(opts.theme); this.theme = theme; - this.opts = Object.assign({}, { - id: PIXI.utils.uid(), - x: 0, - y: 0, - width: 250, - height: 2, - container: null, - fill: theme.fill, - fillAlpha: theme.fillAlpha, - stroke: theme.stroke, - strokeWidth: theme.strokeWidth, - strokeAlpha: theme.strokeAlpha, - controlFill: theme.fill, - controlFillAlpha: .5, - controlStroke: theme.primaryColor, - controlStrokeWidth: 2, - controlStrokeAlpha: theme.strokeAlpha, - controlRadius: 16, - orientation: 'horizontal', - min: 0, - max: 100, - value: 0, - disabled: false, - onStart: null, - onUpdate: null, - onComplete: null, - tooltip: null, - visible: true - }, opts); - + this.opts = Object.assign( + {}, + { + id: PIXI.utils.uid(), + x: 0, + y: 0, + width: 250, + height: 2, + container: null, + fill: theme.fill, + fillAlpha: theme.fillAlpha, + stroke: theme.stroke, + strokeWidth: theme.strokeWidth, + strokeAlpha: theme.strokeAlpha, + controlFill: theme.fill, + controlFillAlpha: 0.5, + controlStroke: theme.primaryColor, + controlStrokeWidth: 2, + controlStrokeAlpha: theme.strokeAlpha, + controlRadius: 16, + orientation: 'horizontal', + min: 0, + max: 100, + value: 0, + disabled: false, + onStart: null, + onUpdate: null, + onComplete: null, + tooltip: null, + visible: true + }, + opts + ); + this.opts.container = this.opts.container || this; // Validation @@ -13586,7 +14152,7 @@ this.sliderObj = null; this.control = null; this.tooltip = null; - + this.visible = this.opts.visible; // setup @@ -13597,23 +14163,26 @@ //----------------- this.layout(); } - + /** * Creates children and instantiates everything. - * + * * @private * @return {Slider} A reference to the slider for chaining. */ setup() { - // Container events //----------------- const container = this.opts.container; this.on('pointermove', e => { if (this.control.dragging) { - const moveX = this.control.event.data.getLocalPosition(this.control.parent).x; - this._value = this.pixelToValue(moveX - this.control.delta - this.opts.controlRadius); + const moveX = this.control.event.data.getLocalPosition( + this.control.parent + ).x; + this._value = this.pixelToValue( + moveX - this.control.delta - this.opts.controlRadius + ); let x = this.valueToPixel(this._value) + this.opts.controlRadius; this.control.x = x; @@ -13625,8 +14194,16 @@ if (container instanceof Element) { container.addEventListener('pointerup', e => this.onEnd(e), false); - container.addEventListener('pointercancel', e => this.onEnd(e), false); - container.addEventListener('pointerleave', e => this.onEnd(e), false); + container.addEventListener( + 'pointercancel', + e => this.onEnd(e), + false + ); + container.addEventListener( + 'pointerleave', + e => this.onEnd(e), + false + ); container.addEventListener('pointerout', e => this.onEnd(e), false); container.addEventListener('mouseup', e => this.onEnd(e), false); container.addEventListener('mousecancel', e => this.onEnd(e), false); @@ -13657,7 +14234,7 @@ control.event = e; control.delta = e.data.getLocalPosition(this.control).x; control.dragging = true; - + if (this.opts.onStart) { this.opts.onStart.call(this, e, this); } @@ -13666,20 +14243,20 @@ this.control = control; this.addChild(this.control); - + // interaction //----------------- this.sliderObj.on('pointerover', e => { - TweenLite.to(this.control, this.theme.fast, {alpha: .83}); + TweenLite.to(this.control, this.theme.fast, { alpha: 0.83 }); }); this.sliderObj.on('pointerout', e => { - TweenLite.to(this.control, this.theme.fast, {alpha: 1}); + TweenLite.to(this.control, this.theme.fast, { alpha: 1 }); }); this.sliderObj.on('pointerdown', e => { this.sliderObj.pointerdowned = true; - TweenLite.to(this.control, this.theme.fast, {alpha: .7}); + TweenLite.to(this.control, this.theme.fast, { alpha: 0.7 }); }); // Click on the slider bar @@ -13687,15 +14264,17 @@ if (this.sliderObj.pointerdowned) { this.sliderObj.pointerdowned = false; const position = e.data.getLocalPosition(this.control.parent); - this.value = this.pixelToValue(position.x - this.opts.controlRadius); - TweenLite.to(this.control, this.theme.fast, {alpha: .83}); + this.value = this.pixelToValue( + position.x - this.opts.controlRadius + ); + TweenLite.to(this.control, this.theme.fast, { alpha: 0.83 }); } }); // disabled //----------------- this.disabled = this.opts.disabled; - + // tooltip //----------------- if (this.opts.tooltip) { @@ -13712,14 +14291,13 @@ return this } - + /** * Should be called to refresh the layout of the slider. Can be used after resizing. - * + * * @return {Slider} A reference to the slider for chaining. */ layout() { - // set position //----------------- this.position.set(this.opts.x, this.opts.y); @@ -13730,15 +14308,14 @@ return this } - + /** * Draws the slider to the canvas. - * + * * @private * @return {Slider} A reference to the slider for chaining. */ draw() { - const r = this.radius; const cr = this.opts.controlRadius; const w = this.opts.width; @@ -13749,12 +14326,16 @@ this.sliderObj.clear(); this.sliderObj.beginFill(0xffffff, 0); this.sliderObj.drawRect(0, 0, x + w + cr, cr * 2); - this.sliderObj.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha); + this.sliderObj.lineStyle( + this.opts.strokeWidth, + this.opts.stroke, + this.opts.strokeAlpha + ); this.sliderObj.beginFill(this.opts.fill, this.opts.fillAlpha); this.sliderObj.moveTo(x, y); this.sliderObj.lineTo(x + w, y); this.sliderObj.arcTo(x + w + r, y, x + w + r, y + r, r); - this.sliderObj.lineTo(x + w + r, y + r + 1); // BUGFIX: If not specified, there is a small area without a stroke. + this.sliderObj.lineTo(x + w + r, y + r + 1); // BUGFIX: If not specified, there is a small area without a stroke. this.sliderObj.arcTo(x + w + r, y + h, x + w, y + h, r); this.sliderObj.lineTo(x, y + h); this.sliderObj.arcTo(x - r, y + h, x - r, y + r, r); @@ -13763,10 +14344,20 @@ // Draw control this.control.clear(); - this.control.lineStyle(this.opts.controlStrokeWidth, this.opts.controlStroke, this.opts.controlStrokeAlpha); - this.control.beginFill(this.opts.controlFill, this.opts.controlFillAlpha); + this.control.lineStyle( + this.opts.controlStrokeWidth, + this.opts.controlStroke, + this.opts.controlStrokeAlpha + ); + this.control.beginFill( + this.opts.controlFill, + this.opts.controlFillAlpha + ); this.control.drawCircle(0, 0, cr - 1); - this.control.beginFill(this.opts.controlStroke, this.opts.controlStrokeAlpha); + this.control.beginFill( + this.opts.controlStroke, + this.opts.controlStrokeAlpha + ); this.control.drawCircle(0, 0, cr / 6); this.control.endFill(); @@ -13775,12 +14366,11 @@ /** * Executed, when the slider control movement ended. - * + * * @private * @return {Slider} A reference to the slider for chaining. */ onEnd(e) { - if (this.control.dragging) { this.control.event = null; this.control.dragging = false; @@ -13794,9 +14384,9 @@ /** * Calculates the value for a given pixel. - * + * * @private - * @param {number} value + * @param {number} value * @returns {number} The calucalted pixel. */ valueToPixel(value) { @@ -13805,14 +14395,17 @@ } else if (value > this.opts.max) { value = this.opts.max; } - return this.opts.width * (value - this.opts.min) / (this.opts.max - this.opts.min) + return ( + (this.opts.width * (value - this.opts.min)) / + (this.opts.max - this.opts.min) + ) } /** * Calculates the pixel for a given value. - * + * * @private - * @param {number} pixel + * @param {number} pixel * @returns {number} The calucalted value. */ pixelToValue(pixel) { @@ -13821,12 +14414,15 @@ } else if (pixel > this.opts.width) { pixel = this.opts.width; } - return this.opts.min + ((this.opts.max - this.opts.min) * pixel / this.opts.width) + return ( + this.opts.min + + ((this.opts.max - this.opts.min) * pixel) / this.opts.width + ) } - + /** * Gets or sets the value. - * + * * @member {number} */ get value() { @@ -13842,27 +14438,26 @@ const x = this.valueToPixel(value) + this.opts.controlRadius; - TweenLite.to(this.control, this.theme.fast, {x}); + TweenLite.to(this.control, this.theme.fast, { x }); } - + /** * Gets or sets the disabled state. When disabled, the slider cannot be clicked. - * + * * @member {boolean} */ get disabled() { return this._disabled } set disabled(value) { - this._disabled = value; - + if (this._disabled) { this.interactive = false; this.sliderObj.interactive = false; this.control.interactive = false; this.control.buttonMode = false; - this.alpha = .5; + this.alpha = 0.5; } else { this.interactive = true; this.sliderObj.interactive = true; @@ -13874,11 +14469,10 @@ /** * Shows the slider (sets his alpha values to 1). - * + * * @return {Slider} A reference to the slider for chaining. */ show() { - this.opts.strokeAlpha = 1; this.opts.fillAlpha = 1; this.opts.controlStrokeAlpha = 1; @@ -13888,14 +14482,13 @@ return this } - + /** * Hides the slider (sets his alpha values to 1). - * + * * @return {Slider} A reference to the slider for chaining. */ hide() { - this.opts.strokeAlpha = 0; this.opts.fillAlpha = 0; this.opts.controlStrokeAlpha = 0; @@ -13910,7 +14503,6 @@ /* eslint-disable no-undef */ class StylusCommand extends Object { - constructor() { super(); } @@ -13929,7 +14521,6 @@ } class StrokeCommand extends StylusCommand { - constructor(stroke) { super(); this.stroke = stroke; @@ -13956,7 +14547,6 @@ } class ClearCommand extends StylusCommand { - do(stylus) { // Clears the command stack stylus.commandStack = []; @@ -13977,20 +14567,20 @@ } } - class Stylus extends PIXI.Graphics { - - constructor({ width = window.innerWidth, + constructor({ + width = window.innerWidth, height = window.innerHeight, interactive = true, color = 0x000000, tiltX = 0, tiltY = 0, backgroundAlpha = 1, - backgroundFill = 0xFFFFFF, + backgroundFill = 0xffffff, colorAlpha = 1, captureEvents = true, - acceptMouseEvents = true } = {}) { + acceptMouseEvents = true + } = {}) { super(); this.activePointers = 0; this.wantedWidth = width; @@ -14001,16 +14591,15 @@ this.color = color; this.interactive = interactive; this.debug = false; - this.tiltX = tiltX; // degrees -90 ... 90 - this.tiltY = tiltY; // degrees -90 ... 90 + this.tiltX = tiltX; // degrees -90 ... 90 + this.tiltY = tiltY; // degrees -90 ... 90 this.captureEvents = captureEvents; this.commandStack = []; this.undoCommandStack = []; this.strokes = []; this.stroke = []; this.minStrokeLength = 4; - if (captureEvents) - this.registerEventHandler(acceptMouseEvents); + if (captureEvents) this.registerEventHandler(acceptMouseEvents); this.drawBackground(); } @@ -14027,9 +14616,12 @@ isStylusPointer(event) { let identifier = event.data.identifier; - if (typeof (event.data.originalEvent.changedTouches) !== 'undefined') { + if (typeof event.data.originalEvent.changedTouches !== 'undefined') { for (let touch of event.data.originalEvent.changedTouches) { - if (touch.identifier === identifier && touch.touchType === 'stylus') { + if ( + touch.identifier === identifier && + touch.touchType === 'stylus' + ) { this.tiltX = Angle.radian2degree(touch.azimuthAngle); this.tiltY = 90.0 - Angle.radian2degree(touch.altitudeAngle); return true @@ -14047,9 +14639,12 @@ isStylusTouch(event) { let identifier = event.data.identifier; - if (typeof (event.data.originalEvent.changedTouches) !== 'undefined') { + if (typeof event.data.originalEvent.changedTouches !== 'undefined') { for (let touch of event.data.originalEvent.changedTouches) { - if (touch.identifier === identifier && touch.pointerType === 'touch') { + if ( + touch.identifier === identifier && + touch.pointerType === 'touch' + ) { return true } } @@ -14071,25 +14666,26 @@ } registerEventHandler() { - window.addEventListener('keydown', (e) => { + window.addEventListener('keydown', e => { switch (e.keyCode) { - case 38: // up arrow - this.tiltX += 5; - break - case 40: // down arrow - this.tiltX -= 5; - break - case 37: // left arrow - this.tiltY -= 5; - break - case 39: // right arrow - this.tiltY += 5; - break + case 38: // up arrow + this.tiltX += 5; + break + case 40: // down arrow + this.tiltX -= 5; + break + case 37: // left arrow + this.tiltY -= 5; + break + case 39: // right arrow + this.tiltY += 5; + break } - if (this.debug) console.log('keydown', e.keyCode, this.tiltX, this.tiltY); + if (this.debug) + console.log('keydown', e.keyCode, this.tiltX, this.tiltY); }); - this.on('pointerdown', (e) => { + this.on('pointerdown', e => { if (this.debug) console.log('pointerdown', e); if (this.eventInside(e)) { this.activePointers += 1; @@ -14099,14 +14695,19 @@ } }); - this.on('pointermove', (e) => { - if (Events$1.isPointerDown(e.data.originalEvent) || this.isStylusPointer(e) || this.isStylusTouch(e)) { - if (this.debug) console.log('pointermove', e, this.eventInside(e)); + this.on('pointermove', e => { + if ( + Events$1.isPointerDown(e.data.originalEvent) || + this.isStylusPointer(e) || + this.isStylusTouch(e) + ) { + if (this.debug) + console.log('pointermove', e, this.eventInside(e)); if (this.eventInside(e) && this.singlePointer()) this.moveStroke(this.toStroke(e)); } }); - this.on('pointerup', (e) => { + this.on('pointerup', e => { if (this.eventInside(e)) { if (this.activePointers > 0) { this.activePointers -= 1; @@ -14115,13 +14716,13 @@ } if (this.debug) console.log('pointerup', this.activePointers); }); - this.on('pointerleave', (e) => { + this.on('pointerleave', e => { if (this.activePointers > 0) { this.activePointers -= 1; } this.endStroke(this.toStroke(e)); }); - this.on('pointercancel', (e) => { + this.on('pointercancel', e => { if (this.activePointers > 0) { this.activePointers -= 1; } @@ -14152,7 +14753,6 @@ } eventInside(event) { - let local = this.toLocal(event.data.global); for (let child of this.children) { let r = child.getBounds(); @@ -14161,10 +14761,8 @@ return false } } - if (local.x < 0 || local.x > this.wantedWidth) - return false - if (local.y < 0 || local.y > this.wantedHeight) - return false + if (local.x < 0 || local.x > this.wantedWidth) return false + if (local.y < 0 || local.y > this.wantedHeight) return false event.stopPropagation(); // if (this.debug) console.log('stopPropagation', event) if (event.data.originalEvent.claimedByScatter) { @@ -14182,9 +14780,11 @@ let x = Math.max(0, Math.min(local.x, this.wantedWidth)); let y = Math.max(0, Math.min(local.y, this.wantedHeight)); let desc = { - x, y, + x, + y, pressure: event.pressure || null, - tiltX: this.tiltX, tiltY: this.tiltY, + tiltX: this.tiltX, + tiltY: this.tiltY, color: this.color }; return desc @@ -14219,8 +14819,11 @@ this.moveTo(start.x, start.y); for (let i = 1; i < stroke.length; i++) { let info = stroke[i]; - this.lineStyle(this.tiltToLineWidth(info.tiltY), - info.color, this.colorAlpha); + this.lineStyle( + this.tiltToLineWidth(info.tiltY), + info.color, + this.colorAlpha + ); this.lineTo(info.x, info.y); } this.endFill(); @@ -14235,7 +14838,7 @@ drawStrokes() { this.drawBackground(); - this.lineStyle(1.0, 0xFF0000, 1); + this.lineStyle(1.0, 0xff0000, 1); for (let stroke of this.iterStrokes()) { this.drawStroke(stroke); } @@ -14361,7 +14964,7 @@ /** * Class that represents a PixiJS Switch. - * + * * @example * // Create the app * const app = new PIXIApp({ @@ -14369,7 +14972,7 @@ * width: 900, * height: 250 * }).setup().run() - * + * * // Create the switch * const switch1 = new Switch({ * x: 10, @@ -14385,10 +14988,9 @@ * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/switch.html|DocTest} */ class Switch extends PIXI.Container { - /** * Creates an instance of a Switch. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the switch. * @param {number} [opts.id=auto generated] - The id of the switch. @@ -14428,56 +15030,61 @@ * @param {beforeActionCallback} [opts.beforeAction] - Executed before an action is triggered. * @param {afterActionCallback} [opts.afterAction] - Executed after an action was triggered. * @param {string|object} [opts.tooltip] - A string for the label of the tooltip or an object to configure the tooltip - * to display. + * to display. * @param {boolean} [opts.visible=true] - Is the switch initially visible (property visible)? */ constructor(opts = {}) { - super(); - + const theme = Theme.fromString(opts.theme); this.theme = theme; - this.opts = Object.assign({}, { - id: PIXI.utils.uid(), - x: 0, - y: 0, - width: 44, - height: 28, - fill: theme.fill, - fillAlpha: theme.fillAlpha, - fillActive: theme.primaryColor, - fillActiveAlpha: theme.fillActiveAlpha, - stroke: theme.stroke, - strokeWidth: theme.strokeWidth, - strokeAlpha: theme.strokeAlpha, - strokeActive: theme.primaryColor, - strokeActiveWidth: theme.strokeActiveWidth, - strokeActiveAlpha: theme.strokeActiveAlpha, - controlFill: theme.stroke, - controlFillAlpha: theme.strokeAlpha, - controlFillActive: theme.stroke, - controlFillActiveAlpha: theme.strokeAlpha, - controlStroke: theme.stroke, - controlStrokeWidth: theme.strokeWidth * .8, - controlStrokeAlpha: theme.strokeAlpha, - controlStrokeActive: theme.stroke, - controlStrokeActiveWidth: theme.strokeActiveWidth * .8, - controlStrokeActiveAlpha: theme.strokeActiveAlpha, - duration: theme.fast, - durationActive: theme.fast, - disabled: false, - active: false, - action: null, - actionActive: null, - beforeAction: null, - afterAction: null, - tooltip: null, - visible: true - }, opts); + this.opts = Object.assign( + {}, + { + id: PIXI.utils.uid(), + x: 0, + y: 0, + width: 44, + height: 28, + fill: theme.fill, + fillAlpha: theme.fillAlpha, + fillActive: theme.primaryColor, + fillActiveAlpha: theme.fillActiveAlpha, + stroke: theme.stroke, + strokeWidth: theme.strokeWidth, + strokeAlpha: theme.strokeAlpha, + strokeActive: theme.primaryColor, + strokeActiveWidth: theme.strokeActiveWidth, + strokeActiveAlpha: theme.strokeActiveAlpha, + controlFill: theme.stroke, + controlFillAlpha: theme.strokeAlpha, + controlFillActive: theme.stroke, + controlFillActiveAlpha: theme.strokeAlpha, + controlStroke: theme.stroke, + controlStrokeWidth: theme.strokeWidth * 0.8, + controlStrokeAlpha: theme.strokeAlpha, + controlStrokeActive: theme.stroke, + controlStrokeActiveWidth: theme.strokeActiveWidth * 0.8, + controlStrokeActiveAlpha: theme.strokeActiveAlpha, + duration: theme.fast, + durationActive: theme.fast, + disabled: false, + active: false, + action: null, + actionActive: null, + beforeAction: null, + afterAction: null, + tooltip: null, + visible: true + }, + opts + ); - this.opts.controlRadius = this.opts.controlRadius || (this.opts.height / 2); - this.opts.controlRadiusActive = this.opts.controlRadiusActive || this.opts.controlRadius; + this.opts.controlRadius = + this.opts.controlRadius || this.opts.height / 2; + this.opts.controlRadiusActive = + this.opts.controlRadiusActive || this.opts.controlRadius; // Validation //----------------- @@ -14496,7 +15103,7 @@ this.switchObj = null; this.control = null; this.tooltip = null; - + this.visible = this.opts.visible; // animated @@ -14523,15 +15130,14 @@ //----------------- this.layout(); } - + /** * Creates children and instantiates everything. - * + * * @private * @return {Switch} A reference to the switch for chaining. */ setup() { - // Switch //----------------- let switchObj = new PIXI.Graphics(); @@ -14542,7 +15148,7 @@ //----------------- this.xInactive = this.opts.controlRadius; this.xActive = this.opts.width - this.opts.controlRadiusActive; - + let control = new PIXI.Graphics(); control.x = this.opts.active ? this.xActive : this.xInactive; control.y = this.opts.height / 2; @@ -14550,23 +15156,22 @@ this.control = control; this.addChild(this.control); - + // interaction //----------------- this.switchObj.on('pointerover', e => { - TweenLite.to(this.control, this.theme.fast, {alpha: .83}); + TweenLite.to(this.control, this.theme.fast, { alpha: 0.83 }); }); this.switchObj.on('pointerout', e => { - TweenLite.to(this.control, this.theme.fast, {alpha: 1}); + TweenLite.to(this.control, this.theme.fast, { alpha: 1 }); }); this.switchObj.on('pointerdown', e => { - TweenLite.to(this.control, this.theme.fast, {alpha: .7}); + TweenLite.to(this.control, this.theme.fast, { alpha: 0.7 }); }); this.switchObj.on('pointerup', e => { - if (this.opts.beforeAction) { this.opts.beforeAction.call(this, e, this); } @@ -14583,7 +15188,7 @@ } } - TweenLite.to(this.control, this.theme.fast, {alpha: .83}); + TweenLite.to(this.control, this.theme.fast, { alpha: 0.83 }); if (this.opts.afterAction) { this.opts.afterAction.call(this, e, this); @@ -14597,7 +15202,7 @@ // active //----------------- this.active = this.opts.active; - + // tooltip //----------------- if (this.opts.tooltip) { @@ -14614,14 +15219,13 @@ return this } - + /** * Should be called to refresh the layout of the switch. Can be used after resizing. - * + * * @return {Switch} A reference to the switch for chaining. */ layout() { - // set position //----------------- this.position.set(this.opts.x, this.opts.y); @@ -14632,28 +15236,50 @@ return this } - + /** * Draws the switch to the canvas. - * + * * @private * @return {Switch} A reference to the switch for chaining. */ draw() { - this.switchObj.clear(); if (this.active) { - this.switchObj.lineStyle(this.opts.strokeActiveWidth, this.opts.strokeActive, this.opts.strokeActiveAlpha); - this.switchObj.beginFill(this.opts.fillActive, this.opts.fillActiveAlpha); + this.switchObj.lineStyle( + this.opts.strokeActiveWidth, + this.opts.strokeActive, + this.opts.strokeActiveAlpha + ); + this.switchObj.beginFill( + this.opts.fillActive, + this.opts.fillActiveAlpha + ); } else { - this.switchObj.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha); + this.switchObj.lineStyle( + this.opts.strokeWidth, + this.opts.stroke, + this.opts.strokeAlpha + ); this.switchObj.beginFill(this.opts.fill, this.opts.fillAlpha); } this.switchObj.moveTo(this.radius, 0); this.switchObj.lineTo(this.opts.width - this.radius, 0); - this.switchObj.arcTo(this.opts.width, 0, this.opts.width, this.radius, this.radius); - this.switchObj.lineTo(this.opts.width, this.radius + 1); // BUGFIX: If not specified, there is a small area without a stroke. - this.switchObj.arcTo(this.opts.width, this.opts.height, this.opts.width - this.radius, this.opts.height, this.radius); + this.switchObj.arcTo( + this.opts.width, + 0, + this.opts.width, + this.radius, + this.radius + ); + this.switchObj.lineTo(this.opts.width, this.radius + 1); // BUGFIX: If not specified, there is a small area without a stroke. + this.switchObj.arcTo( + this.opts.width, + this.opts.height, + this.opts.width - this.radius, + this.opts.height, + this.radius + ); this.switchObj.lineTo(this.radius, this.opts.height); this.switchObj.arcTo(0, this.opts.height, 0, this.radius, this.radius); this.switchObj.arcTo(0, 0, this.radius, 0, this.radius); @@ -14662,52 +15288,91 @@ // Draw control this.control.clear(); if (this.active) { - this.control.lineStyle(this.opts.controlStrokeActiveWidth, this.opts.controlStrokeActive, this.opts.controlStrokeActiveAlpha); - this.control.beginFill(this.opts.controlFillActive, this.opts.controlFillActiveAlpha); + this.control.lineStyle( + this.opts.controlStrokeActiveWidth, + this.opts.controlStrokeActive, + this.opts.controlStrokeActiveAlpha + ); + this.control.beginFill( + this.opts.controlFillActive, + this.opts.controlFillActiveAlpha + ); this.control.drawCircle(0, 0, this.opts.controlRadiusActive - 1); } else { - this.control.lineStyle(this.opts.controlStrokeWidth, this.opts.controlStroke, this.opts.controlStrokeAlpha); - this.control.beginFill(this.opts.controlFill, this.opts.controlFillAlpha); + this.control.lineStyle( + this.opts.controlStrokeWidth, + this.opts.controlStroke, + this.opts.controlStrokeAlpha + ); + this.control.beginFill( + this.opts.controlFill, + this.opts.controlFillAlpha + ); this.control.drawCircle(0, 0, this.opts.controlRadius - 1); } this.control.endFill(); return this } - + /** * Draws the animation. - * + * * @private * @return {Switch} A reference to the switch for chaining. */ drawAnimated() { - this.switchObj.clear(); - this.switchObj.lineStyle(this.tempAnimated.strokeWidth, this.tempAnimated.stroke, this.tempAnimated.strokeAlpha); - this.switchObj.beginFill(this.tempAnimated.fill, this.tempAnimated.fillAlpha); + this.switchObj.lineStyle( + this.tempAnimated.strokeWidth, + this.tempAnimated.stroke, + this.tempAnimated.strokeAlpha + ); + this.switchObj.beginFill( + this.tempAnimated.fill, + this.tempAnimated.fillAlpha + ); this.switchObj.moveTo(this.radius, 0); this.switchObj.lineTo(this.opts.width - this.radius, 0); - this.switchObj.arcTo(this.opts.width, 0, this.opts.width, this.radius, this.radius); - this.switchObj.lineTo(this.opts.width, this.radius + 1); // BUGFIX: If not specified, there is a small area without a stroke. - this.switchObj.arcTo(this.opts.width, this.opts.height, this.opts.width - this.radius, this.opts.height, this.radius); + this.switchObj.arcTo( + this.opts.width, + 0, + this.opts.width, + this.radius, + this.radius + ); + this.switchObj.lineTo(this.opts.width, this.radius + 1); // BUGFIX: If not specified, there is a small area without a stroke. + this.switchObj.arcTo( + this.opts.width, + this.opts.height, + this.opts.width - this.radius, + this.opts.height, + this.radius + ); this.switchObj.lineTo(this.radius, this.opts.height); this.switchObj.arcTo(0, this.opts.height, 0, this.radius, this.radius); this.switchObj.arcTo(0, 0, this.radius, 0, this.radius); this.switchObj.endFill(); this.control.clear(); - this.control.lineStyle(this.tempAnimated.controlStrokeWidth, this.tempAnimated.controlStroke, this.tempAnimated.controlStrokeAlpha); - this.control.beginFill(this.tempAnimated.controlFill, this.tempAnimated.controlFillAlpha); + this.control.lineStyle( + this.tempAnimated.controlStrokeWidth, + this.tempAnimated.controlStroke, + this.tempAnimated.controlStrokeAlpha + ); + this.control.beginFill( + this.tempAnimated.controlFill, + this.tempAnimated.controlFillAlpha + ); this.control.drawCircle(0, 0, this.tempAnimated.controlRadius - 1); this.control.endFill(); return this } - + /** * Gets or sets the active state. - * + * * @member {boolean} */ get active() { @@ -14715,12 +15380,10 @@ } set active(value) { - this._active = value; if (this._active) { - - TweenLite.to(this.control, this.opts.duration, {x: this.xActive}); + TweenLite.to(this.control, this.opts.duration, { x: this.xActive }); TweenLite.to(this.tempAnimated, this.opts.duration, { colorProps: { fill: this.opts.fillActive, @@ -14739,10 +15402,10 @@ onUpdate: () => this.drawAnimated(), onComplete: () => this.draw() }); - - } else { - TweenLite.to(this.control, this.opts.durationActive, {x: this.xInactive}); + TweenLite.to(this.control, this.opts.durationActive, { + x: this.xInactive + }); TweenLite.to(this.tempAnimated, this.opts.durationActive, { colorProps: { fill: this.opts.fill, @@ -14763,10 +15426,10 @@ }); } } - + /** * Gets or sets the disabled state. When disabled, the switch cannot be clicked. - * + * * @member {boolean} */ get disabled() { @@ -14774,14 +15437,13 @@ } set disabled(value) { - this._disabled = value; - + if (this._disabled) { this.switchObj.interactive = false; this.switchObj.buttonMode = false; - this.switchObj.alpha = .5; - this.control.alpha = .5; + this.switchObj.alpha = 0.5; + this.control.alpha = 0.5; } else { this.switchObj.interactive = true; this.switchObj.buttonMode = true; @@ -14792,11 +15454,10 @@ /** * Shows the switch (sets his alpha values to 1). - * + * * @return {Switch} A reference to the switch for chaining. */ show() { - this.opts.strokeAlpha = 1; this.opts.strokeActiveAlpha = 1; this.opts.fillAlpha = 1; @@ -14810,14 +15471,13 @@ return this } - + /** * Hides the switch (sets his alpha values to 1). - * + * * @return {Switch} A reference to the switch for chaining. */ hide() { - this.opts.strokeAlpha = 0; this.opts.strokeActiveAlpha = 0; this.opts.fillAlpha = 0; @@ -14835,7 +15495,7 @@ /** * Class that represents a PixiJS PopupMenu. - * + * * @example * // Create the button and the modal when clicked * const button = new Button({ @@ -14860,10 +15520,9 @@ * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/popupmenu.html|DocTest} */ class PopupMenu extends Popup { - /** * Creates an instance of a PopupMenu. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the modal. * @param {object[]} [opts.items=[]] - A list of the menu items. Each item must be of type object. @@ -14875,38 +15534,42 @@ * @param {boolean} [opts.closeOnPopup=true] - The opacity of the background. */ constructor(opts = {}) { - const theme = Theme.fromString(opts.theme); - - opts = Object.assign({}, { - items: [], - margin: theme.margin / 2, - textStyle: theme.textStyle, - closeOnPopup: true - }, opts); + + opts = Object.assign( + {}, + { + items: [], + margin: theme.margin / 2, + textStyle: theme.textStyle, + closeOnPopup: true + }, + opts + ); super(opts); } - + /** * Creates children and instantiates everything. - * + * * @private * @return {PopupMenu} A reference to the popupmenu for chaining. */ setup() { - // content //----------------- const content = new PIXI.Container(); - + let y = 0; for (let item of this.opts.items) { - let object = null; if (item.label) { - object = new PIXI.Text(item.label, item.textStyle || this.opts.textStyle); + object = new PIXI.Text( + item.label, + item.textStyle || this.opts.textStyle + ); } else { object = item.content; } @@ -14915,16 +15578,22 @@ if (item.action) { if (item.disabled) { - object.alpha = .5; + object.alpha = 0.5; } else { object.interactive = true; object.buttonMode = true; } object.on('pointerover', e => { - TweenLite.to(object, this.theme.fast, {alpha: .83, overwrite: 'none'}); + TweenLite.to(object, this.theme.fast, { + alpha: 0.83, + overwrite: 'none' + }); }); object.on('pointerout', e => { - TweenLite.to(object, this.theme.fast, {alpha: 1, overwrite: 'none'}); + TweenLite.to(object, this.theme.fast, { + alpha: 1, + overwrite: 'none' + }); }); object.on('pointerup', e => { item.action.call(object, e, object); @@ -14949,14 +15618,14 @@ /** * Class that represents a PixiJS Volatile. - * + * * @example * const app = new PIXIApp({ * view: canvas, * width: 900, * height: 250 * }).setup().run() - * + * * const button = new Button({ * label: 'Volatile!', * action: () => { @@ -14967,17 +15636,16 @@ * }) * } * }) - * + * * app.scene.addChild(button) * * @class * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/volatile.html|DocTest} */ class Volatile { - /** * Creates an instance of a Volatile. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the modal. * @param {number} [opts.id=auto generated] - The id of the tooltip. @@ -14991,21 +15659,24 @@ * @param {boolean} [opts.destroyOnComplete=true] - Should the object be destroyed after the volatile animation? */ constructor(opts = {}) { - const theme = Theme.fromString(opts.theme); this.theme = theme; - this.opts = Object.assign({}, { - id: PIXI.utils.uid(), - object: null, - direction: 'top', // top, right, bottom, left - onStart: null, - onComplete: null, - distance: 160, - duration: 1.5, - ease: Quad.easeOut, - destroyOnComplete: true - }, opts); + this.opts = Object.assign( + {}, + { + id: PIXI.utils.uid(), + object: null, + direction: 'top', // top, right, bottom, left + onStart: null, + onComplete: null, + distance: 160, + duration: 1.5, + ease: Quad.easeOut, + destroyOnComplete: true + }, + opts + ); this.id = this.opts.id; @@ -15027,38 +15698,34 @@ //----------------- this.run(); } - + /** * Creates children and instantiates everything. - * + * * @private * @return {Volatile} A reference to the volatile for chaining. */ setup() { - return this } - + /** * Should be called to refresh the layout of the volatile. Can be used after resizing. - * + * * @return {Volatile} A reference to the volatile for chaining. */ layout() { - return this } - + /** * Starts the volatile animation. - * + * * @private * @return {Volatile} A reference to the volatile for chaining. */ run() { - for (let object of this.objects) { - let x = object.x; let y = object.y; @@ -15089,13 +15756,12 @@ } }, onComplete: () => { - if (this.opts.onComplete) { this.opts.onComplete.call(object, object); } if (this.opts.destroyOnComplete) { - object.destroy({children: true}); + object.destroy({ children: true }); } } }); @@ -15113,10 +15779,10 @@ * @example * const elephant1 = PIXI.Sprite.fromImage('./assets/elephant-1.jpg') * const elephant2 = PIXI.Sprite.fromImage('./assets/elephant-2.jpg') - * + * * // Create the list * const list = new List([elephant1, elephant2]) - * + * * app.scene.addChild(list) * * @class @@ -15125,7 +15791,6 @@ * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/list.html|DocTest} */ class List extends PIXI.Container { - /** * Creates an instance of a Flippable. * @@ -15147,19 +15812,22 @@ * scroll your list. */ constructor(items = [], opts = {}) { - super(); - this.opts = Object.assign({}, { - padding: 10, - margin: 10, - orientation: 'vertical', - align: 'left', - verticalAlign: 'middle', - width: null, - height: null, - app: null - }, opts); + this.opts = Object.assign( + {}, + { + padding: 10, + margin: 10, + orientation: 'vertical', + align: 'left', + verticalAlign: 'middle', + width: null, + height: null, + app: null + }, + opts + ); this.__items = items; this.__dragging = false; @@ -15176,7 +15844,6 @@ * @return {List} A reference to the list for chaining. */ setup() { - // inner container //-------------------- const container = new PIXI.Container(); @@ -15191,7 +15858,7 @@ // add items //-------------------- - for(let item of this.__items) { + for (let item of this.__items) { container.addChild(item); } @@ -15211,7 +15878,9 @@ if (this.opts.app) { const app = this.opts.app; app.view.addEventListener('mousewheel', event => { - const bounds = this.mask ? this.mask.getBounds() : this.getBounds(); + const bounds = this.mask + ? this.mask.getBounds() + : this.getBounds(); const x = event.clientX - app.view.getBoundingClientRect().left; const y = event.clientY - app.view.getBoundingClientRect().top; if (bounds.contains(x, y)) { @@ -15235,7 +15904,7 @@ setItems(items) { this.container.removeChildren(); this.__items = items; - for(let item of this.__items) { + for (let item of this.__items) { this.container.addChild(item); } this.layout(); @@ -15247,14 +15916,12 @@ * @return {List} A reference to the list for chaining. */ layout() { - const margin = this.opts.margin; let x = margin; let y = margin; for (let item of this.__items) { - item.x = x; item.y = y; @@ -15270,13 +15937,17 @@ if (this.opts.orientation === 'vertical') { switch (this.opts.align) { case 'center': - this.__items.forEach(it => it.x = margin + this.width / 2 - it.width / 2); + this.__items.forEach( + it => (it.x = margin + this.width / 2 - it.width / 2) + ); break case 'right': - this.__items.forEach(it => it.x = margin + this.width - it.width); + this.__items.forEach( + it => (it.x = margin + this.width - it.width) + ); break default: - this.__items.forEach(it => it.x = margin); + this.__items.forEach(it => (it.x = margin)); break } @@ -15296,13 +15967,17 @@ if (this.opts.orientation === 'horizontal') { switch (this.opts.verticalAlign) { case 'top': - this.__items.forEach(it => it.y = margin); + this.__items.forEach(it => (it.y = margin)); break case 'bottom': - this.__items.forEach(it => it.y = margin + this.height - it.height); + this.__items.forEach( + it => (it.y = margin + this.height - it.height) + ); break default: - this.__items.forEach(it => it.y = margin + this.height / 2 - it.height / 2); + this.__items.forEach( + it => (it.y = margin + this.height / 2 - it.height / 2) + ); break } @@ -15321,13 +15996,12 @@ } /** - * + * */ get innerWidth() { - let size = 0; - this.__items.forEach(it => size += it.width); + this.__items.forEach(it => (size += it.width)); size += this.opts.padding * (this.__items.length - 1); size += 2 * this.opts.margin; @@ -15335,13 +16009,12 @@ } /** - * + * */ get innerHeight() { - let size = 0; - this.__items.forEach(it => size += it.height); + this.__items.forEach(it => (size += it.height)); size += this.opts.padding * (this.__items.length - 1); size += 2 * this.opts.margin; @@ -15350,11 +16023,10 @@ /** * Resizes the list. - * + * * @param {number} widthOrHeight - The new width (if orientation is horizontal) or height (if orientation is vertical) of the list. */ resize(widthOrHeight) { - if (this.opts.orientation === 'horizontal') { this.opts.width = widthOrHeight; } else { @@ -15365,12 +16037,11 @@ } /** - * + * * @private - * @param {*} event + * @param {*} event */ onStart(event) { - this.__dragging = true; this.capture(event); @@ -15380,21 +16051,19 @@ y: this.container.position.y - event.data.global.y }; - TweenLite.killTweensOf(this.container.position, {x: true, y: true}); - if (typeof ThrowPropsPlugin != "undefined") { + TweenLite.killTweensOf(this.container.position, { x: true, y: true }); + if (typeof ThrowPropsPlugin != 'undefined') { ThrowPropsPlugin.track(this.container.position, 'x,y'); } } /** - * + * * @private - * @param {*} event + * @param {*} event */ onMove(event) { - if (this.__dragging) { - this.capture(event); if (this.opts.orientation === 'horizontal') { @@ -15406,19 +16075,18 @@ } /** - * + * * @private - * @param {*} event + * @param {*} event */ onEnd(event) { - if (this.__dragging) { this.__dragging = false; this.capture(event); const throwProps = {}; - + if (this.opts.orientation === 'horizontal') { let min = this.opts.width - this.innerWidth; min = min > 0 ? 0 : min; @@ -15437,37 +16105,48 @@ }; } - if (typeof ThrowPropsPlugin != "undefined") { - ThrowPropsPlugin.to(this.container.position, { - throwProps, - ease: Strong.easeOut, - onComplete: () => ThrowPropsPlugin.untrack(this.container.position) - }, .8, .4); + if (typeof ThrowPropsPlugin != 'undefined') { + ThrowPropsPlugin.to( + this.container.position, + { + throwProps, + ease: Strong.easeOut, + onComplete: () => + ThrowPropsPlugin.untrack(this.container.position) + }, + 0.8, + 0.4 + ); } } } /** - * + * * @private - * @param {*} event + * @param {*} event */ onScroll(event) { - this.capture(event); if (this.opts.orientation === 'horizontal') { this.container.position.x -= event.deltaX; if (this.container.position.x > 0) { this.container.position.x = 0; - } else if (this.container.position.x + this.innerWidth < this.opts.width) { + } else if ( + this.container.position.x + this.innerWidth < + this.opts.width + ) { this.container.position.x = this.opts.width - this.innerWidth; } } else { this.container.position.y -= event.deltaY; if (this.container.position.y > 0) { this.container.position.y = 0; - } else if (this.container.position.y + this.innerHeight < this.opts.height) { + } else if ( + this.container.position.y + this.innerHeight < + this.opts.height + ) { this.container.position.y = this.opts.height - this.innerHeight; } } @@ -15479,7 +16158,10 @@ * @param {event|PIXI.InteractionEvent} event - The PIXI event to capture. */ capture(event) { - const originalEvent = event.data && event.data.originalEvent ? event.data.originalEvent : event; + const originalEvent = + event.data && event.data.originalEvent + ? event.data.originalEvent + : event; Events$1.capturedBy(originalEvent, this); } } diff --git a/doc/out/AbstractPopup.html b/doc/out/AbstractPopup.html index e544c7b..938d746 100644 --- a/doc/out/AbstractPopup.html +++ b/doc/out/AbstractPopup.html @@ -1467,7 +1467,7 @@ like Popup, Message, Tooltip...

@@ -2491,7 +2491,7 @@ a string, a number or a PIXI.Text object.

@@ -2648,7 +2648,7 @@ a string, a number or a PIXI.Text object.

@@ -2753,7 +2753,7 @@ a string, a number or a PIXI.Text object.

@@ -2912,7 +2912,7 @@ a string, a number or a PIXI.Text object.

diff --git a/doc/out/Badge.html b/doc/out/Badge.html index 50b4fee..1d623cb 100644 --- a/doc/out/Badge.html +++ b/doc/out/Badge.html @@ -1465,7 +1465,7 @@ @@ -1939,7 +1939,7 @@ a string, a number or a PIXI.Text object.

@@ -2100,7 +2100,7 @@ a string, a number or a PIXI.Text object.

@@ -2209,7 +2209,7 @@ a string, a number or a PIXI.Text object.

@@ -2368,7 +2368,7 @@ a string, a number or a PIXI.Text object.

diff --git a/doc/out/BlurFilter.html b/doc/out/BlurFilter.html index d1189d0..9514f8d 100644 --- a/doc/out/BlurFilter.html +++ b/doc/out/BlurFilter.html @@ -1469,7 +1469,7 @@ is assigned to!

@@ -1792,7 +1792,7 @@ app.scene.filters = [blurFilter]
diff --git a/doc/out/Button.html b/doc/out/Button.html index 4e5672c..130f6df 100644 --- a/doc/out/Button.html +++ b/doc/out/Button.html @@ -1465,7 +1465,7 @@ @@ -3369,7 +3369,7 @@ the tint property of the icon sprite.

@@ -3493,7 +3493,7 @@ the tint property of the icon sprite.

@@ -3598,7 +3598,7 @@ the tint property of the icon sprite.

@@ -3703,7 +3703,7 @@ the tint property of the icon sprite.

@@ -3810,7 +3810,7 @@ the tint property of the icon sprite.

diff --git a/doc/out/ButtonGroup.html b/doc/out/ButtonGroup.html index 994bc8d..30aaabf 100644 --- a/doc/out/ButtonGroup.html +++ b/doc/out/ButtonGroup.html @@ -1465,7 +1465,7 @@ @@ -2889,7 +2889,7 @@ app.scene.addChild(buttonGroup) @@ -2994,7 +2994,7 @@ app.scene.addChild(buttonGroup) @@ -3099,7 +3099,7 @@ app.scene.addChild(buttonGroup) @@ -3206,7 +3206,7 @@ app.scene.addChild(buttonGroup)
diff --git a/doc/out/DeepZoomImage.html b/doc/out/DeepZoomImage.html index 542710c..2ac1c23 100644 --- a/doc/out/DeepZoomImage.html +++ b/doc/out/DeepZoomImage.html @@ -5090,7 +5090,7 @@ i.e. after loading a single tile

diff --git a/doc/out/DeepZoomInfo.html b/doc/out/DeepZoomInfo.html index fc03cd0..fecf0d4 100644 --- a/doc/out/DeepZoomInfo.html +++ b/doc/out/DeepZoomInfo.html @@ -2603,7 +2603,7 @@ on completion.

diff --git a/doc/out/Flippable.html b/doc/out/Flippable.html index 1b15689..4b6c486 100644 --- a/doc/out/Flippable.html +++ b/doc/out/Flippable.html @@ -1465,7 +1465,7 @@ @@ -2399,7 +2399,7 @@ front.on('click', event => flippable.toggle()) @@ -2506,7 +2506,7 @@ front.on('click', event => flippable.toggle())
diff --git a/doc/out/FontInfo.html b/doc/out/FontInfo.html index 7983e52..d0b9130 100644 --- a/doc/out/FontInfo.html +++ b/doc/out/FontInfo.html @@ -1465,7 +1465,7 @@ @@ -1553,7 +1553,7 @@
diff --git a/doc/out/Hypenate.html b/doc/out/Hypenate.html index cc69b96..c018c72 100644 --- a/doc/out/Hypenate.html +++ b/doc/out/Hypenate.html @@ -1463,7 +1463,7 @@ @@ -1557,7 +1557,7 @@ @@ -1755,7 +1755,7 @@
diff --git a/doc/out/InteractivePopup.html b/doc/out/InteractivePopup.html index 1e9d4b6..358e7ac 100644 --- a/doc/out/InteractivePopup.html +++ b/doc/out/InteractivePopup.html @@ -1467,7 +1467,7 @@ like Popup, Message...

@@ -1910,7 +1910,7 @@ a string, a number or a PIXI.Text object.

@@ -2069,7 +2069,7 @@ a string, a number or a PIXI.Text object.

@@ -2178,7 +2178,7 @@ a string, a number or a PIXI.Text object.

@@ -2337,7 +2337,7 @@ a string, a number or a PIXI.Text object.

diff --git a/doc/out/LabeledGraphics.exports.LabeledGraphics.html b/doc/out/LabeledGraphics.exports.LabeledGraphics.html index 2aacb44..e64996c 100644 --- a/doc/out/LabeledGraphics.exports.LabeledGraphics.html +++ b/doc/out/LabeledGraphics.exports.LabeledGraphics.html @@ -1463,7 +1463,7 @@ @@ -1555,7 +1555,7 @@
diff --git a/doc/out/LabeledGraphics.html b/doc/out/LabeledGraphics.html index 515e009..14e6732 100644 --- a/doc/out/LabeledGraphics.html +++ b/doc/out/LabeledGraphics.html @@ -1463,7 +1463,7 @@ @@ -1571,7 +1571,7 @@ resuse and place labels across different layout variants

@@ -1647,7 +1647,7 @@ resuse and place labels across different layout variants

@@ -1996,7 +1996,7 @@ maxWidth: {number} word wraps text using hyphenation if possible

@@ -2146,7 +2146,7 @@ maxWidth: {number} word wraps text using hyphenation if possible

@@ -2267,7 +2267,7 @@ maxWidth: {number} word wraps text using hyphenation if possible

@@ -2388,7 +2388,7 @@ maxWidth: {number} word wraps text using hyphenation if possible

@@ -2620,7 +2620,7 @@ than wanted

diff --git a/doc/out/List.html b/doc/out/List.html index 607ec99..2250f6d 100644 --- a/doc/out/List.html +++ b/doc/out/List.html @@ -1465,7 +1465,7 @@ @@ -2077,7 +2077,7 @@ app.scene.addChild(list) @@ -2201,7 +2201,7 @@ app.scene.addChild(list) @@ -2306,7 +2306,7 @@ app.scene.addChild(list) @@ -2427,7 +2427,7 @@ app.scene.addChild(list) @@ -2579,7 +2579,7 @@ app.scene.addChild(list)
diff --git a/doc/out/Message.html b/doc/out/Message.html index cae27e1..aea87a6 100644 --- a/doc/out/Message.html +++ b/doc/out/Message.html @@ -1465,7 +1465,7 @@ @@ -2169,7 +2169,7 @@ a string, a number or a PIXI.Text object.

@@ -2328,7 +2328,7 @@ a string, a number or a PIXI.Text object.

@@ -2435,7 +2435,7 @@ a string, a number or a PIXI.Text object.

diff --git a/doc/out/MessageInteractivePopup.html b/doc/out/MessageInteractivePopup.html index 1d71f6c..495f1b2 100644 --- a/doc/out/MessageInteractivePopup.html +++ b/doc/out/MessageInteractivePopup.html @@ -1469,7 +1469,7 @@ like Popup, Message...

@@ -1783,7 +1783,7 @@ like Popup, Message...

diff --git a/doc/out/MessageMessageInteractivePopup.html b/doc/out/MessageMessageInteractivePopup.html index 2eb8e87..1aaf8e4 100644 --- a/doc/out/MessageMessageInteractivePopup.html +++ b/doc/out/MessageMessageInteractivePopup.html @@ -1469,7 +1469,7 @@ like Popup, Message...

@@ -1783,7 +1783,7 @@ like Popup, Message...

diff --git a/doc/out/Modal.html b/doc/out/Modal.html index 3a16d4d..09b033f 100644 --- a/doc/out/Modal.html +++ b/doc/out/Modal.html @@ -1465,7 +1465,7 @@ @@ -2015,7 +2015,7 @@ a string or a PIXI.Text object.

@@ -2122,7 +2122,7 @@ a string or a PIXI.Text object.

@@ -2229,7 +2229,7 @@ a string or a PIXI.Text object.

@@ -2336,7 +2336,7 @@ a string or a PIXI.Text object.

diff --git a/doc/out/ModalInteractivePopup.html b/doc/out/ModalInteractivePopup.html index 57ad45d..fdaf3e1 100644 --- a/doc/out/ModalInteractivePopup.html +++ b/doc/out/ModalInteractivePopup.html @@ -1469,7 +1469,7 @@ like Popup, Message...

@@ -1783,7 +1783,7 @@ like Popup, Message...

diff --git a/doc/out/ModalModalInteractivePopup.html b/doc/out/ModalModalInteractivePopup.html index fed0040..96e34e2 100644 --- a/doc/out/ModalModalInteractivePopup.html +++ b/doc/out/ModalModalInteractivePopup.html @@ -1469,7 +1469,7 @@ like Popup, Message...

@@ -1783,7 +1783,7 @@ like Popup, Message...

diff --git a/doc/out/PIXIApp.html b/doc/out/PIXIApp.html index 97702ce..6888662 100644 --- a/doc/out/PIXIApp.html +++ b/doc/out/PIXIApp.html @@ -2316,7 +2316,7 @@ const app = new PIXIApp({ @@ -2423,7 +2423,7 @@ const app = new PIXIApp({ @@ -2552,7 +2552,7 @@ handler for the orientationchange event.

@@ -2749,7 +2749,7 @@ to browser page coordinates.

@@ -2946,7 +2946,7 @@ to local DisplayObject coordinates.

@@ -3023,7 +3023,7 @@ to the layout method.

@@ -3188,7 +3188,7 @@ to the layout method.

@@ -3347,7 +3347,7 @@ adapt their layout to the new app size.

@@ -3680,7 +3680,7 @@ renderer resolution?

@@ -4013,7 +4013,7 @@ renderer resolution?

@@ -4170,7 +4170,7 @@ renderer resolution?

@@ -4327,7 +4327,7 @@ renderer resolution?

@@ -4528,7 +4528,7 @@ rejected with an error. @@ -4633,7 +4633,7 @@ rejected with an error. @@ -4769,7 +4769,7 @@ rejected with an error. @@ -4930,7 +4930,7 @@ called without a parameter. @@ -5131,7 +5131,7 @@ rejected with an error. @@ -5428,7 +5428,7 @@ rejected with an error. @@ -5534,7 +5534,7 @@ Overwrite this method if you need additonal views and components.

@@ -5737,7 +5737,7 @@ rejected with an error.
diff --git a/doc/out/Popup.html b/doc/out/Popup.html index 4df70cc..a7139d1 100644 --- a/doc/out/Popup.html +++ b/doc/out/Popup.html @@ -1465,7 +1465,7 @@ @@ -1901,7 +1901,7 @@ a string, a number or a PIXI.Text object.

@@ -2062,7 +2062,7 @@ a string, a number or a PIXI.Text object.

@@ -2171,7 +2171,7 @@ a string, a number or a PIXI.Text object.

@@ -2330,7 +2330,7 @@ a string, a number or a PIXI.Text object.

diff --git a/doc/out/PopupInteractivePopup.html b/doc/out/PopupInteractivePopup.html index 604c74b..c32d641 100644 --- a/doc/out/PopupInteractivePopup.html +++ b/doc/out/PopupInteractivePopup.html @@ -1469,7 +1469,7 @@ like Popup, Message...

@@ -1783,7 +1783,7 @@ like Popup, Message...

diff --git a/doc/out/PopupMenu.html b/doc/out/PopupMenu.html index ca6e439..95d90a8 100644 --- a/doc/out/PopupMenu.html +++ b/doc/out/PopupMenu.html @@ -1465,7 +1465,7 @@ @@ -1955,7 +1955,7 @@ a string, a number or a PIXI.Text object.

@@ -2116,7 +2116,7 @@ a string, a number or a PIXI.Text object.

@@ -2225,7 +2225,7 @@ a string, a number or a PIXI.Text object.

@@ -2384,7 +2384,7 @@ a string, a number or a PIXI.Text object.

diff --git a/doc/out/PopupMenuPopupInteractivePopup.html b/doc/out/PopupMenuPopupInteractivePopup.html index 9b99a95..fb28912 100644 --- a/doc/out/PopupMenuPopupInteractivePopup.html +++ b/doc/out/PopupMenuPopupInteractivePopup.html @@ -1469,7 +1469,7 @@ like Popup, Message...

@@ -1783,7 +1783,7 @@ like Popup, Message...

diff --git a/doc/out/PopupMenuPopupMenuPopupInteractivePopup.html b/doc/out/PopupMenuPopupMenuPopupInteractivePopup.html index d0a01e5..34a86bc 100644 --- a/doc/out/PopupMenuPopupMenuPopupInteractivePopup.html +++ b/doc/out/PopupMenuPopupMenuPopupInteractivePopup.html @@ -1469,7 +1469,7 @@ like Popup, Message...

@@ -1783,7 +1783,7 @@ like Popup, Message...

diff --git a/doc/out/PopupMenuPopupMenuPopupPopupInteractivePopup.html b/doc/out/PopupMenuPopupMenuPopupPopupInteractivePopup.html index fa3de9b..04b4996 100644 --- a/doc/out/PopupMenuPopupMenuPopupPopupInteractivePopup.html +++ b/doc/out/PopupMenuPopupMenuPopupPopupInteractivePopup.html @@ -1469,7 +1469,7 @@ like Popup, Message...

@@ -1783,7 +1783,7 @@ like Popup, Message...

diff --git a/doc/out/PopupMenuPopupPopupInteractivePopup.html b/doc/out/PopupMenuPopupPopupInteractivePopup.html index ba4305c..9fb5615 100644 --- a/doc/out/PopupMenuPopupPopupInteractivePopup.html +++ b/doc/out/PopupMenuPopupPopupInteractivePopup.html @@ -1469,7 +1469,7 @@ like Popup, Message...

@@ -1783,7 +1783,7 @@ like Popup, Message...

diff --git a/doc/out/PopupPopupInteractivePopup.html b/doc/out/PopupPopupInteractivePopup.html index db3d8c4..f2535ed 100644 --- a/doc/out/PopupPopupInteractivePopup.html +++ b/doc/out/PopupPopupInteractivePopup.html @@ -1469,7 +1469,7 @@ like Popup, Message...

@@ -1783,7 +1783,7 @@ like Popup, Message...

diff --git a/doc/out/Progress.html b/doc/out/Progress.html index 76aca61..81b3498 100644 --- a/doc/out/Progress.html +++ b/doc/out/Progress.html @@ -1465,7 +1465,7 @@ @@ -2552,7 +2552,7 @@ app.scene.addChild(progress) @@ -2657,7 +2657,7 @@ app.scene.addChild(progress) @@ -2762,7 +2762,7 @@ app.scene.addChild(progress) @@ -2869,7 +2869,7 @@ app.scene.addChild(progress)
diff --git a/doc/out/Scrollview.html b/doc/out/Scrollview.html index c024568..30dd5f4 100644 --- a/doc/out/Scrollview.html +++ b/doc/out/Scrollview.html @@ -1465,7 +1465,7 @@ @@ -1594,7 +1594,7 @@ app.loader @@ -1701,7 +1701,7 @@ app.loader
diff --git a/doc/out/Slider.html b/doc/out/Slider.html index 84ab5f4..0837f2e 100644 --- a/doc/out/Slider.html +++ b/doc/out/Slider.html @@ -1465,7 +1465,7 @@ @@ -2643,7 +2643,7 @@ app.scene.addChild(slider) @@ -2748,7 +2748,7 @@ app.scene.addChild(slider) @@ -2853,7 +2853,7 @@ app.scene.addChild(slider) @@ -2960,7 +2960,7 @@ app.scene.addChild(slider)
diff --git a/doc/out/Switch.html b/doc/out/Switch.html index 4854327..9e9d798 100644 --- a/doc/out/Switch.html +++ b/doc/out/Switch.html @@ -1465,7 +1465,7 @@ @@ -3073,7 +3073,7 @@ app.scene.addChild(switch1) @@ -3178,7 +3178,7 @@ app.scene.addChild(switch1) @@ -3283,7 +3283,7 @@ app.scene.addChild(switch1) @@ -3390,7 +3390,7 @@ app.scene.addChild(switch1)
diff --git a/doc/out/TextLabel.TextLabel.html b/doc/out/TextLabel.TextLabel.html index b66c0bc..9ade891 100644 --- a/doc/out/TextLabel.TextLabel.html +++ b/doc/out/TextLabel.TextLabel.html @@ -1463,7 +1463,7 @@ @@ -1684,7 +1684,7 @@
diff --git a/doc/out/Theme.html b/doc/out/Theme.html index 4b4ba90..a144eef 100644 --- a/doc/out/Theme.html +++ b/doc/out/Theme.html @@ -1465,7 +1465,7 @@ @@ -2999,7 +2999,7 @@ const app = new PIXIApp({ @@ -3159,7 +3159,7 @@ const app = new PIXIApp({
diff --git a/doc/out/ThemeDark.html b/doc/out/ThemeDark.html index c5ff4c4..d6780a8 100644 --- a/doc/out/ThemeDark.html +++ b/doc/out/ThemeDark.html @@ -1465,7 +1465,7 @@ @@ -1580,7 +1580,7 @@ const app = new PIXIApp({
diff --git a/doc/out/ThemeLight.html b/doc/out/ThemeLight.html index f8f8cdc..2da33fd 100644 --- a/doc/out/ThemeLight.html +++ b/doc/out/ThemeLight.html @@ -1466,7 +1466,7 @@ The color1 is set to 0xf6f6f6, color2 to 0x282828.

@@ -1592,7 +1592,7 @@ const app = new PIXIApp({
diff --git a/doc/out/ThemeRed.html b/doc/out/ThemeRed.html index e44322c..c95b6ac 100644 --- a/doc/out/ThemeRed.html +++ b/doc/out/ThemeRed.html @@ -1466,7 +1466,7 @@ The primaryColor is set to 0xd92f31.

@@ -1592,7 +1592,7 @@ const app = new PIXIApp({
diff --git a/doc/out/TileQuadNode.html b/doc/out/TileQuadNode.html index b7d84e9..23880b0 100644 --- a/doc/out/TileQuadNode.html +++ b/doc/out/TileQuadNode.html @@ -2044,7 +2044,7 @@ an indicator of tiles to free.

diff --git a/doc/out/Tooltip.html b/doc/out/Tooltip.html index f424668..7fc26e5 100644 --- a/doc/out/Tooltip.html +++ b/doc/out/Tooltip.html @@ -1465,7 +1465,7 @@ @@ -2077,7 +2077,7 @@ a string, a number or a PIXI.Text object.

@@ -2238,7 +2238,7 @@ a string, a number or a PIXI.Text object.

@@ -2347,7 +2347,7 @@ a string, a number or a PIXI.Text object.

@@ -2506,7 +2506,7 @@ a string, a number or a PIXI.Text object.

diff --git a/doc/out/UITest.html b/doc/out/UITest.html index 7a8820b..8a3bb49 100644 --- a/doc/out/UITest.html +++ b/doc/out/UITest.html @@ -1465,7 +1465,7 @@ @@ -1857,7 +1857,7 @@ test.start() @@ -1962,7 +1962,7 @@ test.start() @@ -2596,7 +2596,7 @@ test.start() @@ -3340,7 +3340,7 @@ test.start() @@ -3445,7 +3445,7 @@ test.start() @@ -3550,7 +3550,7 @@ test.start() @@ -3655,7 +3655,7 @@ test.start() @@ -4177,7 +4177,7 @@ test.start()
diff --git a/doc/out/Volatile.html b/doc/out/Volatile.html index da507d2..ee09a08 100644 --- a/doc/out/Volatile.html +++ b/doc/out/Volatile.html @@ -1465,7 +1465,7 @@ @@ -1986,7 +1986,7 @@ app.scene.addChild(button) @@ -2093,7 +2093,7 @@ app.scene.addChild(button)
diff --git a/doc/out/global.html b/doc/out/global.html index 155d3d0..ce1d837 100644 --- a/doc/out/global.html +++ b/doc/out/global.html @@ -3314,7 +3314,7 @@
diff --git a/doc/out/index.html b/doc/out/index.html index eab4b55..4d36a1e 100644 --- a/doc/out/index.html +++ b/doc/out/index.html @@ -1479,7 +1479,7 @@
diff --git a/doc/out/pixi_abstractpopup.js.html b/doc/out/pixi_abstractpopup.js.html index ecf57a9..d938b46 100644 --- a/doc/out/pixi_abstractpopup.js.html +++ b/doc/out/pixi_abstractpopup.js.html @@ -1451,10 +1451,9 @@ * @see {@link http://pixijs.download/dev/docs/PIXI.Graphics.html|PIXI.Graphics} */ export default class AbstractPopup extends PIXI.Graphics { - /** * Creates an instance of an AbstractPopup (only for internal use). - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the popup. * @param {number} [opts.id=auto generated] - The id of the popup. @@ -1485,34 +1484,37 @@ export default class AbstractPopup extends PIXI.Graphics { * to landscape, the popup cannot be displayed in portrait mode. */ constructor(opts = {}) { - super() - + const theme = Theme.fromString(opts.theme) this.theme = theme - this.opts = Object.assign({}, { - id: PIXI.utils.uid(), - x: 0, - y: 0, - header: null, // null or null - content: null, // null or String or PIXI.DisplayObject - minWidth: 320, - minHeight: 130, - maxWidth: null, - padding: theme.padding, - fill: theme.fill, - fillAlpha: theme.fillAlpha, - stroke: theme.stroke, - strokeWidth: theme.strokeWidth, - strokeAlpha: theme.strokeAlpha, - headerStyle: theme.textStyleLarge, - textStyle: theme.textStyleSmall, - radius: theme.radius, - onHidden: null, - visible: true, - orientation: null - }, opts) + this.opts = Object.assign( + {}, + { + id: PIXI.utils.uid(), + x: 0, + y: 0, + header: null, // null or null + content: null, // null or String or PIXI.DisplayObject + minWidth: 320, + minHeight: 130, + maxWidth: null, + padding: theme.padding, + fill: theme.fill, + fillAlpha: theme.fillAlpha, + stroke: theme.stroke, + strokeWidth: theme.strokeWidth, + strokeAlpha: theme.strokeAlpha, + headerStyle: theme.textStyleLarge, + textStyle: theme.textStyleSmall, + radius: theme.radius, + onHidden: null, + visible: true, + orientation: null + }, + opts + ) this.id = this.opts.id @@ -1521,10 +1523,12 @@ export default class AbstractPopup extends PIXI.Graphics { if (this.opts.maxWidth) { this.headerStyle.wordWrap = true - this.headerStyle.wordWrapWidth = this.opts.maxWidth - (2 * this.opts.padding) + this.headerStyle.wordWrapWidth = + this.opts.maxWidth - 2 * this.opts.padding this.textStyle.wordWrap = true - this.textStyle.wordWrapWidth = this.opts.maxWidth - (2 * this.opts.padding) + this.textStyle.wordWrapWidth = + this.opts.maxWidth - 2 * this.opts.padding } this.alpha = 0 @@ -1539,7 +1543,7 @@ export default class AbstractPopup extends PIXI.Graphics { // padding this.innerPadding = this.opts.padding * 1.5 - + // interaction //----------------- this.interactive = true @@ -1547,15 +1551,14 @@ export default class AbstractPopup extends PIXI.Graphics { this.show() }) } - + /** * Creates the framework and instantiates everything. - * + * * @private * @return {AbstractPopup} A reference to the popup for chaining. */ setup() { - // position //----------------- this.sy = this.opts.padding @@ -1563,15 +1566,17 @@ export default class AbstractPopup extends PIXI.Graphics { // header //----------------- if (this.opts.header != null) { - let header = null if (this.opts.header instanceof PIXI.Text) { header = this.opts.header } else if (typeof this.opts.header === 'number') { - header = new PIXI.Text(this.opts.header.toString(), this.headerStyle) + header = new PIXI.Text( + this.opts.header.toString(), + this.headerStyle + ) } else { - header = new PIXI.Text(this.opts.header, this.headerStyle) + header = new PIXI.Text(this.opts.header, this.headerStyle) } header.x = this.opts.padding @@ -1591,13 +1596,15 @@ export default class AbstractPopup extends PIXI.Graphics { // content //----------------- if (this.opts.content != null) { - let content = null if (typeof this.opts.content === 'string') { content = new PIXI.Text(this.opts.content, this.textStyle) } else if (typeof this.opts.content === 'number') { - content = new PIXI.Text(this.opts.content.toString(), this.textStyle) + content = new PIXI.Text( + this.opts.content.toString(), + this.textStyle + ) } else { content = this.opts.content } @@ -1614,24 +1621,23 @@ export default class AbstractPopup extends PIXI.Graphics { return this } - + /** * Should be called to refresh the layout of the popup. Can be used after resizing. - * + * * @return {AbstractPopup} A reference to the popup for chaining. */ layout() { - // wanted width & wanted height //----------------- const padding = this.opts.padding const size = this.getInnerSize() - const width = size.width + (2 * padding) - const height = size.height + (2 * padding) + const width = size.width + 2 * padding + const height = size.height + 2 * padding this.wantedWidth = Math.max(width, this.opts.minWidth) this.wantedHeight = Math.max(height, this.opts.minHeight) - + if (this.opts.maxWidth) { this.wantedWidth = Math.min(this.wantedWidth, this.opts.maxWidth) } @@ -1661,41 +1667,54 @@ export default class AbstractPopup extends PIXI.Graphics { return this } - + /** * Draws the canvas. - * + * * @private * @return {AbstractPopup} A reference to the popup for chaining. */ draw() { - - const square = Math.round(this.wantedWidth) === Math.round(this.wantedHeight) + const square = + Math.round(this.wantedWidth) === Math.round(this.wantedHeight) const diameter = Math.round(this.opts.radius * 2) this.clear() - this.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha) + this.lineStyle( + this.opts.strokeWidth, + this.opts.stroke, + this.opts.strokeAlpha + ) this.beginFill(this.opts.fill, this.opts.fillAlpha) if (square && diameter === this.wantedWidth) { - this.drawCircle(this.wantedWidth / 2, this.wantedHeight / 2, this.opts.radius) + this.drawCircle( + this.wantedWidth / 2, + this.wantedHeight / 2, + this.opts.radius + ) } else { - this.drawRoundedRect(0, 0, this.wantedWidth, this.wantedHeight, this.opts.radius) + this.drawRoundedRect( + 0, + 0, + this.wantedWidth, + this.wantedHeight, + this.opts.radius + ) } this.endFill() return this } - + /** * Calculates the size of the children of the AbstractPopup. * Cannot use getBounds() because it is not updated when children * are removed. - * + * * @private * @returns {object} An JavaScript object width the keys width and height. */ getInnerSize() { - let width = 0 let height = 0 @@ -1713,17 +1732,16 @@ export default class AbstractPopup extends PIXI.Graphics { height += this._content.height } - return {width, height} + return { width, height } } - + /** * Shows the popup (sets his alpha values to 1). - * + * * @param {callback} [cb] - Executed when show animation was completed. * @return {AbstractPopup} A reference to the popup for chaining. */ show(cb) { - TweenLite.to(this, this.theme.fast, { alpha: 1, onComplete: () => { @@ -1735,15 +1753,14 @@ export default class AbstractPopup extends PIXI.Graphics { return this } - + /** * Hides the popup (sets his alpha values to 0). - * + * * @param {callback} [cb] - Executed when hide animation was completed. * @return {AbstractPopup} A reference to the popup for chaining. */ hide(cb) { - TweenLite.to(this, this.theme.fast, { alpha: 0, onComplete: () => { @@ -1764,7 +1781,7 @@ export default class AbstractPopup extends PIXI.Graphics { /** * Sets or gets the header. The getter always returns a PIXI.Text object. The setter can receive * a string, a number or a PIXI.Text object. - * + * * @member {string|number|PIXI.Text} */ get header() { @@ -1777,11 +1794,11 @@ export default class AbstractPopup extends PIXI.Graphics { this.opts.header = value this.setup().layout() } - + /** * Sets or gets the content. The getter always returns an PIXI.DisplayObject. The setter can receive * a string, a number or a PIXI.DisplayObject. - * + * * @member {string|number|PIXI.DisplayObject} */ get content() { @@ -1808,7 +1825,7 @@ export default class AbstractPopup extends PIXI.Graphics {
diff --git a/doc/out/pixi_app.js.html b/doc/out/pixi_app.js.html index 07b8935..82b3b27 100644 --- a/doc/out/pixi_app.js.html +++ b/doc/out/pixi_app.js.html @@ -1444,7 +1444,7 @@ import Theme from './theme.js' import Progress from './progress.js' import Modal from './modal.js' import Message from './message.js' -import {debounce} from '../utils.js' +import { debounce } from '../utils.js' /** * A special InteractionManager for fullscreen apps, which may @@ -1461,7 +1461,6 @@ import {debounce} from '../utils.js' * @see {@link https://stackoverflow.com/questions/29710696/webgl-drawing-buffer-size-does-not-equal-canvas-size} */ class FullscreenInteractionManager extends PIXI.interaction.InteractionManager { - mapPositionToPoint(point, x, y) { let resolution = this.renderer.resolution let extendWidth = 1.0 @@ -1469,8 +1468,10 @@ class FullscreenInteractionManager extends PIXI.interaction.InteractionManager { let dy = 0 let canvas = this.renderer.view let context = canvas.getContext('webgl') - if (context.drawingBufferWidth < canvas.width || - context.drawingBufferHeight < canvas.height) { + if ( + context.drawingBufferWidth < canvas.width || + context.drawingBufferHeight < canvas.height + ) { extendWidth = context.drawingBufferWidth / canvas.width extendHeight = context.drawingBufferHeight / canvas.height //dx = wantedWidth - context.drawingBufferWidth @@ -1503,7 +1504,6 @@ class FullscreenInteractionManager extends PIXI.interaction.InteractionManager { * @see {@link http://pixijs.download/dev/docs/PIXI.Application.html|PIXI.Application} */ export default class PIXIApp extends PIXI.Application { - /** * Creates an instance of a PixiApp. * @@ -1526,12 +1526,23 @@ export default class PIXIApp extends PIXI.Application { * @param {boolean} [opts.adaptive=true] - Adds Graphics adaptive calculation of quadratic curve and arc subdivision. */ constructor({ - width = null, height = null, view = null, - transparent = true, backgroundColor = 0x282828, theme = 'dark', - antialias = true, resolution = window.devicePixelRatio || 1, autoResize = true, - fpsLogging = false, progress = {}, forceCanvas = false, roundPixels = true, monkeyPatchMapping = true, adaptive = true, - graphql = false }) { - + width = null, + height = null, + view = null, + transparent = true, + backgroundColor = 0x282828, + theme = 'dark', + antialias = true, + resolution = window.devicePixelRatio || 1, + autoResize = true, + fpsLogging = false, + progress = {}, + forceCanvas = false, + roundPixels = true, + monkeyPatchMapping = true, + adaptive = true, + graphql = false + }) { const fullScreen = !width || !height if (fullScreen) { @@ -1549,7 +1560,7 @@ export default class PIXIApp extends PIXI.Application { autoResize, backgroundColor, forceCanvas, - roundPixels // not needed for PixiJS >= 5 + roundPixels // not needed for PixiJS >= 5 }) this.width = width @@ -1572,7 +1583,10 @@ export default class PIXIApp extends PIXI.Application { console.log('App is in fullScreen mode or autoResize mode') const resizeDebounced = debounce(event => this.resize(event), 50) window.addEventListener('resize', resizeDebounced) - document.body.addEventListener('orientationchange', this.checkOrientation.bind(this)) + document.body.addEventListener( + 'orientationchange', + this.checkOrientation.bind(this) + ) } if (monkeyPatchMapping) { console.log('Using monkey patched coordinate mapping') @@ -1599,15 +1613,17 @@ export default class PIXIApp extends PIXI.Application { // GraphQL if (this.graphql && typeof apollo !== 'undefined') { - const networkInterface = apollo.createNetworkInterface({ uri: '/graphql' }) - const wsClient = new subscriptions.SubscriptionClient(`wss://${location.hostname}/subscriptions`, { - reconnect: true, - connectionParams: {} - }) + const wsClient = new subscriptions.SubscriptionClient( + `wss://${location.hostname}/subscriptions`, + { + reconnect: true, + connectionParams: {} + } + ) const networkInterfaceWithSubscriptions = subscriptions.addGraphQLSubscriptions( networkInterface, @@ -1620,7 +1636,11 @@ export default class PIXIApp extends PIXI.Application { } // progress - this._progress = new Progress(Object.assign({ theme: this.theme }, this.progressOpts, { app: this })) + this._progress = new Progress( + Object.assign({ theme: this.theme }, this.progressOpts, { + app: this + }) + ) this._progress.visible = false this.stage.addChild(this._progress) @@ -1645,9 +1665,12 @@ export default class PIXIApp extends PIXI.Application { checkOrientation(event) { var value = this.orientation() if (value != this.orient) { - setTimeout(100, function () { - this.orientationChanged(true) - }.bind(this)) + setTimeout( + 100, + function() { + this.orientationChanged(true) + }.bind(this) + ) this.orient = value } } @@ -1670,9 +1693,7 @@ export default class PIXIApp extends PIXI.Application { * @param {number} [width] - The width of the app. * @param {number} [height] - The height of the app. */ - layout(width, height) { - - } + layout(width, height) {} /** * Draws the display tree of the app. Typically this can be delegated @@ -1743,7 +1764,10 @@ export default class PIXIApp extends PIXI.Application { * @param {number} [opts.height=window.innerHeight] - The height of the app to resize to. * @return {PIXIApp} - Returns the PIXIApp for chaining. */ - resize(event, { width = window.innerWidth, height = window.innerHeight } = {}) { + resize( + event, + { width = window.innerWidth, height = window.innerHeight } = {} + ) { this.width = width this.height = height this.expandRenderer() @@ -1764,7 +1788,8 @@ export default class PIXIApp extends PIXI.Application { monkeyPatchPixiMapping() { if (this.originalMapPositionToPoint === null) { let interactionManager = this.renderer.plugins.interaction - this.originalMapPositionToPoint = interactionManager.mapPositionToPoint + this.originalMapPositionToPoint = + interactionManager.mapPositionToPoint interactionManager.mapPositionToPoint = (point, x, y) => { return this.fixedMapPositionToPoint(point, x, y) } @@ -1772,7 +1797,7 @@ export default class PIXIApp extends PIXI.Application { } /** - * In some browsers the canvas is distorted if the screen resolution and + * In some browsers the canvas is distorted if the screen resolution and * overall size of the canvas exceeds the internal limits (e.g. 4096 x 4096 pixels). * To compensate these distortions we need to fix the mapping to the actual * drawing buffer coordinates. @@ -1791,8 +1816,11 @@ export default class PIXIApp extends PIXI.Application { let canvas = this.renderer.view let context = canvas.getContext('webgl') - if (context !== null && (context.drawingBufferWidth < canvas.width || - context.drawingBufferHeight < canvas.height)) { + if ( + context !== null && + (context.drawingBufferWidth < canvas.width || + context.drawingBufferHeight < canvas.height) + ) { extendWidth = context.drawingBufferWidth / canvas.width extendHeight = context.drawingBufferHeight / canvas.height //dx = wantedWidth - context.drawingBufferWidth @@ -1800,7 +1828,12 @@ export default class PIXIApp extends PIXI.Application { } x *= extendWidth y *= extendHeight - return this.originalMapPositionToPoint.call(interactionManager, local, x, y + dy) + return this.originalMapPositionToPoint.call( + interactionManager, + local, + x, + y + dy + ) } /** @@ -1834,7 +1867,6 @@ export default class PIXIApp extends PIXI.Application { * called without a parameter. */ progress(value) { - if (typeof value === 'undefined') { return this._progress } @@ -1852,8 +1884,9 @@ export default class PIXIApp extends PIXI.Application { * @return {Modal} Returns the Modal object. */ modal(opts = {}) { - - let modal = new Modal(Object.assign({ theme: this.theme }, opts, { app: this })) + let modal = new Modal( + Object.assign({ theme: this.theme }, opts, { app: this }) + ) this.scene.addChild(modal) return modal @@ -1866,8 +1899,9 @@ export default class PIXIApp extends PIXI.Application { * @return {Message} Returns the Message object. */ message(opts = {}) { - - let message = new Message(Object.assign({ theme: this.theme }, opts, { app: this })) + let message = new Message( + Object.assign({ theme: this.theme }, opts, { app: this }) + ) this.scene.addChild(message) return message @@ -1886,21 +1920,26 @@ export default class PIXIApp extends PIXI.Application { * @param {boolean} [opts.progress=false] - Should a progress bar display the loading status? * @return {PIXIApp} The PIXIApp object for chaining. */ - loadSprites(resources, loaded = null, { resolutionDependent = true, progress = false } = {}) { + loadSprites( + resources, + loaded = null, + { resolutionDependent = true, progress = false } = {} + ) { + this.loadTextures( + resources, + textures => { + let sprites = new Map() - this.loadTextures(resources, textures => { + for (let [key, texture] of textures) { + sprites.set(key, new PIXI.Sprite(texture)) + } - let sprites = new Map() - - for (let [key, texture] of textures) { - sprites.set(key, new PIXI.Sprite(texture)) - } - - if (loaded) { - loaded.call(this, sprites) - } - - }, { resolutionDependent, progress }) + if (loaded) { + loaded.call(this, sprites) + } + }, + { resolutionDependent, progress } + ) return this } @@ -1918,8 +1957,11 @@ export default class PIXIApp extends PIXI.Application { * @param {boolean} [opts.progress=false] - Should a progress bar display the loading status? * @return {PIXIApp} The PIXIApp object for chaining. */ - loadTextures(resources, loaded = null, { resolutionDependent = true, progress = false } = {}) { - + loadTextures( + resources, + loaded = null, + { resolutionDependent = true, progress = false } = {} + ) { if (!Array.isArray(resources)) { resources = [resources] } @@ -1927,17 +1969,21 @@ export default class PIXIApp extends PIXI.Application { const loader = this.loader for (let resource of resources) { - if (!loader.resources[resource]) { - if (resolutionDependent) { let resolution = Math.round(this.renderer.resolution) switch (resolution) { case 2: - loader.add(resource, resource.replace(/\.([^.]*)$/, '@2x.$1')) + loader.add( + resource, + resource.replace(/\.([^.]*)$/, '@2x.$1') + ) break case 3: - loader.add(resource, resource.replace(/\.([^.]*)$/, '@3x.$1')) + loader.add( + resource, + resource.replace(/\.([^.]*)$/, '@3x.$1') + ) break default: loader.add(resource) @@ -1980,7 +2026,6 @@ export default class PIXIApp extends PIXI.Application { * rejected with an error. */ query(query, opts = {}) { - if (typeof query === 'string') { opts = Object.assign({}, opts, { query }) } else { @@ -2012,7 +2057,6 @@ export default class PIXIApp extends PIXI.Application { * rejected with an error. */ mutate(mutation, opts = {}) { - if (typeof mutation === 'string') { opts = Object.assign({}, opts, { mutation }) } else { @@ -2044,7 +2088,6 @@ export default class PIXIApp extends PIXI.Application { * rejected with an error. */ subscribe(subscription, opts = {}) { - if (typeof subscription === 'string') { opts = Object.assign({}, opts, { subscription }) } else { @@ -2075,13 +2118,13 @@ export default class PIXIApp extends PIXI.Application { * @param {DisplayObject} displayObject - The PIXI displayObject. * @param {number} x - The x coordinate. * @param {number} y - The y coordinate. - * + * * @return {PIXI.Point} Returns a PIXI.Point. */ convertPointFromPageToNode(displayObject, x, y) { let resolution = this.renderer.resolution - console.log("resolution", resolution) + console.log('resolution', resolution) let pixiGlobal = window.convertPointFromPageToNode(app.view, x, y) pixiGlobal.x /= resolution pixiGlobal.y /= resolution @@ -2095,7 +2138,7 @@ export default class PIXIApp extends PIXI.Application { * @param {DisplayObject} displayObject - The PIXI displayObject. * @param {number} x - The x coordinate. * @param {number} y - The y coordinate. - * + * * @return {Point} Returns a DOM Point. */ @@ -2105,7 +2148,11 @@ export default class PIXIApp extends PIXI.Application { pixiGlobal.x *= resolution pixiGlobal.y *= resolution // console.log("app.convertPointFromNodeToPage", pixiGlobal) - return window.convertPointFromNodeToPage(app.view, pixiGlobal.x, pixiGlobal.y) + return window.convertPointFromNodeToPage( + app.view, + pixiGlobal.x, + pixiGlobal.y + ) } } @@ -2119,7 +2166,6 @@ export default class PIXIApp extends PIXI.Application { * @see {@link http://pixijs.download/dev/docs/PIXI.Graphics.html|PIXI.Graphics} */ class FpsDisplay extends PIXI.Graphics { - /** * Creates an instance of a FpsDisplay. * @@ -2127,25 +2173,27 @@ class FpsDisplay extends PIXI.Graphics { * @param {PIXIApp} app - The PIXIApp where the frames per second should be displayed. */ constructor(app) { - super() this.app = app this.lineStyle(3, 0x434f4f, 1) - .beginFill(0x434f4f, .6) + .beginFill(0x434f4f, 0.6) .drawRoundedRect(0, 0, 68, 32, 5) .endFill() .position.set(20, 20) - this.text = new PIXI.Text(this.fps, new PIXI.TextStyle({ - fontFamily: 'Arial', - fontSize: 14, - fontWeight: 'bold', - fill: '#f6f6f6', - stroke: '#434f4f', - strokeThickness: 3 - })) + this.text = new PIXI.Text( + this.fps, + new PIXI.TextStyle({ + fontFamily: 'Arial', + fontSize: 14, + fontWeight: 'bold', + fill: '#f6f6f6', + stroke: '#434f4f', + strokeThickness: 3 + }) + ) this.text.position.set(6, 6) this.addChild(this.text) @@ -2161,7 +2209,7 @@ class FpsDisplay extends PIXI.Graphics { * @return {PIXIApp} Returns the PIXIApp object for chaining. */ refreshFps() { - this.text.text = `${(this.app.ticker.FPS).toFixed(1)} fps` + this.text.text = `${this.app.ticker.FPS.toFixed(1)} fps` return this } @@ -2179,7 +2227,7 @@ class FpsDisplay extends PIXI.Graphics {
diff --git a/doc/out/pixi_badge.js.html b/doc/out/pixi_badge.js.html index f9e7b50..bc0f61b 100644 --- a/doc/out/pixi_badge.js.html +++ b/doc/out/pixi_badge.js.html @@ -1444,7 +1444,7 @@ import Tooltip from './tooltip.js' /** * Class that represents a PixiJS Badge. - * + * * @example * // Create the app * const app = new PIXIApp({ @@ -1452,13 +1452,13 @@ import Tooltip from './tooltip.js' * width: 900, * height: 250 * }).setup().run() - * + * * // Add an DisplayObject to the app * const circle = new PIXI.Graphics() * circle.beginFill(0x5251a3) * circle.drawCircle(50, 50, 40) * app.scene.addChild(circle) - * + * * const badge1 = new Badge({ * object: circle, * container: app.scene, @@ -1470,10 +1470,9 @@ import Tooltip from './tooltip.js' * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/badge.html|DocTest} */ export default class Badge extends AbstractPopup { - /** * Creates an instance of a Badge. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the badge. * @param {number} [opts.minWidth=0] - The minimum width of the badge. @@ -1483,15 +1482,18 @@ export default class Badge extends AbstractPopup { * to display. */ constructor(opts = {}) { - const theme = Theme.fromString(opts.theme) - - opts = Object.assign({}, { - minWidth: 0, - minHeight: 0, - padding: theme.padding / 2, - tooltip: null - }, opts) + + opts = Object.assign( + {}, + { + minWidth: 0, + minHeight: 0, + padding: theme.padding / 2, + tooltip: null + }, + opts + ) super(opts) @@ -1505,7 +1507,7 @@ export default class Badge extends AbstractPopup { //----------------- this.layout() } - + /** * Creates children and instantiates everything. * @@ -1514,35 +1516,44 @@ export default class Badge extends AbstractPopup { * @return {Badge} A reference to the badge for chaining. */ setup() { - super.setup() // tooltip //----------------- if (this.opts.tooltip) { if (typeof this.opts.tooltip === 'string') { - this.tooltip = new Tooltip({object: this, content: this.opts.tooltip}) + this.tooltip = new Tooltip({ + object: this, + content: this.opts.tooltip + }) } else { - this.opts.tooltip = Object.assign({}, {object: this}, this.opts.tooltip) + this.opts.tooltip = Object.assign( + {}, + { object: this }, + this.opts.tooltip + ) this.tooltip = new Tooltip(this.opts.tooltip) } } return this } - + /** * Should be called to refresh the layout of the badge. Can be used after resizing. - * + * * @override * @return {Badge} A reference to the badge for chaining. */ layout() { - super.layout() - this.content.x = this.width / 2 - this.content.width / 2 - this.opts.strokeWidth / 2 - this.content.y = this.height / 2 - this.content.height / 2 - this.opts.strokeWidth / 2 + this.content.x = + this.width / 2 - this.content.width / 2 - this.opts.strokeWidth / 2 + this.content.y = + this.height / 2 - + this.content.height / 2 - + this.opts.strokeWidth / 2 return this } @@ -1560,7 +1571,7 @@ export default class Badge extends AbstractPopup {
diff --git a/doc/out/pixi_blurfilter.js.html b/doc/out/pixi_blurfilter.js.html index fdeca0d..3e43189 100644 --- a/doc/out/pixi_blurfilter.js.html +++ b/doc/out/pixi_blurfilter.js.html @@ -1453,17 +1453,17 @@ * height: 270, * transparent: false * }).setup().run() - * + * * // Add a video sprite * const sprite = new PIXI.Sprite(PIXI.Texture.fromVideo("assets/blurfilter.mp4")) * sprite.width = app.size.width * sprite.height = app.size.height * app.scene.addChild(sprite) - * + * * // Create the filter and assign it to the scene * const blurFilter = new BlurFilter(new PIXI.Rectangle(20, 20, 80, 60)) * app.scene.filters = [blurFilter] - * + * * @class * @extends PIXI.Filter * @param {PIXI.Rectangle|PIXI.Circle|PIXI.DisplayObject} shape The area where the blur effect should be applied to. Relative to the @@ -1471,7 +1471,6 @@ * @param {number} [blur=50] The strength of the blur. */ export default class BlurFilter extends PIXI.Filter { - constructor(shape, blur = 50) { super() @@ -1499,7 +1498,7 @@ export default class BlurFilter extends PIXI.Filter { set blur(value) { this.tiltShiftXFilter.blur = this.tiltShiftYFilter.blur = value } - + /** * The blur shape. * @@ -1509,26 +1508,39 @@ export default class BlurFilter extends PIXI.Filter { return this.tiltShiftXFilter.shape } set shape(value) { - this.tiltShiftXFilter.shape = this.tiltShiftYFilter.shape = this.normalize(value) + this.tiltShiftXFilter.shape = this.tiltShiftYFilter.shape = this.normalize( + value + ) } /** - * + * * @private * @param {PIXI.Rectangle|PIXI.Circle|PIXI.DisplayObject} value * @returns {Object} */ normalize(value) { - let shape = null if (value instanceof PIXI.Circle) { - shape = {type: 'circle', x: value.x, y: value.y, r: value.radius} + shape = { type: 'circle', x: value.x, y: value.y, r: value.radius } } else if (value instanceof PIXI.Rectangle) { - shape = {type: 'rectangle', x: value.x, y: value.y, width: value.width, height: value.height} + shape = { + type: 'rectangle', + x: value.x, + y: value.y, + width: value.width, + height: value.height + } } else { const bounds = value.getBounds() - shape = {type: 'rectangle', x: bounds.x, y: bounds.y, width: bounds.width, height: bounds.height} + shape = { + type: 'rectangle', + x: bounds.x, + y: bounds.y, + width: bounds.width, + height: bounds.height + } } return shape @@ -1544,9 +1556,7 @@ export default class BlurFilter extends PIXI.Filter { * @private */ class TiltShiftAxisFilter extends PIXI.Filter { - - constructor(shape, blur){ - + constructor(shape, blur) { const vertex = ` attribute vec2 aVertexPosition; attribute vec2 aTextureCoord; @@ -1613,13 +1623,18 @@ class TiltShiftAxisFilter extends PIXI.Filter { ` super(vertex, fragment) - + if (shape.type === 'circle') { this.uniforms.shape = 1 this.uniforms.circle = [shape.x, shape.y, shape.r] } else { this.uniforms.shape = 2 - this.uniforms.rectangle = [shape.x, shape.y, shape.x + shape.width, shape.y + shape.height] + this.uniforms.rectangle = [ + shape.x, + shape.y, + shape.x + shape.width, + shape.y + shape.height + ] } this.uniforms.blur = blur this.uniforms.delta = new PIXI.Point(0, 0) @@ -1640,7 +1655,7 @@ class TiltShiftAxisFilter extends PIXI.Filter { set blur(value) { this.uniforms.blur = value } - + /** * The blur shape. * @@ -1653,7 +1668,12 @@ class TiltShiftAxisFilter extends PIXI.Filter { return new PIXI.Circle(circle[0], circle[1], circle[2]) } else { const rectangle = this.uniforms.rectangle - return new PIXI.Rectangle(rectangle[0], rectangle[1], rectangle[2], rectangle[3]) + return new PIXI.Rectangle( + rectangle[0], + rectangle[1], + rectangle[2], + rectangle[3] + ) } } set shape(value) { @@ -1662,7 +1682,12 @@ class TiltShiftAxisFilter extends PIXI.Filter { this.uniforms.circle = [value.x, value.y, value.r] } else { this.uniforms.shape = 2 - this.uniforms.rectangle = [value.x, value.y, value.x + value.width, value.y + value.height] + this.uniforms.rectangle = [ + value.x, + value.y, + value.x + value.width, + value.y + value.height + ] } } } @@ -1700,7 +1725,6 @@ class TiltShiftYFilter extends TiltShiftAxisFilter { this.uniforms.delta.y = 0.1 } } - @@ -1714,7 +1738,7 @@ class TiltShiftYFilter extends TiltShiftAxisFilter {
diff --git a/doc/out/pixi_button.js.html b/doc/out/pixi_button.js.html index ee53060..b9e3dde 100644 --- a/doc/out/pixi_button.js.html +++ b/doc/out/pixi_button.js.html @@ -1487,7 +1487,6 @@ import Events from '../events.js' * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/button.html|DocTest} */ export default class Button extends PIXI.Container { - /** * Creates an instance of a Button. * @@ -1546,62 +1545,76 @@ export default class Button extends PIXI.Container { * @param {boolean} [opts.visible=true] - Is the button initially visible (property visible)? */ constructor(opts = {}) { - super() const theme = Theme.fromString(opts.theme) this.theme = theme - this.opts = Object.assign({}, { - id: PIXI.utils.uid(), - label: null, - x: 0, - y: 0, - minWidth: 44, - minHeight: 44, - padding: theme.padding, - icon: undefined, - iconActive: undefined, - iconPosition: 'left', - iconColor: theme.iconColor, - iconColorActive: theme.iconColorActive, - fill: theme.fill, - fillAlpha: theme.fillAlpha, - fillActive: theme.fillActive, - fillActiveAlpha: theme.fillActiveAlpha, - stroke: theme.stroke, - strokeWidth: theme.strokeWidth, - strokeAlpha: theme.strokeAlpha, - strokeActive: theme.strokeActive, - strokeActiveWidth: theme.strokeActiveWidth, - strokeActiveAlpha: theme.strokeActiveAlpha, - textStyle: theme.textStyle, - textStyleActive: theme.textStyleActive, - style: 'default', - radius: theme.radius, - disabled: false, - active: false, - action: null, - beforeAction: null, - afterAction: null, - type: 'default', - align: 'center', - verticalAlign: 'middle', - tooltip: null, - badge: null, - visible: true - }, opts) + this.opts = Object.assign( + {}, + { + id: PIXI.utils.uid(), + label: null, + x: 0, + y: 0, + minWidth: 44, + minHeight: 44, + padding: theme.padding, + icon: undefined, + iconActive: undefined, + iconPosition: 'left', + iconColor: theme.iconColor, + iconColorActive: theme.iconColorActive, + fill: theme.fill, + fillAlpha: theme.fillAlpha, + fillActive: theme.fillActive, + fillActiveAlpha: theme.fillActiveAlpha, + stroke: theme.stroke, + strokeWidth: theme.strokeWidth, + strokeAlpha: theme.strokeAlpha, + strokeActive: theme.strokeActive, + strokeActiveWidth: theme.strokeActiveWidth, + strokeActiveAlpha: theme.strokeActiveAlpha, + textStyle: theme.textStyle, + textStyleActive: theme.textStyleActive, + style: 'default', + radius: theme.radius, + disabled: false, + active: false, + action: null, + beforeAction: null, + afterAction: null, + type: 'default', + align: 'center', + verticalAlign: 'middle', + tooltip: null, + badge: null, + visible: true + }, + opts + ) this.id = this.opts.id - if (typeof this.opts.icon === 'undefined' && typeof this.opts.iconActive !== 'undefined') { + if ( + typeof this.opts.icon === 'undefined' && + typeof this.opts.iconActive !== 'undefined' + ) { this.opts.icon = this.opts.iconActive - } else if (typeof this.opts.icon !== 'undefined' && typeof this.opts.iconActive === 'undefined') { + } else if ( + typeof this.opts.icon !== 'undefined' && + typeof this.opts.iconActive === 'undefined' + ) { this.opts.iconActive = this.opts.icon } if (this.opts.style === 'link') { - Object.assign(this.opts, { strokeAlpha: 0, strokeActiveAlpha: 0, fillAlpha: 0, fillActiveAlpha: 0 }) + Object.assign(this.opts, { + strokeAlpha: 0, + strokeActiveAlpha: 0, + fillAlpha: 0, + fillActiveAlpha: 0 + }) } this._active = null @@ -1640,7 +1653,6 @@ export default class Button extends PIXI.Container { * @return {Button} A reference to the button for chaining. */ setup() { - // Button //----------------- let button = new PIXI.Graphics() @@ -1662,18 +1674,27 @@ export default class Button extends PIXI.Container { // Icon //----------------- if (this.opts.icon) { - this.iconInactive = this.loadIcon(this.opts.icon, this.opts.iconColor) + this.iconInactive = this.loadIcon( + this.opts.icon, + this.opts.iconColor + ) } if (this.opts.iconActive) { - this.iconActive = this.loadIcon(this.opts.iconActive, this.opts.iconColorActive) + this.iconActive = this.loadIcon( + this.opts.iconActive, + this.opts.iconColorActive + ) } // interaction //----------------- this.button.on('pointerover', e => { this.capture(e) - TweenLite.to([this.button, this.content], this.theme.fast, { alpha: .83, overwrite: 'none' }) + TweenLite.to([this.button, this.content], this.theme.fast, { + alpha: 0.83, + overwrite: 'none' + }) }) this.button.on('pointermove', e => { @@ -1682,13 +1703,19 @@ export default class Button extends PIXI.Container { this.button.on('pointerout', e => { this.capture(e) - TweenLite.to([this.button, this.content], this.theme.fast, { alpha: 1, overwrite: 'none' }) + TweenLite.to([this.button, this.content], this.theme.fast, { + alpha: 1, + overwrite: 'none' + }) }) // eslint-disable-next-line no-unused-vars this.button.on('pointerdown', e => { //this.capture(e) - TweenLite.to([this.button, this.content], this.theme.fast, { alpha: .7, overwrite: 'none' }) + TweenLite.to([this.button, this.content], this.theme.fast, { + alpha: 0.7, + overwrite: 'none' + }) }) this.button.on('pointerup', e => { @@ -1701,7 +1728,10 @@ export default class Button extends PIXI.Container { this.opts.action.call(this, e, this) } - TweenLite.to([this.button, this.content], this.theme.fast, { alpha: .83, overwrite: 'none' }) + TweenLite.to([this.button, this.content], this.theme.fast, { + alpha: 0.83, + overwrite: 'none' + }) if (this.opts.type === 'checkbox') { this.active = !this.active @@ -1718,15 +1748,22 @@ export default class Button extends PIXI.Container { // active //----------------- - this.active = this.opts.active // calls .layout() + this.active = this.opts.active // calls .layout() // tooltip //----------------- if (this.opts.tooltip) { if (typeof this.opts.tooltip === 'string') { - this.tooltip = new Tooltip({ object: this, content: this.opts.tooltip }) + this.tooltip = new Tooltip({ + object: this, + content: this.opts.tooltip + }) } else { - this.opts.tooltip = Object.assign({}, { object: this }, this.opts.tooltip) + this.opts.tooltip = Object.assign( + {}, + { object: this }, + this.opts.tooltip + ) this.tooltip = new Tooltip(this.opts.tooltip) } } @@ -1734,12 +1771,15 @@ export default class Button extends PIXI.Container { // badge //----------------- if (this.opts.badge) { - let opts = Object.assign({}, { - align: 'right', - verticalAlign: 'top', - offsetLeft: 0, - offsetTop: 0 - }) + let opts = Object.assign( + {}, + { + align: 'right', + verticalAlign: 'top', + offsetLeft: 0, + offsetTop: 0 + } + ) if (typeof this.opts.badge === 'string') { opts = Object.assign(opts, { content: this.opts.badge }) } else { @@ -1749,25 +1789,35 @@ export default class Button extends PIXI.Container { const badge = new Badge(opts) switch (opts.align) { - case 'left': - badge.x = this.x - badge.width / 2 + opts.offsetLeft - break - case 'center': - badge.x = this.x + this.width / 2 - badge.width / 2 + opts.offsetLeft - break - case 'right': - badge.x = this.x + this.width - badge.width / 2 + opts.offsetLeft + case 'left': + badge.x = this.x - badge.width / 2 + opts.offsetLeft + break + case 'center': + badge.x = + this.x + + this.width / 2 - + badge.width / 2 + + opts.offsetLeft + break + case 'right': + badge.x = + this.x + this.width - badge.width / 2 + opts.offsetLeft } switch (opts.verticalAlign) { - case 'top': - badge.y = this.y - badge.height / 2 + opts.offsetTop - break - case 'middle': - badge.y = this.y + this.height / 2 - badge.height / 2 + opts.offsetTop - break - case 'bottom': - badge.y = this.y + this.height - badge.height / 2 + opts.offsetTop + case 'top': + badge.y = this.y - badge.height / 2 + opts.offsetTop + break + case 'middle': + badge.y = + this.y + + this.height / 2 - + badge.height / 2 + + opts.offsetTop + break + case 'bottom': + badge.y = + this.y + this.height - badge.height / 2 + opts.offsetTop } this.addChild(badge) @@ -1788,7 +1838,6 @@ export default class Button extends PIXI.Container { * @return {Button} A reference to the button for chaining. */ layout() { - // Clear content //----------------- this.removeChild(this.content) @@ -1874,18 +1923,17 @@ export default class Button extends PIXI.Container { * @return {Button} A reference to the button for chaining. */ layoutInnerContent() { - for (let child of this.content.children) { switch (this.opts.verticalAlign) { - case 'top': - child.y = 0 - break - case 'middle': - child.y = this.content.height / 2 - child.height / 2 - break - case 'bottom': - child.y = this.content.height - child.height - break + case 'top': + child.y = 0 + break + case 'middle': + child.y = this.content.height / 2 - child.height / 2 + break + case 'bottom': + child.y = this.content.height - child.height + break } } @@ -1900,29 +1948,30 @@ export default class Button extends PIXI.Container { * @return {Button} A reference to the button for chaining. */ layoutContent() { - switch (this.opts.align) { - case 'left': - this.content.x = this.opts.padding - break - case 'center': - this.content.x = ((this._width - this.content.width) / 2) - break - case 'right': - this.content.x = this._width - this.opts.padding - this.content.width - break + case 'left': + this.content.x = this.opts.padding + break + case 'center': + this.content.x = (this._width - this.content.width) / 2 + break + case 'right': + this.content.x = + this._width - this.opts.padding - this.content.width + break } switch (this.opts.verticalAlign) { - case 'top': - this.content.y = this.opts.padding - break - case 'middle': - this.content.y = (this._height - this.content.height) / 2 - break - case 'bottom': - this.content.y = this._height - this.opts.padding - this.content.height - break + case 'top': + this.content.y = this.opts.padding + break + case 'middle': + this.content.y = (this._height - this.content.height) / 2 + break + case 'bottom': + this.content.y = + this._height - this.opts.padding - this.content.height + break } return this @@ -1935,16 +1984,32 @@ export default class Button extends PIXI.Container { * @return {Button} A reference to the button for chaining. */ draw() { - this.button.clear() if (this.active) { - this.button.lineStyle(this.opts.strokeActiveWidth, this.opts.strokeActive, this.opts.strokeActiveAlpha) - this.button.beginFill(this.opts.fillActive, this.opts.fillActiveAlpha) + this.button.lineStyle( + this.opts.strokeActiveWidth, + this.opts.strokeActive, + this.opts.strokeActiveAlpha + ) + this.button.beginFill( + this.opts.fillActive, + this.opts.fillActiveAlpha + ) } else { - this.button.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha) + this.button.lineStyle( + this.opts.strokeWidth, + this.opts.stroke, + this.opts.strokeAlpha + ) this.button.beginFill(this.opts.fill, this.opts.fillAlpha) } - this.button.drawRoundedRect(0, 0, this._width, this._height, this.opts.radius) + this.button.drawRoundedRect( + 0, + 0, + this._width, + this._height, + this.opts.radius + ) this.button.endFill() return this @@ -1959,7 +2024,6 @@ export default class Button extends PIXI.Container { return this._active } set active(value) { - this._active = value if (this._active) { @@ -1984,18 +2048,17 @@ export default class Button extends PIXI.Container { return this._disabled } set disabled(value) { - this._disabled = value if (this._disabled) { this.button.interactive = false this.button.buttonMode = false - this.button.alpha = .5 + this.button.alpha = 0.5 if (this.icon) { - this.icon.alpha = .5 + this.icon.alpha = 0.5 } if (this.text) { - this.text.alpha = .5 + this.text.alpha = 0.5 } } else { this.button.interactive = true @@ -2016,7 +2079,6 @@ export default class Button extends PIXI.Container { * @return {Button} A reference to the button for chaining. */ show() { - this.opts.strokeAlpha = 1 this.opts.strokeActiveAlpha = 1 this.opts.fillAlpha = 1 @@ -2033,7 +2095,6 @@ export default class Button extends PIXI.Container { * @return {Button} A reference to the button for chaining. */ hide() { - this.opts.strokeAlpha = 0 this.opts.strokeActiveAlpha = 0 this.opts.fillAlpha = 0 @@ -2053,7 +2114,6 @@ export default class Button extends PIXI.Container { * @return {PIXI.DisplayObject} Return the icon as an PIXI.DisplayObject. */ loadIcon(icon, color) { - let displayObject = null if (icon instanceof PIXI.DisplayObject) { @@ -2063,10 +2123,12 @@ export default class Button extends PIXI.Container { if (this.text) { size = this.text.height } else if (this.opts.minHeight) { - size = this.opts.minHeight - (2 * this.opts.padding) + size = this.opts.minHeight - 2 * this.opts.padding } - const url = Button.iconIsUrl(icon) ? icon : `../../assets/icons/${icon}.png` + const url = Button.iconIsUrl(icon) + ? icon + : `../../assets/icons/${icon}.png` const iconTexture = PIXI.Texture.fromImage(url, true) const sprite = new PIXI.Sprite(iconTexture) @@ -2120,7 +2182,7 @@ export default class Button extends PIXI.Container {
diff --git a/doc/out/pixi_buttongroup.js.html b/doc/out/pixi_buttongroup.js.html index 8ffcf70..663cb6f 100644 --- a/doc/out/pixi_buttongroup.js.html +++ b/doc/out/pixi_buttongroup.js.html @@ -1443,7 +1443,7 @@ import Button from './button.js' /** * Class that represents a PixiJS ButtonGroup. - * + * * @example * // Create the button group * const buttonGroup = new ButtonGroup({ @@ -1464,10 +1464,9 @@ import Button from './button.js' * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/buttongroup.html|DocTest} */ export default class ButtonGroup extends PIXI.Graphics { - /** * Creates an instance of a ButtonGroup. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the button group. * @param {number} [opts.id=auto generated] - The id of the button group. @@ -1514,50 +1513,53 @@ export default class ButtonGroup extends PIXI.Graphics { * @param {boolean} [opts.visible=true] - Is the button group initially visible (property visible)? */ constructor(opts = {}) { - super() - + const theme = Theme.fromString(opts.theme) this.theme = theme - this.opts = Object.assign({}, { - id: PIXI.utils.uid(), - x: 0, - y: 0, - buttons: [], - minWidth: 44, - minHeight: 44, - padding: theme.padding, - margin: theme.margin, - iconPosition: 'left', // left, right - iconColor: theme.iconColor, - iconColorActive: theme.iconColorActive, - fill: theme.fill, - fillAlpha: theme.fillAlpha, - fillActive: theme.fillActive, - fillActiveAlpha: theme.fillActiveAlpha, - stroke: theme.stroke, - strokeWidth: theme.strokeWidth, - strokeAlpha: theme.strokeAlpha, - strokeActive: theme.strokeActive, - strokeActiveWidth: theme.strokeActiveWidth, - strokeActiveAlpha: theme.strokeActiveAlpha, - textStyle: theme.textStyle, - textStyleActive: theme.textStyleActive, - style: 'default', - radius: theme.radius, - disabled: null, - type: 'default', // default, checkbox, radio - orientation: 'horizontal', - align: 'center', // left, center, right - verticalAlign: 'middle', // top, middle, bottom - visible: true - }, opts) + this.opts = Object.assign( + {}, + { + id: PIXI.utils.uid(), + x: 0, + y: 0, + buttons: [], + minWidth: 44, + minHeight: 44, + padding: theme.padding, + margin: theme.margin, + iconPosition: 'left', // left, right + iconColor: theme.iconColor, + iconColorActive: theme.iconColorActive, + fill: theme.fill, + fillAlpha: theme.fillAlpha, + fillActive: theme.fillActive, + fillActiveAlpha: theme.fillActiveAlpha, + stroke: theme.stroke, + strokeWidth: theme.strokeWidth, + strokeAlpha: theme.strokeAlpha, + strokeActive: theme.strokeActive, + strokeActiveWidth: theme.strokeActiveWidth, + strokeActiveAlpha: theme.strokeActiveAlpha, + textStyle: theme.textStyle, + textStyleActive: theme.textStyleActive, + style: 'default', + radius: theme.radius, + disabled: null, + type: 'default', // default, checkbox, radio + orientation: 'horizontal', + align: 'center', // left, center, right + verticalAlign: 'middle', // top, middle, bottom + visible: true + }, + opts + ) this.buttons = [] this._disabled = null - + this.visible = this.opts.visible // setup @@ -1568,21 +1570,19 @@ export default class ButtonGroup extends PIXI.Graphics { //----------------- this.layout() } - + /** * Creates children and instantiates everything. - * + * * @private * @return {ButtonGroup} A reference to the button group for chaining. */ setup() { - // Buttons //----------------- let position = 0 for (let it of this.opts.buttons) { - delete it.x delete it.y @@ -1604,11 +1604,19 @@ export default class ButtonGroup extends PIXI.Graphics { it.fillActive = it.fillActive || this.opts.fillActive it.fillActiveAlpha = it.fillActiveAlpha || this.opts.fillActiveAlpha it.stroke = it.stroke || this.opts.stroke - it.strokeWidth = it.strokeWidth != null ? it.strokeWidth : this.opts.strokeWidth - it.strokeAlpha = it.strokeAlpha != null ? it.strokeAlpha : this.opts.strokeAlpha + it.strokeWidth = + it.strokeWidth != null ? it.strokeWidth : this.opts.strokeWidth + it.strokeAlpha = + it.strokeAlpha != null ? it.strokeAlpha : this.opts.strokeAlpha it.strokeActive = it.strokeActive || this.opts.strokeActive - it.strokeActiveWidth = it.strokeActiveWidth != null ? it.strokeActiveWidth : this.opts.strokeActiveWidth - it.strokeActiveAlpha = it.strokeActiveAlpha != null ? it.strokeActiveAlpha : this.opts.strokeActiveAlpha + it.strokeActiveWidth = + it.strokeActiveWidth != null + ? it.strokeActiveWidth + : this.opts.strokeActiveWidth + it.strokeActiveAlpha = + it.strokeActiveAlpha != null + ? it.strokeActiveAlpha + : this.opts.strokeActiveAlpha it.textStyle = it.textStyle || this.opts.textStyle it.textStyleActive = it.textStyleActive || this.opts.textStyleActive it.style = it.style || this.opts.style @@ -1627,7 +1635,10 @@ export default class ButtonGroup extends PIXI.Graphics { it.align = it.align || this.opts.align it.verticalAlign = it.verticalAlign || this.opts.verticalAlign it.afterAction = (event, button) => { - if (this.opts.type === 'radio' && button.opts.type === 'default') { + if ( + this.opts.type === 'radio' && + button.opts.type === 'default' + ) { this.buttons.forEach(it => { if (it.opts.type === 'default') { it.active = false @@ -1642,18 +1653,25 @@ export default class ButtonGroup extends PIXI.Graphics { if (it.tooltip) { if (typeof it.tooltip === 'string') { - it.tooltip = {content: it.tooltip, container: this} + it.tooltip = { content: it.tooltip, container: this } } else { - it.tooltip = Object.assign({}, {container: this}, it.tooltip) + it.tooltip = Object.assign( + {}, + { container: this }, + it.tooltip + ) } } - + let button = new Button(it) this.addChild(button) this.buttons.push(button) - position += (this.opts.orientation === 'horizontal' ? button.width : button.height) + this.opts.margin + position += + (this.opts.orientation === 'horizontal' + ? button.width + : button.height) + this.opts.margin } if (this.opts.orientation === 'vertical') { @@ -1673,14 +1691,13 @@ export default class ButtonGroup extends PIXI.Graphics { return this } - + /** * Should be called to refresh the layout of the button group. Can be used after resizing. - * + * * @return {ButtonGroup} A reference to the button group for chaining. */ layout() { - // set position //----------------- this.position.set(this.opts.x, this.opts.y) @@ -1691,26 +1708,38 @@ export default class ButtonGroup extends PIXI.Graphics { return this } - + /** * Draws the canvas. - * + * * @private * @return {ButtonGroup} A reference to the button group for chaining. */ draw() { - if (this.opts.margin === 0) { - this.buttons.forEach(it => it.hide()) this.clear() - this.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha) + this.lineStyle( + this.opts.strokeWidth, + this.opts.stroke, + this.opts.strokeAlpha + ) this.beginFill(this.opts.fill, this.opts.fillAlpha) - this.drawRoundedRect(0, 0, this.width, this.height, this.opts.radius) + this.drawRoundedRect( + 0, + 0, + this.width, + this.height, + this.opts.radius + ) // Draw borders - this.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha / 2) + this.lineStyle( + this.opts.strokeWidth, + this.opts.stroke, + this.opts.strokeAlpha / 2 + ) this.buttons.forEach((it, i) => { if (i > 0) { @@ -1721,7 +1750,6 @@ export default class ButtonGroup extends PIXI.Graphics { } else { this.lineTo(it.width, it.y) } - } }) @@ -1730,10 +1758,10 @@ export default class ButtonGroup extends PIXI.Graphics { return this } - + /** * Gets or sets the disabled state. When disabled, no button of the button group can be clicked. - * + * * @member {boolean} */ get disabled() { @@ -1741,32 +1769,29 @@ export default class ButtonGroup extends PIXI.Graphics { } set disabled(value) { - this._disabled = value - this.buttons.forEach(it => it.disabled = value) + this.buttons.forEach(it => (it.disabled = value)) } - + /** * Searches all buttons of the button group and returns the maximum width of one button. - * + * * @private * @return {number} The maximum with of a button of the button group. */ getMaxButtonWidth() { - let widths = this.buttons.map(it => it.width) return Math.max(...widths) } - + /** * Shows the button group (sets his alpha value to 1). - * + * * @return {ButtonGroup} A reference to the button group for chaining. */ show() { - this.alpha = 1 return this @@ -1774,11 +1799,10 @@ export default class ButtonGroup extends PIXI.Graphics { /** * Hides the button group (sets his alpha value to 0). - * + * * @return {ButtonGroup} A reference to the button group for chaining. */ hide() { - this.alpha = 0 return this @@ -1797,7 +1821,7 @@ export default class ButtonGroup extends PIXI.Graphics {
diff --git a/doc/out/pixi_deepzoom_image.js.html b/doc/out/pixi_deepzoom_image.js.html index 0ba14a4..6541224 100644 --- a/doc/out/pixi_deepzoom_image.js.html +++ b/doc/out/pixi_deepzoom_image.js.html @@ -2545,7 +2545,7 @@ export class DeepZoomImage extends PIXI.Container {
diff --git a/doc/out/pixi_flippable.js.html b/doc/out/pixi_flippable.js.html index c2731db..2d66435 100644 --- a/doc/out/pixi_flippable.js.html +++ b/doc/out/pixi_flippable.js.html @@ -1469,10 +1469,10 @@ * const front = PIXI.Sprite.fromImage('./assets/front.jpg') * const back = PIXI.Sprite.fromImage('./assets/back.jpg') * app.scene.addChild(front) - * + * * // Create the flippable * const flippable = new Flippable(front, back, app.renderer) - * + * * front.interactive = true * front.on('click', event => flippable.toggle()) * @@ -1482,7 +1482,6 @@ * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/flippable.html|DocTest} */ export default class Flippable extends PIXI.projection.Camera3d { - /** * Creates an instance of a Flippable. * @@ -1508,30 +1507,38 @@ export default class Flippable extends PIXI.projection.Camera3d { * @param {function} [opts.onComplete=null] - A callback executed when the flip animation is finished. */ constructor(front, back, renderer, opts = {}) { - super() - this.opts = Object.assign({}, { - front, - back, - renderer, - duration: 1, - ease: Power2.easeOut, - shadow: false, - eulerX: 0, - eulerY: 0, - eulerEase: Power1.easeOut, - useBackTransforms: false, - transformEase: Power2.easeOut, - focus: 800, - near: 10, - far: 10000, - orthographic: false - }, opts) + this.opts = Object.assign( + {}, + { + front, + back, + renderer, + duration: 1, + ease: Power2.easeOut, + shadow: false, + eulerX: 0, + eulerY: 0, + eulerEase: Power1.easeOut, + useBackTransforms: false, + transformEase: Power2.easeOut, + focus: 800, + near: 10, + far: 10000, + orthographic: false + }, + opts + ) // planes //-------------------- - this.setPlanes(this.opts.focus, this.opts.near, this.opts.far, this.opts.orthographic) + this.setPlanes( + this.opts.focus, + this.opts.near, + this.opts.far, + this.opts.orthographic + ) // flipped //-------------------- @@ -1553,8 +1560,7 @@ export default class Flippable extends PIXI.projection.Camera3d { * @return {Flippable} A reference to the flippable for chaining. */ setup() { - - const scale = .5 + const scale = 0.5 // filters //-------------------- @@ -1571,16 +1577,18 @@ export default class Flippable extends PIXI.projection.Camera3d { // shadow //-------------------- - const shadow = new PIXI.projection.Sprite3d(PIXI.Texture.fromImage('../../assets/images/shadow.png')) + const shadow = new PIXI.projection.Sprite3d( + PIXI.Texture.fromImage('../../assets/images/shadow.png') + ) shadow.renderable = false shadow.anchor.set(0.5) - shadow.scale3d.set(.98) + shadow.scale3d.set(0.98) shadow.alpha = 0.7 shadow.filters = [blurFilter] shadow.visible = this.opts.shadow outer.addChild(shadow) this.objects.shadow = shadow - + // inner //-------------------- const inner = new PIXI.projection.Container3d() @@ -1593,7 +1601,7 @@ export default class Flippable extends PIXI.projection.Camera3d { const front = new PIXI.projection.Sprite3d(PIXI.Texture.EMPTY) front.scale.set(-1 / scale, 1 / scale) front.renderable = true - front.anchor.set(.5) + front.anchor.set(0.5) inner.addChild(front) this.objects.front = front @@ -1602,7 +1610,7 @@ export default class Flippable extends PIXI.projection.Camera3d { const back = new PIXI.projection.Sprite3d(PIXI.Texture.EMPTY) back.scale.set(1 / scale, 1 / scale) back.renderable = false - back.anchor.set(.5) + back.anchor.set(0.5) inner.addChild(back) this.objects.back = back @@ -1618,7 +1626,6 @@ export default class Flippable extends PIXI.projection.Camera3d { return this._flipped } set flipped(toBack) { - this._flipped = toBack // references @@ -1639,7 +1646,7 @@ export default class Flippable extends PIXI.projection.Camera3d { //-------------------- front.texture = this.generateTexture(this.opts.front) back.texture = this.generateTexture(this.opts.back) - + // switch objects and set params for virtual objects //-------------------- const fromCenter = this.anchorToCenter(fromObject) @@ -1664,11 +1671,21 @@ export default class Flippable extends PIXI.projection.Camera3d { y: this.opts.useBackTransforms ? toCenter.y : fromCenter.y, anchorX: this.opts.useBackTransforms ? toObject.x : fromObject.x, anchorY: this.opts.useBackTransforms ? toObject.y : fromObject.y, - width: this.opts.useBackTransforms ? toObject.width * 2 : fromObject.width * 2, - height: this.opts.useBackTransforms ? toObject.height * 2 : fromObject.height * 2, - rotation: this.opts.useBackTransforms ? toObject.rotation : fromObject.rotation, - skewX: this.opts.useBackTransforms ? toObject.skew.x : fromObject.skew.x, - skewY: this.opts.useBackTransforms ? toObject.skew.y : fromObject.skew.y + width: this.opts.useBackTransforms + ? toObject.width * 2 + : fromObject.width * 2, + height: this.opts.useBackTransforms + ? toObject.height * 2 + : fromObject.height * 2, + rotation: this.opts.useBackTransforms + ? toObject.rotation + : fromObject.rotation, + skewX: this.opts.useBackTransforms + ? toObject.skew.x + : fromObject.skew.x, + skewY: this.opts.useBackTransforms + ? toObject.skew.y + : fromObject.skew.y } // set toObject end values @@ -1745,20 +1762,24 @@ export default class Flippable extends PIXI.projection.Camera3d { // camera //-------------------- new TimelineMax() - .to(this.euler, half, {x: this.opts.eulerX, y: this.opts.eulerY, ease}) - .to(this.euler, half, {x: 0, y: 0, ease}) + .to(this.euler, half, { + x: this.opts.eulerX, + y: this.opts.eulerY, + ease + }) + .to(this.euler, half, { x: 0, y: 0, ease }) // shadow //-------------------- new TimelineMax() - .to(shadow, half, {alpha: .3, ease}) - .to(shadow, half, {alpha: .7, ease}) - + .to(shadow, half, { alpha: 0.3, ease }) + .to(shadow, half, { alpha: 0.7, ease }) + // blurfilter //-------------------- new TimelineMax() - .to(blurFilter, half, {blur: 6, ease}) - .to(blurFilter, half, {blur: .2, ease}) + .to(blurFilter, half, { blur: 6, ease }) + .to(blurFilter, half, { blur: 0.2, ease }) } /** @@ -1767,18 +1788,18 @@ export default class Flippable extends PIXI.projection.Camera3d { * @return {Flippable} A reference to the flippable for chaining. */ layout() { - const front = this.objects.front const back = this.objects.back const shadow = this.objects.shadow const inner = this.objects.inner - - inner.position3d.z = -Math.sin(inner.euler.y) * front.texture.baseTexture.width * 2 + + inner.position3d.z = + -Math.sin(inner.euler.y) * front.texture.baseTexture.width * 2 //this.objects.shadow.euler = this.objects.inner.euler shadow.euler.x = -inner.euler.x shadow.euler.y = -inner.euler.y - + if (this.frontSideInFront) { front.renderable = true back.renderable = false @@ -1838,13 +1859,25 @@ export default class Flippable extends PIXI.projection.Camera3d { * @return {PIXI.Texture} The generated PIXI.Texture. */ generateTexture(displayObject) { - // renderTexture //-------------------- - const renderTexture = PIXI.RenderTexture.create(displayObject.width, displayObject.height) + const renderTexture = PIXI.RenderTexture.create( + displayObject.width, + displayObject.height + ) // save position - const transform = [displayObject.x, displayObject.y, displayObject.scale.x, displayObject.scale.y, displayObject.rotation, displayObject.skew.x, displayObject.skew.y, displayObject.pivot.x, displayObject.pivot.y] + const transform = [ + displayObject.x, + displayObject.y, + displayObject.scale.x, + displayObject.scale.y, + displayObject.rotation, + displayObject.skew.x, + displayObject.skew.y, + displayObject.pivot.x, + displayObject.pivot.y + ] displayObject.position.set(0, 0) displayObject.skew.set(0, 0) @@ -1853,7 +1886,7 @@ export default class Flippable extends PIXI.projection.Camera3d { // render //-------------------- this.opts.renderer.render(displayObject, renderTexture) - + // restore position displayObject.setTransform(...transform) @@ -1892,7 +1925,7 @@ export default class Flippable extends PIXI.projection.Camera3d {
diff --git a/doc/out/pixi_labeledgraphics.js.html b/doc/out/pixi_labeledgraphics.js.html index b73fab7..d1be3f5 100644 --- a/doc/out/pixi_labeledgraphics.js.html +++ b/doc/out/pixi_labeledgraphics.js.html @@ -1438,13 +1438,10 @@
-

-
-/**
+            
/**
  * Defines usefull default text styles.
  */
 export class FontInfo {
-
     static get small() {
         return app.theme.textStyleSmall
     }
@@ -1460,15 +1457,13 @@ export class FontInfo {
 
 /**
  * Static methods to support hyphenation of lines.
- * 
+ *
  * @class Hypenate
  */
 export class Hypenate {
-
     static splitPart(part) {
         let parts = part.split('-')
-        if (parts.length == 1)
-            return [part]
+        if (parts.length == 1) return [part]
         let result = []
         let last = parts.pop()
         for (let p of parts) {
@@ -1479,7 +1474,7 @@ export class Hypenate {
     }
 
     static splitWord(word) {
-        if (typeof (language) == 'undefined') {
+        if (typeof language == 'undefined') {
             if (word.indexOf('-') > -1) {
                 return word.split('-')
             }
@@ -1496,13 +1491,13 @@ export class Hypenate {
     }
 
     static abbreviateLine(label, style, width) {
-        const pixiStyle = new PIXI.TextStyle(style)   
+        const pixiStyle = new PIXI.TextStyle(style)
         let metrics = PIXI.TextMetrics.measureText(label, pixiStyle)
-        while(metrics.width > width && label.length > 3) {
-            label = label.slice(0, label.length-1)
+        while (metrics.width > width && label.length > 3) {
+            label = label.slice(0, label.length - 1)
             metrics = PIXI.TextMetrics.measureText(label, pixiStyle)
         }
-        label = label.slice(0, label.length-1)
+        label = label.slice(0, label.length - 1)
         return label + '…'
     }
 
@@ -1518,17 +1513,21 @@ export class Hypenate {
                 if (parts.length == 1) {
                     newWord += '\n' + word + ' '
                     x = wordMetrics.width + space.width
-                }
-                else {
+                } else {
                     let first = true
                     let lastPart = ''
                     for (let part of parts) {
-                        let partMetrics = PIXI.TextMetrics.measureText(part, pixiStyle)
+                        let partMetrics = PIXI.TextMetrics.measureText(
+                            part,
+                            pixiStyle
+                        )
                         if (x + partMetrics.width + space.width > width) {
-                            newWord += ((first || lastPart.endsWith('-')) ? '\n' : '-\n') + part
+                            newWord +=
+                                (first || lastPart.endsWith('-')
+                                    ? '\n'
+                                    : '-\n') + part
                             x = partMetrics.width
-                        }
-                        else {
+                        } else {
                             newWord += part
                             x += partMetrics.width
                         }
@@ -1538,8 +1537,7 @@ export class Hypenate {
                     x += space.width
                 }
                 result += newWord + ' '
-            }
-            else {
+            } else {
                 result += word + ' '
                 x += wordMetrics.width + space.width
             }
@@ -1548,7 +1546,7 @@ export class Hypenate {
     }
 
     /**
-     *  Main method and entry point for text hyphenation 
+     *  Main method and entry point for text hyphenation
      *
      * @static
      * @param {*} text
@@ -1571,17 +1569,21 @@ export class Hypenate {
 }
 
 class TextLabel extends PIXI.Text {
-
     /**
      *Creates an instance of TextLabel.
      * @param {string} text - The string that you would like the text to display
-     * @param {object|PIXI.TextStyle} [style] - The style parameters 
-     * @param {canvas} 
+     * @param {object|PIXI.TextStyle} [style] - The style parameters
+     * @param {canvas}
      * @memberof TextLabel
      */
-    constructor(text, style=null, canvas=null, { minZoom = 0.1, maxZoom = 10} = {}) {
-        super(text, style, canvas )
-        this.normFontSize = this.style.fontSize 
+    constructor(
+        text,
+        style = null,
+        canvas = null,
+        { minZoom = 0.1, maxZoom = 10 } = {}
+    ) {
+        super(text, style, canvas)
+        this.normFontSize = this.style.fontSize
         this.minZoom = minZoom
         this.maxZoom = maxZoom
     }
@@ -1620,10 +1622,9 @@ class TextLabel extends PIXI.Text {
  * @extends {PIXI.Graphics}
  */
 export class LabeledGraphics extends PIXI.Graphics {
-
     /**
      * Creates an instance of LabeledGraphics and defines a local label cache.
-     * 
+     *
      * @memberof LabeledGraphics
      */
     constructor() {
@@ -1635,14 +1636,13 @@ export class LabeledGraphics extends PIXI.Graphics {
         return new TextLabel(label, fontInfo)
     }
 
-    
     /**
      * Main additional method. Ensures that a text object is created that is cached
      * under the given key.
      *
      * @param {*} key - The cache key
      * @param {*} label - The label to show
-     * @param {*} [attrs={}] - Defines attributes of the text object. 
+     * @param {*} [attrs={}] - Defines attributes of the text object.
      *                               align: 'right', 'left', or 'center'
      *                               justify: 'top', 'bottom', or 'center'
      *                               maxLines: {integer} truncates the text and adds ellipsis
@@ -1653,11 +1653,9 @@ export class LabeledGraphics extends PIXI.Graphics {
      * @memberof LabeledGraphics
      */
     ensureLabel(key, label, attrs = {}, fontInfo = FontInfo.normal) {
-
         if (attrs.maxWidth && attrs.maxLines == 1) {
             label = Hypenate.abbreviateLine(label, fontInfo, attrs.maxWidth)
-        }
-        else {
+        } else {
             if (attrs.maxWidth) {
                 label = Hypenate.splitLines(label, fontInfo, attrs.maxWidth)
             }
@@ -1671,7 +1669,7 @@ export class LabeledGraphics extends PIXI.Graphics {
                 label = this.truncateLabel(label, fontInfo, maxLines)
             }
         }
-       
+
         if (!this.labels.has(key)) {
             let text = this._createText(label, fontInfo)
             this.labels.set(key, text)
@@ -1681,8 +1679,7 @@ export class LabeledGraphics extends PIXI.Graphics {
         for (let k in attrs) {
             text[k] = attrs[k]
         }
-        if (label != text.text)
-            text.text = label
+        if (label != text.text) text.text = label
         // We do not follow the flexbox jargon and use align for x and justify for y axis
         // This deviation is needed to ensure backward compatability
         switch (attrs.justify || null) {
@@ -1733,17 +1730,30 @@ export class LabeledGraphics extends PIXI.Graphics {
             const truncatedLines = lines.slice(0, maxLines)
             const lastLine = truncatedLines[truncatedLines.length - 1]
             const words = lastLine.split(' ')
-            const wordMetrics = PIXI.TextMetrics.measureText(`\u00A0\n...\n${words.join('\n')}`, pixiStyle)
-            const [spaceLength, dotsLength, ...wordLengths] = wordMetrics.lineWidths
-            const { text: newLastLine } = wordLengths.reduce((data, wordLength, i) => {
-                if (data.length + wordLength + spaceLength >= wordWrapWidth) {
-                    return { ...data, length: wordWrapWidth }
-                }
-                return {
-                    text: `${data.text}${i > 0 ? ' ' : ''}${words[i]}`,
-                    length: data.length + wordLength + spaceLength,
-                };
-            }, { text: '', length: dotsLength })
+            const wordMetrics = PIXI.TextMetrics.measureText(
+                `\u00A0\n...\n${words.join('\n')}`,
+                pixiStyle
+            )
+            const [
+                spaceLength,
+                dotsLength,
+                ...wordLengths
+            ] = wordMetrics.lineWidths
+            const { text: newLastLine } = wordLengths.reduce(
+                (data, wordLength, i) => {
+                    if (
+                        data.length + wordLength + spaceLength >=
+                        wordWrapWidth
+                    ) {
+                        return { ...data, length: wordWrapWidth }
+                    }
+                    return {
+                        text: `${data.text}${i > 0 ? ' ' : ''}${words[i]}`,
+                        length: data.length + wordLength + spaceLength
+                    }
+                },
+                { text: '', length: dotsLength }
+            )
             truncatedLines[truncatedLines.length - 1] = `${newLastLine}...`
             newText = truncatedLines.join('\n')
         }
@@ -1761,7 +1771,7 @@ export class LabeledGraphics extends PIXI.Graphics {
         return this.labels.get(key)
     }
 
-    /** 
+    /**
      * Hides the label with the given key.
      * @param {*} key
      * @memberof LabeledGraphics
@@ -1773,7 +1783,7 @@ export class LabeledGraphics extends PIXI.Graphics {
         }
     }
 
-    /** 
+    /**
      * Removes the label with the given key.
      * @param {*} key
      * @memberof LabeledGraphics
@@ -1784,7 +1794,6 @@ export class LabeledGraphics extends PIXI.Graphics {
         label.destroy()
     }
 
-   
     /**
      * Ensures that labels are hidden on clear.
      *
@@ -1807,7 +1816,6 @@ export class LabeledGraphics extends PIXI.Graphics {
     }
 }
 
-
 const labelCache = new Map()
 
 function getTexture(label, fontInfo = FontInfo.normal) {
@@ -1825,7 +1833,6 @@ function getTexture(label, fontInfo = FontInfo.normal) {
 }
 
 class SpriteLabel extends PIXI.Sprite {
-
     constructor(label, fontInfo) {
         let texture = getTexture(label, fontInfo)
         super(texture)
@@ -1845,12 +1852,10 @@ class SpriteLabel extends PIXI.Sprite {
 }
 
 export class BitmapLabeledGraphics extends LabeledGraphics {
-
     _createText(label, fontInfo) {
         let texture = getTexture(label, fontInfo)
         return new SpriteLabel(texture)
     }
-
 }
 
@@ -1865,7 +1870,7 @@ export class BitmapLabeledGraphics extends LabeledGraphics {
diff --git a/doc/out/pixi_list.js.html b/doc/out/pixi_list.js.html index 51e3b2c..fd54631 100644 --- a/doc/out/pixi_list.js.html +++ b/doc/out/pixi_list.js.html @@ -1449,10 +1449,10 @@ import Events from '../events.js' * @example * const elephant1 = PIXI.Sprite.fromImage('./assets/elephant-1.jpg') * const elephant2 = PIXI.Sprite.fromImage('./assets/elephant-2.jpg') - * + * * // Create the list * const list = new List([elephant1, elephant2]) - * + * * app.scene.addChild(list) * * @class @@ -1461,7 +1461,6 @@ import Events from '../events.js' * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/list.html|DocTest} */ export default class List extends PIXI.Container { - /** * Creates an instance of a Flippable. * @@ -1483,19 +1482,22 @@ export default class List extends PIXI.Container { * scroll your list. */ constructor(items = [], opts = {}) { - super() - this.opts = Object.assign({}, { - padding: 10, - margin: 10, - orientation: 'vertical', - align: 'left', - verticalAlign: 'middle', - width: null, - height: null, - app: null - }, opts) + this.opts = Object.assign( + {}, + { + padding: 10, + margin: 10, + orientation: 'vertical', + align: 'left', + verticalAlign: 'middle', + width: null, + height: null, + app: null + }, + opts + ) this.__items = items this.__dragging = false @@ -1512,7 +1514,6 @@ export default class List extends PIXI.Container { * @return {List} A reference to the list for chaining. */ setup() { - // inner container //-------------------- const container = new PIXI.Container() @@ -1527,7 +1528,7 @@ export default class List extends PIXI.Container { // add items //-------------------- - for(let item of this.__items) { + for (let item of this.__items) { container.addChild(item) } @@ -1547,7 +1548,9 @@ export default class List extends PIXI.Container { if (this.opts.app) { const app = this.opts.app app.view.addEventListener('mousewheel', event => { - const bounds = this.mask ? this.mask.getBounds() : this.getBounds() + const bounds = this.mask + ? this.mask.getBounds() + : this.getBounds() const x = event.clientX - app.view.getBoundingClientRect().left const y = event.clientY - app.view.getBoundingClientRect().top if (bounds.contains(x, y)) { @@ -1571,7 +1574,7 @@ export default class List extends PIXI.Container { setItems(items) { this.container.removeChildren() this.__items = items - for(let item of this.__items) { + for (let item of this.__items) { this.container.addChild(item) } this.layout() @@ -1583,14 +1586,12 @@ export default class List extends PIXI.Container { * @return {List} A reference to the list for chaining. */ layout() { - const margin = this.opts.margin let x = margin let y = margin for (let item of this.__items) { - item.x = x item.y = y @@ -1606,13 +1607,17 @@ export default class List extends PIXI.Container { if (this.opts.orientation === 'vertical') { switch (this.opts.align) { case 'center': - this.__items.forEach(it => it.x = margin + this.width / 2 - it.width / 2) + this.__items.forEach( + it => (it.x = margin + this.width / 2 - it.width / 2) + ) break case 'right': - this.__items.forEach(it => it.x = margin + this.width - it.width) + this.__items.forEach( + it => (it.x = margin + this.width - it.width) + ) break default: - this.__items.forEach(it => it.x = margin) + this.__items.forEach(it => (it.x = margin)) break } @@ -1632,13 +1637,17 @@ export default class List extends PIXI.Container { if (this.opts.orientation === 'horizontal') { switch (this.opts.verticalAlign) { case 'top': - this.__items.forEach(it => it.y = margin) + this.__items.forEach(it => (it.y = margin)) break case 'bottom': - this.__items.forEach(it => it.y = margin + this.height - it.height) + this.__items.forEach( + it => (it.y = margin + this.height - it.height) + ) break default: - this.__items.forEach(it => it.y = margin + this.height / 2 - it.height / 2) + this.__items.forEach( + it => (it.y = margin + this.height / 2 - it.height / 2) + ) break } @@ -1657,13 +1666,12 @@ export default class List extends PIXI.Container { } /** - * + * */ get innerWidth() { - let size = 0 - this.__items.forEach(it => size += it.width) + this.__items.forEach(it => (size += it.width)) size += this.opts.padding * (this.__items.length - 1) size += 2 * this.opts.margin @@ -1671,13 +1679,12 @@ export default class List extends PIXI.Container { } /** - * + * */ get innerHeight() { - let size = 0 - this.__items.forEach(it => size += it.height) + this.__items.forEach(it => (size += it.height)) size += this.opts.padding * (this.__items.length - 1) size += 2 * this.opts.margin @@ -1686,11 +1693,10 @@ export default class List extends PIXI.Container { /** * Resizes the list. - * + * * @param {number} widthOrHeight - The new width (if orientation is horizontal) or height (if orientation is vertical) of the list. */ resize(widthOrHeight) { - if (this.opts.orientation === 'horizontal') { this.opts.width = widthOrHeight } else { @@ -1701,12 +1707,11 @@ export default class List extends PIXI.Container { } /** - * + * * @private - * @param {*} event + * @param {*} event */ onStart(event) { - this.__dragging = true this.capture(event) @@ -1716,21 +1721,19 @@ export default class List extends PIXI.Container { y: this.container.position.y - event.data.global.y } - TweenLite.killTweensOf(this.container.position, {x: true, y: true}) - if (typeof ThrowPropsPlugin != "undefined") { + TweenLite.killTweensOf(this.container.position, { x: true, y: true }) + if (typeof ThrowPropsPlugin != 'undefined') { ThrowPropsPlugin.track(this.container.position, 'x,y') } } /** - * + * * @private - * @param {*} event + * @param {*} event */ onMove(event) { - if (this.__dragging) { - this.capture(event) if (this.opts.orientation === 'horizontal') { @@ -1742,19 +1745,18 @@ export default class List extends PIXI.Container { } /** - * + * * @private - * @param {*} event + * @param {*} event */ onEnd(event) { - if (this.__dragging) { this.__dragging = false this.capture(event) const throwProps = {} - + if (this.opts.orientation === 'horizontal') { let min = this.opts.width - this.innerWidth min = min > 0 ? 0 : min @@ -1773,37 +1775,48 @@ export default class List extends PIXI.Container { } } - if (typeof ThrowPropsPlugin != "undefined") { - ThrowPropsPlugin.to(this.container.position, { - throwProps, - ease: Strong.easeOut, - onComplete: () => ThrowPropsPlugin.untrack(this.container.position) - }, .8, .4) + if (typeof ThrowPropsPlugin != 'undefined') { + ThrowPropsPlugin.to( + this.container.position, + { + throwProps, + ease: Strong.easeOut, + onComplete: () => + ThrowPropsPlugin.untrack(this.container.position) + }, + 0.8, + 0.4 + ) } } } /** - * + * * @private - * @param {*} event + * @param {*} event */ onScroll(event) { - this.capture(event) if (this.opts.orientation === 'horizontal') { this.container.position.x -= event.deltaX if (this.container.position.x > 0) { this.container.position.x = 0 - } else if (this.container.position.x + this.innerWidth < this.opts.width) { + } else if ( + this.container.position.x + this.innerWidth < + this.opts.width + ) { this.container.position.x = this.opts.width - this.innerWidth } } else { this.container.position.y -= event.deltaY if (this.container.position.y > 0) { this.container.position.y = 0 - } else if (this.container.position.y + this.innerHeight < this.opts.height) { + } else if ( + this.container.position.y + this.innerHeight < + this.opts.height + ) { this.container.position.y = this.opts.height - this.innerHeight } } @@ -1815,7 +1828,10 @@ export default class List extends PIXI.Container { * @param {event|PIXI.InteractionEvent} event - The PIXI event to capture. */ capture(event) { - const originalEvent = event.data && event.data.originalEvent ? event.data.originalEvent : event + const originalEvent = + event.data && event.data.originalEvent + ? event.data.originalEvent + : event Events.capturedBy(originalEvent, this) } } @@ -1832,7 +1848,7 @@ export default class List extends PIXI.Container {
diff --git a/doc/out/pixi_message.js.html b/doc/out/pixi_message.js.html index f32a385..d1093f6 100644 --- a/doc/out/pixi_message.js.html +++ b/doc/out/pixi_message.js.html @@ -1439,11 +1439,11 @@
import Theme from './theme.js'
-import {InteractivePopup} from './popup.js'
+import { InteractivePopup } from './popup.js'
 
 /**
  * Class that represents a Message. A message pops up and disappears after a specific amount of time.
- * 
+ *
  * @example
  * // Create the PixiJS App
  * const app = new PIXIApp({
@@ -1451,7 +1451,7 @@ import {InteractivePopup} from './popup.js'
  *     width: 900,
  *     height: 250
  * }).setup().run()
- * 
+ *
  * // Create a button
  * let button = new Button({
  *     label: 'Click me',
@@ -1464,7 +1464,7 @@ import {InteractivePopup} from './popup.js'
  *         app.scene.addChild(message)
  *     }
  * })
- * 
+ *
  * // Add the button to the scene
  * app.scene.addChild(button)
  *
@@ -1473,10 +1473,9 @@ import {InteractivePopup} from './popup.js'
  * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/message.html|DocTest}
  */
 export default class Message extends InteractivePopup {
-
     /**
      * Creates an instance of a Message.
-     * 
+     *
      * @constructor
      * @param {object} [opts] - An options object to specify to style and behaviour of the message.
      * @param {PIXIApp} [opts.app=window.app] - The PIXIApp where this message belongs to.
@@ -1493,32 +1492,34 @@ export default class Message extends InteractivePopup {
      * @param {number} [opts.closeDuration=Theme.fast] - The duration in seconds of the closing of the message box.
      */
     constructor(opts = {}) {
-        
         const theme = Theme.fromString(opts.theme)
 
-        opts = Object.assign({}, {
-            app: window.app,
-            closeButton: false,
-            minWidth: 280,
-            minHeight: 100,
-            margin: theme.margin,
-            align: 'right',                     // left, center, right
-            verticalAlign: 'top',               // top, middle, bottom
-            duration: 5,
-            autoClose: true,
-            closeDuration: theme.fast
-        }, opts)
+        opts = Object.assign(
+            {},
+            {
+                app: window.app,
+                closeButton: false,
+                minWidth: 280,
+                minHeight: 100,
+                margin: theme.margin,
+                align: 'right', // left, center, right
+                verticalAlign: 'top', // top, middle, bottom
+                duration: 5,
+                autoClose: true,
+                closeDuration: theme.fast
+            },
+            opts
+        )
 
         super(opts)
     }
 
     /**
      * Relayouts the position of the message box.
-     * 
+     *
      * @return {Message} Returns the message box for chaining.
      */
     layout() {
-
         super.layout()
 
         // horizontal
@@ -1527,10 +1528,11 @@ export default class Message extends InteractivePopup {
                 this.x = this.opts.margin
                 break
             case 'center':
-                this.x = (this.opts.app.size.width / 2) - (this.width / 2)
+                this.x = this.opts.app.size.width / 2 - this.width / 2
                 break
             case 'right':
-                this.x = this.opts.app.size.width - this.opts.margin - this.width
+                this.x =
+                    this.opts.app.size.width - this.opts.margin - this.width
                 break
         }
 
@@ -1540,21 +1542,21 @@ export default class Message extends InteractivePopup {
                 this.y = this.opts.margin
                 break
             case 'middle':
-                this.y = (this.opts.app.size.height / 2) - (this.height / 2)
+                this.y = this.opts.app.size.height / 2 - this.height / 2
                 break
             case 'bottom':
-                this.y = this.opts.app.size.height - this.opts.margin - this.height
+                this.y =
+                    this.opts.app.size.height - this.opts.margin - this.height
                 break
         }
     }
 
     /**
      * Shows the message box.
-     * 
+     *
      * @private
      */
     show() {
-
         super.show()
 
         if (this.opts.autoClose) {
@@ -1577,7 +1579,7 @@ export default class Message extends InteractivePopup {
 
         
diff --git a/doc/out/pixi_modal.js.html b/doc/out/pixi_modal.js.html index 81edddf..1588b6a 100644 --- a/doc/out/pixi_modal.js.html +++ b/doc/out/pixi_modal.js.html @@ -1439,11 +1439,11 @@
import Theme from './theme.js'
-import {InteractivePopup} from './popup.js'
+import { InteractivePopup } from './popup.js'
 
 /**
  * Class that represents a PixiJS Modal.
- * 
+ *
  * @example
  * // Create the button and the modal when clicked
  * const button = new Button({
@@ -1468,10 +1468,9 @@ import {InteractivePopup} from './popup.js'
  * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/modal.html|DocTest}
  */
 export default class Modal extends PIXI.Container {
-
     /**
      * Creates an instance of a Modal.
-     * 
+     *
      * @constructor
      * @param {object} [opts] - An options object to specify to style and behaviour of the modal.
      * @param {number} [opts.id=auto generated] - The id of the modal.
@@ -1483,20 +1482,23 @@ export default class Modal extends PIXI.Container {
      * @param {boolean} [opts.visible=true] - Is the modal initially visible (property visible)?
      */
     constructor(opts = {}) {
-
         super()
-        
+
         const theme = Theme.fromString(opts.theme)
         this.theme = theme
 
-        this.opts = Object.assign({}, {
-            id: PIXI.utils.uid(),
-            app: window.app,
-            backgroundFill: theme.background,
-            backgroundFillAlpha: .6,
-            closeOnBackground: true,
-            visible: true
-        }, opts)
+        this.opts = Object.assign(
+            {},
+            {
+                id: PIXI.utils.uid(),
+                app: window.app,
+                backgroundFill: theme.background,
+                backgroundFillAlpha: 0.6,
+                closeOnBackground: true,
+                visible: true
+            },
+            opts
+        )
 
         this.id = this.opts.id
 
@@ -1514,15 +1516,14 @@ export default class Modal extends PIXI.Container {
         //-----------------
         this.layout()
     }
-    
+
     /**
      * Creates children and instantiates everything.
-     * 
+     *
      * @private
      * @return {Modal} A reference to the modal for chaining.
      */
     setup() {
-
         // interaction
         //-----------------
         this.interactive = true
@@ -1560,21 +1561,23 @@ export default class Modal extends PIXI.Container {
 
         return this
     }
-    
+
     /**
      * Should be called to refresh the layout of the modal. Can be used after resizing.
-     * 
+     *
      * @return {Modal} A reference to the modal for chaining.
      */
     layout() {
-
         const width = this.opts.app.size.width
         const height = this.opts.app.size.height
 
         // background
         //-----------------
         this.background.clear()
-        this.background.beginFill(this.opts.backgroundFill, this.opts.backgroundFillAlpha)
+        this.background.beginFill(
+            this.opts.backgroundFill,
+            this.opts.backgroundFillAlpha
+        )
         this.background.drawRect(0, 0, width, height)
         this.background.endFill()
 
@@ -1584,33 +1587,39 @@ export default class Modal extends PIXI.Container {
 
         return this
     }
-    
+
     /**
      * Shows the modal (sets his alpha values to 1).
-     * 
+     *
      * @return {Modal} A reference to the modal for chaining.
      */
     show() {
-        TweenLite.to(this, this.theme.fast, {alpha: 1, onStart: () => this.visible = true})
+        TweenLite.to(this, this.theme.fast, {
+            alpha: 1,
+            onStart: () => (this.visible = true)
+        })
 
         return this
     }
-    
+
     /**
      * Hides the modal (sets his alpha values to 0).
-     * 
+     *
      * @return {Modal} A reference to the modal for chaining.
      */
     hide() {
-        TweenLite.to(this, this.theme.fast, {alpha: 0, onComplete: () => this.visible = false})
+        TweenLite.to(this, this.theme.fast, {
+            alpha: 0,
+            onComplete: () => (this.visible = false)
+        })
 
         return this
     }
-    
+
     /**
      * Sets or gets the header. The getter always returns a PIXI.Text object. The setter can receive
      * a string or a PIXI.Text object.
-     * 
+     *
      * @member {string|PIXI.Text}
      */
     get header() {
@@ -1622,11 +1631,11 @@ export default class Modal extends PIXI.Container {
         this.popup.destroy()
         this.setup().layout()
     }
-    
+
     /**
      * Sets or gets the content. The getter always returns an PIXI.DisplayObject. The setter can receive
      * a string or a PIXI.DisplayObject.
-     * 
+     *
      * @member {string|PIXI.DisplayObject}
      */
     get content() {
@@ -1652,7 +1661,7 @@ export default class Modal extends PIXI.Container {
 
         
diff --git a/doc/out/pixi_popup.js.html b/doc/out/pixi_popup.js.html index 3d0a07a..a140d09 100644 --- a/doc/out/pixi_popup.js.html +++ b/doc/out/pixi_popup.js.html @@ -1452,7 +1452,6 @@ import ButtonGroup from './buttongroup.js' * @extends AbstractPopup */ export class InteractivePopup extends AbstractPopup { - /** * Creates an instance of an InteractivePopup (only for internal use). * @@ -1464,13 +1463,16 @@ export class InteractivePopup extends AbstractPopup { * @param {object} [opts.buttonGroup] - A ButtonGroup object to be displayed on the lower right corner. */ constructor(opts = {}) { - - opts = Object.assign({}, { - closeOnPopup: false, - closeButton: true, - button: null, - buttonGroup: null - }, opts) + opts = Object.assign( + {}, + { + closeOnPopup: false, + closeButton: true, + button: null, + buttonGroup: null + }, + opts + ) super(opts) @@ -1496,7 +1498,6 @@ export class InteractivePopup extends AbstractPopup { * @return {AbstractPopup} A reference to the popup for chaining. */ setup() { - super.setup() // interaction @@ -1512,7 +1513,10 @@ export class InteractivePopup extends AbstractPopup { // closeButton //----------------- if (this.opts.closeButton) { - let closeButton = PIXI.Sprite.fromImage('../../assets/icons/close.png', true) + let closeButton = PIXI.Sprite.fromImage( + '../../assets/icons/close.png', + true + ) closeButton.width = this.headerStyle.fontSize closeButton.height = closeButton.width closeButton.tint = this.theme.color2 @@ -1535,7 +1539,11 @@ export class InteractivePopup extends AbstractPopup { // maxWidth is set and a closeButton should be displayed //----------------- if (this.opts.maxWidth) { - const wordWrapWidth = this.opts.maxWidth - (2 * this.opts.padding) - this.smallPadding - this._closeButton.width + const wordWrapWidth = + this.opts.maxWidth - + 2 * this.opts.padding - + this.smallPadding - + this._closeButton.width if (this._header) { this.headerStyle.wordWrapWidth = wordWrapWidth } else if (this._content) { @@ -1548,9 +1556,19 @@ export class InteractivePopup extends AbstractPopup { //----------------- if (this.opts.button || this.opts.buttonGroup) { if (this.opts.button) { - this._buttons = new Button(Object.assign({textStyle: this.theme.textStyleSmall}, this.opts.button)) + this._buttons = new Button( + Object.assign( + { textStyle: this.theme.textStyleSmall }, + this.opts.button + ) + ) } else { - this._buttons = new ButtonGroup(Object.assign({textStyle: this.theme.textStyleSmall}, this.opts.buttonGroup)) + this._buttons = new ButtonGroup( + Object.assign( + { textStyle: this.theme.textStyleSmall }, + this.opts.buttonGroup + ) + ) } this.addChild(this._buttons) @@ -1566,21 +1584,23 @@ export class InteractivePopup extends AbstractPopup { * @return {AbstractPopup} A reference to the popup for chaining. */ layout() { - super.layout() - + // closeButton //----------------- if (this.opts.closeButton) { - this._closeButton.x = this.wantedWidth - this.smallPadding - this._closeButton.width + this._closeButton.x = + this.wantedWidth - this.smallPadding - this._closeButton.width this._closeButton.y = this.smallPadding } // buttons //----------------- if (this._buttons) { - this._buttons.x = this.wantedWidth - this.opts.padding - this._buttons.width - this._buttons.y = this.wantedHeight - this.opts.padding - this._buttons.height + this._buttons.x = + this.wantedWidth - this.opts.padding - this._buttons.width + this._buttons.y = + this.wantedHeight - this.opts.padding - this._buttons.height } return this @@ -1590,13 +1610,12 @@ export class InteractivePopup extends AbstractPopup { * Calculates the size of the children of the AbstractPopup. * Cannot use getBounds() because it is not updated when children * are removed. - * + * * @private * @override * @returns {object} An JavaScript object width the keys width and height. */ getInnerSize() { - let size = super.getInnerSize() if (this._closeButton) { @@ -1604,7 +1623,10 @@ export class InteractivePopup extends AbstractPopup { } if (this._buttons) { - size.width = Math.max(size.width, this._buttons.x + this._buttons.width) + size.width = Math.max( + size.width, + this._buttons.x + this._buttons.width + ) size.height += this.innerPadding + this._buttons.height } @@ -1630,7 +1652,6 @@ export class InteractivePopup extends AbstractPopup { * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/popup.html|DocTest} */ export default class Popup extends InteractivePopup { - /** * Creates an instance of a Popup. * @@ -1641,12 +1662,15 @@ export default class Popup extends InteractivePopup { * @param {number} [opts.minHeight=0] - The minimum height of the popup. */ constructor(opts = {}) { - - opts = Object.assign({}, { - closeButton: false, - minWidth: 0, - minHeight: 0 - }, opts) + opts = Object.assign( + {}, + { + closeButton: false, + minWidth: 0, + minHeight: 0 + }, + opts + ) super(opts) } @@ -1664,7 +1688,7 @@ export default class Popup extends InteractivePopup {
diff --git a/doc/out/pixi_popupmenu.js.html b/doc/out/pixi_popupmenu.js.html index 5aac331..9c5d94b 100644 --- a/doc/out/pixi_popupmenu.js.html +++ b/doc/out/pixi_popupmenu.js.html @@ -1443,7 +1443,7 @@ import Popup from './popup.js' /** * Class that represents a PixiJS PopupMenu. - * + * * @example * // Create the button and the modal when clicked * const button = new Button({ @@ -1468,10 +1468,9 @@ import Popup from './popup.js' * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/popupmenu.html|DocTest} */ export default class PopupMenu extends Popup { - /** * Creates an instance of a PopupMenu. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the modal. * @param {object[]} [opts.items=[]] - A list of the menu items. Each item must be of type object. @@ -1483,38 +1482,42 @@ export default class PopupMenu extends Popup { * @param {boolean} [opts.closeOnPopup=true] - The opacity of the background. */ constructor(opts = {}) { - const theme = Theme.fromString(opts.theme) - - opts = Object.assign({}, { - items: [], - margin: theme.margin / 2, - textStyle: theme.textStyle, - closeOnPopup: true - }, opts) + + opts = Object.assign( + {}, + { + items: [], + margin: theme.margin / 2, + textStyle: theme.textStyle, + closeOnPopup: true + }, + opts + ) super(opts) } - + /** * Creates children and instantiates everything. - * + * * @private * @return {PopupMenu} A reference to the popupmenu for chaining. */ setup() { - // content //----------------- const content = new PIXI.Container() - + let y = 0 for (let item of this.opts.items) { - let object = null if (item.label) { - object = new PIXI.Text(item.label, item.textStyle || this.opts.textStyle) + object = new PIXI.Text( + item.label, + item.textStyle || this.opts.textStyle + ) } else { object = item.content } @@ -1523,16 +1526,22 @@ export default class PopupMenu extends Popup { if (item.action) { if (item.disabled) { - object.alpha = .5 + object.alpha = 0.5 } else { object.interactive = true object.buttonMode = true } object.on('pointerover', e => { - TweenLite.to(object, this.theme.fast, {alpha: .83, overwrite: 'none'}) + TweenLite.to(object, this.theme.fast, { + alpha: 0.83, + overwrite: 'none' + }) }) object.on('pointerout', e => { - TweenLite.to(object, this.theme.fast, {alpha: 1, overwrite: 'none'}) + TweenLite.to(object, this.theme.fast, { + alpha: 1, + overwrite: 'none' + }) }) object.on('pointerup', e => { item.action.call(object, e, object) @@ -1565,7 +1574,7 @@ export default class PopupMenu extends Popup {
diff --git a/doc/out/pixi_progress.js.html b/doc/out/pixi_progress.js.html index 3099c33..67d8359 100644 --- a/doc/out/pixi_progress.js.html +++ b/doc/out/pixi_progress.js.html @@ -1442,7 +1442,7 @@ /** * Class that represents a PixiJS Progress. - * + * * @example * // Create the progress * const progress = new Progress({ @@ -1458,10 +1458,9 @@ * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/progress.html|DocTest} */ export default class Progress extends PIXI.Container { - /** * Creates an instance of a Progress. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the progress. * @param {number} [opts.id=auto generated] - The id of the progress. @@ -1493,36 +1492,39 @@ export default class Progress extends PIXI.Container { * @param {boolean} [opts.visible=true] - Is the progress initially visible (property visible)? */ constructor(opts = {}) { - super() - + const theme = Theme.fromString(opts.theme) this.theme = theme - this.opts = Object.assign({}, { - id: PIXI.utils.uid(), - app: window.app, - width: null, - height: 2, - margin: 100, - padding: 0, - fill: theme.fill, - fillAlpha: theme.fillAlpha, - fillActive: theme.primaryColor, - fillActiveAlpha: theme.fillActiveAlpha, - stroke: theme.stroke, - strokeWidth: 0, - strokeAlpha: theme.strokeAlpha, - strokeActive: theme.strokeActive, - strokeActiveWidth: 0, - strokeActiveAlpha: theme.strokeActiveAlpha, - background: false, - backgroundFill: theme.background, - backgroundFillAlpha: 1, - radius: theme.radius, - destroyOnComplete: true, - visible: true - }, opts) + this.opts = Object.assign( + {}, + { + id: PIXI.utils.uid(), + app: window.app, + width: null, + height: 2, + margin: 100, + padding: 0, + fill: theme.fill, + fillAlpha: theme.fillAlpha, + fillActive: theme.primaryColor, + fillActiveAlpha: theme.fillActiveAlpha, + stroke: theme.stroke, + strokeWidth: 0, + strokeAlpha: theme.strokeAlpha, + strokeActive: theme.strokeActive, + strokeActiveWidth: 0, + strokeActiveAlpha: theme.strokeActiveAlpha, + background: false, + backgroundFill: theme.background, + backgroundFillAlpha: 1, + radius: theme.radius, + destroyOnComplete: true, + visible: true + }, + opts + ) this.id = this.opts.id @@ -1531,7 +1533,7 @@ export default class Progress extends PIXI.Container { this.barActive = null this.alpha = 0 - + this.visible = this.opts.visible this._progress = 0 @@ -1544,15 +1546,14 @@ export default class Progress extends PIXI.Container { //----------------- this.layout() } - + /** * Creates children and instantiates everything. - * + * * @private * @return {Progress} A reference to the progress for chaining. */ setup() { - // interaction //----------------- this.on('added', e => { @@ -1579,14 +1580,13 @@ export default class Progress extends PIXI.Container { return this } - + /** * Should be called to refresh the layout of the progress. Can be used after resizing. - * + * * @return {Progress} A reference to the progress for chaining. */ layout() { - const width = this.opts.app.size.width const height = this.opts.app.size.height @@ -1594,7 +1594,10 @@ export default class Progress extends PIXI.Container { //----------------- if (this.opts.background) { this.background.clear() - this.background.beginFill(this.opts.backgroundFill, this.opts.backgroundFillAlpha) + this.background.beginFill( + this.opts.backgroundFill, + this.opts.backgroundFillAlpha + ) this.background.drawRect(0, 0, width, height) this.background.endFill() } @@ -1603,15 +1606,14 @@ export default class Progress extends PIXI.Container { return this } - + /** * Draws the canvas. - * + * * @private * @return {Progress} A reference to the progress for chaining. */ draw() { - this.bar.clear() this.barActive.clear() @@ -1620,59 +1622,80 @@ export default class Progress extends PIXI.Container { return this } - + /** * Draws the bar. - * + * * @private * @return {Progress} A reference to the progress for chaining. */ drawBar() { - const width = this.opts.app.size.width const height = this.opts.app.size.height this.radius = this.opts.radius - if ((this.radius * 2) > this.opts.height) { + if (this.radius * 2 > this.opts.height) { this.radius = this.opts.height / 2 } - const wantedWidth = this.opts.width || (width - (2 * this.opts.margin)) + const wantedWidth = this.opts.width || width - 2 * this.opts.margin const wantedHeight = this.opts.height - this.bar.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha) + this.bar.lineStyle( + this.opts.strokeWidth, + this.opts.stroke, + this.opts.strokeAlpha + ) this.bar.beginFill(this.opts.fill, this.opts.fillAlpha) if (this.radius > 1) { - this.bar.drawRoundedRect(0, 0, wantedWidth, wantedHeight, this.radius) + this.bar.drawRoundedRect( + 0, + 0, + wantedWidth, + wantedHeight, + this.radius + ) } else { this.bar.drawRect(0, 0, wantedWidth, wantedHeight) } this.bar.endFill() - + this.bar.x = width / 2 - this.bar.width / 2 this.bar.y = height / 2 - this.bar.height / 2 return this } - + /** * Draws the active bar. - * + * * @private * @return {Progress} A reference to the progress for chaining. */ drawBarActive() { + const wantedWidth = this.bar.width - 2 * this.opts.padding + const wantedHeight = this.bar.height - 2 * this.opts.padding - const wantedWidth = this.bar.width - (2 * this.opts.padding) - const wantedHeight = this.bar.height - (2 * this.opts.padding) - - const barActiveWidth = wantedWidth * this._progress / 100 + const barActiveWidth = (wantedWidth * this._progress) / 100 - this.barActive.lineStyle(this.opts.strokeActiveWidth, this.opts.strokeActive, this.opts.strokeActiveAlpha) - this.barActive.beginFill(this.opts.fillActive, this.opts.fillActiveAlpha) + this.barActive.lineStyle( + this.opts.strokeActiveWidth, + this.opts.strokeActive, + this.opts.strokeActiveAlpha + ) + this.barActive.beginFill( + this.opts.fillActive, + this.opts.fillActiveAlpha + ) if (barActiveWidth > 0) { if (this.radius > 1) { - this.barActive.drawRoundedRect(0, 0, barActiveWidth, wantedHeight, this.radius) + this.barActive.drawRoundedRect( + 0, + 0, + barActiveWidth, + wantedHeight, + this.radius + ) } else { this.barActive.drawRect(0, 0, barActiveWidth, wantedHeight) } @@ -1684,39 +1707,41 @@ export default class Progress extends PIXI.Container { return this } - + /** * Shows the progress (sets his alpha values to 1). - * + * * @return {Progress} A reference to the progress for chaining. */ show() { - TweenLite.to(this, this.theme.fast, {alpha: 1}) + TweenLite.to(this, this.theme.fast, { alpha: 1 }) return this } - + /** * Hides the progress (sets his alpha values to 1). - * + * * @return {Progress} A reference to the progress for chaining. */ hide() { - TweenLite.to(this, this.theme.fast, {alpha: 0, onComplete: () => this.visible = false}) + TweenLite.to(this, this.theme.fast, { + alpha: 0, + onComplete: () => (this.visible = false) + }) return this } - + /** * Gets or sets the progress. Has to be a number between 0 and 100. - * + * * @member {number} */ get progress() { return this._progress } set progress(value) { - value = Math.round(value) if (value < 0) { @@ -1734,7 +1759,7 @@ export default class Progress extends PIXI.Container { if (value === 100 && this.opts.destroyOnComplete) { TweenLite.to(this, this.theme.fast, { alpha: 0, - onComplete: () => this.destroy({children: true}) + onComplete: () => this.destroy({ children: true }) }) } } @@ -1754,7 +1779,7 @@ export default class Progress extends PIXI.Container {
diff --git a/doc/out/pixi_scrollview.js.html b/doc/out/pixi_scrollview.js.html index e8953a9..b953d5b 100644 --- a/doc/out/pixi_scrollview.js.html +++ b/doc/out/pixi_scrollview.js.html @@ -1442,7 +1442,7 @@ /** * Class that represents a PixiJS Scrollview. - * + * * @example * // Create the app * const app = new PIXIApp({ @@ -1450,7 +1450,7 @@ * width: 600, * height: 400 * }).setup().run() - * + * * // Create the Scrollview * app.loader * .add('elephant', './assets/elephant-1.jpg') @@ -1466,38 +1466,34 @@ * @see {@link https://davidfig.github.io/pixi-viewport/jsdoc/Viewport.html|Viewport} */ export default class Scrollview extends Scrollbox { - /** * Creates an instance of a Scrollview. - * + * * @constructor * @see https://davidfig.github.io/pixi-scrollbox/jsdoc/Scrollbox.html */ constructor(opts = {}) { - super(opts) this.opts = opts } - + /** * Creates children and instantiates everything. - * + * * @private * @return {Scrollview} A reference to the Scrollview for chaining. */ setup() { - return this } - + /** * Should be called to refresh the layout of the Scrollview. Can be used after resizing. - * + * * @return {Scrollview} A reference to the Scrollview for chaining. */ layout() { - this.update() return this @@ -1516,7 +1512,7 @@ export default class Scrollview extends Scrollbox {
diff --git a/doc/out/pixi_slider.js.html b/doc/out/pixi_slider.js.html index 65ece88..a36eaa2 100644 --- a/doc/out/pixi_slider.js.html +++ b/doc/out/pixi_slider.js.html @@ -1467,7 +1467,7 @@ import Tooltip from './tooltip.js' /** * Class that represents a PixiJS Slider. - * + * * @example * // Create the app * const app = new PIXIApp({ @@ -1475,7 +1475,7 @@ import Tooltip from './tooltip.js' * width: 900, * height: 250 * }).setup().run() - * + * * // Create the slider * const slider = new Slider({ * x: 10, @@ -1491,10 +1491,9 @@ import Tooltip from './tooltip.js' * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/slider.html|DocTest} */ export default class Slider extends PIXI.Container { - /** * Creates an instance of a Slider. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the slider. * @param {number} [opts.id=auto generated] - The id of the slider. @@ -1522,46 +1521,49 @@ export default class Slider extends PIXI.Container { * @param {onUpdateCallback} [opts.onUpdate] - Executed when the slider control is moved. * @param {onCompleteCallback} [opts.onComplete] - Executed when the slider control was dropped. * @param {string|object} [opts.tooltip] - A string for the label of the tooltip or an object to configure the tooltip - * to display. + * to display. * @param {boolean} [opts.visible=true] - Is the slider initially visible (property visible)? */ constructor(opts = {}) { - super() - + const theme = Theme.fromString(opts.theme) this.theme = theme - this.opts = Object.assign({}, { - id: PIXI.utils.uid(), - x: 0, - y: 0, - width: 250, - height: 2, - container: null, - fill: theme.fill, - fillAlpha: theme.fillAlpha, - stroke: theme.stroke, - strokeWidth: theme.strokeWidth, - strokeAlpha: theme.strokeAlpha, - controlFill: theme.fill, - controlFillAlpha: .5, - controlStroke: theme.primaryColor, - controlStrokeWidth: 2, - controlStrokeAlpha: theme.strokeAlpha, - controlRadius: 16, - orientation: 'horizontal', - min: 0, - max: 100, - value: 0, - disabled: false, - onStart: null, - onUpdate: null, - onComplete: null, - tooltip: null, - visible: true - }, opts) - + this.opts = Object.assign( + {}, + { + id: PIXI.utils.uid(), + x: 0, + y: 0, + width: 250, + height: 2, + container: null, + fill: theme.fill, + fillAlpha: theme.fillAlpha, + stroke: theme.stroke, + strokeWidth: theme.strokeWidth, + strokeAlpha: theme.strokeAlpha, + controlFill: theme.fill, + controlFillAlpha: 0.5, + controlStroke: theme.primaryColor, + controlStrokeWidth: 2, + controlStrokeAlpha: theme.strokeAlpha, + controlRadius: 16, + orientation: 'horizontal', + min: 0, + max: 100, + value: 0, + disabled: false, + onStart: null, + onUpdate: null, + onComplete: null, + tooltip: null, + visible: true + }, + opts + ) + this.opts.container = this.opts.container || this // Validation @@ -1589,7 +1591,7 @@ export default class Slider extends PIXI.Container { this.sliderObj = null this.control = null this.tooltip = null - + this.visible = this.opts.visible // setup @@ -1600,23 +1602,26 @@ export default class Slider extends PIXI.Container { //----------------- this.layout() } - + /** * Creates children and instantiates everything. - * + * * @private * @return {Slider} A reference to the slider for chaining. */ setup() { - // Container events //----------------- const container = this.opts.container this.on('pointermove', e => { if (this.control.dragging) { - const moveX = this.control.event.data.getLocalPosition(this.control.parent).x - this._value = this.pixelToValue(moveX - this.control.delta - this.opts.controlRadius) + const moveX = this.control.event.data.getLocalPosition( + this.control.parent + ).x + this._value = this.pixelToValue( + moveX - this.control.delta - this.opts.controlRadius + ) let x = this.valueToPixel(this._value) + this.opts.controlRadius this.control.x = x @@ -1628,8 +1633,16 @@ export default class Slider extends PIXI.Container { if (container instanceof Element) { container.addEventListener('pointerup', e => this.onEnd(e), false) - container.addEventListener('pointercancel', e => this.onEnd(e), false) - container.addEventListener('pointerleave', e => this.onEnd(e), false) + container.addEventListener( + 'pointercancel', + e => this.onEnd(e), + false + ) + container.addEventListener( + 'pointerleave', + e => this.onEnd(e), + false + ) container.addEventListener('pointerout', e => this.onEnd(e), false) container.addEventListener('mouseup', e => this.onEnd(e), false) container.addEventListener('mousecancel', e => this.onEnd(e), false) @@ -1660,7 +1673,7 @@ export default class Slider extends PIXI.Container { control.event = e control.delta = e.data.getLocalPosition(this.control).x control.dragging = true - + if (this.opts.onStart) { this.opts.onStart.call(this, e, this) } @@ -1669,20 +1682,20 @@ export default class Slider extends PIXI.Container { this.control = control this.addChild(this.control) - + // interaction //----------------- this.sliderObj.on('pointerover', e => { - TweenLite.to(this.control, this.theme.fast, {alpha: .83}) + TweenLite.to(this.control, this.theme.fast, { alpha: 0.83 }) }) this.sliderObj.on('pointerout', e => { - TweenLite.to(this.control, this.theme.fast, {alpha: 1}) + TweenLite.to(this.control, this.theme.fast, { alpha: 1 }) }) this.sliderObj.on('pointerdown', e => { this.sliderObj.pointerdowned = true - TweenLite.to(this.control, this.theme.fast, {alpha: .7}) + TweenLite.to(this.control, this.theme.fast, { alpha: 0.7 }) }) // Click on the slider bar @@ -1690,15 +1703,17 @@ export default class Slider extends PIXI.Container { if (this.sliderObj.pointerdowned) { this.sliderObj.pointerdowned = false const position = e.data.getLocalPosition(this.control.parent) - this.value = this.pixelToValue(position.x - this.opts.controlRadius) - TweenLite.to(this.control, this.theme.fast, {alpha: .83}) + this.value = this.pixelToValue( + position.x - this.opts.controlRadius + ) + TweenLite.to(this.control, this.theme.fast, { alpha: 0.83 }) } }) // disabled //----------------- this.disabled = this.opts.disabled - + // tooltip //----------------- if (this.opts.tooltip) { @@ -1715,14 +1730,13 @@ export default class Slider extends PIXI.Container { return this } - + /** * Should be called to refresh the layout of the slider. Can be used after resizing. - * + * * @return {Slider} A reference to the slider for chaining. */ layout() { - // set position //----------------- this.position.set(this.opts.x, this.opts.y) @@ -1733,15 +1747,14 @@ export default class Slider extends PIXI.Container { return this } - + /** * Draws the slider to the canvas. - * + * * @private * @return {Slider} A reference to the slider for chaining. */ draw() { - const r = this.radius const cr = this.opts.controlRadius const w = this.opts.width @@ -1752,12 +1765,16 @@ export default class Slider extends PIXI.Container { this.sliderObj.clear() this.sliderObj.beginFill(0xffffff, 0) this.sliderObj.drawRect(0, 0, x + w + cr, cr * 2) - this.sliderObj.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha) + this.sliderObj.lineStyle( + this.opts.strokeWidth, + this.opts.stroke, + this.opts.strokeAlpha + ) this.sliderObj.beginFill(this.opts.fill, this.opts.fillAlpha) this.sliderObj.moveTo(x, y) this.sliderObj.lineTo(x + w, y) this.sliderObj.arcTo(x + w + r, y, x + w + r, y + r, r) - this.sliderObj.lineTo(x + w + r, y + r + 1) // BUGFIX: If not specified, there is a small area without a stroke. + this.sliderObj.lineTo(x + w + r, y + r + 1) // BUGFIX: If not specified, there is a small area without a stroke. this.sliderObj.arcTo(x + w + r, y + h, x + w, y + h, r) this.sliderObj.lineTo(x, y + h) this.sliderObj.arcTo(x - r, y + h, x - r, y + r, r) @@ -1766,10 +1783,20 @@ export default class Slider extends PIXI.Container { // Draw control this.control.clear() - this.control.lineStyle(this.opts.controlStrokeWidth, this.opts.controlStroke, this.opts.controlStrokeAlpha) - this.control.beginFill(this.opts.controlFill, this.opts.controlFillAlpha) + this.control.lineStyle( + this.opts.controlStrokeWidth, + this.opts.controlStroke, + this.opts.controlStrokeAlpha + ) + this.control.beginFill( + this.opts.controlFill, + this.opts.controlFillAlpha + ) this.control.drawCircle(0, 0, cr - 1) - this.control.beginFill(this.opts.controlStroke, this.opts.controlStrokeAlpha) + this.control.beginFill( + this.opts.controlStroke, + this.opts.controlStrokeAlpha + ) this.control.drawCircle(0, 0, cr / 6) this.control.endFill() @@ -1778,12 +1805,11 @@ export default class Slider extends PIXI.Container { /** * Executed, when the slider control movement ended. - * + * * @private * @return {Slider} A reference to the slider for chaining. */ onEnd(e) { - if (this.control.dragging) { this.control.event = null this.control.dragging = false @@ -1797,9 +1823,9 @@ export default class Slider extends PIXI.Container { /** * Calculates the value for a given pixel. - * + * * @private - * @param {number} value + * @param {number} value * @returns {number} The calucalted pixel. */ valueToPixel(value) { @@ -1808,14 +1834,17 @@ export default class Slider extends PIXI.Container { } else if (value > this.opts.max) { value = this.opts.max } - return this.opts.width * (value - this.opts.min) / (this.opts.max - this.opts.min) + return ( + (this.opts.width * (value - this.opts.min)) / + (this.opts.max - this.opts.min) + ) } /** * Calculates the pixel for a given value. - * + * * @private - * @param {number} pixel + * @param {number} pixel * @returns {number} The calucalted value. */ pixelToValue(pixel) { @@ -1824,12 +1853,15 @@ export default class Slider extends PIXI.Container { } else if (pixel > this.opts.width) { pixel = this.opts.width } - return this.opts.min + ((this.opts.max - this.opts.min) * pixel / this.opts.width) + return ( + this.opts.min + + ((this.opts.max - this.opts.min) * pixel) / this.opts.width + ) } - + /** * Gets or sets the value. - * + * * @member {number} */ get value() { @@ -1845,27 +1877,26 @@ export default class Slider extends PIXI.Container { const x = this.valueToPixel(value) + this.opts.controlRadius - TweenLite.to(this.control, this.theme.fast, {x}) + TweenLite.to(this.control, this.theme.fast, { x }) } - + /** * Gets or sets the disabled state. When disabled, the slider cannot be clicked. - * + * * @member {boolean} */ get disabled() { return this._disabled } set disabled(value) { - this._disabled = value - + if (this._disabled) { this.interactive = false this.sliderObj.interactive = false this.control.interactive = false this.control.buttonMode = false - this.alpha = .5 + this.alpha = 0.5 } else { this.interactive = true this.sliderObj.interactive = true @@ -1877,11 +1908,10 @@ export default class Slider extends PIXI.Container { /** * Shows the slider (sets his alpha values to 1). - * + * * @return {Slider} A reference to the slider for chaining. */ show() { - this.opts.strokeAlpha = 1 this.opts.fillAlpha = 1 this.opts.controlStrokeAlpha = 1 @@ -1891,14 +1921,13 @@ export default class Slider extends PIXI.Container { return this } - + /** * Hides the slider (sets his alpha values to 1). - * + * * @return {Slider} A reference to the slider for chaining. */ hide() { - this.opts.strokeAlpha = 0 this.opts.fillAlpha = 0 this.opts.controlStrokeAlpha = 0 @@ -1922,7 +1951,7 @@ export default class Slider extends PIXI.Container {
diff --git a/doc/out/pixi_switch.js.html b/doc/out/pixi_switch.js.html index b3c5c5c..8f0ffe6 100644 --- a/doc/out/pixi_switch.js.html +++ b/doc/out/pixi_switch.js.html @@ -1475,7 +1475,7 @@ import Tooltip from './tooltip.js' /** * Class that represents a PixiJS Switch. - * + * * @example * // Create the app * const app = new PIXIApp({ @@ -1483,7 +1483,7 @@ import Tooltip from './tooltip.js' * width: 900, * height: 250 * }).setup().run() - * + * * // Create the switch * const switch1 = new Switch({ * x: 10, @@ -1499,10 +1499,9 @@ import Tooltip from './tooltip.js' * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/switch.html|DocTest} */ export default class Switch extends PIXI.Container { - /** * Creates an instance of a Switch. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the switch. * @param {number} [opts.id=auto generated] - The id of the switch. @@ -1542,56 +1541,61 @@ export default class Switch extends PIXI.Container { * @param {beforeActionCallback} [opts.beforeAction] - Executed before an action is triggered. * @param {afterActionCallback} [opts.afterAction] - Executed after an action was triggered. * @param {string|object} [opts.tooltip] - A string for the label of the tooltip or an object to configure the tooltip - * to display. + * to display. * @param {boolean} [opts.visible=true] - Is the switch initially visible (property visible)? */ constructor(opts = {}) { - super() - + const theme = Theme.fromString(opts.theme) this.theme = theme - this.opts = Object.assign({}, { - id: PIXI.utils.uid(), - x: 0, - y: 0, - width: 44, - height: 28, - fill: theme.fill, - fillAlpha: theme.fillAlpha, - fillActive: theme.primaryColor, - fillActiveAlpha: theme.fillActiveAlpha, - stroke: theme.stroke, - strokeWidth: theme.strokeWidth, - strokeAlpha: theme.strokeAlpha, - strokeActive: theme.primaryColor, - strokeActiveWidth: theme.strokeActiveWidth, - strokeActiveAlpha: theme.strokeActiveAlpha, - controlFill: theme.stroke, - controlFillAlpha: theme.strokeAlpha, - controlFillActive: theme.stroke, - controlFillActiveAlpha: theme.strokeAlpha, - controlStroke: theme.stroke, - controlStrokeWidth: theme.strokeWidth * .8, - controlStrokeAlpha: theme.strokeAlpha, - controlStrokeActive: theme.stroke, - controlStrokeActiveWidth: theme.strokeActiveWidth * .8, - controlStrokeActiveAlpha: theme.strokeActiveAlpha, - duration: theme.fast, - durationActive: theme.fast, - disabled: false, - active: false, - action: null, - actionActive: null, - beforeAction: null, - afterAction: null, - tooltip: null, - visible: true - }, opts) + this.opts = Object.assign( + {}, + { + id: PIXI.utils.uid(), + x: 0, + y: 0, + width: 44, + height: 28, + fill: theme.fill, + fillAlpha: theme.fillAlpha, + fillActive: theme.primaryColor, + fillActiveAlpha: theme.fillActiveAlpha, + stroke: theme.stroke, + strokeWidth: theme.strokeWidth, + strokeAlpha: theme.strokeAlpha, + strokeActive: theme.primaryColor, + strokeActiveWidth: theme.strokeActiveWidth, + strokeActiveAlpha: theme.strokeActiveAlpha, + controlFill: theme.stroke, + controlFillAlpha: theme.strokeAlpha, + controlFillActive: theme.stroke, + controlFillActiveAlpha: theme.strokeAlpha, + controlStroke: theme.stroke, + controlStrokeWidth: theme.strokeWidth * 0.8, + controlStrokeAlpha: theme.strokeAlpha, + controlStrokeActive: theme.stroke, + controlStrokeActiveWidth: theme.strokeActiveWidth * 0.8, + controlStrokeActiveAlpha: theme.strokeActiveAlpha, + duration: theme.fast, + durationActive: theme.fast, + disabled: false, + active: false, + action: null, + actionActive: null, + beforeAction: null, + afterAction: null, + tooltip: null, + visible: true + }, + opts + ) - this.opts.controlRadius = this.opts.controlRadius || (this.opts.height / 2) - this.opts.controlRadiusActive = this.opts.controlRadiusActive || this.opts.controlRadius + this.opts.controlRadius = + this.opts.controlRadius || this.opts.height / 2 + this.opts.controlRadiusActive = + this.opts.controlRadiusActive || this.opts.controlRadius // Validation //----------------- @@ -1610,7 +1614,7 @@ export default class Switch extends PIXI.Container { this.switchObj = null this.control = null this.tooltip = null - + this.visible = this.opts.visible // animated @@ -1637,15 +1641,14 @@ export default class Switch extends PIXI.Container { //----------------- this.layout() } - + /** * Creates children and instantiates everything. - * + * * @private * @return {Switch} A reference to the switch for chaining. */ setup() { - // Switch //----------------- let switchObj = new PIXI.Graphics() @@ -1656,7 +1659,7 @@ export default class Switch extends PIXI.Container { //----------------- this.xInactive = this.opts.controlRadius this.xActive = this.opts.width - this.opts.controlRadiusActive - + let control = new PIXI.Graphics() control.x = this.opts.active ? this.xActive : this.xInactive control.y = this.opts.height / 2 @@ -1664,23 +1667,22 @@ export default class Switch extends PIXI.Container { this.control = control this.addChild(this.control) - + // interaction //----------------- this.switchObj.on('pointerover', e => { - TweenLite.to(this.control, this.theme.fast, {alpha: .83}) + TweenLite.to(this.control, this.theme.fast, { alpha: 0.83 }) }) this.switchObj.on('pointerout', e => { - TweenLite.to(this.control, this.theme.fast, {alpha: 1}) + TweenLite.to(this.control, this.theme.fast, { alpha: 1 }) }) this.switchObj.on('pointerdown', e => { - TweenLite.to(this.control, this.theme.fast, {alpha: .7}) + TweenLite.to(this.control, this.theme.fast, { alpha: 0.7 }) }) this.switchObj.on('pointerup', e => { - if (this.opts.beforeAction) { this.opts.beforeAction.call(this, e, this) } @@ -1697,7 +1699,7 @@ export default class Switch extends PIXI.Container { } } - TweenLite.to(this.control, this.theme.fast, {alpha: .83}) + TweenLite.to(this.control, this.theme.fast, { alpha: 0.83 }) if (this.opts.afterAction) { this.opts.afterAction.call(this, e, this) @@ -1711,7 +1713,7 @@ export default class Switch extends PIXI.Container { // active //----------------- this.active = this.opts.active - + // tooltip //----------------- if (this.opts.tooltip) { @@ -1728,14 +1730,13 @@ export default class Switch extends PIXI.Container { return this } - + /** * Should be called to refresh the layout of the switch. Can be used after resizing. - * + * * @return {Switch} A reference to the switch for chaining. */ layout() { - // set position //----------------- this.position.set(this.opts.x, this.opts.y) @@ -1746,28 +1747,50 @@ export default class Switch extends PIXI.Container { return this } - + /** * Draws the switch to the canvas. - * + * * @private * @return {Switch} A reference to the switch for chaining. */ draw() { - this.switchObj.clear() if (this.active) { - this.switchObj.lineStyle(this.opts.strokeActiveWidth, this.opts.strokeActive, this.opts.strokeActiveAlpha) - this.switchObj.beginFill(this.opts.fillActive, this.opts.fillActiveAlpha) + this.switchObj.lineStyle( + this.opts.strokeActiveWidth, + this.opts.strokeActive, + this.opts.strokeActiveAlpha + ) + this.switchObj.beginFill( + this.opts.fillActive, + this.opts.fillActiveAlpha + ) } else { - this.switchObj.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha) + this.switchObj.lineStyle( + this.opts.strokeWidth, + this.opts.stroke, + this.opts.strokeAlpha + ) this.switchObj.beginFill(this.opts.fill, this.opts.fillAlpha) } this.switchObj.moveTo(this.radius, 0) this.switchObj.lineTo(this.opts.width - this.radius, 0) - this.switchObj.arcTo(this.opts.width, 0, this.opts.width, this.radius, this.radius) - this.switchObj.lineTo(this.opts.width, this.radius + 1) // BUGFIX: If not specified, there is a small area without a stroke. - this.switchObj.arcTo(this.opts.width, this.opts.height, this.opts.width - this.radius, this.opts.height, this.radius) + this.switchObj.arcTo( + this.opts.width, + 0, + this.opts.width, + this.radius, + this.radius + ) + this.switchObj.lineTo(this.opts.width, this.radius + 1) // BUGFIX: If not specified, there is a small area without a stroke. + this.switchObj.arcTo( + this.opts.width, + this.opts.height, + this.opts.width - this.radius, + this.opts.height, + this.radius + ) this.switchObj.lineTo(this.radius, this.opts.height) this.switchObj.arcTo(0, this.opts.height, 0, this.radius, this.radius) this.switchObj.arcTo(0, 0, this.radius, 0, this.radius) @@ -1776,52 +1799,91 @@ export default class Switch extends PIXI.Container { // Draw control this.control.clear() if (this.active) { - this.control.lineStyle(this.opts.controlStrokeActiveWidth, this.opts.controlStrokeActive, this.opts.controlStrokeActiveAlpha) - this.control.beginFill(this.opts.controlFillActive, this.opts.controlFillActiveAlpha) + this.control.lineStyle( + this.opts.controlStrokeActiveWidth, + this.opts.controlStrokeActive, + this.opts.controlStrokeActiveAlpha + ) + this.control.beginFill( + this.opts.controlFillActive, + this.opts.controlFillActiveAlpha + ) this.control.drawCircle(0, 0, this.opts.controlRadiusActive - 1) } else { - this.control.lineStyle(this.opts.controlStrokeWidth, this.opts.controlStroke, this.opts.controlStrokeAlpha) - this.control.beginFill(this.opts.controlFill, this.opts.controlFillAlpha) + this.control.lineStyle( + this.opts.controlStrokeWidth, + this.opts.controlStroke, + this.opts.controlStrokeAlpha + ) + this.control.beginFill( + this.opts.controlFill, + this.opts.controlFillAlpha + ) this.control.drawCircle(0, 0, this.opts.controlRadius - 1) } this.control.endFill() return this } - + /** * Draws the animation. - * + * * @private * @return {Switch} A reference to the switch for chaining. */ drawAnimated() { - this.switchObj.clear() - this.switchObj.lineStyle(this.tempAnimated.strokeWidth, this.tempAnimated.stroke, this.tempAnimated.strokeAlpha) - this.switchObj.beginFill(this.tempAnimated.fill, this.tempAnimated.fillAlpha) + this.switchObj.lineStyle( + this.tempAnimated.strokeWidth, + this.tempAnimated.stroke, + this.tempAnimated.strokeAlpha + ) + this.switchObj.beginFill( + this.tempAnimated.fill, + this.tempAnimated.fillAlpha + ) this.switchObj.moveTo(this.radius, 0) this.switchObj.lineTo(this.opts.width - this.radius, 0) - this.switchObj.arcTo(this.opts.width, 0, this.opts.width, this.radius, this.radius) - this.switchObj.lineTo(this.opts.width, this.radius + 1) // BUGFIX: If not specified, there is a small area without a stroke. - this.switchObj.arcTo(this.opts.width, this.opts.height, this.opts.width - this.radius, this.opts.height, this.radius) + this.switchObj.arcTo( + this.opts.width, + 0, + this.opts.width, + this.radius, + this.radius + ) + this.switchObj.lineTo(this.opts.width, this.radius + 1) // BUGFIX: If not specified, there is a small area without a stroke. + this.switchObj.arcTo( + this.opts.width, + this.opts.height, + this.opts.width - this.radius, + this.opts.height, + this.radius + ) this.switchObj.lineTo(this.radius, this.opts.height) this.switchObj.arcTo(0, this.opts.height, 0, this.radius, this.radius) this.switchObj.arcTo(0, 0, this.radius, 0, this.radius) this.switchObj.endFill() this.control.clear() - this.control.lineStyle(this.tempAnimated.controlStrokeWidth, this.tempAnimated.controlStroke, this.tempAnimated.controlStrokeAlpha) - this.control.beginFill(this.tempAnimated.controlFill, this.tempAnimated.controlFillAlpha) + this.control.lineStyle( + this.tempAnimated.controlStrokeWidth, + this.tempAnimated.controlStroke, + this.tempAnimated.controlStrokeAlpha + ) + this.control.beginFill( + this.tempAnimated.controlFill, + this.tempAnimated.controlFillAlpha + ) this.control.drawCircle(0, 0, this.tempAnimated.controlRadius - 1) this.control.endFill() return this } - + /** * Gets or sets the active state. - * + * * @member {boolean} */ get active() { @@ -1829,12 +1891,10 @@ export default class Switch extends PIXI.Container { } set active(value) { - this._active = value if (this._active) { - - TweenLite.to(this.control, this.opts.duration, {x: this.xActive}) + TweenLite.to(this.control, this.opts.duration, { x: this.xActive }) TweenLite.to(this.tempAnimated, this.opts.duration, { colorProps: { fill: this.opts.fillActive, @@ -1853,10 +1913,10 @@ export default class Switch extends PIXI.Container { onUpdate: () => this.drawAnimated(), onComplete: () => this.draw() }) - - } else { - TweenLite.to(this.control, this.opts.durationActive, {x: this.xInactive}) + TweenLite.to(this.control, this.opts.durationActive, { + x: this.xInactive + }) TweenLite.to(this.tempAnimated, this.opts.durationActive, { colorProps: { fill: this.opts.fill, @@ -1877,10 +1937,10 @@ export default class Switch extends PIXI.Container { }) } } - + /** * Gets or sets the disabled state. When disabled, the switch cannot be clicked. - * + * * @member {boolean} */ get disabled() { @@ -1888,14 +1948,13 @@ export default class Switch extends PIXI.Container { } set disabled(value) { - this._disabled = value - + if (this._disabled) { this.switchObj.interactive = false this.switchObj.buttonMode = false - this.switchObj.alpha = .5 - this.control.alpha = .5 + this.switchObj.alpha = 0.5 + this.control.alpha = 0.5 } else { this.switchObj.interactive = true this.switchObj.buttonMode = true @@ -1906,11 +1965,10 @@ export default class Switch extends PIXI.Container { /** * Shows the switch (sets his alpha values to 1). - * + * * @return {Switch} A reference to the switch for chaining. */ show() { - this.opts.strokeAlpha = 1 this.opts.strokeActiveAlpha = 1 this.opts.fillAlpha = 1 @@ -1924,14 +1982,13 @@ export default class Switch extends PIXI.Container { return this } - + /** * Hides the switch (sets his alpha values to 1). - * + * * @return {Switch} A reference to the switch for chaining. */ hide() { - this.opts.strokeAlpha = 0 this.opts.strokeActiveAlpha = 0 this.opts.fillAlpha = 0 @@ -1959,7 +2016,7 @@ export default class Switch extends PIXI.Container {
diff --git a/doc/out/pixi_theme.js.html b/doc/out/pixi_theme.js.html index 213871b..0c6d67a 100644 --- a/doc/out/pixi_theme.js.html +++ b/doc/out/pixi_theme.js.html @@ -1471,7 +1471,6 @@ * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/theme.html|DocTest} */ export default class Theme { - /** * Creates an instance of a Theme. * @@ -1521,52 +1520,86 @@ export default class Theme { * is used for large actived text. */ constructor(opts = {}) { + const colorPrimary = + opts.primaryColor != null ? opts.primaryColor : 0x5ec7f8 // blue + const color1 = opts.color1 != null ? opts.color1 : 0x282828 // black + const color2 = opts.color2 != null ? opts.color2 : 0xf6f6f6 // white - const colorPrimary = opts.primaryColor != null ? opts.primaryColor : 0x5ec7f8 // blue - const color1 = opts.color1 != null ? opts.color1 : 0x282828 // black - const color2 = opts.color2 != null ? opts.color2 : 0xf6f6f6 // white - - this.opts = Object.assign({}, { - margin: 12, - padding: 12, - radius: 4, - fast: .25, - normal: .5, - slow: 1, - primaryColor: colorPrimary, - color1: color1, - color2: color2, - fill: color1, - fillAlpha: 1, - fillActive: color1, - fillActiveAlpha: 1, - stroke: color2, - strokeWidth: .6, - strokeAlpha: 1, - strokeActive: color2, - strokeActiveWidth: .6, - strokeActiveAlpha: 1, - iconColor: color2, - iconColorActive: colorPrimary, - background: color1 - }, opts) + this.opts = Object.assign( + {}, + { + margin: 12, + padding: 12, + radius: 4, + fast: 0.25, + normal: 0.5, + slow: 1, + primaryColor: colorPrimary, + color1: color1, + color2: color2, + fill: color1, + fillAlpha: 1, + fillActive: color1, + fillActiveAlpha: 1, + stroke: color2, + strokeWidth: 0.6, + strokeAlpha: 1, + strokeActive: color2, + strokeActiveWidth: 0.6, + strokeActiveAlpha: 1, + iconColor: color2, + iconColorActive: colorPrimary, + background: color1 + }, + opts + ) // Set textStyle and variants - this.opts.textStyle = Object.assign({}, { - fontFamily: '"Avenir Next", "Open Sans", "Segoe UI", "Roboto", "Helvetica Neue", -apple-system, system-ui, BlinkMacSystemFont, Arial, sans-serif !default', - fontWeight: '500', - fontSize: 18, - fill: color2, - stroke: color1, - strokeThickness: 0, - miterLimit: 1, - lineJoin: 'round' - }, this.opts.textStyle) - this.opts.textStyleSmall = Object.assign({}, this.opts.textStyle, {fontSize: this.opts.textStyle.fontSize - 3}, this.opts.textStyleSmall) - this.opts.textStyleLarge = Object.assign({}, this.opts.textStyle, {fontSize: this.opts.textStyle.fontSize + 3}, this.opts.textStyleLarge) - this.opts.textStyleActive = Object.assign({}, this.opts.textStyle, {fill: this.opts.primaryColor}, this.opts.textStyleActive) - this.opts.textStyleSmallActive = Object.assign({}, this.opts.textStyleSmall, {fill: this.opts.primaryColor}, this.opts.textStyleSmallActive) - this.opts.textStyleLargeActive = Object.assign({}, this.opts.textStyleLarge, {fill: this.opts.primaryColor}, this.opts.textStyleLargeActive) + this.opts.textStyle = Object.assign( + {}, + { + fontFamily: + '"Avenir Next", "Open Sans", "Segoe UI", "Roboto", "Helvetica Neue", -apple-system, system-ui, BlinkMacSystemFont, Arial, sans-serif !default', + fontWeight: '500', + fontSize: 18, + fill: color2, + stroke: color1, + strokeThickness: 0, + miterLimit: 1, + lineJoin: 'round' + }, + this.opts.textStyle + ) + this.opts.textStyleSmall = Object.assign( + {}, + this.opts.textStyle, + { fontSize: this.opts.textStyle.fontSize - 3 }, + this.opts.textStyleSmall + ) + this.opts.textStyleLarge = Object.assign( + {}, + this.opts.textStyle, + { fontSize: this.opts.textStyle.fontSize + 3 }, + this.opts.textStyleLarge + ) + this.opts.textStyleActive = Object.assign( + {}, + this.opts.textStyle, + { fill: this.opts.primaryColor }, + this.opts.textStyleActive + ) + this.opts.textStyleSmallActive = Object.assign( + {}, + this.opts.textStyleSmall, + { fill: this.opts.primaryColor }, + this.opts.textStyleSmallActive + ) + this.opts.textStyleLargeActive = Object.assign( + {}, + this.opts.textStyleLarge, + { fill: this.opts.primaryColor }, + this.opts.textStyleLargeActive + ) Object.assign(this, this.opts) } @@ -1579,7 +1612,6 @@ export default class Theme { * @return {Theme} Returns a newly created Theme object. */ static fromString(theme) { - if (theme && typeof theme === 'object') { return theme } @@ -1611,9 +1643,7 @@ export default class Theme { * @extends Theme * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/theme.html|DocTest} */ -export class ThemeDark extends Theme { - -} +export class ThemeDark extends Theme {} /** * Class that represents a PixiJS ThemeLight. @@ -1633,15 +1663,13 @@ export class ThemeDark extends Theme { * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/theme.html|DocTest} */ export class ThemeLight extends Theme { - /** * Creates an instance of a ThemeLight. * * @constructor */ constructor() { - - super({color1: 0xf6f6f6, color2: 0x282828}) + super({ color1: 0xf6f6f6, color2: 0x282828 }) } } @@ -1663,15 +1691,13 @@ export class ThemeLight extends Theme { * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/theme.html|DocTest} */ export class ThemeRed extends Theme { - /** * Creates an instance of a ThemeRed. * * @constructor */ constructor() { - - super({primaryColor: 0xd92f31}) + super({ primaryColor: 0xd92f31 }) } }
@@ -1687,7 +1713,7 @@ export class ThemeRed extends Theme {
diff --git a/doc/out/pixi_tooltip.js.html b/doc/out/pixi_tooltip.js.html index 2002845..b880d59 100644 --- a/doc/out/pixi_tooltip.js.html +++ b/doc/out/pixi_tooltip.js.html @@ -1443,7 +1443,7 @@ import AbstractPopup from './abstractpopup.js' /** * Class that represents a PixiJS Tooltip. - * + * * @example * // Create the app * const app = new PIXIApp({ @@ -1451,13 +1451,13 @@ import AbstractPopup from './abstractpopup.js' * width: 900, * height: 250 * }).setup().run() - * + * * // Add an DisplayObject to the app * const circle = new PIXI.Graphics() * circle.beginFill(0x5251a3) * circle.drawCircle(50, 50, 40) * app.scene.addChild(circle) - * + * * const tooltip = new Tooltip({ * object: circle, * container: app.scene, @@ -1469,10 +1469,9 @@ import AbstractPopup from './abstractpopup.js' * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/tooltip.html|DocTest} */ export default class Tooltip extends AbstractPopup { - /** * Creates an instance of a Tooltip. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the tooltip. * @param {number} [opts.minWidth=0] - The minimum width of the tooltip. @@ -1485,19 +1484,22 @@ export default class Tooltip extends AbstractPopup { * @param {number} [opts.delay=0] - A delay, after which the tooltip should be opened. */ constructor(opts = {}) { - const theme = Theme.fromString(opts.theme) - - opts = Object.assign({}, { - minWidth: 0, - minHeight: 0, - padding: theme.padding / 2, - object: null, - container: null, - offsetLeft: 8, - offsetTop: -8, - delay: 0 - }, opts) + + opts = Object.assign( + {}, + { + minWidth: 0, + minHeight: 0, + padding: theme.padding / 2, + object: null, + container: null, + offsetLeft: 8, + offsetTop: -8, + delay: 0 + }, + opts + ) opts.container = opts.container || opts.object @@ -1511,15 +1513,14 @@ export default class Tooltip extends AbstractPopup { //----------------- this.layout() } - + /** * Creates children and instantiates everything. - * + * * @private * @return {Tooltip} A reference to the tooltip for chaining. */ setup() { - super.setup() // bind events this @@ -1527,7 +1528,7 @@ export default class Tooltip extends AbstractPopup { this.interactive = true let mouseoverTooltip = false - + this.on('mouseover', e => { mouseoverTooltip = true }) @@ -1540,7 +1541,7 @@ export default class Tooltip extends AbstractPopup { }) } }) - + // bind events object //----------------- const object = this.opts.object @@ -1549,7 +1550,6 @@ export default class Tooltip extends AbstractPopup { let mouseoverObject = false object.on('mouseover', e => { - this.timeout = window.setTimeout(() => { mouseoverObject = true this.visible = true @@ -1576,15 +1576,14 @@ export default class Tooltip extends AbstractPopup { return this } - + /** * Calculates and sets the position of the tooltip. - * + * * @private * @return {Tooltip} A reference to the tooltip for chaining. */ setPosition(e) { - const position = e.data.getLocalPosition(this.opts.container) this.x = position.x + this.opts.offsetLeft @@ -1606,7 +1605,7 @@ export default class Tooltip extends AbstractPopup {
diff --git a/doc/out/pixi_volatile.js.html b/doc/out/pixi_volatile.js.html index ee775f9..f8d7566 100644 --- a/doc/out/pixi_volatile.js.html +++ b/doc/out/pixi_volatile.js.html @@ -1444,14 +1444,14 @@ import Theme from './theme.js' /** * Class that represents a PixiJS Volatile. - * + * * @example * const app = new PIXIApp({ * view: canvas, * width: 900, * height: 250 * }).setup().run() - * + * * const button = new Button({ * label: 'Volatile!', * action: () => { @@ -1462,17 +1462,16 @@ import Theme from './theme.js' * }) * } * }) - * + * * app.scene.addChild(button) * * @class * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/volatile.html|DocTest} */ export default class Volatile { - /** * Creates an instance of a Volatile. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the modal. * @param {number} [opts.id=auto generated] - The id of the tooltip. @@ -1486,21 +1485,24 @@ export default class Volatile { * @param {boolean} [opts.destroyOnComplete=true] - Should the object be destroyed after the volatile animation? */ constructor(opts = {}) { - const theme = Theme.fromString(opts.theme) this.theme = theme - this.opts = Object.assign({}, { - id: PIXI.utils.uid(), - object: null, - direction: 'top', // top, right, bottom, left - onStart: null, - onComplete: null, - distance: 160, - duration: 1.5, - ease: Quad.easeOut, - destroyOnComplete: true - }, opts) + this.opts = Object.assign( + {}, + { + id: PIXI.utils.uid(), + object: null, + direction: 'top', // top, right, bottom, left + onStart: null, + onComplete: null, + distance: 160, + duration: 1.5, + ease: Quad.easeOut, + destroyOnComplete: true + }, + opts + ) this.id = this.opts.id @@ -1522,38 +1524,34 @@ export default class Volatile { //----------------- this.run() } - + /** * Creates children and instantiates everything. - * + * * @private * @return {Volatile} A reference to the volatile for chaining. */ setup() { - return this } - + /** * Should be called to refresh the layout of the volatile. Can be used after resizing. - * + * * @return {Volatile} A reference to the volatile for chaining. */ layout() { - return this } - + /** * Starts the volatile animation. - * + * * @private * @return {Volatile} A reference to the volatile for chaining. */ run() { - for (let object of this.objects) { - let x = object.x let y = object.y @@ -1584,13 +1582,12 @@ export default class Volatile { } }, onComplete: () => { - if (this.opts.onComplete) { this.opts.onComplete.call(object, object) } if (this.opts.destroyOnComplete) { - object.destroy({children: true}) + object.destroy({ children: true }) } } }) @@ -1612,7 +1609,7 @@ export default class Volatile {
diff --git a/doc/out/uitest.js.html b/doc/out/uitest.js.html index 306ffae..01e3689 100644 --- a/doc/out/uitest.js.html +++ b/doc/out/uitest.js.html @@ -1456,7 +1456,7 @@ * * // Add an action to the test case * test.tap(button, {eventType: 'click'}) - * + * * // Start the test case * test.start() * @@ -1464,10 +1464,9 @@ * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/uitest.html|DocTest} */ export default class UITest { - /** * Creates an instance of an UITest. - * + * * In the background, the class UITest uses the Greensock TimelineMax class. The opts object is passed directly to the TimelineMax class, so it can use any key that uses the TimelineMax class. * * @constructor @@ -1478,19 +1477,28 @@ export default class UITest { * @param {number} [opts.defaultInterval] - The interval used when no action is specified for an action. */ constructor(opts = {}) { - - this.opts = Object.assign({}, { - timeScale: 1, - eventType: 'auto', - debug: false, - defaultInterval: null - }, opts) + this.opts = Object.assign( + {}, + { + timeScale: 1, + eventType: 'auto', + debug: false, + defaultInterval: null + }, + opts + ) // timeline //-------------------- - this._timeline = new TimelineMax(Object.assign({}, { - paused: true - }, this.opts)) + this._timeline = new TimelineMax( + Object.assign( + {}, + { + paused: true + }, + this.opts + ) + ) this._timeline.timeScale(this.opts.timeScale) // eventType @@ -1558,7 +1566,7 @@ export default class UITest { /** * Clears all instructions of the test case. - * + * * @return {UITest} A reference to the UITest for chaining. */ clear() { @@ -1568,7 +1576,7 @@ export default class UITest { /** * Restarts the test case. - * + * * @return {UITest} A reference to the UITest for chaining. */ restart() { @@ -1578,7 +1586,7 @@ export default class UITest { /** * Executes a tap event (pointerdown, pointerup) on a specific element. - * + * * @param {HTMLElement|string} element - The HTML element on which the event is to be executed, e.g. button, document, h2, canvas, etc. or an selector string. If a selector has been specified, it is evaluated immediately before the event is called using the querySelector method. * @param {number[]|object|PIXI.DisplayObject} [position=The center of the element.] - The local position of the event in the context of the specified HTML element. If no position is specified, the center of the HTML element is used. The position can be specified as an array of numbers, as an object with the two properties x and y, or as a PIXI.Display object. * @param {number} [timelinePosition=One second after the last action.] - The position in seconds when the event should be triggered, see shttps://greensock.com/docs/TimelineMax/addCallback(). @@ -1592,91 +1600,118 @@ export default class UITest { * @param {boolean} [opts.cancelable=true] - Events' cancelable property indicates if the event can be canceled, and therefore prevented as if the event never happened. If the event is not cancelable, then its cancelable property will be false and the event listener cannot stop the event from occurring. */ tap(element, position, timelinePosition, opts = {}) { - // arguments //-------------------- - [position, timelinePosition, opts] = this.reorderArguments(arguments) + ;[position, timelinePosition, opts] = this.reorderArguments(arguments) this._timelinePositions.push(timelinePosition) // debug //-------------------- - if (this.opts.debug) console.log('tap params', {element, position, timelinePosition, opts}) + if (this.opts.debug) + console.log('tap params', { + element, + position, + timelinePosition, + opts + }) // opts //-------------------- - opts = Object.assign({}, { - onStart: null, - onComplete: null, - eventTypes: this.resolveEvents(['down', 'up']), - eventType: null, - context: window, - bubbles: true, - cancelable: true - }, opts) + opts = Object.assign( + {}, + { + onStart: null, + onComplete: null, + eventTypes: this.resolveEvents(['down', 'up']), + eventType: null, + context: window, + bubbles: true, + cancelable: true + }, + opts + ) if (opts.eventType) { opts.eventTypes = opts.eventType } - opts.eventTypes = Array.isArray(opts.eventTypes) ? opts.eventTypes : [opts.eventTypes] + opts.eventTypes = Array.isArray(opts.eventTypes) + ? opts.eventTypes + : [opts.eventTypes] // timeline //-------------------- - this._timeline.addCallback(position => { + this._timeline.addCallback( + position => { + // element + //-------------------- + const elem = Util.extractElement(opts.context, element) - // element - //-------------------- - const elem = Util.extractElement(opts.context, element) + // position + //-------------------- + if (position === null) { + const rect = elem.getBoundingClientRect() + position = [rect.width / 2, rect.height / 2] + } - // position - //-------------------- - if (position === null) { - const rect = elem.getBoundingClientRect() - position = [rect.width / 2, rect.height / 2] - } + // coords + //-------------------- + const coords = Util.extractPosition(position) + if (this.opts.debug) console.log('local coords', coords) - // coords - //-------------------- - const coords = Util.extractPosition(position) - if (this.opts.debug) console.log('local coords', coords) + // eventTypes + //-------------------- + if (opts.eventTypes.length === 1) { + opts.eventTypes.unshift(null) + } - // eventTypes - //-------------------- - if (opts.eventTypes.length === 1) { - opts.eventTypes.unshift(null) - } + // event opts + //-------------------- + const eventOpts = { + bubbles: opts.bubbles, + cancelable: opts.cancelable + } - // event opts - //-------------------- - const eventOpts = {bubbles: opts.bubbles, cancelable: opts.cancelable} + if (opts.eventTypes[0]) { + // create and dispatch event + //-------------------- + const eventStart = Event.create( + elem, + coords, + opts.eventTypes[0], + eventOpts + ) + if (this.opts.debug) + console.log('dispatch event', eventStart) + elem.dispatchEvent(eventStart) - if (opts.eventTypes[0]) { + // onStart + //-------------------- + if (opts.onStart) { + opts.onStart.call(this, eventStart) + } + } // create and dispatch event //-------------------- - const eventStart = Event.create(elem, coords, opts.eventTypes[0], eventOpts) - if (this.opts.debug) console.log('dispatch event', eventStart) - elem.dispatchEvent(eventStart) + const eventComplete = Event.create( + elem, + coords, + opts.eventTypes[1], + eventOpts + ) + if (this.opts.debug) + console.log('dispatch event', eventComplete) + elem.dispatchEvent(eventComplete) - // onStart + // onComplete //-------------------- - if (opts.onStart) { - opts.onStart.call(this, eventStart) + if (opts.onComplete) { + opts.onComplete.call(this, eventComplete) } - } - - // create and dispatch event - //-------------------- - const eventComplete = Event.create(elem, coords, opts.eventTypes[1], eventOpts) - if (this.opts.debug) console.log('dispatch event', eventComplete) - elem.dispatchEvent(eventComplete) - - // onComplete - //-------------------- - if (opts.onComplete) { - opts.onComplete.call(this, eventComplete) - } - - }, timelinePosition, [position]) + }, + timelinePosition, + [position] + ) this._actions++ @@ -1685,7 +1720,7 @@ export default class UITest { /** * Executes a pan event (pointerdown, pointermove, pointerup) on a specific element. - * + * * @param {HTMLElement|string} element - The HTML element on which the event is to be executed, e.g. button, document, h2, canvas, etc. or an selector string. If a selector has been specified, it is evaluated immediately before the event is called using the querySelector method. * @param {number[]|object|PIXI.DisplayObject} [position=The center of the element.] - The local position of the event in the context of the specified HTML element. If no position is specified, the center of the HTML element is used. The position can be specified as an array of numbers, as an object with the two properties x and y, or as a PIXI.Display object. * @param {number} [timelinePosition=One second after the last action.] - The position in seconds when the event should be triggered, see shttps://greensock.com/docs/TimelineMax/addCallback(). @@ -1702,104 +1737,133 @@ export default class UITest { * @param {boolean} [opts.cancelable=true] - Events' cancelable property indicates if the event can be canceled, and therefore prevented as if the event never happened. If the event is not cancelable, then its cancelable property will be false and the event listener cannot stop the event from occurring. */ pan(element, position, timelinePosition, opts = {}) { - // arguments //-------------------- - [position, timelinePosition, opts] = this.reorderArguments(arguments) + ;[position, timelinePosition, opts] = this.reorderArguments(arguments) this._timelinePositions.push(timelinePosition) // debug //-------------------- - if (this.opts.debug) console.log('tap params', {element, position, timelinePosition, opts}) + if (this.opts.debug) + console.log('tap params', { + element, + position, + timelinePosition, + opts + }) // opts //-------------------- - opts = Object.assign({}, { - onStart: null, - onUpdate: null, - onComplete: null, - to: {x: 0, y: 0}, - duration: 1, - ease: Power0.easeNone, - eventTypes: this.resolveEvents(['down', 'move', 'up']), - context: window, - bubbles: true, - cancelable: true - }, opts) + opts = Object.assign( + {}, + { + onStart: null, + onUpdate: null, + onComplete: null, + to: { x: 0, y: 0 }, + duration: 1, + ease: Power0.easeNone, + eventTypes: this.resolveEvents(['down', 'move', 'up']), + context: window, + bubbles: true, + cancelable: true + }, + opts + ) // timeline //-------------------- - this._timeline.addCallback(position => { + this._timeline.addCallback( + position => { + // element + //-------------------- + const elem = Util.extractElement(opts.context, element) - // element - //-------------------- - const elem = Util.extractElement(opts.context, element) + // coords + //-------------------- + const from = Util.extractPosition(position) - // coords - //-------------------- - const from = Util.extractPosition(position) + // event opts + //-------------------- + const eventOpts = { + bubbles: opts.bubbles, + cancelable: opts.cancelable + } - // event opts - //-------------------- - const eventOpts = {bubbles: opts.bubbles, cancelable: opts.cancelable} + const gsOpts = { + ease: opts.ease, + onStart: () => { + // create and dispatch event + //-------------------- + const event = Event.create( + elem, + from, + opts.eventTypes[0], + eventOpts + ) + if (this.opts.debug) + console.log('dispatch event', event) + elem.dispatchEvent(event) - const gsOpts = { - ease: opts.ease, - onStart: () => { + // onStart + //-------------------- + if (opts.onStart) { + opts.onStart.call(this, event) + } + }, + onUpdate: () => { + // create and dispatch event + //-------------------- + const event = Event.create( + elem, + from, + opts.eventTypes[1], + eventOpts + ) + if (this.opts.debug) + console.log('dispatch event', event) + elem.dispatchEvent(event) - // create and dispatch event - //-------------------- - const event = Event.create(elem, from, opts.eventTypes[0], eventOpts) - if (this.opts.debug) console.log('dispatch event', event) - elem.dispatchEvent(event) + // onUpdate + //-------------------- + if (opts.onUpdate) { + opts.onUpdate.call(this, event) + } + }, + onComplete: () => { + // create and dispatch event + //-------------------- + const event = Event.create( + elem, + from, + opts.eventTypes[2], + eventOpts + ) + if (this.opts.debug) + console.log('dispatch event', event) + elem.dispatchEvent(event) - // onStart - //-------------------- - if (opts.onStart) { - opts.onStart.call(this, event) - } - }, - onUpdate: () => { - - // create and dispatch event - //-------------------- - const event = Event.create(elem, from, opts.eventTypes[1], eventOpts) - if (this.opts.debug) console.log('dispatch event', event) - elem.dispatchEvent(event) - - // onUpdate - //-------------------- - if (opts.onUpdate) { - opts.onUpdate.call(this, event) - } - }, - onComplete: () => { - - // create and dispatch event - //-------------------- - const event = Event.create(elem, from, opts.eventTypes[2], eventOpts) - if (this.opts.debug) console.log('dispatch event', event) - elem.dispatchEvent(event) - - // onComplete - //-------------------- - if (opts.onComplete) { - opts.onComplete.call(this, event) + // onComplete + //-------------------- + if (opts.onComplete) { + opts.onComplete.call(this, event) + } } } - } - // to - //-------------------- - const object = Util.extractTo(opts) - Object.assign(gsOpts, object) + // to + //-------------------- + const object = Util.extractTo(opts) + Object.assign(gsOpts, object) - // drag animation - //-------------------- - TweenLite.to(from, opts.duration, gsOpts) + // drag animation + //-------------------- + TweenLite.to(from, opts.duration, gsOpts) + }, + timelinePosition, + [position] + ) - }, timelinePosition, [position]) - this._actions++ return this @@ -1807,7 +1871,7 @@ export default class UITest { /** * Executes a pinch event (pointerdown, pointermove, pointerup) on a specific element with two "fingers" simultaneously. - * + * * @param {HTMLElement|string} element - The HTML element on which the event is to be executed, e.g. button, document, h2, canvas, etc. or an selector string. If a selector has been specified, it is evaluated immediately before the event is called using the querySelector method. * @param {number[]|object|PIXI.DisplayObject} [position=The center of the element.] - The local position of the event in the context of the specified HTML element. If no position is specified, the center of the HTML element is used. The position can be specified as an array of numbers, as an object with the two properties x and y, or as a PIXI.Display object. * @param {number} [timelinePosition=One second after the last action.] - The position in seconds when the event should be triggered, see shttps://greensock.com/docs/TimelineMax/addCallback(). @@ -1827,145 +1891,184 @@ export default class UITest { * @param {boolean} [opts.cancelable=true] - Events' cancelable property indicates if the event can be canceled, and therefore prevented as if the event never happened. If the event is not cancelable, then its cancelable property will be false and the event listener cannot stop the event from occurring. */ pinch(element, position, timelinePosition, opts = {}) { - // arguments //-------------------- - [position, timelinePosition, opts] = this.reorderArguments(arguments) + ;[position, timelinePosition, opts] = this.reorderArguments(arguments) this._timelinePositions.push(timelinePosition) // debug //-------------------- - if (this.opts.debug) console.log('tap params', {element, position, timelinePosition, opts}) + if (this.opts.debug) + console.log('tap params', { + element, + position, + timelinePosition, + opts + }) // opts //-------------------- - opts = Object.assign({}, { - onStart: null, - onUpdate: null, - onComplete: null, - doubleCallbacks: false, - duration: 1, - distance: 100, - to: null, - bezier: null, - ease: Power0.easeNone, - eventTypes: this.resolveEvents(['down', 'move', 'up']), - context: window, - bubbles: true, - cancelable: true - }, opts) + opts = Object.assign( + {}, + { + onStart: null, + onUpdate: null, + onComplete: null, + doubleCallbacks: false, + duration: 1, + distance: 100, + to: null, + bezier: null, + ease: Power0.easeNone, + eventTypes: this.resolveEvents(['down', 'move', 'up']), + context: window, + bubbles: true, + cancelable: true + }, + opts + ) // timeline //-------------------- - this._timeline.addCallback(position => { - - // element - //-------------------- - const elem = Util.extractElement(opts.context, element) - - // from - //-------------------- - let from1 = null - let from2 = null - - if (Array.isArray(position) && !Util.isNumber(position[0])) { - from1 = Util.extractPosition(position[0]) - from2 = Util.extractPosition(position[1]) - } else { - from1 = Util.extractPosition(position) - from2 = {x: from1.x, y: from1.y} - } - - // to - //-------------------- - let gsOpts1 = {} - let gsOpts2 = {} - - if (opts.to || opts.bezier) { - [gsOpts1, gsOpts2] = Util.extractMultiTo(opts) - } else { - const distance = opts.distance != null ? opts.distance : 100 - gsOpts1.x = from1.x - distance / 2 - gsOpts1.y = from1.y - gsOpts2.x = from2.x + distance / 2 - gsOpts2.y = from2.y - } - - // pointers - //-------------------- - const pointers = new Map() - pointers.set(0, {element: from1, gsOpts: gsOpts1}) - pointers.set(1, {element: from2, gsOpts: gsOpts2}) - - // loop - //-------------------- - pointers.forEach((value, key) => { + this._timeline.addCallback( + position => { + // element + //-------------------- + const elem = Util.extractElement(opts.context, element) // from //-------------------- - const from = value.element + let from1 = null + let from2 = null - // event opts - //-------------------- - const eventOpts = {bubbles: opts.bubbles, cancelable: opts.cancelable, pointerId: key, isPrimary: key === 0} - - const gsOpts = { - ease: opts.ease, - onStart: () => { - - // create and dispatch event - //-------------------- - const event = Event.create(elem, from, opts.eventTypes[0], eventOpts) - if (this.opts.debug) console.log('dispatch event', event) - elem.dispatchEvent(event) - - // onStart - //-------------------- - if (opts.onStart && (opts.doubleCallbacks || key === 0)) { - opts.onStart.call(this, event) - } - }, - onUpdate: () => { - - // create and dispatch event - //-------------------- - const event = Event.create(elem, from, opts.eventTypes[1], eventOpts) - if (this.opts.debug) console.log('dispatch event', event) - elem.dispatchEvent(event) - - // onUpdate - //-------------------- - if (opts.onUpdate && (opts.doubleCallbacks || key === 0)) { - opts.onUpdate.call(this, event) - } - }, - onComplete: () => { - - // create and dispatch event - //-------------------- - const event = Event.create(elem, from, opts.eventTypes[2], eventOpts) - if (this.opts.debug) console.log('dispatch event', event) - elem.dispatchEvent(event) - - // onComplete - //-------------------- - if (opts.onComplete && (opts.doubleCallbacks || key === 0)) { - opts.onComplete.call(this, event) - } - } + if (Array.isArray(position) && !Util.isNumber(position[0])) { + from1 = Util.extractPosition(position[0]) + from2 = Util.extractPosition(position[1]) + } else { + from1 = Util.extractPosition(position) + from2 = { x: from1.x, y: from1.y } } // to //-------------------- - Object.assign(gsOpts, value.gsOpts) + let gsOpts1 = {} + let gsOpts2 = {} - // drag animation + if (opts.to || opts.bezier) { + ;[gsOpts1, gsOpts2] = Util.extractMultiTo(opts) + } else { + const distance = opts.distance != null ? opts.distance : 100 + gsOpts1.x = from1.x - distance / 2 + gsOpts1.y = from1.y + gsOpts2.x = from2.x + distance / 2 + gsOpts2.y = from2.y + } + + // pointers //-------------------- - TweenLite.to(from, opts.duration, gsOpts) - }) + const pointers = new Map() + pointers.set(0, { element: from1, gsOpts: gsOpts1 }) + pointers.set(1, { element: from2, gsOpts: gsOpts2 }) + + // loop + //-------------------- + pointers.forEach((value, key) => { + // from + //-------------------- + const from = value.element + + // event opts + //-------------------- + const eventOpts = { + bubbles: opts.bubbles, + cancelable: opts.cancelable, + pointerId: key, + isPrimary: key === 0 + } + + const gsOpts = { + ease: opts.ease, + onStart: () => { + // create and dispatch event + //-------------------- + const event = Event.create( + elem, + from, + opts.eventTypes[0], + eventOpts + ) + if (this.opts.debug) + console.log('dispatch event', event) + elem.dispatchEvent(event) + + // onStart + //-------------------- + if ( + opts.onStart && + (opts.doubleCallbacks || key === 0) + ) { + opts.onStart.call(this, event) + } + }, + onUpdate: () => { + // create and dispatch event + //-------------------- + const event = Event.create( + elem, + from, + opts.eventTypes[1], + eventOpts + ) + if (this.opts.debug) + console.log('dispatch event', event) + elem.dispatchEvent(event) + + // onUpdate + //-------------------- + if ( + opts.onUpdate && + (opts.doubleCallbacks || key === 0) + ) { + opts.onUpdate.call(this, event) + } + }, + onComplete: () => { + // create and dispatch event + //-------------------- + const event = Event.create( + elem, + from, + opts.eventTypes[2], + eventOpts + ) + if (this.opts.debug) + console.log('dispatch event', event) + elem.dispatchEvent(event) + + // onComplete + //-------------------- + if ( + opts.onComplete && + (opts.doubleCallbacks || key === 0) + ) { + opts.onComplete.call(this, event) + } + } + } + + // to + //-------------------- + Object.assign(gsOpts, value.gsOpts) + + // drag animation + //-------------------- + TweenLite.to(from, opts.duration, gsOpts) + }) + }, + timelinePosition, + [position] + ) - }, timelinePosition, [position]) - this._actions++ return this @@ -2009,13 +2112,12 @@ export default class UITest { /** * Sorts the parameters so that the second, third, and fourth parameters can be optional (and possibly slip forward). - * + * * @private * @param {arguments} params - The arguments which were passed to the function. * @returns {array} - Returns an array of the position, the timelinePosition and the opts object. */ reorderArguments(params) { - // first parameter //-------------------- const element = params[0] @@ -2025,12 +2127,16 @@ export default class UITest { let position = null let timelinePosition = null let opts = null - + // second parameter //-------------------- if (Util.isNumber(params[1])) { timelinePosition = params[1] - } else if (Util.isObject(params[1]) && !Util.isPixiDisplayObject(params[1]) && (params[1].x == null || params[1].y == null)) { + } else if ( + Util.isObject(params[1]) && + !Util.isPixiDisplayObject(params[1]) && + (params[1].x == null || params[1].y == null) + ) { opts = params[1] } else if (params[1] != null) { position = params[1] @@ -2058,9 +2164,13 @@ export default class UITest { if (timelinePosition === null) { if (this.opts.defaultInterval === null && this._actions > 1) { - throw new Error('No execution time was specified for this action, and a default interval was not set in the class constructor!') + throw new Error( + 'No execution time was specified for this action, and a default interval was not set in the class constructor!' + ) } - timelinePosition = Math.max(...this._timelinePositions) + (this.opts.defaultInterval || 1) + timelinePosition = + Math.max(...this._timelinePositions) + + (this.opts.defaultInterval || 1) } if (opts === null) { @@ -2072,12 +2182,11 @@ export default class UITest { /** * Converts event type shortcuts to real event names. - * + * * @private * @param {string[]} events - An array of event types. */ resolveEvents(events) { - const data = [] if (this.opts.eventType === 'pointer') { @@ -2128,34 +2237,35 @@ export default class UITest { * @class */ class Util { - /** * Resolves the element from a specific context. - * + * * @static * @param {Window|Frame} context - The context within which the optionally specified element selector should be executed. * @return {HTMLElement|string} element - The HTML element on which the event is to be executed, e.g. button, document, h2, canvas, etc. or an selector string. If a selector has been specified, it is evaluated immediately before the event is called using the querySelector method. */ static extractElement(context, element) { - - const cont = Util.isFrame(context) ? context.contentDocument : context.document - const elem = Util.isString(element) ? cont.querySelector(element) : element + const cont = Util.isFrame(context) + ? context.contentDocument + : context.document + const elem = Util.isString(element) + ? cont.querySelector(element) + : element return elem } /** * Extracts the position of the second parameter. - * + * * @static * @param {object} object - Something were the coords should be extracted. * @return {object} - Returns an object with the keys x and y. */ static extractPosition(object) { - // event coords //-------------------- - const position = {x: 0, y: 0} + const position = { x: 0, y: 0 } // get the position //-------------------- @@ -2179,17 +2289,15 @@ class Util { /** * Extracts the to or bezier key. - * + * * @static * @param {object} opts - An options object where to or bezier should be extracted. * @return {object} - Returns an object with the to or bezier keys. */ static extractTo(opts) { - const object = {} if (opts.bezier) { - let bezier = null if (Array.isArray(opts.bezier)) { @@ -2198,7 +2306,9 @@ class Util { type: 'thru' } } else { - opts.bezier.values = opts.bezier.values.map(it => Util.extractPosition(it)) + opts.bezier.values = opts.bezier.values.map(it => + Util.extractPosition(it) + ) bezier = opts.bezier } @@ -2214,19 +2324,16 @@ class Util { /** * Extracts multiple to or bezier keys. - * + * * @static * @param {object} opts - An options object where to or bezier should be extracted. * @return {object[]} - Returns an array of objects with the keys x and y. */ static extractMultiTo(opts) { - const objects = [] if (opts.bezier) { - opts.bezier.forEach(it => { - let bezier = null if (Array.isArray(it)) { @@ -2243,9 +2350,7 @@ class Util { bezier }) }) - } else { - opts.to.forEach(it => { const to = Util.extractPosition(it) objects.push({ @@ -2260,7 +2365,7 @@ class Util { /** * Checks if a thing is a string. - * + * * @static * @param {object} object - The object to test for. * @return {boolean} - true if the thing is a string, otherwise false. @@ -2271,7 +2376,7 @@ class Util { /** * Checks if a thing is a number. - * + * * @static * @param {object} object - The object to test for. * @return {boolean} - true if the thing is a number, otherwise false. @@ -2282,7 +2387,7 @@ class Util { /** * Checks if a thing is an object. - * + * * @static * @param {object} object - The object to test for. * @return {boolean} - true if the thing is an object, otherwise false. @@ -2293,18 +2398,22 @@ class Util { /** * Checks if a thing is an PIXI.DisplayObject. - * + * * @static * @param {object} object - The object to test for. * @return {boolean} - true if the thing is a PIXI.DisplayObject, otherwise false. */ static isPixiDisplayObject(object) { - return typeof object.getBounds === 'function' && typeof object.renderWebGL === 'function' && typeof object.setTransform === 'function' + return ( + typeof object.getBounds === 'function' && + typeof object.renderWebGL === 'function' && + typeof object.setTransform === 'function' + ) } /** * Checks if a thing is a frame. - * + * * @static * @param {object} object - The object to test for. * @return {boolean} - true if the thing is a frame, otherwise false. @@ -2326,19 +2435,25 @@ class Util { * @class */ class Event { - /** * Creates an event object. - * + * * @static * @param {HTMLElement} target - The element on which the event should be executed. * @param {object} position - The local position of the event in relation to the target. The object must have the keys x and y. * @param {string} type - The type of the event, see https://developer.mozilla.org/de/docs/Web/Events * @param {object} opts - An options object. Every paramter of the event object can be overridden, see e.g. https://developer.mozilla.org/de/docs/Web/API/MouseEvent for all the properties. */ - static create(target, position = {x: 0, y: 0}, type = 'pointerup', opts = {}) { - - const rect = typeof target.getBoundingClientRect === 'function' ? target.getBoundingClientRect() : {x: 0, y: 0} + static create( + target, + position = { x: 0, y: 0 }, + type = 'pointerup', + opts = {} + ) { + const rect = + typeof target.getBoundingClientRect === 'function' + ? target.getBoundingClientRect() + : { x: 0, y: 0 } // EventInit const eventOpts = { @@ -2395,11 +2510,27 @@ class Event { } if (type.startsWith('pointer')) { - return new PointerEvent(type, Object.assign({}, eventOpts, uiEventOpts, mouseEventOpts, pointerEventOpts, opts)) + return new PointerEvent( + type, + Object.assign( + {}, + eventOpts, + uiEventOpts, + mouseEventOpts, + pointerEventOpts, + opts + ) + ) } else if (type.startsWith('touch')) { - return new TouchEvent(type, Object.assign({}, eventOpts, uiEventOpts, touchEventOpts, opts)) + return new TouchEvent( + type, + Object.assign({}, eventOpts, uiEventOpts, touchEventOpts, opts) + ) } else { - return new MouseEvent(type, Object.assign({}, eventOpts, uiEventOpts, mouseEventOpts, opts)) + return new MouseEvent( + type, + Object.assign({}, eventOpts, uiEventOpts, mouseEventOpts, opts) + ) } } } @@ -2416,7 +2547,7 @@ class Event {
diff --git a/gulpfile.js b/gulpfile.js index 2a20355..e818761 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -3,6 +3,7 @@ const uglify = require('gulp-uglify') const rename = require('gulp-rename') const concat = require('gulp-concat') const replace = require('gulp-replace') +const prettier = require('gulp-prettier') function vendors() { return src( @@ -52,4 +53,28 @@ function preload() { .pipe(dest('dist', { sourcemaps: false })) } +function prettify() { + return src( + [ + './lib/*.js', + './lib/card/*.js', + './lib/pixi/*.js', + '!./lib/bootstrap.babel.js' + ], + { + base: './lib' + } + ) + .pipe( + prettier({ + singleQuote: true, + jsxSingleQuote: true, + tabWidth: 4, + semi: false + }) + ) + .pipe(dest('./lib')) +} + +exports.prettify = prettify exports.default = parallel(vendors, preload) diff --git a/lib/bootstrap.babel.js b/lib/bootstrap.babel.js index 58ce617..fec5bdb 100644 --- a/lib/bootstrap.babel.js +++ b/lib/bootstrap.babel.js @@ -1,175 +1,275 @@ -'use strict'; +'use strict' -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); +var _createClass = (function() { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + 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) + } + } + return function(Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps) + if (staticProps) defineProperties(Constructor, staticProps) + return Constructor + } +})() -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError('Cannot call a class as a function') + } +} -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } +function _possibleConstructorReturn(self, call) { + if (!self) { + throw new ReferenceError( + "this hasn't been initialised - super() hasn't been called" + ) + } + return call && (typeof call === 'object' || typeof call === 'function') + ? call + : self +} -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } +function _inherits(subClass, superClass) { + if (typeof superClass !== 'function' && superClass !== null) { + throw new TypeError( + 'Super expression must either be null or a function, not ' + + typeof superClass + ) + } + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true + } + }) + if (superClass) + Object.setPrototypeOf + ? Object.setPrototypeOf(subClass, superClass) + : (subClass.__proto__ = superClass) +} -var Bootstrap = function (_Object) { - _inherits(Bootstrap, _Object); +var Bootstrap = (function(_Object) { + _inherits(Bootstrap, _Object) function Bootstrap() { - _classCallCheck(this, Bootstrap); + _classCallCheck(this, Bootstrap) - return _possibleConstructorReturn(this, (Bootstrap.__proto__ || Object.getPrototypeOf(Bootstrap)).apply(this, arguments)); + return _possibleConstructorReturn( + this, + (Bootstrap.__proto__ || Object.getPrototypeOf(Bootstrap)).apply( + this, + arguments + ) + ) } - _createClass(Bootstrap, null, [{ - key: 'import', - value: function _import(src) { - var _this2 = this; + _createClass(Bootstrap, null, [ + { + key: 'import', + value: function _import(src) { + var _this2 = this - var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + var callback = + arguments.length > 1 && arguments[1] !== undefined + ? arguments[1] + : null - if (src.endsWith('babel.js')) { - this.load(this.baseUrl + '/3rdparty/polyfills/babel-polyfill.js', function () { - _this2.load(src, null, null); - }, null); - } else if (this.isModernSafari || this.isModernChrome) { - this.load(src, callback); - } else { - this.load(this.baseUrl + '/3rdparty/systemjs/system.js', function () { - SystemJS.config(_this2.systemjsConfig); - SystemJS.import(src); - }, 'script'); - } - } - }, { - key: 'load', - value: function load(src, callback) { - var _this3 = this; - - var type = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'module'; - - var script = document.createElement('script'); - if (type === 'module') { - script.setAttribute('type', 'module'); - script.setAttribute('crossorigin', 'use-credentials'); - } - script.onload = function () { - if (callback) { - callback.call(_this3, script); - } - }; - script.src = src; - document.head.appendChild(script); - } - }, { - key: 'require', - value: function require(src) { - console.log('Dummy require'); - } - }, { - key: 'renderFont', - value: function renderFont() { - var font = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'Open Sans'; - var _arr = [300, 400, 600, 700, 800]; - - for (var _i = 0; _i < _arr.length; _i++) { - var weight = _arr[_i];var _arr2 = ['normal', 'italic']; - - for (var _i2 = 0; _i2 < _arr2.length; _i2++) { - var style = _arr2[_i2]; - var p = document.createElement('p'); - p.innerHTML = '.'; - document.body.appendChild(p); - p.setAttribute('style', 'font-family: \'' + font + '\'; font-weight: ' + weight + '; font-style: \'' + style + '\'; position: absolute; top: -10000px;'); + if (src.endsWith('babel.js')) { + this.load( + this.baseUrl + '/3rdparty/polyfills/babel-polyfill.js', + function() { + _this2.load(src, null, null) + }, + null + ) + } else if (this.isModernSafari || this.isModernChrome) { + this.load(src, callback) + } else { + this.load( + this.baseUrl + '/3rdparty/systemjs/system.js', + function() { + SystemJS.config(_this2.systemjsConfig) + SystemJS.import(src) + }, + 'script' + ) } } - } - }, { - key: 'isSafari', - get: function get() { - return (/Safari/.test(navigator.userAgent) && /Apple Computer, Inc/.test(navigator.vendor) - ); - } - }, { - key: 'isModernSafari', - get: function get() { - if (!this.isSafari) return false; - var agent = navigator.appVersion; - var offset = agent.indexOf('Version'); - if (offset != -1) { - var version = parseFloat(agent.substring(offset + 8)); - return version >= 10.1; - } - return false; - } - }, { - key: 'isChrome', - get: function get() { - var isChromium = window.chrome; - var winNav = window.navigator; - var vendorName = winNav.vendor; - var isOpera = winNav.userAgent.indexOf('OPR') > -1; - var isIEedge = winNav.userAgent.indexOf('Edge') > -1; - var isIOSChrome = winNav.userAgent.match('CriOS'); + }, + { + key: 'load', + value: function load(src, callback) { + var _this3 = this - if (isIOSChrome) { - return true; - } else if (isChromium !== null && isChromium !== undefined && vendorName === 'Google Inc.' && isOpera == false && isIEedge == false) { - return true; - } else { - return false; - } - } - }, { - key: 'isModernChrome', - get: function get() { - if (!this.isChrome) { - return false; - } - var raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./); - var version = raw ? parseInt(raw[2], 10) : false; - return version > 62; - } - }, { - key: 'systemjsConfig', - get: function get() { + var type = + arguments.length > 2 && arguments[2] !== undefined + ? arguments[2] + : 'module' - var baseUrl = this.baseUrl; + var script = document.createElement('script') + if (type === 'module') { + script.setAttribute('type', 'module') + script.setAttribute('crossorigin', 'use-credentials') + } + script.onload = function() { + if (callback) { + callback.call(_this3, script) + } + } + script.src = src + document.head.appendChild(script) + } + }, + { + key: 'require', + value: function require(src) { + console.log('Dummy require') + } + }, + { + key: 'renderFont', + value: function renderFont() { + var font = + arguments.length > 0 && arguments[0] !== undefined + ? arguments[0] + : 'Open Sans' + var _arr = [300, 400, 600, 700, 800] - return { - baseURL: baseUrl, - map: { - 'plugin-babel': baseUrl + '/3rdparty/systemjs/plugin-babel.js', - 'systemjs-babel-build': baseUrl + '/3rdparty/systemjs/systemjs-babel-browser.js' - }, - transpiler: 'plugin-babel', - meta: { - '*.js': { - authorization: true, - babelOptions: { - es2015: false + for (var _i = 0; _i < _arr.length; _i++) { + var weight = _arr[_i] + var _arr2 = ['normal', 'italic'] + + for (var _i2 = 0; _i2 < _arr2.length; _i2++) { + var style = _arr2[_i2] + var p = document.createElement('p') + p.innerHTML = '.' + document.body.appendChild(p) + p.setAttribute( + 'style', + "font-family: '" + + font + + "'; font-weight: " + + weight + + "; font-style: '" + + style + + "'; position: absolute; top: -10000px;" + ) + } + } + } + }, + { + key: 'isSafari', + get: function get() { + return ( + /Safari/.test(navigator.userAgent) && + /Apple Computer, Inc/.test(navigator.vendor) + ) + } + }, + { + key: 'isModernSafari', + get: function get() { + if (!this.isSafari) return false + var agent = navigator.appVersion + var offset = agent.indexOf('Version') + if (offset != -1) { + var version = parseFloat(agent.substring(offset + 8)) + return version >= 10.1 + } + return false + } + }, + { + key: 'isChrome', + get: function get() { + var isChromium = window.chrome + var winNav = window.navigator + var vendorName = winNav.vendor + var isOpera = winNav.userAgent.indexOf('OPR') > -1 + var isIEedge = winNav.userAgent.indexOf('Edge') > -1 + var isIOSChrome = winNav.userAgent.match('CriOS') + + if (isIOSChrome) { + return true + } else if ( + isChromium !== null && + isChromium !== undefined && + vendorName === 'Google Inc.' && + isOpera == false && + isIEedge == false + ) { + return true + } else { + return false + } + } + }, + { + key: 'isModernChrome', + get: function get() { + if (!this.isChrome) { + return false + } + var raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./) + var version = raw ? parseInt(raw[2], 10) : false + return version > 62 + } + }, + { + key: 'systemjsConfig', + get: function get() { + var baseUrl = this.baseUrl + + return { + baseURL: baseUrl, + map: { + 'plugin-babel': + baseUrl + '/3rdparty/systemjs/plugin-babel.js', + 'systemjs-babel-build': + baseUrl + + '/3rdparty/systemjs/systemjs-babel-browser.js' + }, + transpiler: 'plugin-babel', + meta: { + '*.js': { + authorization: true, + babelOptions: { + es2015: false + } } } } - }; - } - }, { - key: 'baseUrl', - get: function get() { - - var baseUrl = './'; - var scripts = document.getElementsByTagName('script'); - - for (var i = 0; i < scripts.length; i++) { - var script = scripts[i]; - var src = script.getAttribute('src'); - var re = /\/bootstrap(.babel)?\.js$/; - if (re.test(src)) { - baseUrl = src.replace(re, ''); - } } + }, + { + key: 'baseUrl', + get: function get() { + var baseUrl = './' + var scripts = document.getElementsByTagName('script') - return baseUrl; + for (var i = 0; i < scripts.length; i++) { + var script = scripts[i] + var src = script.getAttribute('src') + var re = /\/bootstrap(.babel)?\.js$/ + if (re.test(src)) { + baseUrl = src.replace(re, '') + } + } + + return baseUrl + } } - }]); + ]) - return Bootstrap; -}(Object); + return Bootstrap +})(Object) -window.Bootstrap = Bootstrap; \ No newline at end of file +window.Bootstrap = Bootstrap diff --git a/lib/bootstrap.js b/lib/bootstrap.js index 60c1dce..e94bff0 100644 --- a/lib/bootstrap.js +++ b/lib/bootstrap.js @@ -1,13 +1,13 @@ - class Bootstrap extends Object { - static get isSafari() { - return /Safari/.test(navigator.userAgent) && /Apple Computer, Inc/.test(navigator.vendor) + return ( + /Safari/.test(navigator.userAgent) && + /Apple Computer, Inc/.test(navigator.vendor) + ) } static get isModernSafari() { - if (!this.isSafari) - return false + if (!this.isSafari) return false let agent = navigator.appVersion let offset = agent.indexOf('Version') if (offset != -1) { @@ -27,7 +27,13 @@ class Bootstrap extends Object { if (isIOSChrome) { return true - } else if (isChromium !== null && isChromium !== undefined && vendorName === 'Google Inc.' && isOpera == false && isIEedge == false) { + } else if ( + isChromium !== null && + isChromium !== undefined && + vendorName === 'Google Inc.' && + isOpera == false && + isIEedge == false + ) { return true } else { return false @@ -45,7 +51,6 @@ class Bootstrap extends Object { } static get isFirefox() { - if (window.navigator.userAgent.toLowerCase().indexOf('firefox') > -1) { return true } @@ -54,7 +59,6 @@ class Bootstrap extends Object { } static get isModernFirefox() { - if (!this.isFirefox) { return false } @@ -67,26 +71,35 @@ class Bootstrap extends Object { static import(src, callback = null) { if (src.endsWith('babel.js')) { - this.load(this.baseUrl + '/3rdparty/polyfills/babel-polyfill.js', + this.load( + this.baseUrl + '/3rdparty/polyfills/babel-polyfill.js', () => { this.load(src, callback, null) }, - null) - } - else if (this.isModernSafari || this.isModernChrome || this.isModernFirefox) { + null + ) + } else if ( + this.isModernSafari || + this.isModernChrome || + this.isModernFirefox + ) { this.load(src, callback) } else { - this.load(this.baseUrl + '/3rdparty/systemjs/system.js', () => { - SystemJS.config(this.systemjsConfig) - let promise = SystemJS.import(src) - if (promise) { - promise.then(() => { - if (callback) { - callback.call(this) - } - }) - } - }, 'script') + this.load( + this.baseUrl + '/3rdparty/systemjs/system.js', + () => { + SystemJS.config(this.systemjsConfig) + let promise = SystemJS.import(src) + if (promise) { + promise.then(() => { + if (callback) { + callback.call(this) + } + }) + } + }, + 'script' + ) } } @@ -110,14 +123,14 @@ class Bootstrap extends Object { } static get systemjsConfig() { - const baseUrl = this.baseUrl return { baseURL: baseUrl, map: { 'plugin-babel': baseUrl + '/3rdparty/systemjs/plugin-babel.js', - 'systemjs-babel-build': baseUrl + '/3rdparty/systemjs/systemjs-babel-browser.js' + 'systemjs-babel-build': + baseUrl + '/3rdparty/systemjs/systemjs-babel-browser.js' }, transpiler: 'plugin-babel', meta: { @@ -132,7 +145,6 @@ class Bootstrap extends Object { } static get baseUrl() { - let baseUrl = './' let scripts = document.getElementsByTagName('script') @@ -154,7 +166,10 @@ class Bootstrap extends Object { let p = document.createElement('p') p.innerHTML = '.' document.body.appendChild(p) - p.setAttribute('style', `font-family: '${font}'; font-weight: ${weight}; font-style: '${style}'; position: absolute; top: -10000px;`) + p.setAttribute( + 'style', + `font-family: '${font}'; font-weight: ${weight}; font-style: '${style}'; position: absolute; top: -10000px;` + ) } } } diff --git a/lib/bundle.js b/lib/bundle.js index 7521534..c64ef03 100755 --- a/lib/bundle.js +++ b/lib/bundle.js @@ -2,7 +2,15 @@ import App from './app.js' import Doctest from './doctest.js' import Errors from './errors.js' import Events from './events.js' -import { DOMFlip, DOMFlippable, CardLoader, PDFLoader, ImageLoader, FrameLoader, HTMLLoader } from './flippable.js' +import { + DOMFlip, + DOMFlippable, + CardLoader, + PDFLoader, + ImageLoader, + FrameLoader, + HTMLLoader +} from './flippable.js' import Index from './index.js' import Interface from './interface.js' import Logging from './logging.js' @@ -14,9 +22,44 @@ import { Capabilities, CapabilitiesTests } from './capabilities.js' import { EventRecorder } from './events.js' import { FrameContainer, FrameTarget } from './frames.js' import { Inspect } from './inspect.js' -import { PointMap, InteractionPoints, Interaction, IInteractionTarget, InteractionDelta, InteractionMapper, InteractionDelegate, IInteractionMapperTarget } from './interaction.js' -import { ITapDelegate, ResizeEvent, DOMScatterContainer, AbstractScatter, DOMScatter, ScatterEvent, BaseEvent } from './scatter.js' -import { Cycle, Colors, Elements, Angle, Dates, Points, Polygon, Rect, Sets, Strings, isEmpty, getId, lerp, debounce, randomInt, randomFloat, LowPassFilter } from './utils.js' +import { + PointMap, + InteractionPoints, + Interaction, + IInteractionTarget, + InteractionDelta, + InteractionMapper, + InteractionDelegate, + IInteractionMapperTarget +} from './interaction.js' +import { + ITapDelegate, + ResizeEvent, + DOMScatterContainer, + AbstractScatter, + DOMScatter, + ScatterEvent, + BaseEvent +} from './scatter.js' +import { + Cycle, + Colors, + Elements, + Angle, + Dates, + Points, + Polygon, + Rect, + Sets, + Strings, + isEmpty, + getId, + lerp, + debounce, + randomInt, + randomFloat, + LowPassFilter +} from './utils.js' import UITest from './uitest.js' import Card from './card/card.js' diff --git a/lib/capabilities.js b/lib/capabilities.js index 16c1ea5..1317a18 100644 --- a/lib/capabilities.js +++ b/lib/capabilities.js @@ -1,7 +1,6 @@ /** Report capabilities with guaranteed values. */ export class Capabilities { - /** Returns the browser userAgent. @return {string} */ @@ -14,7 +13,7 @@ export class Capabilities { @return {boolean} */ static get isMobile() { - return (/Mobi/.test(navigator.userAgent)) + return /Mobi/.test(navigator.userAgent) } /** Tests whether the app is running on a iOS device. @@ -22,7 +21,7 @@ export class Capabilities { @return {boolean} */ static get isIOS() { - return (/iPad|iPhone|iPod/.test(navigator.userAgent)) && !window.MSStream + return /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream } /** Tests whether the app is running in a Safari environment. @@ -31,28 +30,44 @@ export class Capabilities { @return {boolean} */ static get isSafari() { - return navigator.vendor && navigator.vendor.indexOf('Apple') > -1 && navigator.userAgent && !navigator.userAgent.match('CriOS') + return ( + navigator.vendor && + navigator.vendor.indexOf('Apple') > -1 && + navigator.userAgent && + !navigator.userAgent.match('CriOS') + ) } /** * Distincts if the app is running inside electron or not. - * + * * source: https://github.com/cheton/is-electron */ static get isElectron() { - // Renderer process - if (typeof window !== 'undefined' && typeof window.process === 'object' && window.process.type === 'renderer') { + if ( + typeof window !== 'undefined' && + typeof window.process === 'object' && + window.process.type === 'renderer' + ) { return true } // Main process - if (typeof process !== 'undefined' && typeof process.versions === 'object' && !!process.versions.electron) { + if ( + typeof process !== 'undefined' && + typeof process.versions === 'object' && + !!process.versions.electron + ) { return true } // Detect the user agent when the `nodeIntegration` option is set to true - if (typeof navigator === 'object' && typeof navigator.userAgent === 'string' && navigator.userAgent.indexOf('Electron') >= 0) { + if ( + typeof navigator === 'object' && + typeof navigator.userAgent === 'string' && + navigator.userAgent.indexOf('Electron') >= 0 + ) { return true } @@ -70,52 +85,56 @@ export class Capabilities { @return {boolean} */ static get isMultiTouchTable() { - return Capabilities.devicePixelRatio > 2 && Capabilities.isMobile === false && /Windows/i.test(Capabilities.userAgent) + return ( + Capabilities.devicePixelRatio > 2 && + Capabilities.isMobile === false && + /Windows/i.test(Capabilities.userAgent) + ) } /** Returns true if mouse events are supported @return {boolean} */ static supportsMouseEvents() { - return typeof(window.MouseEvent) != 'undefined' + return typeof window.MouseEvent != 'undefined' } /** Returns true if touch events are supported @return {boolean} */ static supportsTouchEvents() { - return typeof(window.TouchEvent) != 'undefined' + return typeof window.TouchEvent != 'undefined' } /** Returns true if pointer events are supported @return {boolean} */ static supportsPointerEvents() { - return typeof(window.PointerEvent) != 'undefined' + return typeof window.PointerEvent != 'undefined' } /** Returns true if DOM templates are supported @return {boolean} */ static supportsTemplate() { - return 'content' in document.createElement('template'); + return 'content' in document.createElement('template') } } /** Basic tests for Capabilities. */ export class CapabilitiesTests { - static testConfirm() { let bool = confirm('Please confirm') - document.getElementById('demo').innerHTML = (bool) ? 'Confirmed' : 'Not confirmed' + document.getElementById('demo').innerHTML = bool + ? 'Confirmed' + : 'Not confirmed' } static testPrompt() { let person = prompt('Please enter your name', 'Harry Potter') if (person != null) { - demo.innerHTML = - 'Hello ' + person + '! How are you today?' + demo.innerHTML = 'Hello ' + person + '! How are you today?' } } @@ -130,7 +149,9 @@ export class CapabilitiesTests { } static testMultiTouchTable() { - let value = 'Is the device a multi-touch table? ' + Capabilities.isMultiTouchTable + let value = + 'Is the device a multi-touch table? ' + + Capabilities.isMultiTouchTable multi_touch_table.innerHTML = value } diff --git a/lib/card/card.js b/lib/card/card.js index 374c0f3..d70b53d 100644 --- a/lib/card/card.js +++ b/lib/card/card.js @@ -1,5 +1,3 @@ - - /** To avoid problems with relative URL paths, we use inline data URI to load svg icons. */ const closeIconDataURI = `data:image/svg+xml;utf8, @@ -30,9 +28,8 @@ const enableNearestNeighborTaps = false * The class is used as a namespace and should never called with new. */ export default class Card { - static setup(context, modules = []) { - console.log("Setup Card...", modules) + console.log('Setup Card...', modules) context.modules = [] modules.forEach(module => { if (module.apply(context)) @@ -53,7 +50,7 @@ export default class Card { if (context.onClose) { context.onClose(event) } else context.parentNode.removeChild(context) - } else console.error("Could not find context!", event.target) + } else console.error('Could not find context!', event.target) } /** @@ -68,7 +65,6 @@ export default class Card { static _replaceAttributes(html, attribute, replaceFunc) { let clickables = html.querySelectorAll(`[${attribute}]`) clickables.forEach(element => { - let attributeVal = element.getAttribute(attribute) element.removeAttribute(attribute) replaceFunc.call(this, element, attributeVal) @@ -76,33 +72,33 @@ export default class Card { } /** - * Replaces the onClick callback of the element with an - * Interaction mapper event. - * - * @static - * @param {*} element - * @param {*} attributeVal - * @returns - * @memberof Card - */ + * Replaces the onClick callback of the element with an + * Interaction mapper event. + * + * @static + * @param {*} element + * @param {*} attributeVal + * @returns + * @memberof Card + */ static _replaceCallback(element, attributeVal) { - - if (element.tagName == "A") { - element.addEventListener("click", event => { event.preventDefault() }) + if (element.tagName == 'A') { + element.addEventListener('click', event => { + event.preventDefault() + }) } - - let callbackParts = attributeVal.split("(") + let callbackParts = attributeVal.split('(') let funcPart = callbackParts[0].trim() let trimmedArgs = callbackParts[1].trim() //Remove the closing ')' trimmedArgs = trimmedArgs.substring(0, trimmedArgs.length - 1) - - let callParts = funcPart.split(".") - let argsStrings = trimmedArgs.split(",").filter(entry => { return entry.trim() != "" }) - + let callParts = funcPart.split('.') + let argsStrings = trimmedArgs.split(',').filter(entry => { + return entry.trim() != '' + }) let callStack = window do { @@ -115,28 +111,24 @@ export default class Card { //Remove the events on the circle. // These are 'hardcoded' inside the convert.js. - if (element.tagName == "circle") return false - - - InteractionMapper.on(interactionType, element, (event) => { + if (element.tagName == 'circle') return false + InteractionMapper.on(interactionType, element, event => { /** * Replaces the strings from the listener with the cooresponding variables. */ let args = [] argsStrings.forEach(arg => { arg = arg.trim() - if (arg == "this") - args.push(event.target) - else if (arg == "event") - args.push(event) + if (arg == 'this') args.push(event.target) + else if (arg == 'event') args.push(event) else { const firstCharacter = arg[0] - if (firstCharacter == "\"" || firstCharacter == "'") { + if (firstCharacter == '"' || firstCharacter == "'") { arg = arg.substring(1) } const lastCharacter = arg[arg.length - 1] - if (lastCharacter == "\"" || lastCharacter == "'") { + if (lastCharacter == '"' || lastCharacter == "'") { arg = arg.substring(0, arg.length - 1) } @@ -144,15 +136,16 @@ export default class Card { } }) event.stopPropagation() - if (callStack) - callStack.call(that, ...args) + if (callStack) callStack.call(that, ...args) else { - console.error("Could not call callback function " + attributeVal, ...args) + console.error( + 'Could not call callback function ' + attributeVal, + ...args + ) } }) } - /** * Transform the relative links to absolute ones. * @@ -171,23 +164,27 @@ export default class Card { This RegEx finds all requested tags[1], and all requested attributes[3] and replaces the relative path [4] with the absolute one. while all other attributes [2],[5] are preserved. */ - return html.replace(/<\s*(a|video|img|image|circle)\s(.*?)(xlink:href|href|src)\s*=\s*["'](\..*?)["']\s*(.*?)>/g, function (data) { - let path = that._getRelativePath(arguments[4]) - const tag = `<${arguments[1]} ${arguments[2]} ${arguments[3]}="${path}" ${arguments[5]}>` - /* if (that.debug) */ console.log("Adjusted: ", tag) - return tag - }) + return html.replace( + /<\s*(a|video|img|image|circle)\s(.*?)(xlink:href|href|src)\s*=\s*["'](\..*?)["']\s*(.*?)>/g, + function(data) { + let path = that._getRelativePath(arguments[4]) + const tag = `<${arguments[1]} ${arguments[2]} ${ + arguments[3] + }="${path}" ${arguments[5]}>` + /* if (that.debug) */ console.log('Adjusted: ', tag) + return tag + } + ) } /** * Concats the given path with the relative path specified in the Card (as static variable). */ static _getRelativePath(src) { - let path = (this.relativePath != "") ? this.relativePath + "/" + src : src + let path = this.relativePath != '' ? this.relativePath + '/' + src : src return path } - /** * Loads the card text using an ajax request. * @@ -200,7 +197,7 @@ export default class Card { return new Promise((resolve, reject) => { let request = new XMLHttpRequest() - request.onreadystatechange = function () { + request.onreadystatechange = function() { if (this.readyState == 4) { if (this.status == 200 || Card._isLocal()) { try { @@ -208,11 +205,14 @@ export default class Card { } catch (e) { reject(e) } - } else reject(`Request failed '${path}'. Returned status ${this.status} and ready state ${this.readyState}.`) + } else + reject( + `Request failed '${path}'. Returned status ${this.status} and ready state ${this.readyState}.` + ) } } - request.open("GET", path, true) + request.open('GET', path, true) request.send() }) } @@ -221,7 +221,7 @@ export default class Card { * TODO: Maybe put this in a utility script. */ static _isLocal() { - return (window.location.protocol == "file:") + return window.location.protocol == 'file:' } /** @@ -246,8 +246,7 @@ export default class Card { */ static closestWithClass(node, klass) { if (node && node.classList) { - if (node.classList.contains(klass)) - return node + if (node.classList.contains(klass)) return node return this.closestWithClass(node.parentNode, klass) } return null @@ -284,10 +283,10 @@ export default class Card { * @param {string} [effectAllowed="all"] * @memberof Card */ - static dragStart(event, type = "card", effectAllowed = 'all') { + static dragStart(event, type = 'card', effectAllowed = 'all') { event.dataTransfer.effectAllowed = effectAllowed let html = event.target.outerHTML - event.dataTransfer.setData("text/html", html) + event.dataTransfer.setData('text/html', html) // https://stackoverflow.com/questions/11065803/determine-what-is-being-dragged-from-dragenter-dragover-events event.dataTransfer.setData('iwmbrowser/' + type, '') } @@ -303,13 +302,12 @@ export default class Card { * @memberof Card */ static _openPopup(context, src, position, content, options = {}) { - let maxWidth = null - if (this.debug) console.log("Card._openPopup", position) + if (this.debug) console.log('Card._openPopup', position) //logging if (src) { - let strparts = src.split("/") + let strparts = src.split('/') let cardID = strparts[strparts.length - 2] let cardName = strparts[strparts.length - 1] //console.log('open popup:',cardID,cardName,context,content) @@ -324,38 +322,41 @@ export default class Card { delete options.highlight } - this._createPopup(context, position, content, options).then((popup) => { - if ( - //Test if meanwhile another popup was registered... - this._getPopup(context) || - // Or if an highlight was loaded, if the highlight already was closed. - highlight !== null && !this._isHighlightActive(context, highlight) - ) { - //.. if so remove the create popup instantly. - popup.remove() - } else { - // Otherwise set the popup regularly. - let popupParagraphs = popup.element.querySelectorAll(".popupContent > *") + this._createPopup(context, position, content, options) + .then(popup => { + if ( + //Test if meanwhile another popup was registered... + this._getPopup(context) || + // Or if an highlight was loaded, if the highlight already was closed. + (highlight !== null && + !this._isHighlightActive(context, highlight)) + ) { + //.. if so remove the create popup instantly. + popup.remove() + } else { + // Otherwise set the popup regularly. + let popupParagraphs = popup.element.querySelectorAll( + '.popupContent > *' + ) - // Remove a design error of naming two adjacent elements popup. - // Todo: fix this properly and remove this code. - // let unnecessaryPopupElement = popup.element.querySelector(".popupContent > .popup") - // unnecessaryPopupElement.classList.remove("popup") + // Remove a design error of naming two adjacent elements popup. + // Todo: fix this properly and remove this code. + // let unnecessaryPopupElement = popup.element.querySelector(".popupContent > .popup") + // unnecessaryPopupElement.classList.remove("popup") - popupParagraphs.forEach(popupParagraph => { - popupParagraph.setAttribute("draggable", false) - popupParagraph.addEventListener("mousedown", (event) => { - event.preventDefault() + popupParagraphs.forEach(popupParagraph => { + popupParagraph.setAttribute('draggable', false) + popupParagraph.addEventListener('mousedown', event => { + event.preventDefault() + }) }) - }) - - this._setPopup(context, popup, src) - } - }).catch(e => console.error(e)) + this._setPopup(context, popup, src) + } + }) + .catch(e => console.error(e)) } - /** * Closes a provided popup and unsets it on the context. * @@ -366,12 +367,12 @@ export default class Card { */ static closePopup(context, popup) { if (popup) { - if (this.debug) console.log("Close Popup.", context, popup) + if (this.debug) console.log('Close Popup.', context, popup) window.popup = popup popup.close() this._unsetPopup(context) } else { - console.error("Requested to close popup, but popup was not found.") + console.error('Requested to close popup, but popup was not found.') } } @@ -387,27 +388,33 @@ export default class Card { * @memberof Card */ static _createPopup(context, position, content, options = {}) { - - if (this.debug) console.log("Create Popup.", context, position, content, options) - let popup = new Popup(Object.assign({ - parent: context, - content - }, Object.assign({ - noStyle: true, - // TODO: Remove offset when positioning according to element position - // is working. - posOffset: 10 - }, options))) + if (this.debug) + console.log('Create Popup.', context, position, content, options) + let popup = new Popup( + Object.assign( + { + parent: context, + content + }, + Object.assign( + { + noStyle: true, + // TODO: Remove offset when positioning according to element position + // is working. + posOffset: 10 + }, + options + ) + ) + ) // Placing the popup when it required loading, // it resulted in flahing up at the default position. // We manually prevent this here. - popup.element.style.display = "none" + popup.element.style.display = 'none' - - let promise = new Promise((resolve) => { - if (popup.loaded) - resolve(popup) + let promise = new Promise(resolve => { + if (popup.loaded) resolve(popup) else { popup.onload = () => { resolve(popup) @@ -415,10 +422,9 @@ export default class Card { } }) - promise.then((popup) => { - - popup.element.style.display = "block" - popup.element.style.visibility = "hidden" + promise.then(popup => { + popup.element.style.display = 'block' + popup.element.style.visibility = 'hidden' popup.element.style.opacity = 0 popup.placeAt(position) @@ -435,15 +441,12 @@ export default class Card { autoAlpha: 1, ease: Power2.easeIn }) - }) return promise } - static _overlayCleanup(context, overlay) { - /** * The cleanup functionality is now covered by the _cleanup function. * It cleans up zoomables, popups and open image highlights. @@ -452,7 +455,8 @@ export default class Card { */ if (overlay) { TweenLite.to(overlay, 0.2, { - autoAlpha: 0, onComplete: () => { + autoAlpha: 0, + onComplete: () => { popup.remove() //this._cleanup(context) //overlay.parentNode.removeChild(overlay) @@ -470,7 +474,6 @@ export default class Card { * @memberof Card */ static loadPopup(event, context = null, node = null, local = null) { - let editable = Card.isEditable() if (context == null) { context = this.getContext(event.target) @@ -479,33 +482,33 @@ export default class Card { node = event.target } if (local == null) { - let globalClick = (event.center) ? event.center : { x: event.x, y: event.y } + let globalClick = event.center + ? event.center + : { x: event.x, y: event.y } local = Points.fromPageToNode(context, globalClick) } - if (this.debug) console.log("loadPopup", event) + if (this.debug) console.log('loadPopup', event) // Prevents loading the link in the current tab. // Prevents loading the link in the current tab. - if (event.type != "Follow") - event.preventDefault() + if (event.type != 'Follow') event.preventDefault() if (editable && event.type == 'click') { return false } let overlay = document.createElement('div') - let src = node.getAttribute("href") + let src = node.getAttribute('href') let parentArticle = node.closest('article') const that = this let xhr = new XMLHttpRequest() xhr.open('get', src, true) xhr.onreadystatechange = () => { - - if (this.debug) console.log("Popup Source: ", src) + if (this.debug) console.log('Popup Source: ', src) if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0)) { if (editable) { - if (this.debug) console.log("Append overlay.", context) + if (this.debug) console.log('Append overlay.', context) overlay.classList.add('overlay') TweenLite.set(overlay, { autoAlpha: 0 }) context.appendChild(overlay) @@ -514,11 +517,17 @@ export default class Card { // Extract the body from the Popup site. let parser = new DOMParser() - let popupPage = parser.parseFromString(xhr.responseText, "text/html") + let popupPage = parser.parseFromString( + xhr.responseText, + 'text/html' + ) //Fix the relative path of loaded images in the popup. - popupPage.querySelectorAll("img").forEach(node => { - node.setAttribute("src", that._getRelativePath(node.getAttribute("src"))) + popupPage.querySelectorAll('img').forEach(node => { + node.setAttribute( + 'src', + that._getRelativePath(node.getAttribute('src')) + ) }) let html = popupPage.body.innerHTML /** @@ -536,17 +545,22 @@ export default class Card { let selector = Card.popupHtmlSelector let content = { html, selector } - let isSame = Card._checkForActiveSource(context, src) Card._cleanup(context) - if (!isSame) { - Card._activateCorrespondingHighlights(context, node, parentArticle) - + Card._activateCorrespondingHighlights( + context, + node, + parentArticle + ) let callback = (popup, callback) => { - if (this.debug) console.log("Close popup (Editable = " + editable + ").", popup) + if (this.debug) + console.log( + 'Close popup (Editable = ' + editable + ').', + popup + ) if (editable) { let isDirty = mainController.askSaveNode() if (isDirty) @@ -564,9 +578,8 @@ export default class Card { this._overlayCleanup(context, overlay) } mainController.popController() - } - /** This may be in conflice with the cleanup method. */ - else { + } else { + /** This may be in conflice with the cleanup method. */ //this._overlayCleanup(context, overlay) popup.remove() } @@ -579,12 +592,12 @@ export default class Card { } overlay.onclick = e => { - if (editable) - e.preventDefault() + if (editable) e.preventDefault() } //console.log("onreadystatechange", editable) if (editable) { - if (this.debug) console.log("pushController", src, popup.insertedNode) + if (this.debug) + console.log('pushController', src, popup.insertedNode) mainController.pushController(popup.insertedNode, src) } } @@ -593,15 +606,15 @@ export default class Card { } /** - * When an highlight link is clicked, this method activates all - * corresponding highlights. - * - * @static - * @param {DomElement} context - The context of the element. - * @param {DomElement} node - The node that (may) contain a highlightId. - * @param {DomElement} parent - The parent element that may contain more highlightIds. - * @memberof Card - */ + * When an highlight link is clicked, this method activates all + * corresponding highlights. + * + * @static + * @param {DomElement} context - The context of the element. + * @param {DomElement} node - The node that (may) contain a highlightId. + * @param {DomElement} parent - The parent element that may contain more highlightIds. + * @memberof Card + */ static _activateCorrespondingHighlights(context, node, parent) { let highlightId = node.getAttribute('data-highlight-id') // console.log("Request Highlight: " + highlightId) @@ -614,8 +627,13 @@ export default class Card { } if (correspondingHighlights.length > 0) { for (let highlight of correspondingHighlights) { - if (highlight.parentNode && highlight.parentNode.nodeName.toLowerCase() == 'g') { - Highlight.openHighlight(highlight, { animation: Card.highlightAnimation }) + if ( + highlight.parentNode && + highlight.parentNode.nodeName.toLowerCase() == 'g' + ) { + Highlight.openHighlight(highlight, { + animation: Card.highlightAnimation + }) this._addHighlight(context, highlight) } } @@ -624,16 +642,15 @@ export default class Card { } /** - * Tests if any open item already contains the requested Source. - * - * @static - * @param {DomElement} context - Dom context we are in. - * @param {string} src - Source as dataUrl. - * @returns {boolean} - True if source is already active, false otherwise. - * @memberof Card - */ + * Tests if any open item already contains the requested Source. + * + * @static + * @param {DomElement} context - Dom context we are in. + * @param {string} src - Source as dataUrl. + * @returns {boolean} - True if source is already active, false otherwise. + * @memberof Card + */ static _checkForActiveSource(context, src) { - let requestedSame = false let activePopup = Card._getPopup(context) let activeHighlights = Card._getHighlights(context) @@ -667,8 +684,7 @@ export default class Card { * @memberof Card */ static loadHighlightPopup(event) { - - if (this.debug) console.log("Load Highlight Popup: ", event) + if (this.debug) console.log('Load Highlight Popup: ', event) let node if (event.firstTarget) { node = event.firstTarget @@ -679,10 +695,10 @@ export default class Card { event.stopPropagation() /** - * This node is the documents body, as events wont work - * on svg elements properly. We need a workaround for that. - */ - let src = node.getAttribute("xlink:href") + * This node is the documents body, as events wont work + * on svg elements properly. We need a workaround for that. + */ + let src = node.getAttribute('xlink:href') let isSame = this._checkForActiveSource(context, src) this._cleanup(context) @@ -693,11 +709,11 @@ export default class Card { animation: Card.highlightAnimation, onExpanded: () => { // We assume it's always a circle. This may break, when other svg shapes are used. - let x = node.getAttribute("cx") - let y = node.getAttribute("cy") + let x = node.getAttribute('cx') + let y = node.getAttribute('cy') let position = { x, y } - let radius = parseFloat(node.getAttribute("r")) + let radius = parseFloat(node.getAttribute('r')) /* As the popup is appended directly to the card. We have to @@ -705,7 +721,7 @@ export default class Card { card space. */ - let svgRoot = node.closest("svg") + let svgRoot = node.closest('svg') let svgPoint = svgRoot.createSVGPoint() svgPoint.x = position.x @@ -713,7 +729,10 @@ export default class Card { let matrix = node.getCTM() let point = svgPoint.matrixTransform(matrix) - let global = Points.fromNodeToPage(node.closest("div"), point) + let global = Points.fromNodeToPage( + node.closest('div'), + point + ) let local = Points.fromPageToNode(context, global) let overlay = document.createElement('div') @@ -735,35 +754,40 @@ export default class Card { } }) }) - .catch(err => { console.error(err) }) + .catch(err => { + console.error(err) + }) } }) } } /** - * Loads the popup from a provided source. - * - * @static - * @private - * @param {string} source - Url to a popup file. - * @returns {Promise} - Returns a promise, that's resolved when the data is loaded. - * @memberof Card - */ + * Loads the popup from a provided source. + * + * @static + * @private + * @param {string} source - Url to a popup file. + * @returns {Promise} - Returns a promise, that's resolved when the data is loaded. + * @memberof Card + */ static _loadPopupContent(source) { return new Promise((resolve, reject) => { let xhr = new XMLHttpRequest() xhr.open('get', source, true) xhr.onreadystatechange = () => { if (xhr.readyState == 4) { - - if ((xhr.status == 200 || xhr.status == 0)) { - let html = this.postProcessResponseText(xhr.responseText) + if (xhr.status == 200 || xhr.status == 0) { + let html = this.postProcessResponseText( + xhr.responseText + ) let selector = Card.popupHtmlSelector let content = { html: html.body.innerHTML, selector } resolve(content) } else { - reject(` Popup request failed (Code: ${xhr.status}): Could not load resource: ${src}`) + reject( + ` Popup request failed (Code: ${xhr.status}): Could not load resource: ${src}` + ) } } } @@ -772,7 +796,6 @@ export default class Card { } static openZoomable(event) { - let node = event.target //console.log("Open zoomable: ", node, node.classList) @@ -786,7 +809,6 @@ export default class Card { this._openZoomable(event) } - /** * Retrieve a Rectangle object from the a given zoomable. * @@ -797,8 +819,6 @@ export default class Card { * @memberof Card */ static zoomableCurrentGeometry(zoomable, wrapper) { - - /* I don't think it's wise, that the zoomable calculation relies on some icon that may or may not be present. When the same calculation can be @@ -807,12 +827,12 @@ export default class Card { */ //The div is cloned and animated, therefore we need it's style! - let actuallyZoomedItem = zoomable.querySelector("div") + let actuallyZoomedItem = zoomable.querySelector('div') let zoomableStyle = window.getComputedStyle(actuallyZoomedItem) - let svgElement = zoomable.querySelector("svg") - let videoElement = zoomable.querySelector("video") + let svgElement = zoomable.querySelector('svg') + let videoElement = zoomable.querySelector('video') let curStyle = null if (svgElement) { curStyle = window.getComputedStyle(svgElement) @@ -832,21 +852,29 @@ export default class Card { globalBottomRight = Points.fromNodeToPage(zoomable, globalBottomRight) let globalFigurePos = Points.fromNodeToPage(zoomable, { x: 0, y: 0 }) let localFigurePos = Points.fromPageToNode(wrapper, globalFigurePos) - let relativeBottomRight = Points.fromPageToNode(zoomable, globalBottomRight) + let relativeBottomRight = Points.fromPageToNode( + zoomable, + globalBottomRight + ) - let width = relativeBottomRight.x + parseFloat(zoomableStyle.borderLeftWidth) + parseFloat(zoomableStyle.borderRightWidth)/*+ zoomIconRight*/ - let height = relativeBottomRight.y + parseFloat(zoomableStyle.borderTopWidth) + parseFloat(zoomableStyle.borderBottomWidth) /*+ zoomIconRight*/ + let width = + relativeBottomRight.x + + parseFloat(zoomableStyle.borderLeftWidth) + + parseFloat(zoomableStyle.borderRightWidth) /*+ zoomIconRight*/ + let height = + relativeBottomRight.y + + parseFloat(zoomableStyle.borderTopWidth) + + parseFloat(zoomableStyle.borderBottomWidth) /*+ zoomIconRight*/ return { x: localFigurePos.x, y: localFigurePos.y, width, height } } - /** - * Opens a zoomable object, which can be a figure containing an image or video or an image group - * - * @static - * @param {any} event - The trigger event, typically a click event - * @memberof Card - */ + * Opens a zoomable object, which can be a figure containing an image or video or an image group + * + * @static + * @param {any} event - The trigger event, typically a click event + * @memberof Card + */ static _openZoomable(event, editable = false) { event.stopPropagation() let node = event.target @@ -867,7 +895,7 @@ export default class Card { // Clone the zoomable and create a clone that is zoomed instead. let current = this.zoomableCurrentGeometry(zoomable, wrapper) let zoomedFig = zoomable.cloneNode(true) - let caption = zoomedFig.querySelector("figcaption.cap") + let caption = zoomedFig.querySelector('figcaption.cap') caption.parentNode.removeChild(caption) this._toggleNextIcon(zoomedFig) this._setZoomable(wrapper, zoomable, zoomedFig) @@ -879,9 +907,9 @@ export default class Card { * -SO */ let zoomContainer = document.createElement('div') - zoomContainer.classList.add("zoomable-wrapper") + zoomContainer.classList.add('zoomable-wrapper') Object.assign(zoomContainer.style, { - position: "absolute", + position: 'absolute', top: 0, left: 0, zIndex: 200 @@ -893,8 +921,7 @@ export default class Card { zoomedFig.className = 'zoomed-figure' zoomedFig.style.zIndex = this.zIndices.zoomedFigure let zoomedG = zoomedFig.querySelector('g') - if (zoomedG && !editable) - zoomedG.parentNode.removeChild(zoomedG) + if (zoomedG && !editable) zoomedG.parentNode.removeChild(zoomedG) zoomContainer.appendChild(zoomedFig) let zoomedImg = zoomedFig.querySelector('.mainimg') @@ -905,18 +932,18 @@ export default class Card { zoomedFig.zoomableGeometry = current //play video - let videoElement = zoomedFig.querySelector("video") + let videoElement = zoomedFig.querySelector('video') if (videoElement) { videoElement.play() } //logging - let imgElt = zoomedFig.querySelector("image") - let videoElt = zoomedFig.querySelector("video") + let imgElt = zoomedFig.querySelector('image') + let videoElt = zoomedFig.querySelector('video') //console.log('open zoomable:',imgElt,videoElt) if (imgElt) { let imgSrc = imgElt.getAttribute('xlink:href') - let strparts = imgSrc.split("/") + let strparts = imgSrc.split('/') let cardID = strparts[strparts.length - 2] let cardName = strparts[strparts.length - 1] let msg = 'ShowImage: ' + cardID + '/' + cardName @@ -925,7 +952,7 @@ export default class Card { } if (videoElt) { let videoSrc = videoElt.getAttribute('src') - let strparts = videoSrc.split("/") + let strparts = videoSrc.split('/') let cardID = strparts[strparts.length - 2] let cardName = strparts[strparts.length - 1] let msg = 'ShowVideo: ' + cardID + '/' + cardName @@ -937,14 +964,17 @@ export default class Card { // It's just an indicator that an action is possible. The click must be // captured from the whole subcard. - InteractionMapper.on(this.interactionType, zoomedFig, (event) => { + InteractionMapper.on(this.interactionType, zoomedFig, event => { this._cleanup(wrapper) }) let zoomedFigStyle = window.getComputedStyle(zoomedFig) - let borderX = parseFloat(zoomedFigStyle.borderLeftWidth) + parseFloat(zoomedFigStyle.borderRightWidth) - let borderY = parseFloat(zoomedFigStyle.borderBottomWidth) + parseFloat(zoomedFigStyle.borderTopWidth) - + let borderX = + parseFloat(zoomedFigStyle.borderLeftWidth) + + parseFloat(zoomedFigStyle.borderRightWidth) + let borderY = + parseFloat(zoomedFigStyle.borderBottomWidth) + + parseFloat(zoomedFigStyle.borderTopWidth) const scaleFactor = 2 const transformOrigin = 'bottom right' @@ -958,49 +988,66 @@ export default class Card { }) TweenLite.set(zoomable, { opacity: 0 }) - let icon = zoomedFig.querySelector(".icon") + let icon = zoomedFig.querySelector('.icon') TweenLite.set(icon, { transformOrigin }) - zoomedFig.style.transformOrigin = "calc(100% - " + parseFloat(zoomedFigStyle.borderRightWidth) + "px) calc(100% - " + parseFloat(zoomedFigStyle.borderBottomWidth) + "px)" - + zoomedFig.style.transformOrigin = + 'calc(100% - ' + + parseFloat(zoomedFigStyle.borderRightWidth) + + 'px) calc(100% - ' + + parseFloat(zoomedFigStyle.borderBottomWidth) + + 'px)' let tl = new TimelineLite() - let zoomCaption = zoomedFig.querySelector(".zoomcap") + let zoomCaption = zoomedFig.querySelector('.zoomcap') - tl.to(zoomedFig, Card.animation.zoomable, { - ease: Power2.easeIn, - css: { - scaleX: scaleFactor, - scaleY: scaleFactor - } - }, 0).set(zoomCaption, { - css: { - display: "block", - opacity: 0, - x: -parseFloat(zoomedFigStyle.borderLeftWidth), - width: current.width + borderX - } - }).to(zoomCaption, this.animation.fade, { - autoAlpha: 1 - }) - - } else this._openZoomableEditorBehaviour(wrapper, img, zoomable, zoomedFig, current) + tl.to( + zoomedFig, + Card.animation.zoomable, + { + ease: Power2.easeIn, + css: { + scaleX: scaleFactor, + scaleY: scaleFactor + } + }, + 0 + ) + .set(zoomCaption, { + css: { + display: 'block', + opacity: 0, + x: -parseFloat(zoomedFigStyle.borderLeftWidth), + width: current.width + borderX + } + }) + .to(zoomCaption, this.animation.fade, { + autoAlpha: 1 + }) + } else + this._openZoomableEditorBehaviour( + wrapper, + img, + zoomable, + zoomedFig, + current + ) } /** - * Selects and transforms the zoomicon from a zoomicon to a closeicon - * or the other way around. - * - * @static - * @param {DomElement} parent - Parent to be searched for an zoomicon. - * @memberof Card - */ + * Selects and transforms the zoomicon from a zoomicon to a closeicon + * or the other way around. + * + * @static + * @param {DomElement} parent - Parent to be searched for an zoomicon. + * @memberof Card + */ static _toggleNextIcon(parent) { let zoomIcon = Card._findNextIcon(parent) - const closeClass = "close" - const zoomClass = "zoom" + const closeClass = 'close' + const zoomClass = 'zoom' if (zoomIcon.classList.contains(closeClass)) { zoomIcon.classList.remove(closeClass) @@ -1009,7 +1056,9 @@ export default class Card { zoomIcon.classList.remove(zoomClass) zoomIcon.classList.add(closeClass) } else { - console.error(`Error Toggleing Zoomicon: It did neither contain a class named ${closeClass} or ${zoomClass}.`) + console.error( + `Error Toggleing Zoomicon: It did neither contain a class named ${closeClass} or ${zoomClass}.` + ) } } @@ -1017,9 +1066,13 @@ export default class Card { return parent.querySelector('.icon') } - - static _openZoomableEditorBehaviour(wrapper, img, zoomable, zoomedFig, current) { - + static _openZoomableEditorBehaviour( + wrapper, + img, + zoomable, + zoomedFig, + current + ) { let zoomContainer = document.createElement('div') let zoomIcon = zoomable.querySelector('.zoom-icon') zoomContainer.style.position = 'relative' @@ -1029,7 +1082,12 @@ export default class Card { zoomParent.appendChild(zoomedFig) zoomedFig.style.opacity = 0.5 zoomContainer.appendChild(zoomable) - TweenLite.set(zoomable, { x: current.x, y: current.y, width: current.width, height: current.height }) + TweenLite.set(zoomable, { + x: current.x, + y: current.y, + width: current.width, + height: current.height + }) let editor = mainController.topController().ensureEditor(img) let savedDisplay = zoomIcon.style.display let iconClone = zoomIcon.cloneNode(true) @@ -1067,7 +1125,10 @@ export default class Card { event.preventDefault() let dx = event.pageX - zoomable.dragStartPos.x let dy = event.pageY - zoomable.dragStartPos.y - TweenLite.set([zoomable, iconClone], { x: '+=' + dx, y: '+=' + dy }) + TweenLite.set([zoomable, iconClone], { + x: '+=' + dx, + y: '+=' + dy + }) zoomable.dragStartPos = { x: event.pageX, y: event.pageY } if (editor) { editor.showControls() @@ -1094,7 +1155,6 @@ export default class Card { return } - /** * Closes a zoomable object with animation * @@ -1106,19 +1166,18 @@ export default class Card { * @memberof Card */ static closeZoomable(context, zoomable, zoomedFig) { - - if (this.debug) console.log("Close Zoomable", context, zoomable, zoomedFig) + if (this.debug) + console.log('Close Zoomable', context, zoomable, zoomedFig) if (zoomable) { this._unsetZoomable(context) - let caption = zoomable.querySelector("figcaption.cap") + let caption = zoomable.querySelector('figcaption.cap') zoomable.removeChild(caption) zoomable.appendChild(caption) - let zoomedCaption = zoomedFig.querySelector("figcaption.zoomcap") - + let zoomedCaption = zoomedFig.querySelector('figcaption.zoomcap') TweenLite.to(zoomedCaption, this.animation.fade, { - autoAlpha: 0, + autoAlpha: 0 }) TweenLite.to(zoomedFig, this.animation.zoomable, { @@ -1132,8 +1191,7 @@ export default class Card { }) let div = zoomedFig.parentNode let videoElement = div.querySelector('video') - if (videoElement) - videoElement.pause() + if (videoElement) videoElement.pause() div.parentNode.removeChild(div) } }) @@ -1160,7 +1218,13 @@ export default class Card { * @param {*} src - The src of the expanded element * @param {*} callback - A callback that is called when the expanded element is closed */ - static expandIndexCard(card, html, tagName = 'article', src = null, callback = null) { + static expandIndexCard( + card, + html, + tagName = 'article', + src = null, + callback = null + ) { let editable = Card.isEditable() let context = this.getContext(card) @@ -1168,35 +1232,35 @@ export default class Card { this._cleanup(context) - let angle = 0 // UO: out of context, to be computed from the scatter let clone = card.cloneNode(true) - /** * We have to reorder the clone, as it still contains the * preview text image. And the new html is * inserted before everything else. */ - let cloneWrapper = clone.querySelector(".wrapper") - const article = html.body.querySelector("article") + let cloneWrapper = clone.querySelector('.wrapper') + const article = html.body.querySelector('article') - let subcardContent = clone.querySelector(".subcard-content") + let subcardContent = clone.querySelector('.subcard-content') subcardContent.appendChild(article) cloneWrapper.parentNode.removeChild(cloneWrapper) /* Removes the 'default' cleanup on the card */ - clone.removeAttribute("onclick") - InteractionMapper.on(this.interactionType, clone, (event) => { + clone.removeAttribute('onclick') + InteractionMapper.on(this.interactionType, clone, event => { this._cleanup(context) }) let articleClone = clone.querySelector(tagName) - let globalPreviewRect = Card._getGlobalRect(card) let globalIndexCardRect = Card._getGlobalRect(indexbox) - let localOrigin = Points.fromPageToNode(indexbox, Rect.getPosition(globalPreviewRect)) + let localOrigin = Points.fromPageToNode( + indexbox, + Rect.getPosition(globalPreviewRect) + ) let scaleX = globalPreviewRect.width / globalIndexCardRect.width let scaleY = globalPreviewRect.height / globalIndexCardRect.height @@ -1226,21 +1290,21 @@ export default class Card { scaleX, scaleY, transformOrigin: '0% 0%', - rotation: angle, + rotation: angle }) indexbox.prepend(clone) - let titlebar = clone.querySelector(".titlebar") - let title = titlebar.querySelector("h2") + let titlebar = clone.querySelector('.titlebar') + let title = titlebar.querySelector('h2') let titlebarStyle = window.getComputedStyle(titlebar) let start = { height: parseInt(titlebarStyle.height) } if (this.dynamicHeight) { - let targetHeight = subcardContent.offsetHeight; + let targetHeight = subcardContent.offsetHeight console.log(targetHeight) - subcardContent.classList.add("dynamic-height") + subcardContent.classList.add('dynamic-height') /** * Scale the content from 100% to it's target size. */ @@ -1253,23 +1317,29 @@ export default class Card { } //jquery hyphenate below - if (typeof($) != 'undefined') { - $('.column').not('.overview').children('p').hyphenate('de') + if (typeof $ != 'undefined') { + $('.column') + .not('.overview') + .children('p') + .hyphenate('de') } //logging if (src) { - let strparts = src.split("/") + let strparts = src.split('/') let cardID = strparts[strparts.length - 2] let cardName = strparts[strparts.length - 1] - strparts = card.className.split(" ") + strparts = card.className.split(' ') let cardType = strparts[1] - let msg = 'Card: ' + cardID + ': openTopic: ' + cardType + ', ' + cardName + let msg = + 'Card: ' + cardID + ': openTopic: ' + cardType + ', ' + cardName console.log('Logging:', msg) Logging.log(msg) } - let desiredBorderBottomWidth = parseInt(window.getComputedStyle(titlebar).borderBottomWidth) + let desiredBorderBottomWidth = parseInt( + window.getComputedStyle(titlebar).borderBottomWidth + ) TweenLite.to(clone, Card.animation.articleTransition, { x: -padding, y: -padding, @@ -1277,20 +1347,21 @@ export default class Card { scale: 1, rotation: 0, onComplete: () => { - card.classList.add("visited") + card.classList.add('visited') }, onUpdateParams: ['{self}'], - onUpdate: (self) => { + onUpdate: self => { let transform = self.target._gsTransform TweenLite.set(title, { scale: 1 / transform.scaleX }) TweenLite.set(titlebar, { - height: start.height * 1 / transform.scaleY + height: (start.height * 1) / transform.scaleY }) // Retain the border at same visual thickness. - titlebar.style.borderBottomWidth = desiredBorderBottomWidth / transform.scaleY + "px" + titlebar.style.borderBottomWidth = + desiredBorderBottomWidth / transform.scaleY + 'px' } }) @@ -1308,12 +1379,18 @@ export default class Card { const closeAnimation = () => { //logging if (src) { - let strparts = src.split("/") + let strparts = src.split('/') let cardID = strparts[strparts.length - 2] let cardName = strparts[strparts.length - 1] - strparts = card.className.split(" ") + strparts = card.className.split(' ') let cardType = strparts[1] - let msg = 'Card: ' + cardID + ': closeTopic: ' + cardType + ', ' + cardName + let msg = + 'Card: ' + + cardID + + ': closeTopic: ' + + cardType + + ', ' + + cardName console.log('Logging:', msg) Logging.log(msg) } @@ -1323,9 +1400,9 @@ export default class Card { this._enableCardCloseButton(context) - let previewTitlebar = card.querySelector(".titlebar") + let previewTitlebar = card.querySelector('.titlebar') let titlebarStyle = window.getComputedStyle(previewTitlebar) - let titlebar = clone.querySelector(".titlebar") + let titlebar = clone.querySelector('.titlebar') TweenLite.to(titlebar, this.animation.articleTransition, { height: parseInt(titlebarStyle.height) @@ -1335,14 +1412,14 @@ export default class Card { autoAlpha: 0 }) - let title = titlebar.querySelector("h2") + let title = titlebar.querySelector('h2') let original = { height: parseInt(titlebarStyle.height) } if (this.dynamicHeight) { TweenLite.to(subcardContent, this.animation.articleTransition, { - height: "100%" + height: '100%' }) } @@ -1356,21 +1433,19 @@ export default class Card { rotation: angle, onComplete: () => { // article.remove() - TweenLite.to(clone, this.animation.fade, - { - //delay: 0.2, - autoAlpha: 0, - onComplete: - () => { - if (editable) { - mainController.popController() - } - clone.remove() - } - }) + TweenLite.to(clone, this.animation.fade, { + //delay: 0.2, + autoAlpha: 0, + onComplete: () => { + if (editable) { + mainController.popController() + } + clone.remove() + } + }) }, - onUpdateParams: ["{self}"], - onUpdate: function (self) { + onUpdateParams: ['{self}'], + onUpdate: function(self) { let transform = self.target._gsTransform TweenLite.set(title, { @@ -1378,11 +1453,12 @@ export default class Card { }) TweenLite.set(titlebar, { - height: original.height * 1 / transform.scaleY + height: (original.height * 1) / transform.scaleY }) // Retain the border at same visual thickness. - titlebar.style.borderBottomWidth = desiredBorderBottomWidth / transform.scaleY + "px" + titlebar.style.borderBottomWidth = + desiredBorderBottomWidth / transform.scaleY + 'px' } }) } @@ -1391,16 +1467,22 @@ export default class Card { let iconClone = clone.querySelector('.card-icon') if (iconClone == null) { - iconClone = clone.querySelector(".cardicon") - console.warn("Legacy selector. Change it to 'card-icon' and find a more suitable name.") + iconClone = clone.querySelector('.cardicon') + console.warn( + "Legacy selector. Change it to 'card-icon' and find a more suitable name." + ) } - if (iconClone.tagName == "img") { + if (iconClone.tagName == 'img') { iconClone.src = iconClone.src.replace('info.svg', 'close.svg') } //console.log("ICON: ", iconClone) - iconClone.classList.remove("info") - iconClone.classList.add("close", "view-button", "transparent-background") + iconClone.classList.remove('info') + iconClone.classList.add( + 'close', + 'view-button', + 'transparent-background' + ) // We append the icon clone to the subcard-content. // Then it's always on the content and not on the background @@ -1411,8 +1493,8 @@ export default class Card { if (enableNearestNeighborTaps) { //look for nearby popups on tap - InteractionMapper.on("tap", indexbox, () => { - console.log("Tap handler called", editable) + InteractionMapper.on('tap', indexbox, () => { + console.log('Tap handler called', editable) if (!editable) { this.findNearbyPopups(event, card) } @@ -1421,7 +1503,7 @@ export default class Card { // Use the 'tap' event for closing. // Otherwise the subcard cannot be closed, // when another subcard is touched. - InteractionMapper.on("tap", iconClone, () => { + InteractionMapper.on('tap', iconClone, () => { if (editable) { let isDirty = mainController.askSaveNode() if (isDirty) { @@ -1429,12 +1511,10 @@ export default class Card { callback(url) closeAnimation() }) - } - else { + } else { closeAnimation() } - } - else { + } else { closeAnimation() } }) @@ -1470,23 +1550,22 @@ export default class Card { static openIndexCard(event, src) { //console.log("openIndexCard", src) /* - * Called by the expandIndexCard(...) - */ + * Called by the expandIndexCard(...) + */ let target = event.target - const saveCallback = (url) => { + const saveCallback = url => { let handler = `Card.openIndexCard(event, '${url}')` - console.log("File has changed", target, handler) + console.log('File has changed', target, handler) //TODO If this is required, it should be accessing the interaction type. - target.setAttribute("onclick", handler) + target.setAttribute('onclick', handler) } let context = this.getContext(target) let subcard = this._getSubcard(context) //console.log("openIndexCard", { context, subcard }) //Dont proceeed if a subcard is active - if (subcard != null) - return + if (subcard != null) return // In edit mode we only accept icon clicks let editable = Card.isEditable() @@ -1510,7 +1589,13 @@ export default class Card { // card.insertAdjacentElement('afterbegin', article) // TweenLite.set(article, { autoAlpha: 0 }) - Card.expandIndexCard(card, parsedHTML, 'article', relativeSource, saveCallback) + Card.expandIndexCard( + card, + parsedHTML, + 'article', + relativeSource, + saveCallback + ) } } xhr.onerror = () => { @@ -1519,24 +1604,22 @@ export default class Card { xhr.send() } - static _selectCardCloseButton(context) { - return context.querySelector(".mainview > .button.close") + return context.querySelector('.mainview > .button.close') } static _enableCardCloseButton(context) { //console.log("ENABLE") let btn = this._selectCardCloseButton(context) //console.log(btn) - btn.classList.remove("disabled") + btn.classList.remove('disabled') } static _disableCardCloseButton(context) { let btn = this._selectCardCloseButton(context) - btn.classList.add("disabled") + btn.classList.add('disabled') } - /** * Provides the nearest info-card of the provided item. * @@ -1546,10 +1629,12 @@ export default class Card { * @memberof Card */ static getContext(child) { - let dom = child.closest(".info-card") + let dom = child.closest('.info-card') if (!dom) { - dom = child.querySelector(".wrapper") - console.warn("Change the 'wrapper' class to 'info-card' it's more suitable.") + dom = child.querySelector('.wrapper') + console.warn( + "Change the 'wrapper' class to 'info-card' it's more suitable." + ) } return dom // (dom == null) ? document.body : dom } @@ -1562,7 +1647,6 @@ export default class Card { * @memberof Card */ static _cleanup(context) { - let [zoomable, zoomedFig] = this._getZoomable(context) if (zoomable && zoomedFig) { this.closeZoomable(context, zoomable, zoomedFig) @@ -1575,14 +1659,14 @@ export default class Card { let highlights = this._getHighlights(context) highlights.forEach(highlight => { - Highlight.closeHighlight(highlight, { animation: Card.highlightAnimation }) + Highlight.closeHighlight(highlight, { + animation: Card.highlightAnimation + }) }) this._unsetHighlights(context) } - - /** * Retrieves an Rectangle for an element in the local space of a provided context. * @@ -1596,7 +1680,10 @@ export default class Card { */ static _getContextRect(context, element) { let global = this._getGlobalRect(element) - let localPosition = Points.fromPageToNode(context, { x: global.x, y: global.y }) + let localPosition = Points.fromPageToNode(context, { + x: global.x, + y: global.y + }) return DOMRectReadOnly.fromRect({ x: localPosition.x, y: localPosition.y, @@ -1605,7 +1692,6 @@ export default class Card { }) } - /** * Gets a rectangle in global space for a provided element. * @@ -1630,37 +1716,37 @@ export default class Card { } /** - * Adjusts all links - * - * @static - * @param {*} htmlString - * @returns - * @memberof Card - */ + * Adjusts all links + * + * @static + * @param {*} htmlString + * @returns + * @memberof Card + */ static postProcessResponseText(htmlString) { let editable = this.isEditable() htmlString = this._adjustRelativeLinks(htmlString) //console.log(htmlString) let parser = new DOMParser() - let html = parser.parseFromString(htmlString, "text/html") + let html = parser.parseFromString(htmlString, 'text/html') if (!editable) { - this._replaceAttributes(html, "onclick", this._replaceCallback) + this._replaceAttributes(html, 'onclick', this._replaceCallback) } - let zoomableWrappers = html.querySelectorAll(".svg-wrapper") + let zoomableWrappers = html.querySelectorAll('.svg-wrapper') zoomableWrappers.forEach(wrapper => { - let svg = wrapper.querySelector("svg") + let svg = wrapper.querySelector('svg') Object.assign(wrapper.style, { - width: svg.getAttribute("width") + "px", - height: svg.getAttribute("height") + "px" + width: svg.getAttribute('width') + 'px', + height: svg.getAttribute('height') + 'px' }) }) - let zoomableVideoWrappers = html.querySelectorAll(".video-wrapper") + let zoomableVideoWrappers = html.querySelectorAll('.video-wrapper') zoomableVideoWrappers.forEach(wrapper => { - let video = wrapper.querySelector("video") + let video = wrapper.querySelector('video') Object.assign(wrapper.style, { - width: video.getAttribute("width") + "px", - height: video.getAttribute("height") + "px" + width: video.getAttribute('width') + 'px', + height: video.getAttribute('height') + 'px' }) }) @@ -1675,7 +1761,7 @@ export default class Card { */ static openPopupOrZoomable(event) { let target = this._preferFirstTarget(event) - if (target.tagName == "circle") { + if (target.tagName == 'circle') { Card.loadHighlightPopup(event) event.stopPropagation() } else { @@ -1693,16 +1779,29 @@ export default class Card { if (event.target) { //let column = event.target.closest(".column") let indexbox = this.closestWithClass(card, 'mainview') - if (indexbox != null) { // column != null || - let links = Array.from(indexbox.getElementsByTagName("a")) - let globalClick = (event.center) ? event.center : { x: event.x, y: event.y } + if (indexbox != null) { + // column != null || + let links = Array.from(indexbox.getElementsByTagName('a')) + let globalClick = event.center + ? event.center + : { x: event.x, y: event.y } let localClick = Points.fromPageToNode(indexbox, globalClick) let linkRects = links.map(link => { let rect = link.getBoundingClientRect() let topLeft = Points.fromPageToNode(indexbox, rect) - let center = Points.fromPageToNode(indexbox, { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 }) - return { x: topLeft.x, y: topLeft.y, width: rect.width, height: rect.height, center, link } + let center = Points.fromPageToNode(indexbox, { + x: rect.x + rect.width / 2, + y: rect.y + rect.height / 2 + }) + return { + x: topLeft.x, + y: topLeft.y, + width: rect.width, + height: rect.height, + center, + link + } }) let distances = [] @@ -1720,9 +1819,16 @@ export default class Card { let closestLinkIndex = distances.indexOf(Math.min(...distances)) let closestLink = links[closestLinkIndex] - console.log("finding closest links", closestLink, closestLink.getClientRects()) + console.log( + 'finding closest links', + closestLink, + closestLink.getClientRects() + ) - if (distances[closestLinkIndex] < 44 && closestLink.getAttribute("href")) { + if ( + distances[closestLinkIndex] < 44 && + closestLink.getAttribute('href') + ) { // Adapt context and local position let context = this.getContext(closestLink) let local = Points.fromPageToNode(context, globalClick) @@ -1735,16 +1841,14 @@ export default class Card { } } - /** * Evaluates an event, if it has a first target. If so it returns the first target, * otherwise it returns the target. */ static _preferFirstTarget(event) { - return (event.firstTarget) ? event.firstTarget : event.target + return event.firstTarget ? event.firstTarget : event.target } - /** * Getter, Setter and 'Unsetter' for the properties hooked onto the context element. */ @@ -1757,7 +1861,7 @@ export default class Card { this._setPopupSource(popup, source) context.popup = popup - if (typeof($) != 'undefined') { + if (typeof $ != 'undefined') { //jquery hyphenate below console.log('hyphenated popup:', $('span').hyphenate('de')) } @@ -1768,11 +1872,11 @@ export default class Card { } static _setPopupSource(popup, source) { - popup.element.setAttribute("data-src", source) + popup.element.setAttribute('data-src', source) } static _getPopupSource(popup) { - return popup.element.getAttribute("data-src") + return popup.element.getAttribute('data-src') } static _unsetZoomable(context) { @@ -1784,20 +1888,20 @@ export default class Card { } static _getZoomable(context) { - return (context.zoomable) ? context.zoomable : [] + return context.zoomable ? context.zoomable : [] } /** - * Helper function to determine if a proided element is still - * an active highlight. - */ + * Helper function to determine if a proided element is still + * an active highlight. + */ static _isHighlightActive(context, element) { let highlights = this._getHighlights(context) - return (highlights.indexOf(element) != -1) + return highlights.indexOf(element) != -1 } static _getHighlights(context) { - return (context.highlights) ? context.highlights : [] + return context.highlights ? context.highlights : [] } static _addHighlight(context, highlight) { @@ -1810,11 +1914,11 @@ export default class Card { } static _getHighlightSource(highlight) { - return highlight.getAttribute("xlink:href") + return highlight.getAttribute('xlink:href') } static _getActiveSubcard(context) { - return context.querySelector(".mainview > .subcard") + return context.querySelector('.mainview > .subcard') } static _setSubcard(context, subcard) { @@ -1836,7 +1940,7 @@ export default class Card { } static getZIndex(context) { - return (context.zIndex || 0) + return context.zIndex || 0 } /** @@ -1856,14 +1960,13 @@ export default class Card { static get relativePath() { return Card._relativePath } - } Card.debug = true -Card._relativePath = "" +Card._relativePath = '' Card.scatterContainer = null -Card.interactionType = "tap" -Card.popupHtmlSelector = ".popupHtml" +Card.interactionType = 'tap' +Card.popupHtmlSelector = '.popupHtml' Card.dynamicHeight = false Card.popupYOffset = -15 @@ -1882,4 +1985,3 @@ Card.animation = { highlight: 0.4, zoomable: 0.5 } - diff --git a/lib/card/highlight.js b/lib/card/highlight.js index b559c79..b0abdfc 100644 --- a/lib/card/highlight.js +++ b/lib/card/highlight.js @@ -4,17 +4,15 @@ let _HighlightEnabled = true let _CircleIds = 0 - /** Helper method to round values with one digit precision */ function round(value) { return Math.round(parseFloat(value) * 10) / 10 } - /** * A namespace with static functions to expand and shrink highlighted image regions. * Assumes an SVG image with the following structure: - * + * * * * @@ -23,15 +21,14 @@ function round(value) { * * * - * + * * The SVG root element should use a viewbox with 0 0 100 100 to ensure that the positions and size of the * circles can be represnted in percent. - * + * * @class Highlight * @extends {Object} */ export default class Highlight extends Object { - static disableAnimations() { _HighlightEnabled = false let expanded = document.querySelectorAll('.expanded') @@ -64,7 +61,10 @@ export default class Highlight extends Object { if (circle.classList.length == 0) { circle.removeAttribute('class') } - if (circle.hasAttribute('id') && circle.getAttribute('id').startsWith('@@')) { + if ( + circle.hasAttribute('id') && + circle.getAttribute('id').startsWith('@@') + ) { circle.removeAttribute('id') } circle.removeAttribute('data-svg-origin') @@ -79,9 +79,11 @@ export default class Highlight extends Object { } } - static expand(obj, { scale = 2, duration = 3, stroke = 2, onComplete = null } = {}) { - if (obj == null) - return + static expand( + obj, + { scale = 2, duration = 3, stroke = 2, onComplete = null } = {} + ) { + if (obj == null) return //console.log("expand") obj.classList.add('zooming') TweenLite.to(obj, duration, { @@ -102,8 +104,7 @@ export default class Highlight extends Object { static shrink(obj, { duration = 0.5, stroke = 2 } = {}) { //console.log("shrink") - if (obj == null) - return + if (obj == null) return obj.classList.add('zooming') TweenLite.to(obj, duration, { scale: 1, @@ -141,7 +142,6 @@ export default class Highlight extends Object { let circleGroup = circle.parentNode let image = svgRoot.querySelector('image') - let stroke = parseFloat(circleGroup.getAttribute('stroke-width') || 6) let defs = svgRoot.querySelector('defs') @@ -160,15 +160,16 @@ export default class Highlight extends Object { this.shrink(maskImage, { stroke }) return } - //console.log("animate called while zooming out -> expand") - } - else if (circle.classList.contains('zooming')) { + //console.log("animate called while zooming out -> expand") + } else if (circle.classList.contains('zooming')) { //console.log("animate called while zooming in -> shrink") this.shrink(circle, { stroke }) this.shrink(maskImage, { stroke }) return } - let circles = Array.from(circleGroup.children).filter(e => e.tagName == 'circle') + let circles = Array.from(circleGroup.children).filter( + e => e.tagName == 'circle' + ) for (let c of circles) { //console.log("shrinking all circles") this.shrink(c, { stroke }) @@ -188,11 +189,10 @@ export default class Highlight extends Object { return false } - static openHighlight(target, { - animation = 0.5, - scale = 2, - onExpanded = null - } = {}) { + static openHighlight( + target, + { animation = 0.5, scale = 2, onExpanded = null } = {} + ) { if (Highlight._isExpanded(target)) { console.log('Target is already expanded!') return @@ -206,7 +206,10 @@ export default class Highlight extends Object { let image = parent.querySelector(imageId) if (image) { this._bringToFront(image) - } else console.error('Could not find corresponding image element.') + } else + console.error( + 'Could not find corresponding image element.' + ) } else console.log('Element was no parent:', target) } this._bringToFront(target) @@ -215,10 +218,15 @@ export default class Highlight extends Object { let image = svgRoot.querySelector('image') // eslint-disable-next-line no-unused-vars - let [mask, maskImage] = Highlight._getSVGMask(target, { svgRoot, image }) + let [mask, maskImage] = Highlight._getSVGMask(target, { + svgRoot, + image + }) let center = Highlight._calculateCenterRelativeTo(target, image) - TweenLite.set(maskImage, { transformOrigin: `${center.x}% ${center.y}%` }) + TweenLite.set(maskImage, { + transformOrigin: `${center.x}% ${center.y}%` + }) TweenLite.set(target, { transformOrigin: '50% 50%' }) TweenLite.to([target, maskImage], animation, { @@ -233,8 +241,7 @@ export default class Highlight extends Object { static toggleHighlight(node) { if (Highlight._isExpanded(node)) { Highlight.closeHighlight(node) - } - else { + } else { Highlight.openHighlight(node) } } @@ -244,7 +251,12 @@ export default class Highlight extends Object { if (target && parent) { parent.removeChild(target) parent.appendChild(target) - } else console.error('Could not bring to front. Either no target or no parent.', target, parent) + } else + console.error( + 'Could not bring to front. Either no target or no parent.', + target, + parent + ) } static _getSVGMask(circle, { svgRoot = null, image = null } = {}) { @@ -258,13 +270,15 @@ export default class Highlight extends Object { let maskImage = svgRoot.getElementById(maskImageId) if (!mask || !maskImage) - [mask, maskImage] = Highlight._createSVGMask(circle, { svgRoot, image, id }) + [mask, maskImage] = Highlight._createSVGMask(circle, { + svgRoot, + image, + id + }) return [mask, maskImage] } - - /** * Creates an SVG mask for a provided svgElement. * @@ -277,8 +291,10 @@ export default class Highlight extends Object { * @returns * @memberof Highlight */ - static _createSVGMask(element, { svgRoot = null, image = null, id = null } = {}) { - + static _createSVGMask( + element, + { svgRoot = null, image = null, id = null } = {} + ) { // We can fetch these values here, but it's more efficient to // simply pass them in, as it's likely they were already retrieved beforehand. if (svgRoot == null) svgRoot = element.closest('svg') @@ -316,7 +332,6 @@ export default class Highlight extends Object { let height = bbox.height if (maskImage == null) { - maskImage = document.createElementNS(svg, 'image') maskImage.style.pointerEvents = 'none' maskImage.setAttribute('id', maskImageId) @@ -369,8 +384,7 @@ export default class Highlight extends Object { } static animate(event) { - if (!_HighlightEnabled) - return + if (!_HighlightEnabled) return event.stopPropagation() Highlight.animateCircle(event.target) @@ -394,4 +408,3 @@ export default class Highlight extends Object { } Highlight.expandedClass = 'expanded' - diff --git a/lib/card/plugin.js b/lib/card/plugin.js index 82afa87..9d38249 100644 --- a/lib/card/plugin.js +++ b/lib/card/plugin.js @@ -1,13 +1,12 @@ export var CardPlugin = CardPlugin || {} export class CardPluginBase { - apply(context) { if (this.verify(context)) { this.append(context) - console.log("Plugin " + this.name + " was verified successfully.") + console.log('Plugin ' + this.name + ' was verified successfully.') return true - } else console.error("Could not verify module " + this.name + ".") + } else console.error('Could not verify module ' + this.name + '.') return false } @@ -32,19 +31,20 @@ export class CardPluginBase { missing.push(selector) } } - const valid = (missing.length == 0) - if (!valid) console.error("Elements were missing: ", missing.join(", ")) + const valid = missing.length == 0 + if (!valid) console.error('Elements were missing: ', missing.join(', ')) return valid } - /** * Appends the Plugin to the context. * * @memberof CardPlugin */ append(context) { - console.error("Call of abstract method CardPlugin.prototype.append(context). Plugins need to overwrite the append method!") + console.error( + 'Call of abstract method CardPlugin.prototype.append(context). Plugins need to overwrite the append method!' + ) } _getVerificationFunctions(context) { @@ -56,7 +56,7 @@ export class CardPluginBase { _verifyContext(context) { if (!(context instanceof HTMLElement)) { - console.error("Context is not of type HTML Element.", context) + console.error('Context is not of type HTML Element.', context) return false } else return true } @@ -71,13 +71,18 @@ export class CardPluginBase { } }) - const valid = (missing.length == 0) - if (!valid) console.error("Could not apply module '" + this.name + "'. Following modules are required but were missing: " + missing.join(",")) - else console.log("All requirements were met! Well done!") + const valid = missing.length == 0 + if (!valid) + console.error( + "Could not apply module '" + + this.name + + "'. Following modules are required but were missing: " + + missing.join(',') + ) + else console.log('All requirements were met! Well done!') return valid } - _collectAllRequirements() { let requirements = [] let klass = this.__proto__ @@ -91,9 +96,6 @@ export class CardPluginBase { } } - - - CardPlugin.LightBox = class LightBox extends CardPluginBase { constructor(className, style = {}) { super() @@ -102,27 +104,30 @@ CardPlugin.LightBox = class LightBox extends CardPluginBase { } append(context) { - let wrapper = document.createElement("div") + let wrapper = document.createElement('div') wrapper.className = this.className - Object.assign(wrapper.style, { - zIndex: 1000, - // backgroundColor: "black", - top: 0, - left: 0, - width: "100%", - height: "100%" - }, this.style, { - display: "none", - position: "absolute", - }) + Object.assign( + wrapper.style, + { + zIndex: 1000, + // backgroundColor: "black", + top: 0, + left: 0, + width: '100%', + height: '100%' + }, + this.style, + { + display: 'none', + position: 'absolute' + } + ) context.appendChild(wrapper) } - } - /** * The Enlargeable Overlay module allows the user to click on the thumbnail image, * and the images gets enlarged inside the card. @@ -131,12 +136,15 @@ CardPlugin.LightBox = class LightBox extends CardPluginBase { * @extends {CardPlugin} */ CardPlugin.EnlargeableThumbnail = class EnlargeableThumbnail extends CardPluginBase { - - constructor(wrapperSelector, overlaySelector = null, { - zoomAnimationDuration = 0.4, - fadeAnimationDuration = 0.4, - interactionType = "tap" - } = {}) { + constructor( + wrapperSelector, + overlaySelector = null, + { + zoomAnimationDuration = 0.4, + fadeAnimationDuration = 0.4, + interactionType = 'tap' + } = {} + ) { super() this.wrapperSelector = wrapperSelector this.overlaySelector = overlaySelector @@ -147,15 +155,18 @@ CardPlugin.EnlargeableThumbnail = class EnlargeableThumbnail extends CardPluginB } get require() { - return [ - CardPlugin.LightBox - ] + return [CardPlugin.LightBox] } _getVerificationFunctions(context) { let arr = super._getVerificationFunctions(context) let funcs = [ - this._verifyElementsExist.bind(this, context, this.wrapperSelector, this.overlaySelector) + this._verifyElementsExist.bind( + this, + context, + this.wrapperSelector, + this.overlaySelector + ) ] return arr.concat(funcs) } @@ -165,7 +176,6 @@ CardPlugin.EnlargeableThumbnail = class EnlargeableThumbnail extends CardPluginB this.setupEnlargeableThumbnail(context, source) } - /** * Get the preview image. * @@ -177,26 +187,25 @@ CardPlugin.EnlargeableThumbnail = class EnlargeableThumbnail extends CardPluginB * @memberof EnlargeableThumbnail */ _retrieveSource(context) { - let img = context.querySelector(this.wrapperSelector + " img") - let src = img.getAttribute("src") - let parts = src.split("/") + let img = context.querySelector(this.wrapperSelector + ' img') + let src = img.getAttribute('src') + let parts = src.split('/') parts.pop() parts.push(parts[parts.length - 1]) - let imagePath = parts.join("/") + ".jpg" + let imagePath = parts.join('/') + '.jpg' return imagePath } - setupEnlargeableThumbnail(context, src) { let wrapper = context.querySelector(this.wrapperSelector) let overlay = context.querySelector(this.overlaySelector) - let icon = document.createElement("div") - icon.className = "button corner-button bottom-right icon zoom" + let icon = document.createElement('div') + icon.className = 'button corner-button bottom-right icon zoom' wrapper.appendChild(icon) Object.assign(wrapper.style, { - cursor: "pointer" + cursor: 'pointer' }) InteractionMapper.on(this.interactionType, wrapper, () => { @@ -209,28 +218,28 @@ CardPlugin.EnlargeableThumbnail = class EnlargeableThumbnail extends CardPluginB } openThumbnailDetail(context, src) { - let overlay = context.querySelector(".img-overlay") - overlay.innerHTML = "" + let overlay = context.querySelector('.img-overlay') + overlay.innerHTML = '' let source = context.querySelector(this.wrapperSelector) let sourceStyle = window.getComputedStyle(source) let imageWrapper = source.cloneNode(true) - let image = imageWrapper.querySelector("img") + let image = imageWrapper.querySelector('img') Object.assign(imageWrapper.style, { - maxWidth: "none", - maxHeight: "none" + maxWidth: 'none', + maxHeight: 'none' }) Object.assign(image.style, { - width: "100%", - height: "100%", - objectFit: "cover" + width: '100%', + height: '100%', + objectFit: 'cover' }) this._replaceIcon(imageWrapper) image.onload = () => { - let header = context.querySelector("header") + let header = context.querySelector('header') let headerStlye = window.getComputedStyle(header) /** @@ -242,20 +251,20 @@ CardPlugin.EnlargeableThumbnail = class EnlargeableThumbnail extends CardPluginB /** * The minor side should not exceed the height of the context window. */ - const maxMinorSize = context.offsetHeight - 2 * parseInt(headerStlye.paddingTop) - 2 * parseInt(headerStlye.marginTop) - - + const maxMinorSize = + context.offsetHeight - + 2 * parseInt(headerStlye.paddingTop) - + 2 * parseInt(headerStlye.marginTop) const max = { width: context.offsetWidth * maxFillRatio, height: context.offsetHeight * maxFillRatio } - let majorSide let minorSide - const _width = { name: "width", axis: "x" } - const _height = { name: "height", axis: "y" } + const _width = { name: 'width', axis: 'x' } + const _height = { name: 'height', axis: 'y' } if (image.naturalHeight > image.naturalWidth) { majorSide = _height minorSide = _width @@ -268,14 +277,17 @@ CardPlugin.EnlargeableThumbnail = class EnlargeableThumbnail extends CardPluginB return string.charAt(0).toUpperCase() + string.slice(1) } function getImageSize(side) { - return image["natural" + capitalize(side.name)] + return image['natural' + capitalize(side.name)] } const majorImageSize = getImageSize(majorSide) // const minorImageSize = getImageSize(minorSide) let ratio = getImageSize(minorSide) / getImageSize(majorSide) - let size = (majorImageSize > max[majorSide.name]) ? max[majorSide.name] : majorImageSize + let size = + majorImageSize > max[majorSide.name] + ? max[majorSide.name] + : majorImageSize if (size * ratio > maxMinorSize) { size = maxMinorSize / ratio @@ -286,8 +298,10 @@ CardPlugin.EnlargeableThumbnail = class EnlargeableThumbnail extends CardPluginB height: 0 } - - let position = Points.fromPageToNode(context, Points.fromNodeToPage(source, { x: 0, y: 0 })) + let position = Points.fromPageToNode( + context, + Points.fromNodeToPage(source, { x: 0, y: 0 }) + ) let targetOffset = { x: 0, @@ -297,8 +311,14 @@ CardPlugin.EnlargeableThumbnail = class EnlargeableThumbnail extends CardPluginB targetDimensions[majorSide.name] = size targetDimensions[minorSide.name] = size * ratio - targetOffset[majorSide.axis] = (context["offset" + capitalize(majorSide.name)] - targetDimensions[majorSide.name]) / 2 - targetOffset[minorSide.axis] = (context["offset" + capitalize(minorSide.name)] - targetDimensions[minorSide.name]) / 2 + targetOffset[majorSide.axis] = + (context['offset' + capitalize(majorSide.name)] - + targetDimensions[majorSide.name]) / + 2 + targetOffset[minorSide.axis] = + (context['offset' + capitalize(minorSide.name)] - + targetDimensions[minorSide.name]) / + 2 overlay.appendChild(imageWrapper) @@ -307,14 +327,13 @@ CardPlugin.EnlargeableThumbnail = class EnlargeableThumbnail extends CardPluginB top: 0, x: position.x, y: position.y, - position: "absolute", + position: 'absolute', width: parseInt(sourceStyle.width), height: parseInt(sourceStyle.height) }) - TweenMax.set(overlay, { - display: "flex", + display: 'flex', autoAlpha: 0 }) @@ -322,7 +341,7 @@ CardPlugin.EnlargeableThumbnail = class EnlargeableThumbnail extends CardPluginB x: targetOffset.x, y: targetOffset.y, width: targetDimensions.width, - height: targetDimensions.height, + height: targetDimensions.height }) TweenMax.to(overlay, this.fadeAnimationTime, { autoAlpha: 1 @@ -333,35 +352,40 @@ CardPlugin.EnlargeableThumbnail = class EnlargeableThumbnail extends CardPluginB } _replaceIcon(clone) { - let zoomIcon = clone.querySelector(".icon.zoom") - zoomIcon.classList.remove("zoom") - zoomIcon.classList.add("close") + let zoomIcon = clone.querySelector('.icon.zoom') + zoomIcon.classList.remove('zoom') + zoomIcon.classList.add('close') } getBorderHeight(style) { - const borderWidth = parseInt(style.borderTopWidth) + parseInt(style.borderBottomWidth) - const padding = parseInt(style.paddingTop) + parseInt(style.paddingBottom) + const borderWidth = + parseInt(style.borderTopWidth) + parseInt(style.borderBottomWidth) + const padding = + parseInt(style.paddingTop) + parseInt(style.paddingBottom) return parseInt(style.width) + borderWidth + padding } getBorderWidth(style) { - const borderWidth = parseInt(style.borderLeftWidth) + parseInt(style.borderRightWidth) - const padding = parseInt(style.paddingLeft) + parseInt(style.paddingRight) + const borderWidth = + parseInt(style.borderLeftWidth) + parseInt(style.borderRightWidth) + const padding = + parseInt(style.paddingLeft) + parseInt(style.paddingRight) return parseInt(style.width) + borderWidth + padding } closeThumnailDetail(context) { - let overlay = context.querySelector(".img-overlay") + let overlay = context.querySelector('.img-overlay') let timeline = new TimelineLite() - timeline.to(overlay, this.fadeAnimationDuration, { - autoAlpha: 0 - }).set(overlay, { - display: "none" - }) + timeline + .to(overlay, this.fadeAnimationDuration, { + autoAlpha: 0 + }) + .set(overlay, { + display: 'none' + }) } - } CardPlugin.Ui = class UiPlugin extends CardPluginBase { @@ -373,56 +397,52 @@ CardPlugin.Ui = class UiPlugin extends CardPluginBase { _getVerificationFunctions(context) { let arr = super._getVerificationFunctions(context) - let func = [ - this._doesParentExist.bind(this, context, this.parent) - ] + let func = [this._doesParentExist.bind(this, context, this.parent)] return arr.concat(func) } _doesParentExist(context, parent) { if (parent == null) return true - let valid = (context.querySelector(parent) != null) - if (!valid) console.error("Could not find parent on context.", context, parent) + let valid = context.querySelector(parent) != null + if (!valid) + console.error('Could not find parent on context.', context, parent) return valid } append(context) { - parent = (this.parent == null) ? context : context.querySelector(this.parent).appendChild(container) - let container = document.createElement("div") + parent = + this.parent == null + ? context + : context.querySelector(this.parent).appendChild(container) + let container = document.createElement('div') container.className = this.className parent.appendChild(container) } - } CardPlugin.Speech = class SpeechPlugin extends CardPluginBase { - - constructor(parentSelector, className, interactionType = "tap") { + constructor(parentSelector, className, interactionType = 'tap') { super() this.className = className this.parentSelector = parentSelector this.interactionType = interactionType - } get require() { - return [ - CardPlugin.Ui - ] + return [CardPlugin.Ui] } append(context) { let container = context.querySelector(this.parentSelector) - this.button = document.createElement("div") - this.button.className = "icon button " + this.className + this.button = document.createElement('div') + this.button.className = 'icon button ' + this.className container.appendChild(this.button) InteractionMapper.on(this.interactionType, this.button, () => { - let subcard = context.querySelector(".mainview > .subcard") - let target = (subcard) ? subcard : context + let subcard = context.querySelector('.mainview > .subcard') + let target = subcard ? subcard : context this.speak(target) - }) } @@ -433,8 +453,7 @@ CardPlugin.Speech = class SpeechPlugin extends CardPluginBase { } _activateButton() { - if (this.button) - this.button.classList.add("active") + if (this.button) this.button.classList.add('active') } _deactivate() { @@ -442,36 +461,32 @@ CardPlugin.Speech = class SpeechPlugin extends CardPluginBase { } _deactivateButton() { - if (this.button) - this.button.classList.remove("active") + if (this.button) this.button.classList.remove('active') } _isSameNode(node) { //console.log(this.currentText, node.innerText) - return (this.currentText == node.innerText) + return this.currentText == node.innerText } speak(node) { - console.log(this._isSameNode(node)) if (!window.speechSynthesis.speaking) { - console.log("Noone talking!") + console.log('Noone talking!') this._start(node) } else if (this._isSameNode(node)) { - console.log("Requested same!") + console.log('Requested same!') this._stop() - } else { - console.log("Requested Different!") + console.log('Requested Different!') this._stop() this._start(node) } - } _disableActive() { - console.log("disableActive:", this.active) + console.log('disableActive:', this.active) if (this.active) { this.active._deactivate() } @@ -483,28 +498,40 @@ CardPlugin.Speech = class SpeechPlugin extends CardPluginBase { let voices = window.speechSynthesis.getVoices() console.log(voices) - let voice = voices.filter((val) => { + let voice = voices.filter(val => { //console.log(val) - return val.name == "Microsoft Hedda Desktop - German" + return val.name == 'Microsoft Hedda Desktop - German' })[0] //console.log(voice) utterance.voice = voice - console.log("TALK: ", utterance) + console.log('TALK: ', utterance) window.speechSynthesis.speak(utterance) this._activate() window.speechSynthesis.resume() - - utterance.onboundary = () => { console.log("onboundary", node.innerText); if (this.currentText.substring(0, 5) != node.innerText.substring(0, 5)) { console.log("text for speech synth changed!", this.currentText, node.innerText); this._stop() } } - utterance.onend = () => console.log("onend", node.innerText) - utterance.onerror = () => console.log("onerror", node.innerText) - utterance.onmark = () => console.log("onmark", node.innerText) - utterance.onpause = () => console.log("onpause", node.innerText) - utterance.onresume = () => console.log("onresume", node.innerText) - utterance.onstart = () => console.log("onstart", node.innerText) - utterance.onerror = () => console.log("onerror", node.innerText) + utterance.onboundary = () => { + console.log('onboundary', node.innerText) + if ( + this.currentText.substring(0, 5) != + node.innerText.substring(0, 5) + ) { + console.log( + 'text for speech synth changed!', + this.currentText, + node.innerText + ) + this._stop() + } + } + utterance.onend = () => console.log('onend', node.innerText) + utterance.onerror = () => console.log('onerror', node.innerText) + utterance.onmark = () => console.log('onmark', node.innerText) + utterance.onpause = () => console.log('onpause', node.innerText) + utterance.onresume = () => console.log('onresume', node.innerText) + utterance.onstart = () => console.log('onstart', node.innerText) + utterance.onerror = () => console.log('onerror', node.innerText) } _stop() { @@ -517,7 +544,9 @@ CardPlugin.Speech = class SpeechPlugin extends CardPluginBase { return this.constructor.active } - set active(val) { this.constructor.active = val } + set active(val) { + this.constructor.active = val + } get currentText() { return this.constructor.text @@ -526,5 +555,4 @@ CardPlugin.Speech = class SpeechPlugin extends CardPluginBase { set currentText(val) { this.constructor.text = val } - } diff --git a/lib/card/scatter.js b/lib/card/scatter.js index 184761e..ffd4ac2 100644 --- a/lib/card/scatter.js +++ b/lib/card/scatter.js @@ -6,8 +6,6 @@ import Card from './card.js' * @class ScatterCard */ export default class ScatterCard extends Card { - - /** * TODO: Find a more suitable name. * Adjusts the HTML to work in the new context. @@ -19,32 +17,27 @@ export default class ScatterCard extends Card { * @param {*} [opts={}] * @memberof Card */ - static setup(context, htmlString, { - basePath = "./", - modules = [] - } = {}) { - context.classList.add("info-card") + static setup(context, htmlString, { basePath = './', modules = [] } = {}) { + context.classList.add('info-card') this.relativePath = basePath htmlString = this._adjustRelativeLinks(htmlString) let parser = new DOMParser() - let html = parser.parseFromString(htmlString, "text/html") + let html = parser.parseFromString(htmlString, 'text/html') /** * Conflicts with the FindTarget method of the Abstract scatter. */ - this._replaceAttributes(html, "onclick", this._replaceCallback) + this._replaceAttributes(html, 'onclick', this._replaceCallback) - - let content = html.querySelector(".mainview") + let content = html.querySelector('.mainview') context.appendChild(content) super.setup(context, modules) return context } - /** * Appends a close listener to the scatter element. * @@ -59,7 +52,6 @@ export default class ScatterCard extends Card { } } - /** * Creates a scatter for the card and applies the card to it, * @@ -71,11 +63,12 @@ export default class ScatterCard extends Card { * @returns * @memberof Card */ - static createCardScatter(html, scatterContainer, { - basePath = "./", - modules = [] - } = {}) { - let element = document.createElement("div") + static createCardScatter( + html, + scatterContainer, + { basePath = './', modules = [] } = {} + ) { + let element = document.createElement('div') scatterContainer.element.appendChild(element) new DOMScatter(element, scatterContainer, { @@ -90,8 +83,6 @@ export default class ScatterCard extends Card { return element } - - /** *Utility function to create a fully functional card scatter. * @@ -103,24 +94,27 @@ export default class ScatterCard extends Card { * @returns * @memberof CardScatter */ - static loadAndCreateScatterCard(scatterContainer, item, { - basePath = "../", - modules = [], - onClose = null - } = {}) { + static loadAndCreateScatterCard( + scatterContainer, + item, + { basePath = '../', modules = [], onClose = null } = {} + ) { console.log(basePath) return new Promise((resolve, reject) => { - let url = basePath + "/" + item + "/index.html" - console.log("Loading", url) + let url = basePath + '/' + item + '/index.html' + console.log('Loading', url) this.loadHTML(url) .then(html => { - console.log("Received", html) - let element = this.createCardScatter(html, scatterContainer, { - basePath, - modules - }) - if (onClose) - this.addOnCloseListener(element, onClose) + console.log('Received', html) + let element = this.createCardScatter( + html, + scatterContainer, + { + basePath, + modules + } + ) + if (onClose) this.addOnCloseListener(element, onClose) resolve(element) }) .catch(e => reject(e)) @@ -134,14 +128,12 @@ export default class ScatterCard extends Card { static _getLanguage(context) { return context.language } - } ScatterCard.selectedLanguage = 0 -ScatterCard.languages = ["Deutsch", "English"] +ScatterCard.languages = ['Deutsch', 'English'] ScatterCard.languageTags = { - Deutsch: "de", - English: "en" + Deutsch: 'de', + English: 'en' } ScatterCard.scatterContainer = null - diff --git a/lib/card/theme.js b/lib/card/theme.js index 9ff54e3..8b30feb 100644 --- a/lib/card/theme.js +++ b/lib/card/theme.js @@ -7,7 +7,6 @@ * @class Theme */ export default class Theme { - /** * Loads a config file and parses it to JSON. * @@ -18,17 +17,15 @@ export default class Theme { */ static loadConfig(path = null) { return new Promise((resolve, reject) => { - path = (path) ? path : './config.json' + path = path ? path : './config.json' let xhttp = new XMLHttpRequest() - xhttp.onreadystatechange = function () { + xhttp.onreadystatechange = function() { if (this.readyState == 4) { - if (this.status == 200 || Theme._isLocal()) { try { const json = JSON.parse(this.responseText) resolve(json) - } catch (e) { reject(e) } @@ -41,6 +38,6 @@ export default class Theme { } static _isLocal() { - return (window.location.protocol == 'file:') + return window.location.protocol == 'file:' } } diff --git a/lib/card/wrapper.js b/lib/card/wrapper.js index 7aeef4c..638be2d 100644 --- a/lib/card/wrapper.js +++ b/lib/card/wrapper.js @@ -5,8 +5,10 @@ import Events from '../events.js' import { Points } from '../utils.js' export default class CardWrapper extends Object { - - constructor(domNode, { triggerSVGClicks = true, allowClickDistance = 44 } = {}) { + constructor( + domNode, + { triggerSVGClicks = true, allowClickDistance = 44 } = {} + ) { super() this.domNode = domNode this.triggerSVGClicks = triggerSVGClicks @@ -16,42 +18,43 @@ export default class CardWrapper extends Object { } handleClicks() { - this.domNode.addEventListener('click', event => { - if (event.isTrusted) { - Events.stop(event) - if (this.triggerSVGClicks && this.isSVGNode(event.target)) { - this.tap(event, "triggerSVGClicks") + this.domNode.addEventListener( + 'click', + event => { + if (event.isTrusted) { + Events.stop(event) + if (this.triggerSVGClicks && this.isSVGNode(event.target)) { + this.tap(event, 'triggerSVGClicks') + } } - } - - }, true) + }, + true + ) } handleClicksAsTaps() { - this.domNode.addEventListener('click', event => { - if (event.isTrusted) { - Events.stop(event) - - } - this.tap(event) - }, true) + this.domNode.addEventListener( + 'click', + event => { + if (event.isTrusted) { + Events.stop(event) + } + this.tap(event) + }, + true + ) } isClickable(node) { - if (node == null) - return false - if (node.tagName == 'A' && node.hasAttribute("href")) - return true - if (node.hasAttribute("onclick")) - return true + if (node == null) return false + if (node.tagName == 'A' && node.hasAttribute('href')) return true + if (node.hasAttribute('onclick')) return true return false } hasClickHandler(node) { - if (node == null) - return false - if (this.tapNodes.has(node)) - return true + if (node == null) return false + if (this.tapNodes.has(node)) return true for (let [selector, handler] of this.tapHandler.entries()) { for (let obj of this.domNode.querySelectorAll(selector)) { if (node == obj) { @@ -68,15 +71,13 @@ export default class CardWrapper extends Object { * See https://stackoverflow.com/questions/11455515/how-to-check-whether-dynamically-attached-event-listener-exists-or-not * Therefore we can only detect the following standard cases: * I. All clickable objects like activeNodes - * II. Objects that have been attached a click handler by the scatter itself via + * II. Objects that have been attached a click handler by the scatter itself via */ activeNodes() { let result = [] - for (let node of this.domNode.querySelectorAll("*")) { - if (this.isClickable(node)) - result.push(node) - if (this.hasClickHandler(node)) - result.push(node) + for (let node of this.domNode.querySelectorAll('*')) { + if (this.isClickable(node)) result.push(node) + if (this.hasClickHandler(node)) result.push(node) } return result } @@ -84,14 +85,26 @@ export default class CardWrapper extends Object { nearestActive(event) { let element = this.domNode let activeNodes = this.activeNodes() - let globalClick = (event.center) ? event.center : { x: event.x, y: event.y } + let globalClick = event.center + ? event.center + : { x: event.x, y: event.y } let localClick = Points.fromPageToNode(element, globalClick) let clickRects = activeNodes.map(link => { let rect = link.getBoundingClientRect() let topLeft = Points.fromPageToNode(element, rect) - let center = Points.fromPageToNode(element, { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 }) - return { x: topLeft.x, y: topLeft.y, width: rect.width, height: rect.height, center, link } + let center = Points.fromPageToNode(element, { + x: rect.x + rect.width / 2, + y: rect.y + rect.height / 2 + }) + return { + x: topLeft.x, + y: topLeft.y, + width: rect.width, + height: rect.height, + center, + link + } }) let distances = [] @@ -147,12 +160,12 @@ export default class CardWrapper extends Object { return false } - tap(event, calledBy='unknown') { + tap(event, calledBy = 'unknown') { if (event.isTrusted) { let node = this.nearestActive(event) this.nodeTapped(node, event) - /* let node = document.elementFromPoint(event.clientX, event.clientY) + /* let node = document.elementFromPoint(event.clientX, event.clientY) if (!this.nodeTapped(node, event)) { node = this.nearestActive(event) this.nodeTapped(node, event) @@ -161,13 +174,10 @@ export default class CardWrapper extends Object { } onTap(objOrSelector, handler) { - if (typeof (objOrSelector) == 'string') { + if (typeof objOrSelector == 'string') { this.tapHandler.set(objOrSelector, handler) - } - else { + } else { this.tapNodes.set(objOrSelector, handler) } - } - } diff --git a/lib/doctest.js b/lib/doctest.js index 8a61177..a51eda9 100755 --- a/lib/doctest.js +++ b/lib/doctest.js @@ -5,12 +5,15 @@ var docTestLogMessages = [] Array.prototype.equals = function(array) { - return this.length == array.length && - this.every( function(this_i,i) { return this_i == array[i] } ) + return ( + this.length == array.length && + this.every(function(this_i, i) { + return this_i == array[i] + }) + ) } export default class Doctest { - static assert(value) { if (!value) { throw new Error('Assertion violated') @@ -18,34 +21,42 @@ export default class Doctest { } static pprint(obj) { - if (obj === null) - return 'null' + if (obj === null) return 'null' let stringified = obj.toString() - if (stringified == '[object Object]') - return JSON.stringify(obj) + if (stringified == '[object Object]') return JSON.stringify(obj) return stringified } static expect(expr, value) { if (this.pprint(expr) != this.pprint(value)) { //throw new Error("got `" + expr + "` but expected `" + value + "`.") - throw new Error('got `' + this.pprint(expr) + '` but expected `' + this.pprint(value) + '`.') + throw new Error( + 'got `' + + this.pprint(expr) + + '` but expected `' + + this.pprint(value) + + '`.' + ) } } static expectError(error, message) { let index = error.toString().indexOf(message) if (index < 0) { - throw new Error('got `' + message + '` but expected `' + error + '`.') + throw new Error( + 'got `' + message + '` but expected `' + error + '`.' + ) } } static expectLog(...messages) { - // if (!docTestLogMessages.equals(messages)) { - docTestLogMessages.forEach((msg, i) => { - if (msg != messages[i]) - throw new Error('Unexpected log message: `' + messages[i] + '`.') - }) + // if (!docTestLogMessages.equals(messages)) { + docTestLogMessages.forEach((msg, i) => { + if (msg != messages[i]) + throw new Error( + 'Unexpected log message: `' + messages[i] + '`.' + ) + }) // throw new Error('Uups') //} } @@ -55,37 +66,35 @@ export default class Doctest { } static highlight(code) { - if (typeof(hljs) == 'undefined') - return code + if (typeof hljs == 'undefined') return code return hljs.highlight('javascript', code) } static stripLeadingLines(code) { let result = [] let informative = false - for(let line of code.split('\n')) { + for (let line of code.split('\n')) { if (line.trim().length > 0) { informative = true } - if (informative) - result.push(line) + if (informative) result.push(line) } return result.join('\n') } - static event(type='mouse', {clientX = 0, clientY = 0} = {}) { + static event(type = 'mouse', { clientX = 0, clientY = 0 } = {}) { if (type.startsWith('mouse')) { return new MouseEvent(type, { clientX, clientY }) } return { type, clientX, clientY } } - static run(replaceExpect=false) { - if (typeof(hljs) != 'undefined') { + static run(replaceExpect = false) { + if (typeof hljs != 'undefined') { hljs.initHighlighting() } let doctests = document.querySelectorAll('.doctest') - for(let i=0; i>> ').trim() if (line.endsWith(')') || line.endsWith(',')) { line = line.slice(0, -1) diff --git a/lib/errors.js b/lib/errors.js index 0afbe68..d9084da 100755 --- a/lib/errors.js +++ b/lib/errors.js @@ -1,17 +1,16 @@ var recordedErrors = new Map() export default class Errors { - static countErrors() { let total = 0 - for(let error of recordedErrors.keys()) { + for (let error of recordedErrors.keys()) { total += recordedErrors.get(error).size } return total } static setStyle(element, styles) { - for(let key in styles) { + for (let key in styles) { element.style[key] = styles[key] } } @@ -20,8 +19,7 @@ export default class Errors { if (recordedErrors.has(error)) { let sources = recordedErrors.get(error) sources.add(source) - } - else { + } else { recordedErrors.set(error, new Set([source])) } } @@ -37,16 +35,19 @@ export default class Errors { this.setStyle(document.body, { border: '2px solid red' }) - this.setStyle(errors, {position: 'absolute', + this.setStyle(errors, { + position: 'absolute', top: '0px', padding: '8px', width: '100%', background: 'red', - color: 'white'}) + color: 'white' + }) document.body.appendChild(errors) let counter = document.createElement('div') counter.setAttribute('id', 'runtime-errors-counter') - this.setStyle(counter, {borderRadius: '50%', + this.setStyle(counter, { + borderRadius: '50%', width: '32px', height: '32px', background: 'white', @@ -54,16 +55,19 @@ export default class Errors { fontSize: '18px', textAlign: 'center', lineHeight: '32px', - verticalAlign: 'middle'}) + verticalAlign: 'middle' + }) counter.innerHTML = '1' errors.appendChild(counter) let header = document.createElement('div') - this.setStyle(header, {position: 'absolute', + this.setStyle(header, { + position: 'absolute', top: '6px', left: '48px', height: '44px', - fontSize: '32px'}) + fontSize: '32px' + }) header.innerHTML = 'Runtime Errors' errors.appendChild(header) errors.addEventListener('click', this.toggleErrors.bind(this)) @@ -74,9 +78,9 @@ export default class Errors { static expandErrors() { let errors = document.getElementById('runtime-errors') - for(let error of recordedErrors.keys()) { - for(var source of recordedErrors.get(error)) { - if (typeof(source) == 'undefined') { + for (let error of recordedErrors.keys()) { + for (var source of recordedErrors.get(error)) { + if (typeof source == 'undefined') { source = 'See console for details' return } @@ -93,9 +97,8 @@ export default class Errors { let errors = document.getElementById('runtime-errors') let infos = errors.querySelectorAll('.info') if (infos.length > 0) { - infos.forEach((info) => errors.removeChild(info)) - } - else { + infos.forEach(info => errors.removeChild(info)) + } else { this.expandErrors() } } @@ -111,26 +114,29 @@ export default class Errors { static registerGlobalErrorHandler() { // Register more informative error handler - window.addEventListener('error', (event) => { - // if (typeof(event.error) == 'undefined') { -// console.info("Catched undefined error", event) -// } - this.appendError(event.error, event.filename) - }, true) + window.addEventListener( + 'error', + event => { + // if (typeof(event.error) == 'undefined') { + // console.info("Catched undefined error", event) + // } + this.appendError(event.error, event.filename) + }, + true + ) - document.addEventListener('DOMContentLoaded', (event) => { + document.addEventListener('DOMContentLoaded', event => { this.showErrors() }) } static registerFrameAwaitErrors() { let iframes = document.getElementsByTagName('iframe') - for(let i=0; i { - this.appendError('Cannot load iframe', target.src)}, - frameErrorTimeout) + target.iframeTimeout = setTimeout(() => { + this.appendError('Cannot load iframe', target.src) + }, frameErrorTimeout) target.onload = () => { clearTimeout(target.iframeTimeout) } diff --git a/lib/events.js b/lib/events.js index af675bb..201aa5c 100755 --- a/lib/events.js +++ b/lib/events.js @@ -1,6 +1,4 @@ - export default class Events { - static stop(event) { event.preventDefault() event.stopPropagation() @@ -20,8 +18,7 @@ export default class Events { } static isCaptured(event) { - if (event.__capturedBy) - return true + if (event.__capturedBy) return true return false } @@ -30,7 +27,7 @@ export default class Events { } static isPointerDown(event) { - // According to + // According to // https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events // pointer events use the buttons feature to represent pressed buttons return event.buttons @@ -77,8 +74,15 @@ export default class Events { for (let i = 0; i < targets.length; i++) { let t = targets[i] let touchTarget = document.elementFromPoint(t.pageX, t.pageY) - let touch = new Touch(undefined, touchTarget, t.identifier, - t.pageX, t.pageY, t.screenX, t.screenY) + let touch = new Touch( + undefined, + touchTarget, + t.identifier, + t.pageX, + t.pageY, + t.screenX, + t.screenY + ) touches.push(touch) } return new TouchList(...touches) @@ -168,8 +172,7 @@ export default class Events { for (let key of keys) { try { result += ' ' + key + ':' + event[key] - } - catch (e) { + } catch (e) { console.log('Invalid key: ' + key) } } @@ -179,11 +182,15 @@ export default class Events { static compareExtractedWithSimulated() { var diffs = 0 if (this.extracted.length != this.simulated.length) { - alert('Unequal length of extracted [' + this.extracted.length + - '] and simulated events [' + this.simulated.length + '].') + alert( + 'Unequal length of extracted [' + + this.extracted.length + + '] and simulated events [' + + this.simulated.length + + '].' + ) diffs += 1 - } - else { + } else { for (let i = 0; i < this.extracted.length; i++) { var extracted = this.extracted[i] var simulated = this.simulated[i] @@ -238,8 +245,10 @@ export default class Events { div.innerHTML = line this.popup.appendChild(div) } - Elements.setStyle(this.popup, - { left: event.clientX + 'px', top: event.clientY + 'px' }) + Elements.setStyle(this.popup, { + left: event.clientX + 'px', + top: event.clientY + 'px' + }) } } @@ -250,7 +259,6 @@ Events.simulated = [] Events.simulationRunning = false export class EventRecorder { - constructor() { this.recording = [] this.recorded = [] @@ -262,8 +270,7 @@ export class EventRecorder { if (length == 0) { this.startTime = event.timeStamp Events.reset() - } - else { + } else { let last = this.recording[length - 1] if (event.timeStamp < last.time) { console.log('warning: wrong temporal order') @@ -291,7 +298,7 @@ export class EventRecorder { if (this.step < this.recorded.length) { let { type, time, constructor, data } = this.recorded[this.step] Events.simulateEvent(type, constructor, data) - + this.step += 1 let dt = 0 if (this.step < this.recorded.length) { @@ -305,8 +312,7 @@ export class EventRecorder { let delta = Math.round(dt) setTimeout(() => this.replay(whileCondition, onComplete), delta) } - } - else { + } else { console.log('Played ' + this.step + ' events' + onComplete) Events.simulationRunning = false if (onComplete != null) { @@ -316,4 +322,3 @@ export class EventRecorder { } } } - diff --git a/lib/flippable.js b/lib/flippable.js index 503cd49..9f867c3 100644 --- a/lib/flippable.js +++ b/lib/flippable.js @@ -31,12 +31,10 @@ export class CardLoader { this.maxHeight = maxHeight != null ? maxHeight : window.innerHeight this.addedNode = null console.log({ - width, height, maxWidth, - maxHeight, - + maxHeight }) } @@ -152,11 +150,13 @@ export class HTMLLoader extends CardLoader { domNode.innerHTML = xhr.response this.addedNode = domNode.firstElementChild let { width, height } = this.size(this.addedNode) - console.log("HTMLLoader.load", { added: this.addedNode, width, height }) - if (width) - this.wantedWidth = width || this.wantedWidth - if (height) - this.wantedHeight = height || this.wantedHeight + console.log('HTMLLoader.load', { + added: this.addedNode, + width, + height + }) + if (width) this.wantedWidth = width || this.wantedWidth + if (height) this.wantedHeight = height || this.wantedHeight resolve(this) } xhr.onerror = e => { @@ -169,7 +169,7 @@ export class HTMLLoader extends CardLoader { /** * Tries to determine the size of the addedNode. * Checks for explicit width and height style attributes. - * + * * Overwrite this method if you want to extract values from other infos. * * @returns { width: int, height: int } @@ -248,7 +248,7 @@ export class DOMFlip { this.cardWrapper = dom.querySelector('#' + this.id) let front = this.cardWrapper.querySelector('.front') this.frontLoader.load(front).then(loader => { - this.frontLoaded(loader).then((obj) => { + this.frontLoaded(loader).then(obj => { if (this.onLoaded) this.onLoaded() resolve(this) }) @@ -275,7 +275,9 @@ export class DOMFlip { scalable: this.scalable, rotatable: this.rotatable, overdoScaling: this.overdoScaling, - tapDelegate: (this.tapDelegateFactory) ? this.tapDelegateFactory(this.cardWrapper) : null + tapDelegate: this.tapDelegateFactory + ? this.tapDelegateFactory(this.cardWrapper) + : null } ) @@ -284,7 +286,7 @@ export class DOMFlip { } if (this.closeOnMinScale) { - const removeOnMinScale = function () { + const removeOnMinScale = function() { if (scatter.scale <= scatter.minScale) { this.flippable.close() @@ -294,7 +296,9 @@ export class DOMFlip { //Remove callback if (scatter.onTransform) { - let callbackIdx = scatter.onTransform.indexOf(removeOnMinScale) + let callbackIdx = scatter.onTransform.indexOf( + removeOnMinScale + ) scatter.onTransform.splice(callbackIdx, 1) } } @@ -325,7 +329,7 @@ export class DOMFlip { } setupFlippable(flippable, loader) { - console.log("setupFlippable", loader.wantedWidth) + console.log('setupFlippable', loader.wantedWidth) flippable.wantedWidth = loader.wantedWidth flippable.wantedHeight = loader.wantedHeight flippable.wantedScale = loader.scale @@ -335,12 +339,10 @@ export class DOMFlip { } start({ targetCenter = null } = {}) { - console.log("DOMFlip.start", targetCenter) + console.log('DOMFlip.start', targetCenter) if (this.preloadBack) { - this.flippable.start({ duration: this.flipDuration, targetCenter }) - } - else { + } else { let back = this.cardWrapper.querySelector('.back') let flippable = this.flippable this.backLoader.load(back).then(loader => { @@ -487,7 +489,7 @@ export class DOMFlippable { clickInfo() { this.bringToFront() - console.log("clickInfo") + console.log('clickInfo') this.infoBtn.click() } @@ -585,14 +587,14 @@ export class DOMFlippable { let y = this.flipped ? yy : this.startY let onUpdate = this.onUpdate !== null ? () => this.onUpdate(this) : null - console.log("start", this.flipDuration) + console.log('start', this.flipDuration) TweenLite.to(this.card, this.flipDuration, { rotationY: targetY, ease: Power1.easeOut, transformOrigin: '50% 50%', onUpdate, onComplete: e => { - console.log("start end", this.flipDuration) + console.log('start end', this.flipDuration) if (this.flipped) { //this.hide(this.front) this.enable(this.backBtn) @@ -602,7 +604,6 @@ export class DOMFlippable { this.onFrontFlipped(this) } } else { - if (this.onBackFlipped == null) { this.enable(this.infoBtn, this.fadeDuration) this.enable(this.closeBtn, this.fadeDuration) @@ -625,7 +626,7 @@ export class DOMFlippable { force3D: true }) - console.log("start 2", this.wantedWidth, this.startWidth, {w, h}) + console.log('start 2', this.wantedWidth, this.startWidth, { w, h }) // See https://greensock.com/forums/topic/7997-rotate-the-shortest-way/ TweenLite.to(this.element, this.flipDuration / 2, { scale: targetScale, diff --git a/lib/frames.js b/lib/frames.js index bfbdbb1..8baf519 100755 --- a/lib/frames.js +++ b/lib/frames.js @@ -1,12 +1,12 @@ -import {Points} from './utils.js' -import {Capabilities} from './capabilities.js' +import { Points } from './utils.js' +import { Capabilities } from './capabilities.js' export class FrameContainer { - constructor(element) { this.element = element - this.delegate = new InteractionMapper(element, this, - { mouseWheelElement: window}) + this.delegate = new InteractionMapper(element, this, { + mouseWheelElement: window + }) } capture(event) { @@ -30,8 +30,7 @@ export class FrameContainer { } export class FrameTarget { - - constructor(frame, target, debug=false) { + constructor(frame, target, debug = false) { this.frame = frame this.target = target this.debug = debug @@ -48,22 +47,30 @@ export class FrameTarget { bubbles: true, cancelable: true, clientX: p.x, - clientY: p.y}) + clientY: p.y + }) this.target.dispatchEvent(event) } createTouchList(pointMap) { let touches = [] let doc = this.frame.contentWindow.document - for(let key of pointMap.keys()) { + for (let key of pointMap.keys()) { let point = pointMap.get(key) let p = Points.fromPageToNode(this.frame, point) let touchTarget = doc.elementFromPoint(p.x, p.y) - let touch = new Touch(undefined, touchTarget, key, - p.x, p.y, p.x, p.y) + let touch = new Touch( + undefined, + touchTarget, + key, + p.x, + p.y, + p.x, + p.y + ) touches.push(touch) } - return new TouchList(...touches) + return new TouchList(...touches) } simulateTouchEventChrome(type, point, pointMap) { @@ -80,8 +87,8 @@ export class FrameTarget { radiusX: 2.5, radiusY: 2.5, rotationAngle: 10, - force: 0.5, - }); + force: 0.5 + }) const touchEvent = new TouchEvent(type, { cancelable: true, @@ -89,47 +96,57 @@ export class FrameTarget { touches: [touchObj], targetTouches: [touchObj], changedTouches: [touchObj], - shiftKey: false, - }); - if (this.debug) console.log("simulateTouchEventChrome", touchEvent) - this.target.dispatchEvent(touchEvent); + shiftKey: false + }) + if (this.debug) console.log('simulateTouchEventChrome', touchEvent) + this.target.dispatchEvent(touchEvent) } - simulateTouchEventSafari(type, point, pointMap, touchEventKey='targetTouches') { + simulateTouchEventSafari( + type, + point, + pointMap, + touchEventKey = 'targetTouches' + ) { let p = Points.fromPageToNode(this.frame, point) - let data = { view: this.frame.contentWindow, + let data = { + view: this.frame.contentWindow, bubbles: true, cancelable: true, clientX: p.x, - clientY: p.y} + clientY: p.y + } data[touchEventKey] = this.createTouchList(pointMap) let event = new TouchEvent(type, data) - if (this.debug) console.log("simulateTouchEventChrome", touchEvent) + if (this.debug) console.log('simulateTouchEventChrome', touchEvent) this.target.dispatchEvent(event) } - simulateTouchEvent(type, point, pointMap, touchEventKey='targetTouches') { + simulateTouchEvent(type, point, pointMap, touchEventKey = 'targetTouches') { if (Capabilities.isSafari) { this.simulateTouchEventSafari(type, point, pointMap, touchEventKey) - } - else { + } else { this.simulateTouchEventChrome(type, point, pointMap) } } isMouseLikeEvent(event) { - return event.type.startsWith('mouse') || event.type.startsWith('pointer') + return ( + event.type.startsWith('mouse') || event.type.startsWith('pointer') + ) } onStart(event, interaction) { if (this.debug) console.log('onStart', this.frame.parentNode) - for(let [key, point] of interaction.current.entries()) { + for (let [key, point] of interaction.current.entries()) { if (this.isMouseLikeEvent(event)) { this.simulateMouseEvent('mousedown', point) - } - else { - this.simulateTouchEvent('touchstart', point, - interaction.current) + } else { + this.simulateTouchEvent( + 'touchstart', + point, + interaction.current + ) return } } @@ -137,13 +154,11 @@ export class FrameTarget { onMove(event, interaction) { if (this.debug) console.log('onMove') - for(let [key, point] of interaction.current.entries()) { + for (let [key, point] of interaction.current.entries()) { if (this.isMouseLikeEvent(event)) { this.simulateMouseEvent('mousemove', point) - } - else { - this.simulateTouchEvent('touchmove', point, - interaction.current) + } else { + this.simulateTouchEvent('touchmove', point, interaction.current) return } } @@ -151,13 +166,16 @@ export class FrameTarget { onEnd(event, interaction) { if (this.debug) console.log('onEnd') - for(let [key, point] of interaction.current.entries()) { + for (let [key, point] of interaction.current.entries()) { if (this.isMouseLikeEvent(event)) { this.simulateMouseEvent('mouseend', point) - } - else { - this.simulateTouchEvent('touchend', point, - interaction.ended, 'changedTouches') + } else { + this.simulateTouchEvent( + 'touchend', + point, + interaction.ended, + 'changedTouches' + ) return } } diff --git a/lib/imageloader.js b/lib/imageloader.js index 414c980..abdee0b 100644 --- a/lib/imageloader.js +++ b/lib/imageloader.js @@ -14,7 +14,7 @@ function onerror(event) { } function load() { - loadQueue.forEach((url) => { + loadQueue.forEach(url => { let xhr = new XMLHttpRequest() xhr.responseType = 'blob' xhr.onload = onload @@ -25,11 +25,11 @@ function load() { }) } -self.onmessage = (event) => { +self.onmessage = event => { let msg = event.data - switch(msg.command) { + switch (msg.command) { case 'load': - for(let url of msg.urls) { + for (let url of msg.urls) { console.log('Load', url) loadQueue.push(url) } @@ -37,13 +37,12 @@ self.onmessage = (event) => { break case 'abort': loadQueue = [] - for(let xhr of pendingRequests.values()) { + for (let xhr of pendingRequests.values()) { console.log('Abort') xhr.abort() } break default: - console.warn('Unknown worker command: ' + msg.command) + console.warn('Unknown worker command: ' + msg.command) } - } diff --git a/lib/index.js b/lib/index.js index df1011d..ee17f3f 100755 --- a/lib/index.js +++ b/lib/index.js @@ -1,15 +1,14 @@ -import {Capabilities} from './capabilities.js' +import { Capabilities } from './capabilities.js' export default class Index { - - constructor(template, pages, notfound='thumbnails/notfound.png') { + constructor(template, pages, notfound = 'thumbnails/notfound.png') { this.template = template this.pages = pages this.notfound = notfound } setup() { - for(let pair of this.pages) { + for (let pair of this.pages) { let [title, src] = pair let id = getId() pair.push(id) @@ -18,20 +17,18 @@ export default class Index { wrapper.id = id let clone = document.importNode(t.content, true) container.appendChild(clone) - wrapper = container.querySelector('#'+id) + wrapper = container.querySelector('#' + id) let icon = wrapper.querySelector('.icon') - icon.onerror = (e) => { - if (this.notfound) - icon.src = this.notfound + icon.onerror = e => { + if (this.notfound) icon.src = this.notfound } let iconSrc = src.replace('.html', '.png') //console.log("iconSrc", iconSrc) if (iconSrc.endsWith('index.png')) { icon.src = iconSrc.replace('index.png', 'thumbnail.png') - } - else { + } else { icon.src = 'thumbnails/' + iconSrc } @@ -44,8 +41,7 @@ export default class Index { } frames() { - if (this.pages.length == 0) - return + if (this.pages.length == 0) return let [title, src, id] = this.pages.shift() let iframe = document.createElement('iframe') iframe.frameborder = 0 @@ -53,7 +49,7 @@ export default class Index { let icon = wrapper.querySelector('.icon') icon.parentNode.replaceChild(iframe, icon) - iframe.onload = (e) => { + iframe.onload = e => { this.frames() } iframe.src = src + window.location.search @@ -61,13 +57,11 @@ export default class Index { load() { this.setup() - if (window.location.search.startsWith('?test')) - this.frames() + if (window.location.search.startsWith('?test')) this.frames() } loadAndTest() { this.setup() - if (!Capabilities.isMobile) - this.frames() + if (!Capabilities.isMobile) this.frames() } } diff --git a/lib/inspect.js b/lib/inspect.js index 5dae6bf..0a2f8c9 100755 --- a/lib/inspect.js +++ b/lib/inspect.js @@ -1,8 +1,7 @@ export class Inspect { // Code inspection functions - static allScriptSources() - { + static allScriptSources() { let sources = [] let scripts = document.getElementsByTagName('script') for (let i = 0; i < scripts.length; i++) { diff --git a/lib/interaction.js b/lib/interaction.js index 08867c2..cf85729 100755 --- a/lib/interaction.js +++ b/lib/interaction.js @@ -13,16 +13,15 @@ import Logging from './logging.js' */ export class IInteractionTarget extends Interface { - capture(event) { return typeof true } - onStart(event, interaction) { } - onMove(event, interaction) { } - onEnd(event, interaction) { } + onStart(event, interaction) {} + onMove(event, interaction) {} + onEnd(event, interaction) {} - onMouseWheel(event) { } + onMouseWheel(event) {} } export class IInteractionMapperTarget extends Interface { @@ -230,14 +229,32 @@ export class InteractionPoints { let currentAngle = Points.angle(c1, c2) let previousAngle = Points.angle(p1, p2) let alpha = this.diffAngle(currentAngle, previousAngle) - return new InteractionDelta(delta.x, delta.y, zoom, alpha, cm, csize) - } else if (csize == 1 && psize == 1 && this.current.firstKey() == this.previous.firstKey()) { + return new InteractionDelta( + delta.x, + delta.y, + zoom, + alpha, + cm, + csize + ) + } else if ( + csize == 1 && + psize == 1 && + this.current.firstKey() == this.previous.firstKey() + ) { // We need to ensure that the keys are the same, since single points with different keys // can jump let current = this.current.first() let previous = this.previous.first() let delta = Points.subtract(current, previous) - return new InteractionDelta(delta.x, delta.y, 1.0, 0.0, current, csize) + return new InteractionDelta( + delta.x, + delta.y, + 1.0, + 0.0, + current, + csize + ) } return null } @@ -375,8 +392,7 @@ export class Interaction extends InteractionPoints { if (this.tapCounts.has(key)) { let count = this.tapCounts.get(key) this.tapCounts.set(key, count + 1) - } - else { + } else { this.tapCounts.set(key, 1) } this.tapPositions.set(key, point) @@ -418,7 +434,10 @@ export class Interaction extends InteractionPoints { this.unregisterTap(key) } } - if (this.tapTimestamps.has(key) && performance.now() > this.tapTimestamps.get(key) + this.tapDuration) { + if ( + this.tapTimestamps.has(key) && + performance.now() > this.tapTimestamps.get(key) + this.tapDuration + ) { //console.log("tap too long") this.unregisterTap(key) } @@ -426,8 +445,7 @@ export class Interaction extends InteractionPoints { if (this.isTap(key)) { this.registerTap(key, ended) result = this.tapCounts.get(key) == 2 - } - else { + } else { this.unregisterTap(key) } //console.log("isDoubleTap", this.tapCounts.get(key), result) @@ -494,7 +512,13 @@ export class InteractionDelegate { constructor( element, target, - { mouseWheelElement = null, useCapture = true, capturePointerEvents = true, cancelOnWindowOut = true, debug = false } = {} + { + mouseWheelElement = null, + useCapture = true, + capturePointerEvents = true, + cancelOnWindowOut = true, + debug = false + } = {} ) { this.debug = debug this.interaction = new Interaction() @@ -549,7 +573,8 @@ export class InteractionDelegate { element.addEventListener( 'pointermove', e => { - if (this.debug) console.log('pointermove', e.pointerId, e.pointerType) + if (this.debug) + console.log('pointermove', e.pointerId, e.pointerType) if ( e.pointerType == 'touch' || @@ -566,7 +591,8 @@ export class InteractionDelegate { element.addEventListener( 'pointerup', e => { - if (this.debug) console.log('pointerup', e.pointerId, e.pointerType) + if (this.debug) + console.log('pointerup', e.pointerId, e.pointerType) this.onEnd(e) if (this.capturePointerEvents) { try { @@ -581,7 +607,8 @@ export class InteractionDelegate { element.addEventListener( 'pointercancel', e => { - if (this.debug) console.log('pointercancel', e.pointerId, e.pointerType) + if (this.debug) + console.log('pointercancel', e.pointerId, e.pointerType) this.onEnd(e) if (this.capturePointerEvents) element.releasePointerCapture(e.pointerId) @@ -593,7 +620,12 @@ export class InteractionDelegate { element.addEventListener( 'pointerleave', e => { - if (this.debug) console.log('pointerleave', e.pointerId, e.pointerType) + if (this.debug) + console.log( + 'pointerleave', + e.pointerId, + e.pointerType + ) if (e.target == element) this.onEnd(e) }, useCapture @@ -604,7 +636,12 @@ export class InteractionDelegate { element.addEventListener( 'pointerout', e => { - if (this.debug) console.log('pointerout', e.pointerId, e.pointerType) + if (this.debug) + console.log( + 'pointerout', + e.pointerId, + e.pointerType + ) if (e.target == element) this.onEnd(e) }, useCapture @@ -615,14 +652,20 @@ export class InteractionDelegate { window.addEventListener( 'pointerout', e => { - if (this.debug) console.log('pointerout', e.pointerId, e.pointerType, e.target) + if (this.debug) + console.log( + 'pointerout', + e.pointerId, + e.pointerType, + e.target + ) if (e.target == element) { this.onEnd(e) } }, - useCapture) + useCapture + ) } - } else if (window.TouchEvent) { if (this.debug) console.log('Touch API') element.addEventListener( @@ -698,8 +741,7 @@ export class InteractionDelegate { // && Events.isMouseDown(e)) if (Events.isMouseDown(e)) { - if (this.debug) - console.log('mousemove', e) + if (this.debug) console.log('mousemove', e) this.onMove(e) } }, @@ -720,7 +762,9 @@ export class InteractionDelegate { e => { if (e.target == element) { this.onEnd(e) - console.warn('Shouldn\'t happen: mouseout ends interaction') + console.warn( + "Shouldn't happen: mouseout ends interaction" + ) } }, useCapture @@ -734,7 +778,8 @@ export class InteractionDelegate { this.onEnd(e) } }, - useCapture) + useCapture + ) } } } @@ -823,42 +868,42 @@ export class InteractionDelegate { // 'targetTouches' let result = {} switch (event.constructor.name) { - case 'MouseEvent': { - let buttons = event.buttons || event.which - if (buttons) result['mouse'] = this.getPosition(event) - break - } - case 'PointerEvent': { - result[event.pointerId.toString()] = this.getPosition(event) - break - } - case 'Touch': { - let id = + case 'MouseEvent': { + let buttons = event.buttons || event.which + if (buttons) result['mouse'] = this.getPosition(event) + break + } + case 'PointerEvent': { + result[event.pointerId.toString()] = this.getPosition(event) + break + } + case 'Touch': { + let id = event.touchType === 'stylus' ? 'stylus' : event.identifier.toString() - result[id] = this.getPosition(event) - break - } - // case 'TouchEvent': - // // Needs to be observed: Perhaps changedTouches are all we need. If so - // // we can remove the touchEventKey default parameter - // if (touchEventKey == 'all') { - // for(let t of event.targetTouches) { - // result[t.identifier.toString()] = this.getPosition(t) - // } - // for(let t of event.changedTouches) { - // result[t.identifier.toString()] = this.getPosition(t) - // } - // } - // else { - // for(let t of event.changedTouches) { - // result[t.identifier.toString()] = this.getPosition(t) - // } - // } - // break - default: - break + result[id] = this.getPosition(event) + break + } + // case 'TouchEvent': + // // Needs to be observed: Perhaps changedTouches are all we need. If so + // // we can remove the touchEventKey default parameter + // if (touchEventKey == 'all') { + // for(let t of event.targetTouches) { + // result[t.identifier.toString()] = this.getPosition(t) + // } + // for(let t of event.changedTouches) { + // result[t.identifier.toString()] = this.getPosition(t) + // } + // } + // else { + // for(let t of event.changedTouches) { + // result[t.identifier.toString()] = this.getPosition(t) + // } + // } + // break + default: + break } return result } @@ -871,7 +916,7 @@ export class InteractionDelegate { // Callback: can be overwritten } - interactionFinished(event, key, point) { } + interactionFinished(event, key, point) {} startInteraction(event, extracted) { for (let key in extracted) { @@ -886,7 +931,10 @@ export class InteractionDelegate { let point = extracted[key] let updated = this.interaction.update(key, point) if (updated) { - console.warn('new pointer in updateInteraction shouldn\'t happen', key) + console.warn( + "new pointer in updateInteraction shouldn't happen", + key + ) this.interactionStarted(event, key, point) } } @@ -924,13 +972,23 @@ export class InteractionDelegate { * @extends {InteractionDelegate} */ export class InteractionMapper extends InteractionDelegate { - constructor( element, target, - { tapDistance = 10, longPressTime = 500.0, useCapture = true, mouseWheelElement = null, logInteractionsAbove = 12 } = {} + { + tapDistance = 10, + longPressTime = 500.0, + useCapture = true, + mouseWheelElement = null, + logInteractionsAbove = 12 + } = {} ) { - super(element, target, { tapDistance, useCapture, longPressTime, mouseWheelElement }) + super(element, target, { + tapDistance, + useCapture, + longPressTime, + mouseWheelElement + }) this.logInteractionsAbove = logInteractionsAbove } @@ -1039,10 +1097,7 @@ export class InteractionMapper extends InteractionDelegate { * @param {object} [opts] - An options object. See the hammer documentation for more details. */ static on(types, elements, cb, opts = {}) { - - opts = Object.assign({}, { - - }, opts) + opts = Object.assign({}, {}, opts) if (typeof Hammer === 'undefined') { console.error('Hammer.js not found!') @@ -1051,23 +1106,25 @@ export class InteractionMapper extends InteractionDelegate { // convert to array types = Array.isArray(types) ? types : types.split(/\s/) - if (elements instanceof NodeList || elements instanceof HTMLCollection) { + if ( + elements instanceof NodeList || + elements instanceof HTMLCollection + ) { elements = Array.from(elements) } elements = Array.isArray(elements) ? elements : [elements] for (let i = 0; i < types.length; i++) { - const type = types[i].toLowerCase() // list of hammer events - const useHammer = /^(tap|doubletap|press|pan|swipe|pinch|rotate).*$/.test(type) + const useHammer = /^(tap|doubletap|press|pan|swipe|pinch|rotate).*$/.test( + type + ) // if it is a hammer event if (useHammer) { - for (let j = 0; j < elements.length; j++) { - // if(elements[j].tagName == "svg") return false; let hammer = new Hammer(elements[j], opts) @@ -1078,15 +1135,33 @@ export class InteractionMapper extends InteractionDelegate { // recognizers if (type.startsWith('pan')) { - hammer.get('pan').set(Object.assign({ direction: Hammer.DIRECTION_ALL }, opts)) + hammer + .get('pan') + .set( + Object.assign( + { direction: Hammer.DIRECTION_ALL }, + opts + ) + ) } else if (type.startsWith('pinch')) { - hammer.get('pinch').set(Object.assign({ enable: true }, opts)) + hammer + .get('pinch') + .set(Object.assign({ enable: true }, opts)) } else if (type.startsWith('press')) { hammer.get('press').set(opts) } else if (type.startsWith('rotate')) { - hammer.get('rotate').set(Object.assign({ enable: true }, opts)) + hammer + .get('rotate') + .set(Object.assign({ enable: true }, opts)) } else if (type.startsWith('swipe')) { - hammer.get('swipe').set(Object.assign({ direction: Hammer.DIRECTION_ALL }, opts)) + hammer + .get('swipe') + .set( + Object.assign( + { direction: Hammer.DIRECTION_ALL }, + opts + ) + ) } else if (type.startsWith('tap')) { hammer.get('tap').set(opts) } @@ -1095,9 +1170,7 @@ export class InteractionMapper extends InteractionDelegate { cb(event) }) } - } else { - for (let j = 0; j < elements.length; j++) { Hammer.on(elements[j], type, event => { cb(event) diff --git a/lib/interface.js b/lib/interface.js index 3000c2f..830f63b 100755 --- a/lib/interface.js +++ b/lib/interface.js @@ -7,11 +7,10 @@ export default class Interface { static implementationError(klass) { let interfaceKeys = Reflect.ownKeys(this.prototype) let classKeys = Reflect.ownKeys(klass.prototype) - for(let key of interfaceKeys) { + for (let key of interfaceKeys) { let interfaceDesc = this.prototype[key] let classDesc = klass.prototype[key] - if (typeof(classDesc) == 'undefined') - return 'Missing ' + key + if (typeof classDesc == 'undefined') return 'Missing ' + key } return null } @@ -23,8 +22,8 @@ export default class Interface { return error == null } - // TODO: Specify optional methods -// static optionalMethods() { -// return [this.onMouseWheel] -// } + // TODO: Specify optional methods + // static optionalMethods() { + // return [this.onMouseWheel] + // } } diff --git a/lib/logging.js b/lib/logging.js index 3a0555e..9830414 100644 --- a/lib/logging.js +++ b/lib/logging.js @@ -20,15 +20,14 @@ try { /** Basic class for app specific logging requirements. * Can be used to implement persistent logging in electron apps. - * Uses a logMessage cache to prevent error overflows. This is + * Uses a logMessage cache to prevent error overflows. This is * needed since errors may occur very frequently * (e.g. display update loops at 60fps, programmatic loops, ...). - * + * * The logging handlers can be overwritten by calling the static * setup method. */ export default class Logging { - /** Static log function. * @param {*} message */ @@ -37,9 +36,9 @@ export default class Logging { } /** - * Static warn function. + * Static warn function. * Emits each warning only once per session. - * @param {*} message + * @param {*} message */ static warn(message) { if (!logMessages.has(message)) { @@ -49,10 +48,10 @@ export default class Logging { } /** - * Static error function. - * Emits each error message only once per session. - * @param {*} message - */ + * Static error function. + * Emits each error message only once per session. + * @param {*} message + */ static error(message) { if (!logMessages.has(message)) { logMessages.add(message) @@ -60,7 +59,11 @@ export default class Logging { } } - static setup({log=console.log, warn=console.warn, error=console.error} = {}) { + static setup({ + log = console.log, + warn = console.warn, + error = console.error + } = {}) { logHandlers.log = log logHandlers.warn = warn logHandlers.error = error diff --git a/lib/pixi/abstractpopup.js b/lib/pixi/abstractpopup.js index 2af035b..c239659 100644 --- a/lib/pixi/abstractpopup.js +++ b/lib/pixi/abstractpopup.js @@ -11,10 +11,9 @@ import Theme from './theme.js' * @see {@link http://pixijs.download/dev/docs/PIXI.Graphics.html|PIXI.Graphics} */ export default class AbstractPopup extends PIXI.Graphics { - /** * Creates an instance of an AbstractPopup (only for internal use). - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the popup. * @param {number} [opts.id=auto generated] - The id of the popup. @@ -45,34 +44,37 @@ export default class AbstractPopup extends PIXI.Graphics { * to landscape, the popup cannot be displayed in portrait mode. */ constructor(opts = {}) { - super() - + const theme = Theme.fromString(opts.theme) this.theme = theme - this.opts = Object.assign({}, { - id: PIXI.utils.uid(), - x: 0, - y: 0, - header: null, // null or null - content: null, // null or String or PIXI.DisplayObject - minWidth: 320, - minHeight: 130, - maxWidth: null, - padding: theme.padding, - fill: theme.fill, - fillAlpha: theme.fillAlpha, - stroke: theme.stroke, - strokeWidth: theme.strokeWidth, - strokeAlpha: theme.strokeAlpha, - headerStyle: theme.textStyleLarge, - textStyle: theme.textStyleSmall, - radius: theme.radius, - onHidden: null, - visible: true, - orientation: null - }, opts) + this.opts = Object.assign( + {}, + { + id: PIXI.utils.uid(), + x: 0, + y: 0, + header: null, // null or null + content: null, // null or String or PIXI.DisplayObject + minWidth: 320, + minHeight: 130, + maxWidth: null, + padding: theme.padding, + fill: theme.fill, + fillAlpha: theme.fillAlpha, + stroke: theme.stroke, + strokeWidth: theme.strokeWidth, + strokeAlpha: theme.strokeAlpha, + headerStyle: theme.textStyleLarge, + textStyle: theme.textStyleSmall, + radius: theme.radius, + onHidden: null, + visible: true, + orientation: null + }, + opts + ) this.id = this.opts.id @@ -81,10 +83,12 @@ export default class AbstractPopup extends PIXI.Graphics { if (this.opts.maxWidth) { this.headerStyle.wordWrap = true - this.headerStyle.wordWrapWidth = this.opts.maxWidth - (2 * this.opts.padding) + this.headerStyle.wordWrapWidth = + this.opts.maxWidth - 2 * this.opts.padding this.textStyle.wordWrap = true - this.textStyle.wordWrapWidth = this.opts.maxWidth - (2 * this.opts.padding) + this.textStyle.wordWrapWidth = + this.opts.maxWidth - 2 * this.opts.padding } this.alpha = 0 @@ -99,7 +103,7 @@ export default class AbstractPopup extends PIXI.Graphics { // padding this.innerPadding = this.opts.padding * 1.5 - + // interaction //----------------- this.interactive = true @@ -107,15 +111,14 @@ export default class AbstractPopup extends PIXI.Graphics { this.show() }) } - + /** * Creates the framework and instantiates everything. - * + * * @private * @return {AbstractPopup} A reference to the popup for chaining. */ setup() { - // position //----------------- this.sy = this.opts.padding @@ -123,15 +126,17 @@ export default class AbstractPopup extends PIXI.Graphics { // header //----------------- if (this.opts.header != null) { - let header = null if (this.opts.header instanceof PIXI.Text) { header = this.opts.header } else if (typeof this.opts.header === 'number') { - header = new PIXI.Text(this.opts.header.toString(), this.headerStyle) + header = new PIXI.Text( + this.opts.header.toString(), + this.headerStyle + ) } else { - header = new PIXI.Text(this.opts.header, this.headerStyle) + header = new PIXI.Text(this.opts.header, this.headerStyle) } header.x = this.opts.padding @@ -151,13 +156,15 @@ export default class AbstractPopup extends PIXI.Graphics { // content //----------------- if (this.opts.content != null) { - let content = null if (typeof this.opts.content === 'string') { content = new PIXI.Text(this.opts.content, this.textStyle) } else if (typeof this.opts.content === 'number') { - content = new PIXI.Text(this.opts.content.toString(), this.textStyle) + content = new PIXI.Text( + this.opts.content.toString(), + this.textStyle + ) } else { content = this.opts.content } @@ -174,24 +181,23 @@ export default class AbstractPopup extends PIXI.Graphics { return this } - + /** * Should be called to refresh the layout of the popup. Can be used after resizing. - * + * * @return {AbstractPopup} A reference to the popup for chaining. */ layout() { - // wanted width & wanted height //----------------- const padding = this.opts.padding const size = this.getInnerSize() - const width = size.width + (2 * padding) - const height = size.height + (2 * padding) + const width = size.width + 2 * padding + const height = size.height + 2 * padding this.wantedWidth = Math.max(width, this.opts.minWidth) this.wantedHeight = Math.max(height, this.opts.minHeight) - + if (this.opts.maxWidth) { this.wantedWidth = Math.min(this.wantedWidth, this.opts.maxWidth) } @@ -221,41 +227,54 @@ export default class AbstractPopup extends PIXI.Graphics { return this } - + /** * Draws the canvas. - * + * * @private * @return {AbstractPopup} A reference to the popup for chaining. */ draw() { - - const square = Math.round(this.wantedWidth) === Math.round(this.wantedHeight) + const square = + Math.round(this.wantedWidth) === Math.round(this.wantedHeight) const diameter = Math.round(this.opts.radius * 2) this.clear() - this.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha) + this.lineStyle( + this.opts.strokeWidth, + this.opts.stroke, + this.opts.strokeAlpha + ) this.beginFill(this.opts.fill, this.opts.fillAlpha) if (square && diameter === this.wantedWidth) { - this.drawCircle(this.wantedWidth / 2, this.wantedHeight / 2, this.opts.radius) + this.drawCircle( + this.wantedWidth / 2, + this.wantedHeight / 2, + this.opts.radius + ) } else { - this.drawRoundedRect(0, 0, this.wantedWidth, this.wantedHeight, this.opts.radius) + this.drawRoundedRect( + 0, + 0, + this.wantedWidth, + this.wantedHeight, + this.opts.radius + ) } this.endFill() return this } - + /** * Calculates the size of the children of the AbstractPopup. * Cannot use getBounds() because it is not updated when children * are removed. - * + * * @private * @returns {object} An JavaScript object width the keys width and height. */ getInnerSize() { - let width = 0 let height = 0 @@ -273,17 +292,16 @@ export default class AbstractPopup extends PIXI.Graphics { height += this._content.height } - return {width, height} + return { width, height } } - + /** * Shows the popup (sets his alpha values to 1). - * + * * @param {callback} [cb] - Executed when show animation was completed. * @return {AbstractPopup} A reference to the popup for chaining. */ show(cb) { - TweenLite.to(this, this.theme.fast, { alpha: 1, onComplete: () => { @@ -295,15 +313,14 @@ export default class AbstractPopup extends PIXI.Graphics { return this } - + /** * Hides the popup (sets his alpha values to 0). - * + * * @param {callback} [cb] - Executed when hide animation was completed. * @return {AbstractPopup} A reference to the popup for chaining. */ hide(cb) { - TweenLite.to(this, this.theme.fast, { alpha: 0, onComplete: () => { @@ -324,7 +341,7 @@ export default class AbstractPopup extends PIXI.Graphics { /** * Sets or gets the header. The getter always returns a PIXI.Text object. The setter can receive * a string, a number or a PIXI.Text object. - * + * * @member {string|number|PIXI.Text} */ get header() { @@ -337,11 +354,11 @@ export default class AbstractPopup extends PIXI.Graphics { this.opts.header = value this.setup().layout() } - + /** * Sets or gets the content. The getter always returns an PIXI.DisplayObject. The setter can receive * a string, a number or a PIXI.DisplayObject. - * + * * @member {string|number|PIXI.DisplayObject} */ get content() { diff --git a/lib/pixi/app.js b/lib/pixi/app.js index 05b3208..d20ce7b 100644 --- a/lib/pixi/app.js +++ b/lib/pixi/app.js @@ -4,7 +4,7 @@ import Theme from './theme.js' import Progress from './progress.js' import Modal from './modal.js' import Message from './message.js' -import {debounce} from '../utils.js' +import { debounce } from '../utils.js' /** * A special InteractionManager for fullscreen apps, which may @@ -21,7 +21,6 @@ import {debounce} from '../utils.js' * @see {@link https://stackoverflow.com/questions/29710696/webgl-drawing-buffer-size-does-not-equal-canvas-size} */ class FullscreenInteractionManager extends PIXI.interaction.InteractionManager { - mapPositionToPoint(point, x, y) { let resolution = this.renderer.resolution let extendWidth = 1.0 @@ -29,8 +28,10 @@ class FullscreenInteractionManager extends PIXI.interaction.InteractionManager { let dy = 0 let canvas = this.renderer.view let context = canvas.getContext('webgl') - if (context.drawingBufferWidth < canvas.width || - context.drawingBufferHeight < canvas.height) { + if ( + context.drawingBufferWidth < canvas.width || + context.drawingBufferHeight < canvas.height + ) { extendWidth = context.drawingBufferWidth / canvas.width extendHeight = context.drawingBufferHeight / canvas.height //dx = wantedWidth - context.drawingBufferWidth @@ -63,7 +64,6 @@ class FullscreenInteractionManager extends PIXI.interaction.InteractionManager { * @see {@link http://pixijs.download/dev/docs/PIXI.Application.html|PIXI.Application} */ export default class PIXIApp extends PIXI.Application { - /** * Creates an instance of a PixiApp. * @@ -86,12 +86,23 @@ export default class PIXIApp extends PIXI.Application { * @param {boolean} [opts.adaptive=true] - Adds Graphics adaptive calculation of quadratic curve and arc subdivision. */ constructor({ - width = null, height = null, view = null, - transparent = true, backgroundColor = 0x282828, theme = 'dark', - antialias = true, resolution = window.devicePixelRatio || 1, autoResize = true, - fpsLogging = false, progress = {}, forceCanvas = false, roundPixels = true, monkeyPatchMapping = true, adaptive = true, - graphql = false }) { - + width = null, + height = null, + view = null, + transparent = true, + backgroundColor = 0x282828, + theme = 'dark', + antialias = true, + resolution = window.devicePixelRatio || 1, + autoResize = true, + fpsLogging = false, + progress = {}, + forceCanvas = false, + roundPixels = true, + monkeyPatchMapping = true, + adaptive = true, + graphql = false + }) { const fullScreen = !width || !height if (fullScreen) { @@ -109,7 +120,7 @@ export default class PIXIApp extends PIXI.Application { autoResize, backgroundColor, forceCanvas, - roundPixels // not needed for PixiJS >= 5 + roundPixels // not needed for PixiJS >= 5 }) this.width = width @@ -132,7 +143,10 @@ export default class PIXIApp extends PIXI.Application { console.log('App is in fullScreen mode or autoResize mode') const resizeDebounced = debounce(event => this.resize(event), 50) window.addEventListener('resize', resizeDebounced) - document.body.addEventListener('orientationchange', this.checkOrientation.bind(this)) + document.body.addEventListener( + 'orientationchange', + this.checkOrientation.bind(this) + ) } if (monkeyPatchMapping) { console.log('Using monkey patched coordinate mapping') @@ -159,15 +173,17 @@ export default class PIXIApp extends PIXI.Application { // GraphQL if (this.graphql && typeof apollo !== 'undefined') { - const networkInterface = apollo.createNetworkInterface({ uri: '/graphql' }) - const wsClient = new subscriptions.SubscriptionClient(`wss://${location.hostname}/subscriptions`, { - reconnect: true, - connectionParams: {} - }) + const wsClient = new subscriptions.SubscriptionClient( + `wss://${location.hostname}/subscriptions`, + { + reconnect: true, + connectionParams: {} + } + ) const networkInterfaceWithSubscriptions = subscriptions.addGraphQLSubscriptions( networkInterface, @@ -180,7 +196,11 @@ export default class PIXIApp extends PIXI.Application { } // progress - this._progress = new Progress(Object.assign({ theme: this.theme }, this.progressOpts, { app: this })) + this._progress = new Progress( + Object.assign({ theme: this.theme }, this.progressOpts, { + app: this + }) + ) this._progress.visible = false this.stage.addChild(this._progress) @@ -205,9 +225,12 @@ export default class PIXIApp extends PIXI.Application { checkOrientation(event) { var value = this.orientation() if (value != this.orient) { - setTimeout(100, function () { - this.orientationChanged(true) - }.bind(this)) + setTimeout( + 100, + function() { + this.orientationChanged(true) + }.bind(this) + ) this.orient = value } } @@ -230,9 +253,7 @@ export default class PIXIApp extends PIXI.Application { * @param {number} [width] - The width of the app. * @param {number} [height] - The height of the app. */ - layout(width, height) { - - } + layout(width, height) {} /** * Draws the display tree of the app. Typically this can be delegated @@ -303,7 +324,10 @@ export default class PIXIApp extends PIXI.Application { * @param {number} [opts.height=window.innerHeight] - The height of the app to resize to. * @return {PIXIApp} - Returns the PIXIApp for chaining. */ - resize(event, { width = window.innerWidth, height = window.innerHeight } = {}) { + resize( + event, + { width = window.innerWidth, height = window.innerHeight } = {} + ) { this.width = width this.height = height this.expandRenderer() @@ -324,7 +348,8 @@ export default class PIXIApp extends PIXI.Application { monkeyPatchPixiMapping() { if (this.originalMapPositionToPoint === null) { let interactionManager = this.renderer.plugins.interaction - this.originalMapPositionToPoint = interactionManager.mapPositionToPoint + this.originalMapPositionToPoint = + interactionManager.mapPositionToPoint interactionManager.mapPositionToPoint = (point, x, y) => { return this.fixedMapPositionToPoint(point, x, y) } @@ -332,7 +357,7 @@ export default class PIXIApp extends PIXI.Application { } /** - * In some browsers the canvas is distorted if the screen resolution and + * In some browsers the canvas is distorted if the screen resolution and * overall size of the canvas exceeds the internal limits (e.g. 4096 x 4096 pixels). * To compensate these distortions we need to fix the mapping to the actual * drawing buffer coordinates. @@ -351,8 +376,11 @@ export default class PIXIApp extends PIXI.Application { let canvas = this.renderer.view let context = canvas.getContext('webgl') - if (context !== null && (context.drawingBufferWidth < canvas.width || - context.drawingBufferHeight < canvas.height)) { + if ( + context !== null && + (context.drawingBufferWidth < canvas.width || + context.drawingBufferHeight < canvas.height) + ) { extendWidth = context.drawingBufferWidth / canvas.width extendHeight = context.drawingBufferHeight / canvas.height //dx = wantedWidth - context.drawingBufferWidth @@ -360,7 +388,12 @@ export default class PIXIApp extends PIXI.Application { } x *= extendWidth y *= extendHeight - return this.originalMapPositionToPoint.call(interactionManager, local, x, y + dy) + return this.originalMapPositionToPoint.call( + interactionManager, + local, + x, + y + dy + ) } /** @@ -394,7 +427,6 @@ export default class PIXIApp extends PIXI.Application { * called without a parameter. */ progress(value) { - if (typeof value === 'undefined') { return this._progress } @@ -412,8 +444,9 @@ export default class PIXIApp extends PIXI.Application { * @return {Modal} Returns the Modal object. */ modal(opts = {}) { - - let modal = new Modal(Object.assign({ theme: this.theme }, opts, { app: this })) + let modal = new Modal( + Object.assign({ theme: this.theme }, opts, { app: this }) + ) this.scene.addChild(modal) return modal @@ -426,8 +459,9 @@ export default class PIXIApp extends PIXI.Application { * @return {Message} Returns the Message object. */ message(opts = {}) { - - let message = new Message(Object.assign({ theme: this.theme }, opts, { app: this })) + let message = new Message( + Object.assign({ theme: this.theme }, opts, { app: this }) + ) this.scene.addChild(message) return message @@ -446,21 +480,26 @@ export default class PIXIApp extends PIXI.Application { * @param {boolean} [opts.progress=false] - Should a progress bar display the loading status? * @return {PIXIApp} The PIXIApp object for chaining. */ - loadSprites(resources, loaded = null, { resolutionDependent = true, progress = false } = {}) { + loadSprites( + resources, + loaded = null, + { resolutionDependent = true, progress = false } = {} + ) { + this.loadTextures( + resources, + textures => { + let sprites = new Map() - this.loadTextures(resources, textures => { + for (let [key, texture] of textures) { + sprites.set(key, new PIXI.Sprite(texture)) + } - let sprites = new Map() - - for (let [key, texture] of textures) { - sprites.set(key, new PIXI.Sprite(texture)) - } - - if (loaded) { - loaded.call(this, sprites) - } - - }, { resolutionDependent, progress }) + if (loaded) { + loaded.call(this, sprites) + } + }, + { resolutionDependent, progress } + ) return this } @@ -478,8 +517,11 @@ export default class PIXIApp extends PIXI.Application { * @param {boolean} [opts.progress=false] - Should a progress bar display the loading status? * @return {PIXIApp} The PIXIApp object for chaining. */ - loadTextures(resources, loaded = null, { resolutionDependent = true, progress = false } = {}) { - + loadTextures( + resources, + loaded = null, + { resolutionDependent = true, progress = false } = {} + ) { if (!Array.isArray(resources)) { resources = [resources] } @@ -487,17 +529,21 @@ export default class PIXIApp extends PIXI.Application { const loader = this.loader for (let resource of resources) { - if (!loader.resources[resource]) { - if (resolutionDependent) { let resolution = Math.round(this.renderer.resolution) switch (resolution) { case 2: - loader.add(resource, resource.replace(/\.([^.]*)$/, '@2x.$1')) + loader.add( + resource, + resource.replace(/\.([^.]*)$/, '@2x.$1') + ) break case 3: - loader.add(resource, resource.replace(/\.([^.]*)$/, '@3x.$1')) + loader.add( + resource, + resource.replace(/\.([^.]*)$/, '@3x.$1') + ) break default: loader.add(resource) @@ -540,7 +586,6 @@ export default class PIXIApp extends PIXI.Application { * rejected with an error. */ query(query, opts = {}) { - if (typeof query === 'string') { opts = Object.assign({}, opts, { query }) } else { @@ -572,7 +617,6 @@ export default class PIXIApp extends PIXI.Application { * rejected with an error. */ mutate(mutation, opts = {}) { - if (typeof mutation === 'string') { opts = Object.assign({}, opts, { mutation }) } else { @@ -604,7 +648,6 @@ export default class PIXIApp extends PIXI.Application { * rejected with an error. */ subscribe(subscription, opts = {}) { - if (typeof subscription === 'string') { opts = Object.assign({}, opts, { subscription }) } else { @@ -635,13 +678,13 @@ export default class PIXIApp extends PIXI.Application { * @param {DisplayObject} displayObject - The PIXI displayObject. * @param {number} x - The x coordinate. * @param {number} y - The y coordinate. - * + * * @return {PIXI.Point} Returns a PIXI.Point. */ convertPointFromPageToNode(displayObject, x, y) { let resolution = this.renderer.resolution - console.log("resolution", resolution) + console.log('resolution', resolution) let pixiGlobal = window.convertPointFromPageToNode(app.view, x, y) pixiGlobal.x /= resolution pixiGlobal.y /= resolution @@ -655,7 +698,7 @@ export default class PIXIApp extends PIXI.Application { * @param {DisplayObject} displayObject - The PIXI displayObject. * @param {number} x - The x coordinate. * @param {number} y - The y coordinate. - * + * * @return {Point} Returns a DOM Point. */ @@ -665,7 +708,11 @@ export default class PIXIApp extends PIXI.Application { pixiGlobal.x *= resolution pixiGlobal.y *= resolution // console.log("app.convertPointFromNodeToPage", pixiGlobal) - return window.convertPointFromNodeToPage(app.view, pixiGlobal.x, pixiGlobal.y) + return window.convertPointFromNodeToPage( + app.view, + pixiGlobal.x, + pixiGlobal.y + ) } } @@ -679,7 +726,6 @@ export default class PIXIApp extends PIXI.Application { * @see {@link http://pixijs.download/dev/docs/PIXI.Graphics.html|PIXI.Graphics} */ class FpsDisplay extends PIXI.Graphics { - /** * Creates an instance of a FpsDisplay. * @@ -687,25 +733,27 @@ class FpsDisplay extends PIXI.Graphics { * @param {PIXIApp} app - The PIXIApp where the frames per second should be displayed. */ constructor(app) { - super() this.app = app this.lineStyle(3, 0x434f4f, 1) - .beginFill(0x434f4f, .6) + .beginFill(0x434f4f, 0.6) .drawRoundedRect(0, 0, 68, 32, 5) .endFill() .position.set(20, 20) - this.text = new PIXI.Text(this.fps, new PIXI.TextStyle({ - fontFamily: 'Arial', - fontSize: 14, - fontWeight: 'bold', - fill: '#f6f6f6', - stroke: '#434f4f', - strokeThickness: 3 - })) + this.text = new PIXI.Text( + this.fps, + new PIXI.TextStyle({ + fontFamily: 'Arial', + fontSize: 14, + fontWeight: 'bold', + fill: '#f6f6f6', + stroke: '#434f4f', + strokeThickness: 3 + }) + ) this.text.position.set(6, 6) this.addChild(this.text) @@ -721,7 +769,7 @@ class FpsDisplay extends PIXI.Graphics { * @return {PIXIApp} Returns the PIXIApp object for chaining. */ refreshFps() { - this.text.text = `${(this.app.ticker.FPS).toFixed(1)} fps` + this.text.text = `${this.app.ticker.FPS.toFixed(1)} fps` return this } diff --git a/lib/pixi/blurfilter.js b/lib/pixi/blurfilter.js index 243d87f..0c11e74 100644 --- a/lib/pixi/blurfilter.js +++ b/lib/pixi/blurfilter.js @@ -13,17 +13,17 @@ * height: 270, * transparent: false * }).setup().run() - * + * * // Add a video sprite * const sprite = new PIXI.Sprite(PIXI.Texture.fromVideo("assets/blurfilter.mp4")) * sprite.width = app.size.width * sprite.height = app.size.height * app.scene.addChild(sprite) - * + * * // Create the filter and assign it to the scene * const blurFilter = new BlurFilter(new PIXI.Rectangle(20, 20, 80, 60)) * app.scene.filters = [blurFilter] - * + * * @class * @extends PIXI.Filter * @param {PIXI.Rectangle|PIXI.Circle|PIXI.DisplayObject} shape The area where the blur effect should be applied to. Relative to the @@ -31,7 +31,6 @@ * @param {number} [blur=50] The strength of the blur. */ export default class BlurFilter extends PIXI.Filter { - constructor(shape, blur = 50) { super() @@ -59,7 +58,7 @@ export default class BlurFilter extends PIXI.Filter { set blur(value) { this.tiltShiftXFilter.blur = this.tiltShiftYFilter.blur = value } - + /** * The blur shape. * @@ -69,26 +68,39 @@ export default class BlurFilter extends PIXI.Filter { return this.tiltShiftXFilter.shape } set shape(value) { - this.tiltShiftXFilter.shape = this.tiltShiftYFilter.shape = this.normalize(value) + this.tiltShiftXFilter.shape = this.tiltShiftYFilter.shape = this.normalize( + value + ) } /** - * + * * @private * @param {PIXI.Rectangle|PIXI.Circle|PIXI.DisplayObject} value * @returns {Object} */ normalize(value) { - let shape = null if (value instanceof PIXI.Circle) { - shape = {type: 'circle', x: value.x, y: value.y, r: value.radius} + shape = { type: 'circle', x: value.x, y: value.y, r: value.radius } } else if (value instanceof PIXI.Rectangle) { - shape = {type: 'rectangle', x: value.x, y: value.y, width: value.width, height: value.height} + shape = { + type: 'rectangle', + x: value.x, + y: value.y, + width: value.width, + height: value.height + } } else { const bounds = value.getBounds() - shape = {type: 'rectangle', x: bounds.x, y: bounds.y, width: bounds.width, height: bounds.height} + shape = { + type: 'rectangle', + x: bounds.x, + y: bounds.y, + width: bounds.width, + height: bounds.height + } } return shape @@ -104,9 +116,7 @@ export default class BlurFilter extends PIXI.Filter { * @private */ class TiltShiftAxisFilter extends PIXI.Filter { - - constructor(shape, blur){ - + constructor(shape, blur) { const vertex = ` attribute vec2 aVertexPosition; attribute vec2 aTextureCoord; @@ -173,13 +183,18 @@ class TiltShiftAxisFilter extends PIXI.Filter { ` super(vertex, fragment) - + if (shape.type === 'circle') { this.uniforms.shape = 1 this.uniforms.circle = [shape.x, shape.y, shape.r] } else { this.uniforms.shape = 2 - this.uniforms.rectangle = [shape.x, shape.y, shape.x + shape.width, shape.y + shape.height] + this.uniforms.rectangle = [ + shape.x, + shape.y, + shape.x + shape.width, + shape.y + shape.height + ] } this.uniforms.blur = blur this.uniforms.delta = new PIXI.Point(0, 0) @@ -200,7 +215,7 @@ class TiltShiftAxisFilter extends PIXI.Filter { set blur(value) { this.uniforms.blur = value } - + /** * The blur shape. * @@ -213,7 +228,12 @@ class TiltShiftAxisFilter extends PIXI.Filter { return new PIXI.Circle(circle[0], circle[1], circle[2]) } else { const rectangle = this.uniforms.rectangle - return new PIXI.Rectangle(rectangle[0], rectangle[1], rectangle[2], rectangle[3]) + return new PIXI.Rectangle( + rectangle[0], + rectangle[1], + rectangle[2], + rectangle[3] + ) } } set shape(value) { @@ -222,7 +242,12 @@ class TiltShiftAxisFilter extends PIXI.Filter { this.uniforms.circle = [value.x, value.y, value.r] } else { this.uniforms.shape = 2 - this.uniforms.rectangle = [value.x, value.y, value.x + value.width, value.y + value.height] + this.uniforms.rectangle = [ + value.x, + value.y, + value.x + value.width, + value.y + value.height + ] } } } @@ -260,4 +285,3 @@ class TiltShiftYFilter extends TiltShiftAxisFilter { this.uniforms.delta.y = 0.1 } } - diff --git a/lib/pixi/bundle.js b/lib/pixi/bundle.js index ff7b180..49d51aa 100755 --- a/lib/pixi/bundle.js +++ b/lib/pixi/bundle.js @@ -2,10 +2,10 @@ import PIXIApp from './app.js' import BlurFilter from './blurfilter.js' import FlipEffect from './flipeffect.js' import Flippable from './flippable.js' -import {DeepZoomInfo, DeepZoomImage} from './deepzoom/image.js' +import { DeepZoomInfo, DeepZoomImage } from './deepzoom/image.js' import Popover from './popover.js' -import {ScatterContainer, DisplayObjectScatter} from './scatter.js' -import {AppTest, Command, RecorderTools} from './test.js' +import { ScatterContainer, DisplayObjectScatter } from './scatter.js' +import { AppTest, Command, RecorderTools } from './test.js' import Timeline from './timeline.js' import Theme from './theme.js' import Button from './button.js' @@ -23,7 +23,7 @@ import Tooltip from './tooltip.js' import Badge from './badge.js' import Progress from './progress.js' import List from './list.js' -import {LabeledGraphics, FontInfo} from './labeledgraphics.js' +import { LabeledGraphics, FontInfo } from './labeledgraphics.js' /* Needed to ensure that rollup.js includes class definitions and the classes are visible inside doctests. */ @@ -57,4 +57,4 @@ window.Badge = Badge window.Progress = Progress window.List = List window.LabeledGraphics = LabeledGraphics -window.FontInfo = FontInfo \ No newline at end of file +window.FontInfo = FontInfo diff --git a/lib/pixi/button.js b/lib/pixi/button.js index b86c2e5..9762080 100644 --- a/lib/pixi/button.js +++ b/lib/pixi/button.js @@ -47,7 +47,6 @@ import Events from '../events.js' * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/button.html|DocTest} */ export default class Button extends PIXI.Container { - /** * Creates an instance of a Button. * @@ -106,62 +105,76 @@ export default class Button extends PIXI.Container { * @param {boolean} [opts.visible=true] - Is the button initially visible (property visible)? */ constructor(opts = {}) { - super() const theme = Theme.fromString(opts.theme) this.theme = theme - this.opts = Object.assign({}, { - id: PIXI.utils.uid(), - label: null, - x: 0, - y: 0, - minWidth: 44, - minHeight: 44, - padding: theme.padding, - icon: undefined, - iconActive: undefined, - iconPosition: 'left', - iconColor: theme.iconColor, - iconColorActive: theme.iconColorActive, - fill: theme.fill, - fillAlpha: theme.fillAlpha, - fillActive: theme.fillActive, - fillActiveAlpha: theme.fillActiveAlpha, - stroke: theme.stroke, - strokeWidth: theme.strokeWidth, - strokeAlpha: theme.strokeAlpha, - strokeActive: theme.strokeActive, - strokeActiveWidth: theme.strokeActiveWidth, - strokeActiveAlpha: theme.strokeActiveAlpha, - textStyle: theme.textStyle, - textStyleActive: theme.textStyleActive, - style: 'default', - radius: theme.radius, - disabled: false, - active: false, - action: null, - beforeAction: null, - afterAction: null, - type: 'default', - align: 'center', - verticalAlign: 'middle', - tooltip: null, - badge: null, - visible: true - }, opts) + this.opts = Object.assign( + {}, + { + id: PIXI.utils.uid(), + label: null, + x: 0, + y: 0, + minWidth: 44, + minHeight: 44, + padding: theme.padding, + icon: undefined, + iconActive: undefined, + iconPosition: 'left', + iconColor: theme.iconColor, + iconColorActive: theme.iconColorActive, + fill: theme.fill, + fillAlpha: theme.fillAlpha, + fillActive: theme.fillActive, + fillActiveAlpha: theme.fillActiveAlpha, + stroke: theme.stroke, + strokeWidth: theme.strokeWidth, + strokeAlpha: theme.strokeAlpha, + strokeActive: theme.strokeActive, + strokeActiveWidth: theme.strokeActiveWidth, + strokeActiveAlpha: theme.strokeActiveAlpha, + textStyle: theme.textStyle, + textStyleActive: theme.textStyleActive, + style: 'default', + radius: theme.radius, + disabled: false, + active: false, + action: null, + beforeAction: null, + afterAction: null, + type: 'default', + align: 'center', + verticalAlign: 'middle', + tooltip: null, + badge: null, + visible: true + }, + opts + ) this.id = this.opts.id - if (typeof this.opts.icon === 'undefined' && typeof this.opts.iconActive !== 'undefined') { + if ( + typeof this.opts.icon === 'undefined' && + typeof this.opts.iconActive !== 'undefined' + ) { this.opts.icon = this.opts.iconActive - } else if (typeof this.opts.icon !== 'undefined' && typeof this.opts.iconActive === 'undefined') { + } else if ( + typeof this.opts.icon !== 'undefined' && + typeof this.opts.iconActive === 'undefined' + ) { this.opts.iconActive = this.opts.icon } if (this.opts.style === 'link') { - Object.assign(this.opts, { strokeAlpha: 0, strokeActiveAlpha: 0, fillAlpha: 0, fillActiveAlpha: 0 }) + Object.assign(this.opts, { + strokeAlpha: 0, + strokeActiveAlpha: 0, + fillAlpha: 0, + fillActiveAlpha: 0 + }) } this._active = null @@ -200,7 +213,6 @@ export default class Button extends PIXI.Container { * @return {Button} A reference to the button for chaining. */ setup() { - // Button //----------------- let button = new PIXI.Graphics() @@ -222,18 +234,27 @@ export default class Button extends PIXI.Container { // Icon //----------------- if (this.opts.icon) { - this.iconInactive = this.loadIcon(this.opts.icon, this.opts.iconColor) + this.iconInactive = this.loadIcon( + this.opts.icon, + this.opts.iconColor + ) } if (this.opts.iconActive) { - this.iconActive = this.loadIcon(this.opts.iconActive, this.opts.iconColorActive) + this.iconActive = this.loadIcon( + this.opts.iconActive, + this.opts.iconColorActive + ) } // interaction //----------------- this.button.on('pointerover', e => { this.capture(e) - TweenLite.to([this.button, this.content], this.theme.fast, { alpha: .83, overwrite: 'none' }) + TweenLite.to([this.button, this.content], this.theme.fast, { + alpha: 0.83, + overwrite: 'none' + }) }) this.button.on('pointermove', e => { @@ -242,13 +263,19 @@ export default class Button extends PIXI.Container { this.button.on('pointerout', e => { this.capture(e) - TweenLite.to([this.button, this.content], this.theme.fast, { alpha: 1, overwrite: 'none' }) + TweenLite.to([this.button, this.content], this.theme.fast, { + alpha: 1, + overwrite: 'none' + }) }) // eslint-disable-next-line no-unused-vars this.button.on('pointerdown', e => { //this.capture(e) - TweenLite.to([this.button, this.content], this.theme.fast, { alpha: .7, overwrite: 'none' }) + TweenLite.to([this.button, this.content], this.theme.fast, { + alpha: 0.7, + overwrite: 'none' + }) }) this.button.on('pointerup', e => { @@ -261,7 +288,10 @@ export default class Button extends PIXI.Container { this.opts.action.call(this, e, this) } - TweenLite.to([this.button, this.content], this.theme.fast, { alpha: .83, overwrite: 'none' }) + TweenLite.to([this.button, this.content], this.theme.fast, { + alpha: 0.83, + overwrite: 'none' + }) if (this.opts.type === 'checkbox') { this.active = !this.active @@ -278,15 +308,22 @@ export default class Button extends PIXI.Container { // active //----------------- - this.active = this.opts.active // calls .layout() + this.active = this.opts.active // calls .layout() // tooltip //----------------- if (this.opts.tooltip) { if (typeof this.opts.tooltip === 'string') { - this.tooltip = new Tooltip({ object: this, content: this.opts.tooltip }) + this.tooltip = new Tooltip({ + object: this, + content: this.opts.tooltip + }) } else { - this.opts.tooltip = Object.assign({}, { object: this }, this.opts.tooltip) + this.opts.tooltip = Object.assign( + {}, + { object: this }, + this.opts.tooltip + ) this.tooltip = new Tooltip(this.opts.tooltip) } } @@ -294,12 +331,15 @@ export default class Button extends PIXI.Container { // badge //----------------- if (this.opts.badge) { - let opts = Object.assign({}, { - align: 'right', - verticalAlign: 'top', - offsetLeft: 0, - offsetTop: 0 - }) + let opts = Object.assign( + {}, + { + align: 'right', + verticalAlign: 'top', + offsetLeft: 0, + offsetTop: 0 + } + ) if (typeof this.opts.badge === 'string') { opts = Object.assign(opts, { content: this.opts.badge }) } else { @@ -309,25 +349,35 @@ export default class Button extends PIXI.Container { const badge = new Badge(opts) switch (opts.align) { - case 'left': - badge.x = this.x - badge.width / 2 + opts.offsetLeft - break - case 'center': - badge.x = this.x + this.width / 2 - badge.width / 2 + opts.offsetLeft - break - case 'right': - badge.x = this.x + this.width - badge.width / 2 + opts.offsetLeft + case 'left': + badge.x = this.x - badge.width / 2 + opts.offsetLeft + break + case 'center': + badge.x = + this.x + + this.width / 2 - + badge.width / 2 + + opts.offsetLeft + break + case 'right': + badge.x = + this.x + this.width - badge.width / 2 + opts.offsetLeft } switch (opts.verticalAlign) { - case 'top': - badge.y = this.y - badge.height / 2 + opts.offsetTop - break - case 'middle': - badge.y = this.y + this.height / 2 - badge.height / 2 + opts.offsetTop - break - case 'bottom': - badge.y = this.y + this.height - badge.height / 2 + opts.offsetTop + case 'top': + badge.y = this.y - badge.height / 2 + opts.offsetTop + break + case 'middle': + badge.y = + this.y + + this.height / 2 - + badge.height / 2 + + opts.offsetTop + break + case 'bottom': + badge.y = + this.y + this.height - badge.height / 2 + opts.offsetTop } this.addChild(badge) @@ -348,7 +398,6 @@ export default class Button extends PIXI.Container { * @return {Button} A reference to the button for chaining. */ layout() { - // Clear content //----------------- this.removeChild(this.content) @@ -434,18 +483,17 @@ export default class Button extends PIXI.Container { * @return {Button} A reference to the button for chaining. */ layoutInnerContent() { - for (let child of this.content.children) { switch (this.opts.verticalAlign) { - case 'top': - child.y = 0 - break - case 'middle': - child.y = this.content.height / 2 - child.height / 2 - break - case 'bottom': - child.y = this.content.height - child.height - break + case 'top': + child.y = 0 + break + case 'middle': + child.y = this.content.height / 2 - child.height / 2 + break + case 'bottom': + child.y = this.content.height - child.height + break } } @@ -460,29 +508,30 @@ export default class Button extends PIXI.Container { * @return {Button} A reference to the button for chaining. */ layoutContent() { - switch (this.opts.align) { - case 'left': - this.content.x = this.opts.padding - break - case 'center': - this.content.x = ((this._width - this.content.width) / 2) - break - case 'right': - this.content.x = this._width - this.opts.padding - this.content.width - break + case 'left': + this.content.x = this.opts.padding + break + case 'center': + this.content.x = (this._width - this.content.width) / 2 + break + case 'right': + this.content.x = + this._width - this.opts.padding - this.content.width + break } switch (this.opts.verticalAlign) { - case 'top': - this.content.y = this.opts.padding - break - case 'middle': - this.content.y = (this._height - this.content.height) / 2 - break - case 'bottom': - this.content.y = this._height - this.opts.padding - this.content.height - break + case 'top': + this.content.y = this.opts.padding + break + case 'middle': + this.content.y = (this._height - this.content.height) / 2 + break + case 'bottom': + this.content.y = + this._height - this.opts.padding - this.content.height + break } return this @@ -495,16 +544,32 @@ export default class Button extends PIXI.Container { * @return {Button} A reference to the button for chaining. */ draw() { - this.button.clear() if (this.active) { - this.button.lineStyle(this.opts.strokeActiveWidth, this.opts.strokeActive, this.opts.strokeActiveAlpha) - this.button.beginFill(this.opts.fillActive, this.opts.fillActiveAlpha) + this.button.lineStyle( + this.opts.strokeActiveWidth, + this.opts.strokeActive, + this.opts.strokeActiveAlpha + ) + this.button.beginFill( + this.opts.fillActive, + this.opts.fillActiveAlpha + ) } else { - this.button.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha) + this.button.lineStyle( + this.opts.strokeWidth, + this.opts.stroke, + this.opts.strokeAlpha + ) this.button.beginFill(this.opts.fill, this.opts.fillAlpha) } - this.button.drawRoundedRect(0, 0, this._width, this._height, this.opts.radius) + this.button.drawRoundedRect( + 0, + 0, + this._width, + this._height, + this.opts.radius + ) this.button.endFill() return this @@ -519,7 +584,6 @@ export default class Button extends PIXI.Container { return this._active } set active(value) { - this._active = value if (this._active) { @@ -544,18 +608,17 @@ export default class Button extends PIXI.Container { return this._disabled } set disabled(value) { - this._disabled = value if (this._disabled) { this.button.interactive = false this.button.buttonMode = false - this.button.alpha = .5 + this.button.alpha = 0.5 if (this.icon) { - this.icon.alpha = .5 + this.icon.alpha = 0.5 } if (this.text) { - this.text.alpha = .5 + this.text.alpha = 0.5 } } else { this.button.interactive = true @@ -576,7 +639,6 @@ export default class Button extends PIXI.Container { * @return {Button} A reference to the button for chaining. */ show() { - this.opts.strokeAlpha = 1 this.opts.strokeActiveAlpha = 1 this.opts.fillAlpha = 1 @@ -593,7 +655,6 @@ export default class Button extends PIXI.Container { * @return {Button} A reference to the button for chaining. */ hide() { - this.opts.strokeAlpha = 0 this.opts.strokeActiveAlpha = 0 this.opts.fillAlpha = 0 @@ -613,7 +674,6 @@ export default class Button extends PIXI.Container { * @return {PIXI.DisplayObject} Return the icon as an PIXI.DisplayObject. */ loadIcon(icon, color) { - let displayObject = null if (icon instanceof PIXI.DisplayObject) { @@ -623,10 +683,12 @@ export default class Button extends PIXI.Container { if (this.text) { size = this.text.height } else if (this.opts.minHeight) { - size = this.opts.minHeight - (2 * this.opts.padding) + size = this.opts.minHeight - 2 * this.opts.padding } - const url = Button.iconIsUrl(icon) ? icon : `../../assets/icons/${icon}.png` + const url = Button.iconIsUrl(icon) + ? icon + : `../../assets/icons/${icon}.png` const iconTexture = PIXI.Texture.fromImage(url, true) const sprite = new PIXI.Sprite(iconTexture) diff --git a/lib/pixi/buttongroup.js b/lib/pixi/buttongroup.js index cb9f197..d0e20f8 100644 --- a/lib/pixi/buttongroup.js +++ b/lib/pixi/buttongroup.js @@ -3,7 +3,7 @@ import Button from './button.js' /** * Class that represents a PixiJS ButtonGroup. - * + * * @example * // Create the button group * const buttonGroup = new ButtonGroup({ @@ -24,10 +24,9 @@ import Button from './button.js' * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/buttongroup.html|DocTest} */ export default class ButtonGroup extends PIXI.Graphics { - /** * Creates an instance of a ButtonGroup. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the button group. * @param {number} [opts.id=auto generated] - The id of the button group. @@ -74,50 +73,53 @@ export default class ButtonGroup extends PIXI.Graphics { * @param {boolean} [opts.visible=true] - Is the button group initially visible (property visible)? */ constructor(opts = {}) { - super() - + const theme = Theme.fromString(opts.theme) this.theme = theme - this.opts = Object.assign({}, { - id: PIXI.utils.uid(), - x: 0, - y: 0, - buttons: [], - minWidth: 44, - minHeight: 44, - padding: theme.padding, - margin: theme.margin, - iconPosition: 'left', // left, right - iconColor: theme.iconColor, - iconColorActive: theme.iconColorActive, - fill: theme.fill, - fillAlpha: theme.fillAlpha, - fillActive: theme.fillActive, - fillActiveAlpha: theme.fillActiveAlpha, - stroke: theme.stroke, - strokeWidth: theme.strokeWidth, - strokeAlpha: theme.strokeAlpha, - strokeActive: theme.strokeActive, - strokeActiveWidth: theme.strokeActiveWidth, - strokeActiveAlpha: theme.strokeActiveAlpha, - textStyle: theme.textStyle, - textStyleActive: theme.textStyleActive, - style: 'default', - radius: theme.radius, - disabled: null, - type: 'default', // default, checkbox, radio - orientation: 'horizontal', - align: 'center', // left, center, right - verticalAlign: 'middle', // top, middle, bottom - visible: true - }, opts) + this.opts = Object.assign( + {}, + { + id: PIXI.utils.uid(), + x: 0, + y: 0, + buttons: [], + minWidth: 44, + minHeight: 44, + padding: theme.padding, + margin: theme.margin, + iconPosition: 'left', // left, right + iconColor: theme.iconColor, + iconColorActive: theme.iconColorActive, + fill: theme.fill, + fillAlpha: theme.fillAlpha, + fillActive: theme.fillActive, + fillActiveAlpha: theme.fillActiveAlpha, + stroke: theme.stroke, + strokeWidth: theme.strokeWidth, + strokeAlpha: theme.strokeAlpha, + strokeActive: theme.strokeActive, + strokeActiveWidth: theme.strokeActiveWidth, + strokeActiveAlpha: theme.strokeActiveAlpha, + textStyle: theme.textStyle, + textStyleActive: theme.textStyleActive, + style: 'default', + radius: theme.radius, + disabled: null, + type: 'default', // default, checkbox, radio + orientation: 'horizontal', + align: 'center', // left, center, right + verticalAlign: 'middle', // top, middle, bottom + visible: true + }, + opts + ) this.buttons = [] this._disabled = null - + this.visible = this.opts.visible // setup @@ -128,21 +130,19 @@ export default class ButtonGroup extends PIXI.Graphics { //----------------- this.layout() } - + /** * Creates children and instantiates everything. - * + * * @private * @return {ButtonGroup} A reference to the button group for chaining. */ setup() { - // Buttons //----------------- let position = 0 for (let it of this.opts.buttons) { - delete it.x delete it.y @@ -164,11 +164,19 @@ export default class ButtonGroup extends PIXI.Graphics { it.fillActive = it.fillActive || this.opts.fillActive it.fillActiveAlpha = it.fillActiveAlpha || this.opts.fillActiveAlpha it.stroke = it.stroke || this.opts.stroke - it.strokeWidth = it.strokeWidth != null ? it.strokeWidth : this.opts.strokeWidth - it.strokeAlpha = it.strokeAlpha != null ? it.strokeAlpha : this.opts.strokeAlpha + it.strokeWidth = + it.strokeWidth != null ? it.strokeWidth : this.opts.strokeWidth + it.strokeAlpha = + it.strokeAlpha != null ? it.strokeAlpha : this.opts.strokeAlpha it.strokeActive = it.strokeActive || this.opts.strokeActive - it.strokeActiveWidth = it.strokeActiveWidth != null ? it.strokeActiveWidth : this.opts.strokeActiveWidth - it.strokeActiveAlpha = it.strokeActiveAlpha != null ? it.strokeActiveAlpha : this.opts.strokeActiveAlpha + it.strokeActiveWidth = + it.strokeActiveWidth != null + ? it.strokeActiveWidth + : this.opts.strokeActiveWidth + it.strokeActiveAlpha = + it.strokeActiveAlpha != null + ? it.strokeActiveAlpha + : this.opts.strokeActiveAlpha it.textStyle = it.textStyle || this.opts.textStyle it.textStyleActive = it.textStyleActive || this.opts.textStyleActive it.style = it.style || this.opts.style @@ -187,7 +195,10 @@ export default class ButtonGroup extends PIXI.Graphics { it.align = it.align || this.opts.align it.verticalAlign = it.verticalAlign || this.opts.verticalAlign it.afterAction = (event, button) => { - if (this.opts.type === 'radio' && button.opts.type === 'default') { + if ( + this.opts.type === 'radio' && + button.opts.type === 'default' + ) { this.buttons.forEach(it => { if (it.opts.type === 'default') { it.active = false @@ -202,18 +213,25 @@ export default class ButtonGroup extends PIXI.Graphics { if (it.tooltip) { if (typeof it.tooltip === 'string') { - it.tooltip = {content: it.tooltip, container: this} + it.tooltip = { content: it.tooltip, container: this } } else { - it.tooltip = Object.assign({}, {container: this}, it.tooltip) + it.tooltip = Object.assign( + {}, + { container: this }, + it.tooltip + ) } } - + let button = new Button(it) this.addChild(button) this.buttons.push(button) - position += (this.opts.orientation === 'horizontal' ? button.width : button.height) + this.opts.margin + position += + (this.opts.orientation === 'horizontal' + ? button.width + : button.height) + this.opts.margin } if (this.opts.orientation === 'vertical') { @@ -233,14 +251,13 @@ export default class ButtonGroup extends PIXI.Graphics { return this } - + /** * Should be called to refresh the layout of the button group. Can be used after resizing. - * + * * @return {ButtonGroup} A reference to the button group for chaining. */ layout() { - // set position //----------------- this.position.set(this.opts.x, this.opts.y) @@ -251,26 +268,38 @@ export default class ButtonGroup extends PIXI.Graphics { return this } - + /** * Draws the canvas. - * + * * @private * @return {ButtonGroup} A reference to the button group for chaining. */ draw() { - if (this.opts.margin === 0) { - this.buttons.forEach(it => it.hide()) this.clear() - this.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha) + this.lineStyle( + this.opts.strokeWidth, + this.opts.stroke, + this.opts.strokeAlpha + ) this.beginFill(this.opts.fill, this.opts.fillAlpha) - this.drawRoundedRect(0, 0, this.width, this.height, this.opts.radius) + this.drawRoundedRect( + 0, + 0, + this.width, + this.height, + this.opts.radius + ) // Draw borders - this.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha / 2) + this.lineStyle( + this.opts.strokeWidth, + this.opts.stroke, + this.opts.strokeAlpha / 2 + ) this.buttons.forEach((it, i) => { if (i > 0) { @@ -281,7 +310,6 @@ export default class ButtonGroup extends PIXI.Graphics { } else { this.lineTo(it.width, it.y) } - } }) @@ -290,10 +318,10 @@ export default class ButtonGroup extends PIXI.Graphics { return this } - + /** * Gets or sets the disabled state. When disabled, no button of the button group can be clicked. - * + * * @member {boolean} */ get disabled() { @@ -301,32 +329,29 @@ export default class ButtonGroup extends PIXI.Graphics { } set disabled(value) { - this._disabled = value - this.buttons.forEach(it => it.disabled = value) + this.buttons.forEach(it => (it.disabled = value)) } - + /** * Searches all buttons of the button group and returns the maximum width of one button. - * + * * @private * @return {number} The maximum with of a button of the button group. */ getMaxButtonWidth() { - let widths = this.buttons.map(it => it.width) return Math.max(...widths) } - + /** * Shows the button group (sets his alpha value to 1). - * + * * @return {ButtonGroup} A reference to the button group for chaining. */ show() { - this.alpha = 1 return this @@ -334,11 +359,10 @@ export default class ButtonGroup extends PIXI.Graphics { /** * Hides the button group (sets his alpha value to 0). - * + * * @return {ButtonGroup} A reference to the button group for chaining. */ hide() { - this.alpha = 0 return this diff --git a/lib/pixi/flipeffect.js b/lib/pixi/flipeffect.js index 118d84b..78b659e 100644 --- a/lib/pixi/flipeffect.js +++ b/lib/pixi/flipeffect.js @@ -1,13 +1,12 @@ -import {getId, Angle} from '../utils.js' -import {DOMScatter} from '../scatter.js' -import {CardLoader, DOMFlip, DOMFlippable} from '../flippable.js' -import {Capabilities} from '../capabilities.js' -import {DeepZoomImage} from './deepzoom/image.js' +import { getId, Angle } from '../utils.js' +import { DOMScatter } from '../scatter.js' +import { CardLoader, DOMFlip, DOMFlippable } from '../flippable.js' +import { Capabilities } from '../capabilities.js' +import { DeepZoomImage } from './deepzoom/image.js' let globalScatterLoaderCanvas = null export class ScatterLoader extends CardLoader { - get scatter() { return this.src } @@ -35,8 +34,7 @@ export class ScatterLoader extends CardLoader { if (isSprite) { w = this.scatter.displayObject.texture.width h = this.scatter.displayObject.texture.height - } - else if (isDeepZoom) { + } else if (isDeepZoom) { let [ww, hh] = this.scatter.displayObject.baseSize w = ww h = hh @@ -48,8 +46,9 @@ export class ScatterLoader extends CardLoader { canvas.width = w canvas.height = h let renderer = new PIXI.WebGLRenderer(w, h, { - view: canvas, - resolution: resolution}) + view: canvas, + resolution: resolution + }) let displayObject = this.scatter.displayObject let x = displayObject.x @@ -64,8 +63,7 @@ export class ScatterLoader extends CardLoader { if (Capabilities.isSafari) { displayObject.y = h displayObject.scale.set(1, -1) // sx, -sy) - } - else { + } else { displayObject.y = 0 displayObject.scale.set(1, 1) } @@ -87,12 +85,11 @@ export class ScatterLoader extends CardLoader { return new Promise((resolve, reject) => { let isImage = domNode instanceof HTMLImageElement let isSprite = this.scatter.displayObject instanceof PIXI.Sprite - let image = (isImage) ? domNode : document.createElement("img") + let image = isImage ? domNode : document.createElement('img') let [x, y, w, h, cloneURL] = this.cloneScatterImage() let [ww, hh] = this.unscaledSize() - image.onload = (e) => { - if (!isImage) - domNode.appendChild(image) + image.onload = e => { + if (!isImage) domNode.appendChild(image) this.x = x this.y = y this.wantedWidth = ww @@ -101,40 +98,42 @@ export class ScatterLoader extends CardLoader { this.rotation = this.scatter.rotation resolve(this) } - image.onerror = (e) => { + image.onerror = e => { reject(this) } image.src = cloneURL - }) + }) } - } export default class FlipEffect { - constructor(scatter, domScatterContainer, flipTemplate, backLoader) { this.flipped = false this.scatter = scatter this.backLoader = backLoader this.scatterLoader = new ScatterLoader(scatter) - this.domFlip = new DOMFlip(domScatterContainer, flipTemplate, - this.scatterLoader, - backLoader, { - onBack: this.backCardClosed.bind(this) - }) + this.domFlip = new DOMFlip( + domScatterContainer, + flipTemplate, + this.scatterLoader, + backLoader, + { + onBack: this.backCardClosed.bind(this) + } + ) this.setupInfoButton() } startFlip() { let center = this.flipCenter() let loader = this.backLoader - this.domFlip.load().then((domFlip) => { + this.domFlip.load().then(domFlip => { this.scatter.displayObject.visible = false domFlip.centerAt(center) domFlip.zoom(this.scatter.scale) let target = this.constraintFlipCenter(center, loader) - console.log("FlipEffect.startFlip", target, loader) - domFlip.start({targetCenter: target}) + console.log('FlipEffect.startFlip', target, loader) + domFlip.start({ targetCenter: target }) }) } @@ -144,13 +143,15 @@ export default class FlipEffect { flipCenter() { let isSprite = this.scatter.displayObject instanceof PIXI.Sprite - let resolution = (isSprite) ? app.renderer.resolution : 1 + let resolution = isSprite ? app.renderer.resolution : 1 let center = this.scatter.center let canvas = app.renderer.view let domNode = this.domFlip.domScatterContainer.element - let page = window.convertPointFromNodeToPage(canvas, - center.x*resolution, - center.y*resolution) + let page = window.convertPointFromNodeToPage( + canvas, + center.x * resolution, + center.y * resolution + ) let local = window.convertPointFromPageToNode(domNode, page.x, page.y) return local } @@ -158,18 +159,14 @@ export default class FlipEffect { constraintFlipCenter(center, loader) { let w = loader.wantedWidth let h = loader.wantedHeight - console.log("constraintFlipCenter", w, h) + console.log('constraintFlipCenter', w, h) let canvas = app.renderer.view let x = center.x let y = center.y - if (x < w/2) - x = w/2 - if (y < h/2) - y = h/2 - if (x > canvas.width) - x = canvas.width - w/2 - if (y > canvas.height) - y = canvas.height - h/2 + if (x < w / 2) x = w / 2 + if (y < h / 2) y = h / 2 + if (x > canvas.width) x = canvas.width - w / 2 + if (y > canvas.height) y = canvas.height - h / 2 return { x, y } } @@ -177,22 +174,26 @@ export default class FlipEffect { let iscale = 1.0 / this.scatter.scale this.infoBtn = new PIXI.Graphics() this.infoBtn.beginFill(0x333333) - this.infoBtn.lineStyle(4, 0xFFFFFF) + this.infoBtn.lineStyle(4, 0xffffff) this.infoBtn.drawCircle(0, 0, 22) this.infoBtn.endFill() - this.infoBtn.beginFill(0xFFFFFF) + this.infoBtn.beginFill(0xffffff) this.infoBtn.lineStyle(0) this.infoBtn.drawCircle(0, -8, 4) this.infoBtn.endFill() - this.infoBtn.lineStyle(6, 0xFFFFFF) + this.infoBtn.lineStyle(6, 0xffffff) this.infoBtn.moveTo(0, -2) this.infoBtn.lineTo(0, 14) this.infoBtn.endFill() - this.infoBtn.on('click', (e) => { this.infoSelected() }) - this.infoBtn.on('tap', (e) => { this.infoSelected() }) + this.infoBtn.on('click', e => { + this.infoSelected() + }) + this.infoBtn.on('tap', e => { + this.infoSelected() + }) this.infoBtn.interactive = true this.infoBtn.width = 44 @@ -207,8 +208,7 @@ export default class FlipEffect { this.infoBtn.scale.x = iscale this.infoBtn.scale.y = iscale displayObject.foreground.addChild(this.infoBtn) - } - else { + } else { displayObject.addChild(this.infoBtn) } @@ -231,15 +231,15 @@ export default class FlipEffect { canvas.height = 44 * 4 svgImage.onload = e => { let displayObject = this.scatter.displayObject - canvas.getContext ('2d').drawImage(svgImage, 0, 0, - canvas.width, canvas.height) + canvas + .getContext('2d') + .drawImage(svgImage, 0, 0, canvas.width, canvas.height) let texure = new PIXI.Texture(new PIXI.BaseTexture(canvas)) this.infoBtn = new PIXI.Sprite(texure) this.infoBtn.anchor.set(0.5, 0.5) if (displayObject.foreground) { displayObject.foreground.addChild(this.infoBtn) - } - else { + } else { displayObject.addChild(this.infoBtn) } this.infoBtn.scale.set(0.5, 0.5) @@ -248,8 +248,12 @@ export default class FlipEffect { this.infoBtn.position = new PIXI.Point(w, h) this.infoBtn.interactive = true this.infoBtn.updateTransform() - this.infoBtn.on('click', (e) => { this.infoSelected() }) - this.infoBtn.on('tap', (e) => { this.infoSelected() }) + this.infoBtn.on('click', e => { + this.infoSelected() + }) + this.infoBtn.on('tap', e => { + this.infoSelected() + }) } svgImage.src = url } @@ -275,13 +279,11 @@ export default class FlipEffect { let ortho = 90 let rest = alpha % ortho let delta = 0.0 - if (rest > (ortho / 2.0)) { + if (rest > ortho / 2.0) { delta = ortho - rest - } - else { + } else { delta = -rest } return delta } } - diff --git a/lib/pixi/flippable.js b/lib/pixi/flippable.js index 3b07f24..fc450f0 100644 --- a/lib/pixi/flippable.js +++ b/lib/pixi/flippable.js @@ -29,10 +29,10 @@ * const front = PIXI.Sprite.fromImage('./assets/front.jpg') * const back = PIXI.Sprite.fromImage('./assets/back.jpg') * app.scene.addChild(front) - * + * * // Create the flippable * const flippable = new Flippable(front, back, app.renderer) - * + * * front.interactive = true * front.on('click', event => flippable.toggle()) * @@ -42,7 +42,6 @@ * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/flippable.html|DocTest} */ export default class Flippable extends PIXI.projection.Camera3d { - /** * Creates an instance of a Flippable. * @@ -68,30 +67,38 @@ export default class Flippable extends PIXI.projection.Camera3d { * @param {function} [opts.onComplete=null] - A callback executed when the flip animation is finished. */ constructor(front, back, renderer, opts = {}) { - super() - this.opts = Object.assign({}, { - front, - back, - renderer, - duration: 1, - ease: Power2.easeOut, - shadow: false, - eulerX: 0, - eulerY: 0, - eulerEase: Power1.easeOut, - useBackTransforms: false, - transformEase: Power2.easeOut, - focus: 800, - near: 10, - far: 10000, - orthographic: false - }, opts) + this.opts = Object.assign( + {}, + { + front, + back, + renderer, + duration: 1, + ease: Power2.easeOut, + shadow: false, + eulerX: 0, + eulerY: 0, + eulerEase: Power1.easeOut, + useBackTransforms: false, + transformEase: Power2.easeOut, + focus: 800, + near: 10, + far: 10000, + orthographic: false + }, + opts + ) // planes //-------------------- - this.setPlanes(this.opts.focus, this.opts.near, this.opts.far, this.opts.orthographic) + this.setPlanes( + this.opts.focus, + this.opts.near, + this.opts.far, + this.opts.orthographic + ) // flipped //-------------------- @@ -113,8 +120,7 @@ export default class Flippable extends PIXI.projection.Camera3d { * @return {Flippable} A reference to the flippable for chaining. */ setup() { - - const scale = .5 + const scale = 0.5 // filters //-------------------- @@ -131,16 +137,18 @@ export default class Flippable extends PIXI.projection.Camera3d { // shadow //-------------------- - const shadow = new PIXI.projection.Sprite3d(PIXI.Texture.fromImage('../../assets/images/shadow.png')) + const shadow = new PIXI.projection.Sprite3d( + PIXI.Texture.fromImage('../../assets/images/shadow.png') + ) shadow.renderable = false shadow.anchor.set(0.5) - shadow.scale3d.set(.98) + shadow.scale3d.set(0.98) shadow.alpha = 0.7 shadow.filters = [blurFilter] shadow.visible = this.opts.shadow outer.addChild(shadow) this.objects.shadow = shadow - + // inner //-------------------- const inner = new PIXI.projection.Container3d() @@ -153,7 +161,7 @@ export default class Flippable extends PIXI.projection.Camera3d { const front = new PIXI.projection.Sprite3d(PIXI.Texture.EMPTY) front.scale.set(-1 / scale, 1 / scale) front.renderable = true - front.anchor.set(.5) + front.anchor.set(0.5) inner.addChild(front) this.objects.front = front @@ -162,7 +170,7 @@ export default class Flippable extends PIXI.projection.Camera3d { const back = new PIXI.projection.Sprite3d(PIXI.Texture.EMPTY) back.scale.set(1 / scale, 1 / scale) back.renderable = false - back.anchor.set(.5) + back.anchor.set(0.5) inner.addChild(back) this.objects.back = back @@ -178,7 +186,6 @@ export default class Flippable extends PIXI.projection.Camera3d { return this._flipped } set flipped(toBack) { - this._flipped = toBack // references @@ -199,7 +206,7 @@ export default class Flippable extends PIXI.projection.Camera3d { //-------------------- front.texture = this.generateTexture(this.opts.front) back.texture = this.generateTexture(this.opts.back) - + // switch objects and set params for virtual objects //-------------------- const fromCenter = this.anchorToCenter(fromObject) @@ -224,11 +231,21 @@ export default class Flippable extends PIXI.projection.Camera3d { y: this.opts.useBackTransforms ? toCenter.y : fromCenter.y, anchorX: this.opts.useBackTransforms ? toObject.x : fromObject.x, anchorY: this.opts.useBackTransforms ? toObject.y : fromObject.y, - width: this.opts.useBackTransforms ? toObject.width * 2 : fromObject.width * 2, - height: this.opts.useBackTransforms ? toObject.height * 2 : fromObject.height * 2, - rotation: this.opts.useBackTransforms ? toObject.rotation : fromObject.rotation, - skewX: this.opts.useBackTransforms ? toObject.skew.x : fromObject.skew.x, - skewY: this.opts.useBackTransforms ? toObject.skew.y : fromObject.skew.y + width: this.opts.useBackTransforms + ? toObject.width * 2 + : fromObject.width * 2, + height: this.opts.useBackTransforms + ? toObject.height * 2 + : fromObject.height * 2, + rotation: this.opts.useBackTransforms + ? toObject.rotation + : fromObject.rotation, + skewX: this.opts.useBackTransforms + ? toObject.skew.x + : fromObject.skew.x, + skewY: this.opts.useBackTransforms + ? toObject.skew.y + : fromObject.skew.y } // set toObject end values @@ -305,20 +322,24 @@ export default class Flippable extends PIXI.projection.Camera3d { // camera //-------------------- new TimelineMax() - .to(this.euler, half, {x: this.opts.eulerX, y: this.opts.eulerY, ease}) - .to(this.euler, half, {x: 0, y: 0, ease}) + .to(this.euler, half, { + x: this.opts.eulerX, + y: this.opts.eulerY, + ease + }) + .to(this.euler, half, { x: 0, y: 0, ease }) // shadow //-------------------- new TimelineMax() - .to(shadow, half, {alpha: .3, ease}) - .to(shadow, half, {alpha: .7, ease}) - + .to(shadow, half, { alpha: 0.3, ease }) + .to(shadow, half, { alpha: 0.7, ease }) + // blurfilter //-------------------- new TimelineMax() - .to(blurFilter, half, {blur: 6, ease}) - .to(blurFilter, half, {blur: .2, ease}) + .to(blurFilter, half, { blur: 6, ease }) + .to(blurFilter, half, { blur: 0.2, ease }) } /** @@ -327,18 +348,18 @@ export default class Flippable extends PIXI.projection.Camera3d { * @return {Flippable} A reference to the flippable for chaining. */ layout() { - const front = this.objects.front const back = this.objects.back const shadow = this.objects.shadow const inner = this.objects.inner - - inner.position3d.z = -Math.sin(inner.euler.y) * front.texture.baseTexture.width * 2 + + inner.position3d.z = + -Math.sin(inner.euler.y) * front.texture.baseTexture.width * 2 //this.objects.shadow.euler = this.objects.inner.euler shadow.euler.x = -inner.euler.x shadow.euler.y = -inner.euler.y - + if (this.frontSideInFront) { front.renderable = true back.renderable = false @@ -398,13 +419,25 @@ export default class Flippable extends PIXI.projection.Camera3d { * @return {PIXI.Texture} The generated PIXI.Texture. */ generateTexture(displayObject) { - // renderTexture //-------------------- - const renderTexture = PIXI.RenderTexture.create(displayObject.width, displayObject.height) + const renderTexture = PIXI.RenderTexture.create( + displayObject.width, + displayObject.height + ) // save position - const transform = [displayObject.x, displayObject.y, displayObject.scale.x, displayObject.scale.y, displayObject.rotation, displayObject.skew.x, displayObject.skew.y, displayObject.pivot.x, displayObject.pivot.y] + const transform = [ + displayObject.x, + displayObject.y, + displayObject.scale.x, + displayObject.scale.y, + displayObject.rotation, + displayObject.skew.x, + displayObject.skew.y, + displayObject.pivot.x, + displayObject.pivot.y + ] displayObject.position.set(0, 0) displayObject.skew.set(0, 0) @@ -413,7 +446,7 @@ export default class Flippable extends PIXI.projection.Camera3d { // render //-------------------- this.opts.renderer.render(displayObject, renderTexture) - + // restore position displayObject.setTransform(...transform) diff --git a/lib/pixi/labeledgraphics.js b/lib/pixi/labeledgraphics.js index 38dd5b4..8657b83 100644 --- a/lib/pixi/labeledgraphics.js +++ b/lib/pixi/labeledgraphics.js @@ -1,10 +1,7 @@ - - /** * Defines usefull default text styles. */ export class FontInfo { - static get small() { return app.theme.textStyleSmall } @@ -20,15 +17,13 @@ export class FontInfo { /** * Static methods to support hyphenation of lines. - * + * * @class Hypenate */ export class Hypenate { - static splitPart(part) { let parts = part.split('-') - if (parts.length == 1) - return [part] + if (parts.length == 1) return [part] let result = [] let last = parts.pop() for (let p of parts) { @@ -39,7 +34,7 @@ export class Hypenate { } static splitWord(word) { - if (typeof (language) == 'undefined') { + if (typeof language == 'undefined') { if (word.indexOf('-') > -1) { return word.split('-') } @@ -56,13 +51,13 @@ export class Hypenate { } static abbreviateLine(label, style, width) { - const pixiStyle = new PIXI.TextStyle(style) + const pixiStyle = new PIXI.TextStyle(style) let metrics = PIXI.TextMetrics.measureText(label, pixiStyle) - while(metrics.width > width && label.length > 3) { - label = label.slice(0, label.length-1) + while (metrics.width > width && label.length > 3) { + label = label.slice(0, label.length - 1) metrics = PIXI.TextMetrics.measureText(label, pixiStyle) } - label = label.slice(0, label.length-1) + label = label.slice(0, label.length - 1) return label + '…' } @@ -78,17 +73,21 @@ export class Hypenate { if (parts.length == 1) { newWord += '\n' + word + ' ' x = wordMetrics.width + space.width - } - else { + } else { let first = true let lastPart = '' for (let part of parts) { - let partMetrics = PIXI.TextMetrics.measureText(part, pixiStyle) + let partMetrics = PIXI.TextMetrics.measureText( + part, + pixiStyle + ) if (x + partMetrics.width + space.width > width) { - newWord += ((first || lastPart.endsWith('-')) ? '\n' : '-\n') + part + newWord += + (first || lastPart.endsWith('-') + ? '\n' + : '-\n') + part x = partMetrics.width - } - else { + } else { newWord += part x += partMetrics.width } @@ -98,8 +97,7 @@ export class Hypenate { x += space.width } result += newWord + ' ' - } - else { + } else { result += word + ' ' x += wordMetrics.width + space.width } @@ -108,7 +106,7 @@ export class Hypenate { } /** - * Main method and entry point for text hyphenation + * Main method and entry point for text hyphenation * * @static * @param {*} text @@ -131,17 +129,21 @@ export class Hypenate { } class TextLabel extends PIXI.Text { - /** *Creates an instance of TextLabel. * @param {string} text - The string that you would like the text to display - * @param {object|PIXI.TextStyle} [style] - The style parameters - * @param {canvas} + * @param {object|PIXI.TextStyle} [style] - The style parameters + * @param {canvas} * @memberof TextLabel */ - constructor(text, style=null, canvas=null, { minZoom = 0.1, maxZoom = 10} = {}) { - super(text, style, canvas ) - this.normFontSize = this.style.fontSize + constructor( + text, + style = null, + canvas = null, + { minZoom = 0.1, maxZoom = 10 } = {} + ) { + super(text, style, canvas) + this.normFontSize = this.style.fontSize this.minZoom = minZoom this.maxZoom = maxZoom } @@ -180,10 +182,9 @@ class TextLabel extends PIXI.Text { * @extends {PIXI.Graphics} */ export class LabeledGraphics extends PIXI.Graphics { - /** * Creates an instance of LabeledGraphics and defines a local label cache. - * + * * @memberof LabeledGraphics */ constructor() { @@ -195,14 +196,13 @@ export class LabeledGraphics extends PIXI.Graphics { return new TextLabel(label, fontInfo) } - /** * Main additional method. Ensures that a text object is created that is cached * under the given key. * * @param {*} key - The cache key * @param {*} label - The label to show - * @param {*} [attrs={}] - Defines attributes of the text object. + * @param {*} [attrs={}] - Defines attributes of the text object. * align: 'right', 'left', or 'center' * justify: 'top', 'bottom', or 'center' * maxLines: {integer} truncates the text and adds ellipsis @@ -213,11 +213,9 @@ export class LabeledGraphics extends PIXI.Graphics { * @memberof LabeledGraphics */ ensureLabel(key, label, attrs = {}, fontInfo = FontInfo.normal) { - if (attrs.maxWidth && attrs.maxLines == 1) { label = Hypenate.abbreviateLine(label, fontInfo, attrs.maxWidth) - } - else { + } else { if (attrs.maxWidth) { label = Hypenate.splitLines(label, fontInfo, attrs.maxWidth) } @@ -231,7 +229,7 @@ export class LabeledGraphics extends PIXI.Graphics { label = this.truncateLabel(label, fontInfo, maxLines) } } - + if (!this.labels.has(key)) { let text = this._createText(label, fontInfo) this.labels.set(key, text) @@ -241,8 +239,7 @@ export class LabeledGraphics extends PIXI.Graphics { for (let k in attrs) { text[k] = attrs[k] } - if (label != text.text) - text.text = label + if (label != text.text) text.text = label // We do not follow the flexbox jargon and use align for x and justify for y axis // This deviation is needed to ensure backward compatability switch (attrs.justify || null) { @@ -293,17 +290,30 @@ export class LabeledGraphics extends PIXI.Graphics { const truncatedLines = lines.slice(0, maxLines) const lastLine = truncatedLines[truncatedLines.length - 1] const words = lastLine.split(' ') - const wordMetrics = PIXI.TextMetrics.measureText(`\u00A0\n...\n${words.join('\n')}`, pixiStyle) - const [spaceLength, dotsLength, ...wordLengths] = wordMetrics.lineWidths - const { text: newLastLine } = wordLengths.reduce((data, wordLength, i) => { - if (data.length + wordLength + spaceLength >= wordWrapWidth) { - return { ...data, length: wordWrapWidth } - } - return { - text: `${data.text}${i > 0 ? ' ' : ''}${words[i]}`, - length: data.length + wordLength + spaceLength, - }; - }, { text: '', length: dotsLength }) + const wordMetrics = PIXI.TextMetrics.measureText( + `\u00A0\n...\n${words.join('\n')}`, + pixiStyle + ) + const [ + spaceLength, + dotsLength, + ...wordLengths + ] = wordMetrics.lineWidths + const { text: newLastLine } = wordLengths.reduce( + (data, wordLength, i) => { + if ( + data.length + wordLength + spaceLength >= + wordWrapWidth + ) { + return { ...data, length: wordWrapWidth } + } + return { + text: `${data.text}${i > 0 ? ' ' : ''}${words[i]}`, + length: data.length + wordLength + spaceLength + } + }, + { text: '', length: dotsLength } + ) truncatedLines[truncatedLines.length - 1] = `${newLastLine}...` newText = truncatedLines.join('\n') } @@ -321,7 +331,7 @@ export class LabeledGraphics extends PIXI.Graphics { return this.labels.get(key) } - /** + /** * Hides the label with the given key. * @param {*} key * @memberof LabeledGraphics @@ -333,7 +343,7 @@ export class LabeledGraphics extends PIXI.Graphics { } } - /** + /** * Removes the label with the given key. * @param {*} key * @memberof LabeledGraphics @@ -344,7 +354,6 @@ export class LabeledGraphics extends PIXI.Graphics { label.destroy() } - /** * Ensures that labels are hidden on clear. * @@ -367,7 +376,6 @@ export class LabeledGraphics extends PIXI.Graphics { } } - const labelCache = new Map() function getTexture(label, fontInfo = FontInfo.normal) { @@ -385,7 +393,6 @@ function getTexture(label, fontInfo = FontInfo.normal) { } class SpriteLabel extends PIXI.Sprite { - constructor(label, fontInfo) { let texture = getTexture(label, fontInfo) super(texture) @@ -405,10 +412,8 @@ class SpriteLabel extends PIXI.Sprite { } export class BitmapLabeledGraphics extends LabeledGraphics { - _createText(label, fontInfo) { let texture = getTexture(label, fontInfo) return new SpriteLabel(texture) } - } diff --git a/lib/pixi/list.js b/lib/pixi/list.js index b2beb6b..a190299 100644 --- a/lib/pixi/list.js +++ b/lib/pixi/list.js @@ -9,10 +9,10 @@ import Events from '../events.js' * @example * const elephant1 = PIXI.Sprite.fromImage('./assets/elephant-1.jpg') * const elephant2 = PIXI.Sprite.fromImage('./assets/elephant-2.jpg') - * + * * // Create the list * const list = new List([elephant1, elephant2]) - * + * * app.scene.addChild(list) * * @class @@ -21,7 +21,6 @@ import Events from '../events.js' * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/list.html|DocTest} */ export default class List extends PIXI.Container { - /** * Creates an instance of a Flippable. * @@ -43,19 +42,22 @@ export default class List extends PIXI.Container { * scroll your list. */ constructor(items = [], opts = {}) { - super() - this.opts = Object.assign({}, { - padding: 10, - margin: 10, - orientation: 'vertical', - align: 'left', - verticalAlign: 'middle', - width: null, - height: null, - app: null - }, opts) + this.opts = Object.assign( + {}, + { + padding: 10, + margin: 10, + orientation: 'vertical', + align: 'left', + verticalAlign: 'middle', + width: null, + height: null, + app: null + }, + opts + ) this.__items = items this.__dragging = false @@ -72,7 +74,6 @@ export default class List extends PIXI.Container { * @return {List} A reference to the list for chaining. */ setup() { - // inner container //-------------------- const container = new PIXI.Container() @@ -87,7 +88,7 @@ export default class List extends PIXI.Container { // add items //-------------------- - for(let item of this.__items) { + for (let item of this.__items) { container.addChild(item) } @@ -107,7 +108,9 @@ export default class List extends PIXI.Container { if (this.opts.app) { const app = this.opts.app app.view.addEventListener('mousewheel', event => { - const bounds = this.mask ? this.mask.getBounds() : this.getBounds() + const bounds = this.mask + ? this.mask.getBounds() + : this.getBounds() const x = event.clientX - app.view.getBoundingClientRect().left const y = event.clientY - app.view.getBoundingClientRect().top if (bounds.contains(x, y)) { @@ -131,7 +134,7 @@ export default class List extends PIXI.Container { setItems(items) { this.container.removeChildren() this.__items = items - for(let item of this.__items) { + for (let item of this.__items) { this.container.addChild(item) } this.layout() @@ -143,14 +146,12 @@ export default class List extends PIXI.Container { * @return {List} A reference to the list for chaining. */ layout() { - const margin = this.opts.margin let x = margin let y = margin for (let item of this.__items) { - item.x = x item.y = y @@ -166,13 +167,17 @@ export default class List extends PIXI.Container { if (this.opts.orientation === 'vertical') { switch (this.opts.align) { case 'center': - this.__items.forEach(it => it.x = margin + this.width / 2 - it.width / 2) + this.__items.forEach( + it => (it.x = margin + this.width / 2 - it.width / 2) + ) break case 'right': - this.__items.forEach(it => it.x = margin + this.width - it.width) + this.__items.forEach( + it => (it.x = margin + this.width - it.width) + ) break default: - this.__items.forEach(it => it.x = margin) + this.__items.forEach(it => (it.x = margin)) break } @@ -192,13 +197,17 @@ export default class List extends PIXI.Container { if (this.opts.orientation === 'horizontal') { switch (this.opts.verticalAlign) { case 'top': - this.__items.forEach(it => it.y = margin) + this.__items.forEach(it => (it.y = margin)) break case 'bottom': - this.__items.forEach(it => it.y = margin + this.height - it.height) + this.__items.forEach( + it => (it.y = margin + this.height - it.height) + ) break default: - this.__items.forEach(it => it.y = margin + this.height / 2 - it.height / 2) + this.__items.forEach( + it => (it.y = margin + this.height / 2 - it.height / 2) + ) break } @@ -217,13 +226,12 @@ export default class List extends PIXI.Container { } /** - * + * */ get innerWidth() { - let size = 0 - this.__items.forEach(it => size += it.width) + this.__items.forEach(it => (size += it.width)) size += this.opts.padding * (this.__items.length - 1) size += 2 * this.opts.margin @@ -231,13 +239,12 @@ export default class List extends PIXI.Container { } /** - * + * */ get innerHeight() { - let size = 0 - this.__items.forEach(it => size += it.height) + this.__items.forEach(it => (size += it.height)) size += this.opts.padding * (this.__items.length - 1) size += 2 * this.opts.margin @@ -246,11 +253,10 @@ export default class List extends PIXI.Container { /** * Resizes the list. - * + * * @param {number} widthOrHeight - The new width (if orientation is horizontal) or height (if orientation is vertical) of the list. */ resize(widthOrHeight) { - if (this.opts.orientation === 'horizontal') { this.opts.width = widthOrHeight } else { @@ -261,12 +267,11 @@ export default class List extends PIXI.Container { } /** - * + * * @private - * @param {*} event + * @param {*} event */ onStart(event) { - this.__dragging = true this.capture(event) @@ -276,21 +281,19 @@ export default class List extends PIXI.Container { y: this.container.position.y - event.data.global.y } - TweenLite.killTweensOf(this.container.position, {x: true, y: true}) - if (typeof ThrowPropsPlugin != "undefined") { + TweenLite.killTweensOf(this.container.position, { x: true, y: true }) + if (typeof ThrowPropsPlugin != 'undefined') { ThrowPropsPlugin.track(this.container.position, 'x,y') } } /** - * + * * @private - * @param {*} event + * @param {*} event */ onMove(event) { - if (this.__dragging) { - this.capture(event) if (this.opts.orientation === 'horizontal') { @@ -302,19 +305,18 @@ export default class List extends PIXI.Container { } /** - * + * * @private - * @param {*} event + * @param {*} event */ onEnd(event) { - if (this.__dragging) { this.__dragging = false this.capture(event) const throwProps = {} - + if (this.opts.orientation === 'horizontal') { let min = this.opts.width - this.innerWidth min = min > 0 ? 0 : min @@ -333,37 +335,48 @@ export default class List extends PIXI.Container { } } - if (typeof ThrowPropsPlugin != "undefined") { - ThrowPropsPlugin.to(this.container.position, { - throwProps, - ease: Strong.easeOut, - onComplete: () => ThrowPropsPlugin.untrack(this.container.position) - }, .8, .4) + if (typeof ThrowPropsPlugin != 'undefined') { + ThrowPropsPlugin.to( + this.container.position, + { + throwProps, + ease: Strong.easeOut, + onComplete: () => + ThrowPropsPlugin.untrack(this.container.position) + }, + 0.8, + 0.4 + ) } } } /** - * + * * @private - * @param {*} event + * @param {*} event */ onScroll(event) { - this.capture(event) if (this.opts.orientation === 'horizontal') { this.container.position.x -= event.deltaX if (this.container.position.x > 0) { this.container.position.x = 0 - } else if (this.container.position.x + this.innerWidth < this.opts.width) { + } else if ( + this.container.position.x + this.innerWidth < + this.opts.width + ) { this.container.position.x = this.opts.width - this.innerWidth } } else { this.container.position.y -= event.deltaY if (this.container.position.y > 0) { this.container.position.y = 0 - } else if (this.container.position.y + this.innerHeight < this.opts.height) { + } else if ( + this.container.position.y + this.innerHeight < + this.opts.height + ) { this.container.position.y = this.opts.height - this.innerHeight } } @@ -375,7 +388,10 @@ export default class List extends PIXI.Container { * @param {event|PIXI.InteractionEvent} event - The PIXI event to capture. */ capture(event) { - const originalEvent = event.data && event.data.originalEvent ? event.data.originalEvent : event + const originalEvent = + event.data && event.data.originalEvent + ? event.data.originalEvent + : event Events.capturedBy(originalEvent, this) } } diff --git a/lib/pixi/message.js b/lib/pixi/message.js index 5941821..bef9305 100644 --- a/lib/pixi/message.js +++ b/lib/pixi/message.js @@ -1,9 +1,9 @@ import Theme from './theme.js' -import {InteractivePopup} from './popup.js' +import { InteractivePopup } from './popup.js' /** * Class that represents a Message. A message pops up and disappears after a specific amount of time. - * + * * @example * // Create the PixiJS App * const app = new PIXIApp({ @@ -11,7 +11,7 @@ import {InteractivePopup} from './popup.js' * width: 900, * height: 250 * }).setup().run() - * + * * // Create a button * let button = new Button({ * label: 'Click me', @@ -24,7 +24,7 @@ import {InteractivePopup} from './popup.js' * app.scene.addChild(message) * } * }) - * + * * // Add the button to the scene * app.scene.addChild(button) * @@ -33,10 +33,9 @@ import {InteractivePopup} from './popup.js' * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/message.html|DocTest} */ export default class Message extends InteractivePopup { - /** * Creates an instance of a Message. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the message. * @param {PIXIApp} [opts.app=window.app] - The PIXIApp where this message belongs to. @@ -53,32 +52,34 @@ export default class Message extends InteractivePopup { * @param {number} [opts.closeDuration=Theme.fast] - The duration in seconds of the closing of the message box. */ constructor(opts = {}) { - const theme = Theme.fromString(opts.theme) - opts = Object.assign({}, { - app: window.app, - closeButton: false, - minWidth: 280, - minHeight: 100, - margin: theme.margin, - align: 'right', // left, center, right - verticalAlign: 'top', // top, middle, bottom - duration: 5, - autoClose: true, - closeDuration: theme.fast - }, opts) + opts = Object.assign( + {}, + { + app: window.app, + closeButton: false, + minWidth: 280, + minHeight: 100, + margin: theme.margin, + align: 'right', // left, center, right + verticalAlign: 'top', // top, middle, bottom + duration: 5, + autoClose: true, + closeDuration: theme.fast + }, + opts + ) super(opts) } /** * Relayouts the position of the message box. - * + * * @return {Message} Returns the message box for chaining. */ layout() { - super.layout() // horizontal @@ -87,10 +88,11 @@ export default class Message extends InteractivePopup { this.x = this.opts.margin break case 'center': - this.x = (this.opts.app.size.width / 2) - (this.width / 2) + this.x = this.opts.app.size.width / 2 - this.width / 2 break case 'right': - this.x = this.opts.app.size.width - this.opts.margin - this.width + this.x = + this.opts.app.size.width - this.opts.margin - this.width break } @@ -100,21 +102,21 @@ export default class Message extends InteractivePopup { this.y = this.opts.margin break case 'middle': - this.y = (this.opts.app.size.height / 2) - (this.height / 2) + this.y = this.opts.app.size.height / 2 - this.height / 2 break case 'bottom': - this.y = this.opts.app.size.height - this.opts.margin - this.height + this.y = + this.opts.app.size.height - this.opts.margin - this.height break } } /** * Shows the message box. - * + * * @private */ show() { - super.show() if (this.opts.autoClose) { diff --git a/lib/pixi/modal.js b/lib/pixi/modal.js index 330aa9e..cb3a1e5 100644 --- a/lib/pixi/modal.js +++ b/lib/pixi/modal.js @@ -1,9 +1,9 @@ import Theme from './theme.js' -import {InteractivePopup} from './popup.js' +import { InteractivePopup } from './popup.js' /** * Class that represents a PixiJS Modal. - * + * * @example * // Create the button and the modal when clicked * const button = new Button({ @@ -28,10 +28,9 @@ import {InteractivePopup} from './popup.js' * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/modal.html|DocTest} */ export default class Modal extends PIXI.Container { - /** * Creates an instance of a Modal. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the modal. * @param {number} [opts.id=auto generated] - The id of the modal. @@ -43,20 +42,23 @@ export default class Modal extends PIXI.Container { * @param {boolean} [opts.visible=true] - Is the modal initially visible (property visible)? */ constructor(opts = {}) { - super() - + const theme = Theme.fromString(opts.theme) this.theme = theme - this.opts = Object.assign({}, { - id: PIXI.utils.uid(), - app: window.app, - backgroundFill: theme.background, - backgroundFillAlpha: .6, - closeOnBackground: true, - visible: true - }, opts) + this.opts = Object.assign( + {}, + { + id: PIXI.utils.uid(), + app: window.app, + backgroundFill: theme.background, + backgroundFillAlpha: 0.6, + closeOnBackground: true, + visible: true + }, + opts + ) this.id = this.opts.id @@ -74,15 +76,14 @@ export default class Modal extends PIXI.Container { //----------------- this.layout() } - + /** * Creates children and instantiates everything. - * + * * @private * @return {Modal} A reference to the modal for chaining. */ setup() { - // interaction //----------------- this.interactive = true @@ -120,21 +121,23 @@ export default class Modal extends PIXI.Container { return this } - + /** * Should be called to refresh the layout of the modal. Can be used after resizing. - * + * * @return {Modal} A reference to the modal for chaining. */ layout() { - const width = this.opts.app.size.width const height = this.opts.app.size.height // background //----------------- this.background.clear() - this.background.beginFill(this.opts.backgroundFill, this.opts.backgroundFillAlpha) + this.background.beginFill( + this.opts.backgroundFill, + this.opts.backgroundFillAlpha + ) this.background.drawRect(0, 0, width, height) this.background.endFill() @@ -144,33 +147,39 @@ export default class Modal extends PIXI.Container { return this } - + /** * Shows the modal (sets his alpha values to 1). - * + * * @return {Modal} A reference to the modal for chaining. */ show() { - TweenLite.to(this, this.theme.fast, {alpha: 1, onStart: () => this.visible = true}) + TweenLite.to(this, this.theme.fast, { + alpha: 1, + onStart: () => (this.visible = true) + }) return this } - + /** * Hides the modal (sets his alpha values to 0). - * + * * @return {Modal} A reference to the modal for chaining. */ hide() { - TweenLite.to(this, this.theme.fast, {alpha: 0, onComplete: () => this.visible = false}) + TweenLite.to(this, this.theme.fast, { + alpha: 0, + onComplete: () => (this.visible = false) + }) return this } - + /** * Sets or gets the header. The getter always returns a PIXI.Text object. The setter can receive * a string or a PIXI.Text object. - * + * * @member {string|PIXI.Text} */ get header() { @@ -182,11 +191,11 @@ export default class Modal extends PIXI.Container { this.popup.destroy() this.setup().layout() } - + /** * Sets or gets the content. The getter always returns an PIXI.DisplayObject. The setter can receive * a string or a PIXI.DisplayObject. - * + * * @member {string|PIXI.DisplayObject} */ get content() { diff --git a/lib/pixi/popover.js b/lib/pixi/popover.js index 77a1668..58f8f04 100644 --- a/lib/pixi/popover.js +++ b/lib/pixi/popover.js @@ -1,13 +1,30 @@ /** - * + * */ export default class Popover extends PIXI.Graphics { - - constructor({title = null, text = null, x = 0, y = 0, placement = 'top', width = 250, titleStyle = {}, textStyle = {fontSize: '1.6em'}} = {}) { + constructor({ + title = null, + text = null, + x = 0, + y = 0, + placement = 'top', + width = 250, + titleStyle = {}, + textStyle = { fontSize: '1.6em' } + } = {}) { super() - this.opts = {title, text, x, y, placement, width, titleStyle, textStyle} - + this.opts = { + title, + text, + x, + y, + placement, + width, + titleStyle, + textStyle + } + this.padding = 12 let style = { @@ -16,12 +33,16 @@ export default class Popover extends PIXI.Graphics { stroke: '#f6f6f6', strokeThickness: 3, wordWrap: true, - wordWrapWidth: width - (this.padding * 2) + wordWrapWidth: width - this.padding * 2 } - this.titleTextStyle = new PIXI.TextStyle(Object.assign({}, style, titleStyle)) - this.textTextStyle = new PIXI.TextStyle(Object.assign({}, style, textStyle)) - + this.titleTextStyle = new PIXI.TextStyle( + Object.assign({}, style, titleStyle) + ) + this.textTextStyle = new PIXI.TextStyle( + Object.assign({}, style, textStyle) + ) + if (title || text) { this.setup() this.draw() @@ -43,7 +64,10 @@ export default class Popover extends PIXI.Graphics { if (this.opts.text) { this.textText = new PIXI.Text(this.opts.text, this.textTextStyle) - this.textText.position.set(this.padding, this.titleY + this.titleHeight + this.padding) + this.textText.position.set( + this.padding, + this.titleY + this.titleHeight + this.padding + ) this.addChild(this.textText) } @@ -58,7 +82,7 @@ export default class Popover extends PIXI.Graphics { draw() { this.clear() this.beginFill(0xffffff, 1) - this.lineStyle(1, 0x282828, .5) + this.lineStyle(1, 0x282828, 0.5) // Draw rounded rectangle const height = this.height + this.padding @@ -72,7 +96,7 @@ export default class Popover extends PIXI.Graphics { this.lineStyle(0) this.beginFill(0xf7f7f7, 1) let x = 1 - let y = this.titleText.x + this.titleText.height + (this.padding / 2) + let y = this.titleText.x + this.titleText.height + this.padding / 2 this.moveTo(x, y) y = 9 this.lineTo(x, y) @@ -82,7 +106,7 @@ export default class Popover extends PIXI.Graphics { this.lineTo(x, y) this.quadraticCurveTo(x + 5, y, x + 5, y + 8) x += 5 - y += this.titleText.x + this.titleText.height + (this.padding / 2) + y += this.titleText.x + this.titleText.height + this.padding / 2 this.lineTo(x, y) if (this.opts.text) { x = 1 @@ -100,7 +124,6 @@ export default class Popover extends PIXI.Graphics { } drawAnchor(placement) { - let x = 0 let y = 0 @@ -109,7 +132,7 @@ export default class Popover extends PIXI.Graphics { if (this.opts.title) { this.beginFill(0xf7f7f7, 1) } - x = (this.width / 2) - 10 + x = this.width / 2 - 10 y = 1 this.moveTo(x, y) x += 10 @@ -121,7 +144,7 @@ export default class Popover extends PIXI.Graphics { break case 'right': x = 1 - y = (this.height / 2) - 10 + y = this.height / 2 - 10 if (this.titleY + this.titleHeight > y) { this.beginFill(0xf7f7f7, 1) } @@ -135,7 +158,7 @@ export default class Popover extends PIXI.Graphics { break case 'left': x = this.width - 2 - y = (this.height / 2) - 10 + y = this.height / 2 - 10 if (this.titleY + this.titleHeight > y) { this.beginFill(0xf7f7f7, 1) } @@ -148,7 +171,7 @@ export default class Popover extends PIXI.Graphics { this.lineTo(x, y) break default: - x = (this.width / 2) - 10 + x = this.width / 2 - 10 y = this.height - 2 this.moveTo(x, y) x += 10 @@ -162,22 +185,21 @@ export default class Popover extends PIXI.Graphics { } positioning() { - const x = this.opts.x const y = this.opts.y switch (this.opts.placement) { case 'bottom': - this.position.set(x - (this.width / 2), y + 10) + this.position.set(x - this.width / 2, y + 10) break case 'right': - this.position.set(x, y - (this.height / 2)) + this.position.set(x, y - this.height / 2) break case 'left': - this.position.set(x - this.width, y - (this.height / 2)) + this.position.set(x - this.width, y - this.height / 2) break default: - this.position.set(x - (this.width / 2), y - this.height) + this.position.set(x - this.width / 2, y - this.height) break } } diff --git a/lib/pixi/popup.js b/lib/pixi/popup.js index b51d3ba..497d4e5 100644 --- a/lib/pixi/popup.js +++ b/lib/pixi/popup.js @@ -12,7 +12,6 @@ import ButtonGroup from './buttongroup.js' * @extends AbstractPopup */ export class InteractivePopup extends AbstractPopup { - /** * Creates an instance of an InteractivePopup (only for internal use). * @@ -24,13 +23,16 @@ export class InteractivePopup extends AbstractPopup { * @param {object} [opts.buttonGroup] - A ButtonGroup object to be displayed on the lower right corner. */ constructor(opts = {}) { - - opts = Object.assign({}, { - closeOnPopup: false, - closeButton: true, - button: null, - buttonGroup: null - }, opts) + opts = Object.assign( + {}, + { + closeOnPopup: false, + closeButton: true, + button: null, + buttonGroup: null + }, + opts + ) super(opts) @@ -56,7 +58,6 @@ export class InteractivePopup extends AbstractPopup { * @return {AbstractPopup} A reference to the popup for chaining. */ setup() { - super.setup() // interaction @@ -72,7 +73,10 @@ export class InteractivePopup extends AbstractPopup { // closeButton //----------------- if (this.opts.closeButton) { - let closeButton = PIXI.Sprite.fromImage('../../assets/icons/close.png', true) + let closeButton = PIXI.Sprite.fromImage( + '../../assets/icons/close.png', + true + ) closeButton.width = this.headerStyle.fontSize closeButton.height = closeButton.width closeButton.tint = this.theme.color2 @@ -95,7 +99,11 @@ export class InteractivePopup extends AbstractPopup { // maxWidth is set and a closeButton should be displayed //----------------- if (this.opts.maxWidth) { - const wordWrapWidth = this.opts.maxWidth - (2 * this.opts.padding) - this.smallPadding - this._closeButton.width + const wordWrapWidth = + this.opts.maxWidth - + 2 * this.opts.padding - + this.smallPadding - + this._closeButton.width if (this._header) { this.headerStyle.wordWrapWidth = wordWrapWidth } else if (this._content) { @@ -108,9 +116,19 @@ export class InteractivePopup extends AbstractPopup { //----------------- if (this.opts.button || this.opts.buttonGroup) { if (this.opts.button) { - this._buttons = new Button(Object.assign({textStyle: this.theme.textStyleSmall}, this.opts.button)) + this._buttons = new Button( + Object.assign( + { textStyle: this.theme.textStyleSmall }, + this.opts.button + ) + ) } else { - this._buttons = new ButtonGroup(Object.assign({textStyle: this.theme.textStyleSmall}, this.opts.buttonGroup)) + this._buttons = new ButtonGroup( + Object.assign( + { textStyle: this.theme.textStyleSmall }, + this.opts.buttonGroup + ) + ) } this.addChild(this._buttons) @@ -126,21 +144,23 @@ export class InteractivePopup extends AbstractPopup { * @return {AbstractPopup} A reference to the popup for chaining. */ layout() { - super.layout() - + // closeButton //----------------- if (this.opts.closeButton) { - this._closeButton.x = this.wantedWidth - this.smallPadding - this._closeButton.width + this._closeButton.x = + this.wantedWidth - this.smallPadding - this._closeButton.width this._closeButton.y = this.smallPadding } // buttons //----------------- if (this._buttons) { - this._buttons.x = this.wantedWidth - this.opts.padding - this._buttons.width - this._buttons.y = this.wantedHeight - this.opts.padding - this._buttons.height + this._buttons.x = + this.wantedWidth - this.opts.padding - this._buttons.width + this._buttons.y = + this.wantedHeight - this.opts.padding - this._buttons.height } return this @@ -150,13 +170,12 @@ export class InteractivePopup extends AbstractPopup { * Calculates the size of the children of the AbstractPopup. * Cannot use getBounds() because it is not updated when children * are removed. - * + * * @private * @override * @returns {object} An JavaScript object width the keys width and height. */ getInnerSize() { - let size = super.getInnerSize() if (this._closeButton) { @@ -164,7 +183,10 @@ export class InteractivePopup extends AbstractPopup { } if (this._buttons) { - size.width = Math.max(size.width, this._buttons.x + this._buttons.width) + size.width = Math.max( + size.width, + this._buttons.x + this._buttons.width + ) size.height += this.innerPadding + this._buttons.height } @@ -190,7 +212,6 @@ export class InteractivePopup extends AbstractPopup { * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/popup.html|DocTest} */ export default class Popup extends InteractivePopup { - /** * Creates an instance of a Popup. * @@ -201,12 +222,15 @@ export default class Popup extends InteractivePopup { * @param {number} [opts.minHeight=0] - The minimum height of the popup. */ constructor(opts = {}) { - - opts = Object.assign({}, { - closeButton: false, - minWidth: 0, - minHeight: 0 - }, opts) + opts = Object.assign( + {}, + { + closeButton: false, + minWidth: 0, + minHeight: 0 + }, + opts + ) super(opts) } diff --git a/lib/pixi/popupmenu.js b/lib/pixi/popupmenu.js index c06d2fb..2b4ba9e 100644 --- a/lib/pixi/popupmenu.js +++ b/lib/pixi/popupmenu.js @@ -3,7 +3,7 @@ import Popup from './popup.js' /** * Class that represents a PixiJS PopupMenu. - * + * * @example * // Create the button and the modal when clicked * const button = new Button({ @@ -28,10 +28,9 @@ import Popup from './popup.js' * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/popupmenu.html|DocTest} */ export default class PopupMenu extends Popup { - /** * Creates an instance of a PopupMenu. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the modal. * @param {object[]} [opts.items=[]] - A list of the menu items. Each item must be of type object. @@ -43,38 +42,42 @@ export default class PopupMenu extends Popup { * @param {boolean} [opts.closeOnPopup=true] - The opacity of the background. */ constructor(opts = {}) { - const theme = Theme.fromString(opts.theme) - - opts = Object.assign({}, { - items: [], - margin: theme.margin / 2, - textStyle: theme.textStyle, - closeOnPopup: true - }, opts) + + opts = Object.assign( + {}, + { + items: [], + margin: theme.margin / 2, + textStyle: theme.textStyle, + closeOnPopup: true + }, + opts + ) super(opts) } - + /** * Creates children and instantiates everything. - * + * * @private * @return {PopupMenu} A reference to the popupmenu for chaining. */ setup() { - // content //----------------- const content = new PIXI.Container() - + let y = 0 for (let item of this.opts.items) { - let object = null if (item.label) { - object = new PIXI.Text(item.label, item.textStyle || this.opts.textStyle) + object = new PIXI.Text( + item.label, + item.textStyle || this.opts.textStyle + ) } else { object = item.content } @@ -83,16 +86,22 @@ export default class PopupMenu extends Popup { if (item.action) { if (item.disabled) { - object.alpha = .5 + object.alpha = 0.5 } else { object.interactive = true object.buttonMode = true } object.on('pointerover', e => { - TweenLite.to(object, this.theme.fast, {alpha: .83, overwrite: 'none'}) + TweenLite.to(object, this.theme.fast, { + alpha: 0.83, + overwrite: 'none' + }) }) object.on('pointerout', e => { - TweenLite.to(object, this.theme.fast, {alpha: 1, overwrite: 'none'}) + TweenLite.to(object, this.theme.fast, { + alpha: 1, + overwrite: 'none' + }) }) object.on('pointerup', e => { item.action.call(object, e, object) diff --git a/lib/pixi/progress.js b/lib/pixi/progress.js index 0d99a18..faa6095 100644 --- a/lib/pixi/progress.js +++ b/lib/pixi/progress.js @@ -2,7 +2,7 @@ import Theme from './theme.js' /** * Class that represents a PixiJS Progress. - * + * * @example * // Create the progress * const progress = new Progress({ @@ -18,10 +18,9 @@ import Theme from './theme.js' * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/progress.html|DocTest} */ export default class Progress extends PIXI.Container { - /** * Creates an instance of a Progress. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the progress. * @param {number} [opts.id=auto generated] - The id of the progress. @@ -53,36 +52,39 @@ export default class Progress extends PIXI.Container { * @param {boolean} [opts.visible=true] - Is the progress initially visible (property visible)? */ constructor(opts = {}) { - super() - + const theme = Theme.fromString(opts.theme) this.theme = theme - this.opts = Object.assign({}, { - id: PIXI.utils.uid(), - app: window.app, - width: null, - height: 2, - margin: 100, - padding: 0, - fill: theme.fill, - fillAlpha: theme.fillAlpha, - fillActive: theme.primaryColor, - fillActiveAlpha: theme.fillActiveAlpha, - stroke: theme.stroke, - strokeWidth: 0, - strokeAlpha: theme.strokeAlpha, - strokeActive: theme.strokeActive, - strokeActiveWidth: 0, - strokeActiveAlpha: theme.strokeActiveAlpha, - background: false, - backgroundFill: theme.background, - backgroundFillAlpha: 1, - radius: theme.radius, - destroyOnComplete: true, - visible: true - }, opts) + this.opts = Object.assign( + {}, + { + id: PIXI.utils.uid(), + app: window.app, + width: null, + height: 2, + margin: 100, + padding: 0, + fill: theme.fill, + fillAlpha: theme.fillAlpha, + fillActive: theme.primaryColor, + fillActiveAlpha: theme.fillActiveAlpha, + stroke: theme.stroke, + strokeWidth: 0, + strokeAlpha: theme.strokeAlpha, + strokeActive: theme.strokeActive, + strokeActiveWidth: 0, + strokeActiveAlpha: theme.strokeActiveAlpha, + background: false, + backgroundFill: theme.background, + backgroundFillAlpha: 1, + radius: theme.radius, + destroyOnComplete: true, + visible: true + }, + opts + ) this.id = this.opts.id @@ -91,7 +93,7 @@ export default class Progress extends PIXI.Container { this.barActive = null this.alpha = 0 - + this.visible = this.opts.visible this._progress = 0 @@ -104,15 +106,14 @@ export default class Progress extends PIXI.Container { //----------------- this.layout() } - + /** * Creates children and instantiates everything. - * + * * @private * @return {Progress} A reference to the progress for chaining. */ setup() { - // interaction //----------------- this.on('added', e => { @@ -139,14 +140,13 @@ export default class Progress extends PIXI.Container { return this } - + /** * Should be called to refresh the layout of the progress. Can be used after resizing. - * + * * @return {Progress} A reference to the progress for chaining. */ layout() { - const width = this.opts.app.size.width const height = this.opts.app.size.height @@ -154,7 +154,10 @@ export default class Progress extends PIXI.Container { //----------------- if (this.opts.background) { this.background.clear() - this.background.beginFill(this.opts.backgroundFill, this.opts.backgroundFillAlpha) + this.background.beginFill( + this.opts.backgroundFill, + this.opts.backgroundFillAlpha + ) this.background.drawRect(0, 0, width, height) this.background.endFill() } @@ -163,15 +166,14 @@ export default class Progress extends PIXI.Container { return this } - + /** * Draws the canvas. - * + * * @private * @return {Progress} A reference to the progress for chaining. */ draw() { - this.bar.clear() this.barActive.clear() @@ -180,59 +182,80 @@ export default class Progress extends PIXI.Container { return this } - + /** * Draws the bar. - * + * * @private * @return {Progress} A reference to the progress for chaining. */ drawBar() { - const width = this.opts.app.size.width const height = this.opts.app.size.height this.radius = this.opts.radius - if ((this.radius * 2) > this.opts.height) { + if (this.radius * 2 > this.opts.height) { this.radius = this.opts.height / 2 } - const wantedWidth = this.opts.width || (width - (2 * this.opts.margin)) + const wantedWidth = this.opts.width || width - 2 * this.opts.margin const wantedHeight = this.opts.height - this.bar.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha) + this.bar.lineStyle( + this.opts.strokeWidth, + this.opts.stroke, + this.opts.strokeAlpha + ) this.bar.beginFill(this.opts.fill, this.opts.fillAlpha) if (this.radius > 1) { - this.bar.drawRoundedRect(0, 0, wantedWidth, wantedHeight, this.radius) + this.bar.drawRoundedRect( + 0, + 0, + wantedWidth, + wantedHeight, + this.radius + ) } else { this.bar.drawRect(0, 0, wantedWidth, wantedHeight) } this.bar.endFill() - + this.bar.x = width / 2 - this.bar.width / 2 this.bar.y = height / 2 - this.bar.height / 2 return this } - + /** * Draws the active bar. - * + * * @private * @return {Progress} A reference to the progress for chaining. */ drawBarActive() { + const wantedWidth = this.bar.width - 2 * this.opts.padding + const wantedHeight = this.bar.height - 2 * this.opts.padding - const wantedWidth = this.bar.width - (2 * this.opts.padding) - const wantedHeight = this.bar.height - (2 * this.opts.padding) - - const barActiveWidth = wantedWidth * this._progress / 100 + const barActiveWidth = (wantedWidth * this._progress) / 100 - this.barActive.lineStyle(this.opts.strokeActiveWidth, this.opts.strokeActive, this.opts.strokeActiveAlpha) - this.barActive.beginFill(this.opts.fillActive, this.opts.fillActiveAlpha) + this.barActive.lineStyle( + this.opts.strokeActiveWidth, + this.opts.strokeActive, + this.opts.strokeActiveAlpha + ) + this.barActive.beginFill( + this.opts.fillActive, + this.opts.fillActiveAlpha + ) if (barActiveWidth > 0) { if (this.radius > 1) { - this.barActive.drawRoundedRect(0, 0, barActiveWidth, wantedHeight, this.radius) + this.barActive.drawRoundedRect( + 0, + 0, + barActiveWidth, + wantedHeight, + this.radius + ) } else { this.barActive.drawRect(0, 0, barActiveWidth, wantedHeight) } @@ -244,39 +267,41 @@ export default class Progress extends PIXI.Container { return this } - + /** * Shows the progress (sets his alpha values to 1). - * + * * @return {Progress} A reference to the progress for chaining. */ show() { - TweenLite.to(this, this.theme.fast, {alpha: 1}) + TweenLite.to(this, this.theme.fast, { alpha: 1 }) return this } - + /** * Hides the progress (sets his alpha values to 1). - * + * * @return {Progress} A reference to the progress for chaining. */ hide() { - TweenLite.to(this, this.theme.fast, {alpha: 0, onComplete: () => this.visible = false}) + TweenLite.to(this, this.theme.fast, { + alpha: 0, + onComplete: () => (this.visible = false) + }) return this } - + /** * Gets or sets the progress. Has to be a number between 0 and 100. - * + * * @member {number} */ get progress() { return this._progress } set progress(value) { - value = Math.round(value) if (value < 0) { @@ -294,7 +319,7 @@ export default class Progress extends PIXI.Container { if (value === 100 && this.opts.destroyOnComplete) { TweenLite.to(this, this.theme.fast, { alpha: 0, - onComplete: () => this.destroy({children: true}) + onComplete: () => this.destroy({ children: true }) }) } } diff --git a/lib/pixi/scatter.js b/lib/pixi/scatter.js index 238ef7d..f5de08e 100755 --- a/lib/pixi/scatter.js +++ b/lib/pixi/scatter.js @@ -9,30 +9,32 @@ import { InteractionMapper } from '../interaction.js' * on the same level. */ export class ScatterContainer extends PIXI.Graphics { - /** - * @constructor - * @param {PIXI.Renderer} renderer - PIXI renderer, needed for hit testing - * @param {Bool} stopEvents - Whether events should be stopped or propagated - * @param {Bool} claimEvents - Whether events should be marked as claimed - * if findTarget return as non-null value. - * @param {PIXI.Container} container - A container for the scatter - * @param {Bool} showBounds - Show bounds for debugging purposes. - * @param {Bool} showTouches - Show touches and pointer for debugging purposes. - * @param {Color} backgroundColor - Set background color if specified. - * @param {PIXIApp} app - Needed if showBounds is true to register - * update handler. - */ - constructor(renderer, { - stopEvents = true, - claimEvents = true, - container = null, - showBounds = false, - showPolygon = false, - showTouches = false, - backgroundColor = null, - app = window.app - } = {}) { + * @constructor + * @param {PIXI.Renderer} renderer - PIXI renderer, needed for hit testing + * @param {Bool} stopEvents - Whether events should be stopped or propagated + * @param {Bool} claimEvents - Whether events should be marked as claimed + * if findTarget return as non-null value. + * @param {PIXI.Container} container - A container for the scatter + * @param {Bool} showBounds - Show bounds for debugging purposes. + * @param {Bool} showTouches - Show touches and pointer for debugging purposes. + * @param {Color} backgroundColor - Set background color if specified. + * @param {PIXIApp} app - Needed if showBounds is true to register + * update handler. + */ + constructor( + renderer, + { + stopEvents = true, + claimEvents = true, + container = null, + showBounds = false, + showPolygon = false, + showTouches = false, + backgroundColor = null, + app = window.app + } = {} + ) { super() this.container = container if (this.container) @@ -53,7 +55,7 @@ export class ScatterContainer extends PIXI.Graphics { this.backgroundColor = backgroundColor if (showBounds || showTouches || showPolygon) { //console.log("Show TOUCHES!!!") - this.app.ticker.add((delta) => this.update(delta), this) + this.app.ticker.add(delta => this.update(delta), this) } if (backgroundColor) { this.updateBackground() @@ -77,8 +79,12 @@ export class ScatterContainer extends PIXI.Graphics { let y = 0 // @container: We need to call the constant values, as the container // gets resized, when a child moves outside the original boundaries. - let w = (this.container) ? this.containerDimensions.x : (this.backgroundWidth || this.app.width) - let h = (this.container) ? this.containerDimensions.y : (this.backgroundHeight || this.app.height) + let w = this.container + ? this.containerDimensions.x + : this.backgroundWidth || this.app.width + let h = this.container + ? this.containerDimensions.y + : this.backgroundHeight || this.app.height if (this.app.fullscreen && this.app.monkeyPatchMapping) { let fixed = this.mapPositionToPoint({ x: w, y: 0 }) @@ -113,7 +119,7 @@ export class ScatterContainer extends PIXI.Graphics { update(dt) { this.clear() - this.lineStyle(1, 0x0000FF) + this.lineStyle(1, 0x0000ff) if (this.showBounds) { for (let child of this.children) { if (child.scatter) { @@ -125,11 +131,11 @@ export class ScatterContainer extends PIXI.Graphics { this.drawCircle(child.scatter.x, child.scatter.y, 4) } } - this.lineStyle(2, 0x0000FF) + this.lineStyle(2, 0x0000ff) this.drawShape(this.bounds) } if (this.showPolygon) { - this.lineStyle(2, 0xFF0000) + this.lineStyle(2, 0xff0000) for (let child of this.children) { if (child.scatter) { let polygon = child.scatter.polygon @@ -149,8 +155,7 @@ export class ScatterContainer extends PIXI.Graphics { } capture(event) { - if (this.stopEvents) - Events.stop(event) + if (this.stopEvents) Events.stop(event) return true } @@ -162,8 +167,14 @@ export class ScatterContainer extends PIXI.Graphics { // if (hit) { // console.log("findHitScatter", displayObject) // } - if (hit && this.hitScatter === null && typeof (displayObject) != undefined) { - this.hitScatter = (displayObject.scatter) ? displayObject.scatter : null + if ( + hit && + this.hitScatter === null && + typeof displayObject != undefined + ) { + this.hitScatter = displayObject.scatter + ? displayObject.scatter + : null } } @@ -173,7 +184,10 @@ export class ScatterContainer extends PIXI.Graphics { let local = new PIXI.Point() let interactionManager = this.renderer.plugins.interaction interactionManager.mapPositionToPoint(local, point.x, point.y) - if (element instanceof DisplayObjectScatter && element.displayObject.parent != null) { + if ( + element instanceof DisplayObjectScatter && + element.displayObject.parent != null + ) { return element.displayObject.parent.toLocal(local) } return local @@ -190,11 +204,13 @@ export class ScatterContainer extends PIXI.Graphics { this.hitScatter = null let interactionManager = this.renderer.plugins.interaction let fakeEvent = this.fakeInteractionEvent(local) - interactionManager.processInteractive(fakeEvent, + interactionManager.processInteractive( + fakeEvent, this, - this.findHitScatter.bind(this), true) - if (this.claimEvents) - event.claimedByScatter = this.hitScatter + this.findHitScatter.bind(this), + true + ) + if (this.claimEvents) event.claimedByScatter = this.hitScatter return this.hitScatter } @@ -209,19 +225,13 @@ export class ScatterContainer extends PIXI.Graphics { let displayObject = interactionManager.hitTest(local, this) if (displayObject != null && displayObject.scatter != null) this.hitScatter = displayObject.scatter - if (this.claimEvents) - event.claimedByScatter = this.hitScatter + if (this.claimEvents) event.claimedByScatter = this.hitScatter return this.hitScatter } + onStart(event, interaction) {} - onStart(event, interaction) { - - } - - onMove(event, interaction) { - - } + onMove(event, interaction) {} onEnd(event, interaction) { for (let key of interaction.ended.keys()) { @@ -253,7 +263,6 @@ export class ScatterContainer extends PIXI.Graphics { if (this.backgroundColor) { this.updateBackground() } - } } @@ -262,14 +271,20 @@ export class ScatterContainer extends PIXI.Graphics { * PIXI.DisplayObject can be wrapped. */ export class DisplayObjectScatter extends AbstractScatter { - - constructor(displayObject, renderer, - { x = null, y = null, + constructor( + displayObject, + renderer, + { + x = null, + y = null, minScale = 0.1, maxScale = 1.0, startScale = 1.0, autoBringToFront = true, - translatable = true, scalable = true, rotatable = true, resizable = false, + translatable = true, + scalable = true, + rotatable = true, + resizable = false, movableX = true, movableY = true, throwVisibility = 44, @@ -279,19 +294,29 @@ export class DisplayObjectScatter extends AbstractScatter { rotation = null, overdoScaling = 1.5, onTransform = null, - onThrowFinished = null } = {}) { + onThrowFinished = null + } = {} + ) { // For the simulation of named parameters, // see: http://exploringjs.com/es6/ch_parameter-handling.html super({ overdoScaling, - minScale, maxScale, + minScale, + maxScale, startScale, autoBringToFront, - translatable, scalable, rotatable, resizable, - movableX, movableY, throwVisibility, throwDamping, + translatable, + scalable, + rotatable, + resizable, + movableX, + movableY, + throwVisibility, + throwDamping, autoThrow, onThrowFinished, - rotationDegrees, rotation, + rotationDegrees, + rotation, onTransform }) this.displayObject = displayObject @@ -458,7 +483,10 @@ export class DisplayObjectScatter extends AbstractScatter { if (this.displayObject.parent instanceof ScatterContainer) { let scatterContainer = this.displayObject.parent scatterContainer.bringToFront(this.displayObject) - } else if (this.displayObject.parent != null && this.displayObject.parent.scatter) { + } else if ( + this.displayObject.parent != null && + this.displayObject.parent.scatter + ) { this.displayObject.parent.scatter.toFront(this.displayObject) } } diff --git a/lib/pixi/scrollbox.js b/lib/pixi/scrollbox.js index 3b95687..397c4f3 100644 --- a/lib/pixi/scrollbox.js +++ b/lib/pixi/scrollbox.js @@ -1,5 +1,3 @@ - - /** * pixi.js scrollbox: a masked content box that can scroll vertically or horizontally with scrollbars */ @@ -26,26 +24,29 @@ export default class Scrollbox extends PIXI.Container { * @param {number} [options.fadeWait=3000] time to wait before fading the scrollbar if options.fade is set * @param {(string|function)} [options.fadeEase=easeInOutSine] easing function to use for fading */ - constructor(options) - { + constructor(options) { super() - this.options = Object.assign({}, { - boxWidth: 100, - boxHeight: 100, - scrollbarSize: 10, - scrollbarBackground: 14540253, - scrollbarBackgroundAlpha: 1, - scrollbarForeground: 8947848, - scrollbarForegroundAlpha: 1, - dragScroll: true, - stopPropagation: true, - scrollbarOffsetHorizontal: 0, - scrollbarOffsetVertical: 0, - underflow: 'top-left', - fadeScrollbar: false, - fadeWait: 3000, - fadeEase: 'easeInOutSine' - }, options) + this.options = Object.assign( + {}, + { + boxWidth: 100, + boxHeight: 100, + scrollbarSize: 10, + scrollbarBackground: 14540253, + scrollbarBackgroundAlpha: 1, + scrollbarForeground: 8947848, + scrollbarForegroundAlpha: 1, + dragScroll: true, + stopPropagation: true, + scrollbarOffsetHorizontal: 0, + scrollbarOffsetVertical: 0, + underflow: 'top-left', + fadeScrollbar: false, + fadeWait: 3000, + fadeEase: 'easeInOutSine' + }, + options + ) this.ease = new PIXI.extras.Ease.list() this.on('added', event => { @@ -57,10 +58,15 @@ export default class Scrollbox extends PIXI.Container { * you can use any function from pixi-viewport on content to manually move the content (see https://davidfig.github.io/pixi-viewport/jsdoc/) * @type {PIXI.extras.Viewport} */ - this.content = this.addChild(new PIXI.extras.Viewport({ passiveWheel: this.options.stopPropagation, stopPropagation: this.options.stopPropagation, screenWidth: this.options.boxWidth, screenHeight: this.options.boxHeight })) - this.content - .decelerate() - .on('moved', () => this._drawScrollbars()) + this.content = this.addChild( + new PIXI.extras.Viewport({ + passiveWheel: this.options.stopPropagation, + stopPropagation: this.options.stopPropagation, + screenWidth: this.options.boxWidth, + screenHeight: this.options.boxHeight + }) + ) + this.content.decelerate().on('moved', () => this._drawScrollbars()) /** * graphics element for drawing the scrollbars @@ -82,12 +88,10 @@ export default class Scrollbox extends PIXI.Container { * offset of horizontal scrollbar (in pixels) * @type {number} */ - get scrollbarOffsetHorizontal() - { + get scrollbarOffsetHorizontal() { return this.options.scrollbarOffsetHorizontal } - set scrollbarOffsetHorizontal(value) - { + set scrollbarOffsetHorizontal(value) { this.options.scrollbarOffsetHorizontal = value } @@ -95,12 +99,10 @@ export default class Scrollbox extends PIXI.Container { * offset of vertical scrollbar (in pixels) * @type {number} */ - get scrollbarOffsetVertical() - { + get scrollbarOffsetVertical() { return this.options.scrollbarOffsetVertical } - set scrollbarOffsetVertical(value) - { + set scrollbarOffsetVertical(value) { this.options.scrollbarOffsetVertical = value } @@ -108,14 +110,11 @@ export default class Scrollbox extends PIXI.Container { * disable the scrollbox (if set to true this will also remove the mask) * @type {boolean} */ - get disable() - { + get disable() { return this._disabled } - set disable(value) - { - if (this._disabled !== value) - { + set disable(value) { + if (this._disabled !== value) { this._disabled = value this.update() } @@ -125,12 +124,10 @@ export default class Scrollbox extends PIXI.Container { * call stopPropagation on any events that impact scrollbox * @type {boolean} */ - get stopPropagation() - { + get stopPropagation() { return this.options.stopPropagation } - set stopPropagation(value) - { + set stopPropagation(value) { this.options.stopPropagation = value } @@ -138,19 +135,14 @@ export default class Scrollbox extends PIXI.Container { * user may drag the content area to scroll content * @type {boolean} */ - get dragScroll() - { + get dragScroll() { return this.options.dragScroll } - set dragScroll(value) - { + set dragScroll(value) { this.options.dragScroll = value - if (value) - { + if (value) { this.content.drag() - } - else - { + } else { this.content.removePlugin('drag') } this.update() @@ -160,12 +152,10 @@ export default class Scrollbox extends PIXI.Container { * width of scrollbox including the scrollbar (if visible)- this changes the size and not the scale of the box * @type {number} */ - get boxWidth() - { + get boxWidth() { return this.options.boxWidth } - set boxWidth(value) - { + set boxWidth(value) { this.options.boxWidth = value this.content.screenWidth = value this.update() @@ -178,12 +168,10 @@ export default class Scrollbox extends PIXI.Container { * auto = if content is larger than box size, then show scrollbar * @type {string} */ - get overflow() - { + get overflow() { return this.options.overflow } - set overflow(value) - { + set overflow(value) { this.options.overflow = value this.options.overflowX = value this.options.overflowY = value @@ -197,12 +185,10 @@ export default class Scrollbox extends PIXI.Container { * auto = if content is larger than box size, then show scrollbar * @type {string} */ - get overflowX() - { + get overflowX() { return this.options.overflowX } - set overflowX(value) - { + set overflowX(value) { this.options.overflowX = value this.update() } @@ -214,12 +200,10 @@ export default class Scrollbox extends PIXI.Container { * auto = if content is larger than box size, then show scrollbar * @type {string} */ - get overflowY() - { + get overflowY() { return this.options.overflowY } - set overflowY(value) - { + set overflowY(value) { this.options.overflowY = value this.update() } @@ -228,12 +212,10 @@ export default class Scrollbox extends PIXI.Container { * height of scrollbox including the scrollbar (if visible) - this changes the size and not the scale of the box * @type {number} */ - get boxHeight() - { + get boxHeight() { return this.options.boxHeight } - set boxHeight(value) - { + set boxHeight(value) { this.options.boxHeight = value this.content.screenHeight = value this.update() @@ -243,12 +225,10 @@ export default class Scrollbox extends PIXI.Container { * scrollbar size in pixels * @type {number} */ - get scrollbarSize() - { + get scrollbarSize() { return this.options.scrollbarSize } - set scrollbarSize(value) - { + set scrollbarSize(value) { this.options.scrollbarSize = value } @@ -257,9 +237,11 @@ export default class Scrollbox extends PIXI.Container { * @type {number} * @readonly */ - get contentWidth() - { - return this.options.boxWidth - (this.isScrollbarVertical ? this.options.scrollbarSize : 0) + get contentWidth() { + return ( + this.options.boxWidth - + (this.isScrollbarVertical ? this.options.scrollbarSize : 0) + ) } /** @@ -267,9 +249,11 @@ export default class Scrollbox extends PIXI.Container { * @type {number} * @readonly */ - get contentHeight() - { - return this.options.boxHeight - (this.isScrollbarHorizontal ? this.options.scrollbarSize : 0) + get contentHeight() { + return ( + this.options.boxHeight - + (this.isScrollbarHorizontal ? this.options.scrollbarSize : 0) + ) } /** @@ -277,8 +261,7 @@ export default class Scrollbox extends PIXI.Container { * @type {boolean} * @readonly */ - get isScrollbarVertical() - { + get isScrollbarVertical() { return this._isScrollbarVertical } @@ -287,24 +270,21 @@ export default class Scrollbox extends PIXI.Container { * @type {boolean} * @readonly */ - get isScrollbarHorizontal() - { + get isScrollbarHorizontal() { return this._isScrollbarHorizontal } /** * top coordinate of scrollbar */ - get scrollTop() - { + get scrollTop() { return this.content.top } /** * left coordinate of scrollbar */ - get scrollLeft() - { + get scrollLeft() { return this.content.left } @@ -312,12 +292,10 @@ export default class Scrollbox extends PIXI.Container { * width of content area * if not set then it uses content.width to calculate width */ - get scrollWidth() - { + get scrollWidth() { return this._scrollWidth || this.content.width } - set scrollWidth(value) - { + set scrollWidth(value) { this._scrollWidth = value } @@ -325,12 +303,10 @@ export default class Scrollbox extends PIXI.Container { * height of content area * if not set then it uses content.height to calculate height */ - get scrollHeight() - { + get scrollHeight() { return this._scrollHeight || this.content.height } - set scrollHeight(value) - { + set scrollHeight(value) { this._scrollHeight = value } @@ -338,52 +314,111 @@ export default class Scrollbox extends PIXI.Container { * draws scrollbars * @private */ - _drawScrollbars() - { - this._isScrollbarHorizontal = this.overflowX === 'scroll' ? true : ['hidden', 'none'].indexOf(this.overflowX) !== -1 ? false : this.scrollWidth > this.options.boxWidth - this._isScrollbarVertical = this.overflowY === 'scroll' ? true : ['hidden', 'none'].indexOf(this.overflowY) !== -1 ? false : this.scrollHeight > this.options.boxHeight + _drawScrollbars() { + this._isScrollbarHorizontal = + this.overflowX === 'scroll' + ? true + : ['hidden', 'none'].indexOf(this.overflowX) !== -1 + ? false + : this.scrollWidth > this.options.boxWidth + this._isScrollbarVertical = + this.overflowY === 'scroll' + ? true + : ['hidden', 'none'].indexOf(this.overflowY) !== -1 + ? false + : this.scrollHeight > this.options.boxHeight this.scrollbar.clear() let options = {} options.left = 0 - options.right = this.scrollWidth + (this._isScrollbarVertical ? this.options.scrollbarSize : 0) + options.right = + this.scrollWidth + + (this._isScrollbarVertical ? this.options.scrollbarSize : 0) options.top = 0 - options.bottom = this.scrollHeight + (this.isScrollbarHorizontal ? this.options.scrollbarSize : 0) - const width = this.scrollWidth + (this.isScrollbarVertical ? this.options.scrollbarSize : 0) - const height = this.scrollHeight + (this.isScrollbarHorizontal ? this.options.scrollbarSize : 0) + options.bottom = + this.scrollHeight + + (this.isScrollbarHorizontal ? this.options.scrollbarSize : 0) + const width = + this.scrollWidth + + (this.isScrollbarVertical ? this.options.scrollbarSize : 0) + const height = + this.scrollHeight + + (this.isScrollbarHorizontal ? this.options.scrollbarSize : 0) this.scrollbarTop = (this.content.top / height) * this.boxHeight this.scrollbarTop = this.scrollbarTop < 0 ? 0 : this.scrollbarTop this.scrollbarHeight = (this.boxHeight / height) * this.boxHeight - this.scrollbarHeight = this.scrollbarTop + this.scrollbarHeight > this.boxHeight ? this.boxHeight - this.scrollbarTop : this.scrollbarHeight + this.scrollbarHeight = + this.scrollbarTop + this.scrollbarHeight > this.boxHeight + ? this.boxHeight - this.scrollbarTop + : this.scrollbarHeight this.scrollbarLeft = (this.content.left / width) * this.boxWidth this.scrollbarLeft = this.scrollbarLeft < 0 ? 0 : this.scrollbarLeft this.scrollbarWidth = (this.boxWidth / width) * this.boxWidth - this.scrollbarWidth = this.scrollbarWidth + this.scrollbarLeft > this.boxWidth ? this.boxWidth - this.scrollbarLeft : this.scrollbarWidth - if (this.isScrollbarVertical) - { + this.scrollbarWidth = + this.scrollbarWidth + this.scrollbarLeft > this.boxWidth + ? this.boxWidth - this.scrollbarLeft + : this.scrollbarWidth + if (this.isScrollbarVertical) { this.scrollbar - .beginFill(this.options.scrollbarBackground, this.options.scrollbarBackgroundAlpha) - .drawRect(this.boxWidth - this.scrollbarSize + this.options.scrollbarOffsetVertical, 0, this.scrollbarSize, this.boxHeight) + .beginFill( + this.options.scrollbarBackground, + this.options.scrollbarBackgroundAlpha + ) + .drawRect( + this.boxWidth - + this.scrollbarSize + + this.options.scrollbarOffsetVertical, + 0, + this.scrollbarSize, + this.boxHeight + ) .endFill() } - if (this.isScrollbarHorizontal) - { + if (this.isScrollbarHorizontal) { this.scrollbar - .beginFill(this.options.scrollbarBackground, this.options.scrollbarBackgroundAlpha) - .drawRect(0, this.boxHeight - this.scrollbarSize + this.options.scrollbarOffsetHorizontal, this.boxWidth, this.scrollbarSize) + .beginFill( + this.options.scrollbarBackground, + this.options.scrollbarBackgroundAlpha + ) + .drawRect( + 0, + this.boxHeight - + this.scrollbarSize + + this.options.scrollbarOffsetHorizontal, + this.boxWidth, + this.scrollbarSize + ) .endFill() } - if (this.isScrollbarVertical) - { + if (this.isScrollbarVertical) { this.scrollbar - .beginFill(this.options.scrollbarForeground, this.options.scrollbarForegroundAlpha) - .drawRect(this.boxWidth - this.scrollbarSize + this.options.scrollbarOffsetVertical, this.scrollbarTop, this.scrollbarSize, this.scrollbarHeight) + .beginFill( + this.options.scrollbarForeground, + this.options.scrollbarForegroundAlpha + ) + .drawRect( + this.boxWidth - + this.scrollbarSize + + this.options.scrollbarOffsetVertical, + this.scrollbarTop, + this.scrollbarSize, + this.scrollbarHeight + ) .endFill() } - if (this.isScrollbarHorizontal) - { + if (this.isScrollbarHorizontal) { this.scrollbar - .beginFill(this.options.scrollbarForeground, this.options.scrollbarForegroundAlpha) - .drawRect(this.scrollbarLeft, this.boxHeight - this.scrollbarSize + this.options.scrollbarOffsetHorizontal, this.scrollbarWidth, this.scrollbarSize) + .beginFill( + this.options.scrollbarForeground, + this.options.scrollbarForegroundAlpha + ) + .drawRect( + this.scrollbarLeft, + this.boxHeight - + this.scrollbarSize + + this.options.scrollbarOffsetHorizontal, + this.scrollbarWidth, + this.scrollbarSize + ) .endFill() } // this.content.forceHitArea = new PIXI.Rectangle(0, 0 , this.boxWidth, this.boxHeight) @@ -394,8 +429,7 @@ export default class Scrollbox extends PIXI.Container { * draws mask layer * @private */ - _drawMask() - { + _drawMask() { this._maskContent .beginFill(0) .drawRect(0, 0, this.boxWidth, this.boxHeight) @@ -406,19 +440,20 @@ export default class Scrollbox extends PIXI.Container { /** * call when scrollbox content changes */ - update() - { + update() { this.content.mask = null this._maskContent.clear() - if (!this._disabled) - { + if (!this._disabled) { this._drawScrollbars() this._drawMask() - if (this.options.dragScroll) - { - const direction = this.isScrollbarHorizontal && this.isScrollbarVertical ? 'all' : this.isScrollbarHorizontal ? 'x' : 'y' - if (direction !== null) - { + if (this.options.dragScroll) { + const direction = + this.isScrollbarHorizontal && this.isScrollbarVertical + ? 'all' + : this.isScrollbarHorizontal + ? 'x' + : 'y' + if (direction !== null) { this.content .drag({ clampWheel: true, direction }) .clamp({ direction, underflow: this.options.underflow }) @@ -430,18 +465,18 @@ export default class Scrollbox extends PIXI.Container { /** * show the scrollbar and restart the timer for fade if options.fade is set */ - activateFade() - { - if (this.options.fade) - { - if (this.fade) - { + activateFade() { + if (this.options.fade) { + if (this.fade) { this.ease.remove(this.fade) } this.scrollbar.alpha = 1 const time = this.options.fade === true ? 1000 : this.options.fade - this.fade = this.ease.to(this.scrollbar, { alpha: 0 }, time, { wait: this.options.fadeWait, ease: this.options.fadeEase }) - this.fade.on('each', () => this.content.dirty = true) + this.fade = this.ease.to(this.scrollbar, { alpha: 0 }, time, { + wait: this.options.fadeWait, + ease: this.options.fadeEase + }) + this.fade.on('each', () => (this.content.dirty = true)) } } @@ -450,60 +485,47 @@ export default class Scrollbox extends PIXI.Container { * @param {PIXI.interaction.InteractionEvent} e * @private */ - scrollbarDown(e) - { + scrollbarDown(e) { const local = this.toLocal(e.data.global) - if (this.isScrollbarHorizontal) - { - if (local.y > this.boxHeight - this.scrollbarSize) - { - if (local.x >= this.scrollbarLeft && local.x <= this.scrollbarLeft + this.scrollbarWidth) - { + if (this.isScrollbarHorizontal) { + if (local.y > this.boxHeight - this.scrollbarSize) { + if ( + local.x >= this.scrollbarLeft && + local.x <= this.scrollbarLeft + this.scrollbarWidth + ) { this.pointerDown = { type: 'horizontal', last: local } - } - else - { - if (local.x > this.scrollbarLeft) - { + } else { + if (local.x > this.scrollbarLeft) { this.content.left += this.content.worldScreenWidth this.update() - } - else - { + } else { this.content.left -= this.content.worldScreenWidth this.update() } } - if (this.options.stopPropagation) - { + if (this.options.stopPropagation) { e.stopPropagation() } return } } - if (this.isScrollbarVertical) - { - if (local.x > this.boxWidth - this.scrollbarSize) - { - if (local.y >= this.scrollbarTop && local.y <= this.scrollbarTop + this.scrollbarWidth) - { + if (this.isScrollbarVertical) { + if (local.x > this.boxWidth - this.scrollbarSize) { + if ( + local.y >= this.scrollbarTop && + local.y <= this.scrollbarTop + this.scrollbarWidth + ) { this.pointerDown = { type: 'vertical', last: local } - } - else - { - if (local.y > this.scrollbarTop) - { + } else { + if (local.y > this.scrollbarTop) { this.content.top += this.content.worldScreenHeight this.update() - } - else - { + } else { this.content.top -= this.content.worldScreenHeight this.update() } } - if (this.options.stopPropagation) - { + if (this.options.stopPropagation) { e.stopPropagation() } return @@ -516,26 +538,20 @@ export default class Scrollbox extends PIXI.Container { * @param {PIXI.interaction.InteractionEvent} e * @private */ - scrollbarMove(e) - { - if (this.pointerDown) - { - if (this.pointerDown.type === 'horizontal') - { + scrollbarMove(e) { + if (this.pointerDown) { + if (this.pointerDown.type === 'horizontal') { const local = this.toLocal(e.data.global) this.content.left += local.x - this.pointerDown.last.x this.pointerDown.last = local this.update() - } - else if (this.pointerDown.type === 'vertical') - { + } else if (this.pointerDown.type === 'vertical') { const local = this.toLocal(e.data.global) this.content.top += local.y - this.pointerDown.last.y this.pointerDown.last = local this.update() } - if (this.options.stopPropagation) - { + if (this.options.stopPropagation) { e.stopPropagation() } } @@ -545,8 +561,7 @@ export default class Scrollbox extends PIXI.Container { * handle pointer down on scrollbar * @private */ - scrollbarUp() - { + scrollbarUp() { this.pointerDown = null } @@ -558,19 +573,27 @@ export default class Scrollbox extends PIXI.Container { * @param {number} [options.scrollWidth] set the width of the inside of the scrollbox (leave null to use content.width) * @param {number} [options.scrollHeight] set the height of the inside of the scrollbox (leave null to use content.height) */ - resize(options) - { - this.options.boxWidth = typeof options.boxWidth !== 'undefined' ? options.boxWidth : this.options.boxWidth - this.options.boxHeight = typeof options.boxHeight !== 'undefined' ? options.boxHeight : this.options.boxHeight - if (options.scrollWidth) - { + resize(options) { + this.options.boxWidth = + typeof options.boxWidth !== 'undefined' + ? options.boxWidth + : this.options.boxWidth + this.options.boxHeight = + typeof options.boxHeight !== 'undefined' + ? options.boxHeight + : this.options.boxHeight + if (options.scrollWidth) { this.scrollWidth = options.scrollWidth } - if (options.scrollHeight) - { + if (options.scrollHeight) { this.scrollHeight = options.scrollHeight } - this.content.resize(this.options.boxWidth, this.options.boxHeight, this.scrollWidth, this.scrollHeight) + this.content.resize( + this.options.boxWidth, + this.options.boxHeight, + this.scrollWidth, + this.scrollHeight + ) this.update() } @@ -581,8 +604,7 @@ export default class Scrollbox extends PIXI.Container { * @param {number} width * @param {number} height */ - ensureVisible(x, y, width, height) - { + ensureVisible(x, y, width, height) { this.content.ensureVisible(x, y, width, height) this._drawScrollbars() } diff --git a/lib/pixi/scrollview.js b/lib/pixi/scrollview.js index beaab03..f0e7d2b 100644 --- a/lib/pixi/scrollview.js +++ b/lib/pixi/scrollview.js @@ -2,7 +2,7 @@ import Scrollbox from './scrollbox.js' /** * Class that represents a PixiJS Scrollview. - * + * * @example * // Create the app * const app = new PIXIApp({ @@ -10,7 +10,7 @@ import Scrollbox from './scrollbox.js' * width: 600, * height: 400 * }).setup().run() - * + * * // Create the Scrollview * app.loader * .add('elephant', './assets/elephant-1.jpg') @@ -26,38 +26,34 @@ import Scrollbox from './scrollbox.js' * @see {@link https://davidfig.github.io/pixi-viewport/jsdoc/Viewport.html|Viewport} */ export default class Scrollview extends Scrollbox { - /** * Creates an instance of a Scrollview. - * + * * @constructor * @see https://davidfig.github.io/pixi-scrollbox/jsdoc/Scrollbox.html */ constructor(opts = {}) { - super(opts) this.opts = opts } - + /** * Creates children and instantiates everything. - * + * * @private * @return {Scrollview} A reference to the Scrollview for chaining. */ setup() { - return this } - + /** * Should be called to refresh the layout of the Scrollview. Can be used after resizing. - * + * * @return {Scrollview} A reference to the Scrollview for chaining. */ layout() { - this.update() return this diff --git a/lib/pixi/slider.js b/lib/pixi/slider.js index a41ee30..de2841b 100644 --- a/lib/pixi/slider.js +++ b/lib/pixi/slider.js @@ -27,7 +27,7 @@ import Tooltip from './tooltip.js' /** * Class that represents a PixiJS Slider. - * + * * @example * // Create the app * const app = new PIXIApp({ @@ -35,7 +35,7 @@ import Tooltip from './tooltip.js' * width: 900, * height: 250 * }).setup().run() - * + * * // Create the slider * const slider = new Slider({ * x: 10, @@ -51,10 +51,9 @@ import Tooltip from './tooltip.js' * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/slider.html|DocTest} */ export default class Slider extends PIXI.Container { - /** * Creates an instance of a Slider. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the slider. * @param {number} [opts.id=auto generated] - The id of the slider. @@ -82,46 +81,49 @@ export default class Slider extends PIXI.Container { * @param {onUpdateCallback} [opts.onUpdate] - Executed when the slider control is moved. * @param {onCompleteCallback} [opts.onComplete] - Executed when the slider control was dropped. * @param {string|object} [opts.tooltip] - A string for the label of the tooltip or an object to configure the tooltip - * to display. + * to display. * @param {boolean} [opts.visible=true] - Is the slider initially visible (property visible)? */ constructor(opts = {}) { - super() - + const theme = Theme.fromString(opts.theme) this.theme = theme - this.opts = Object.assign({}, { - id: PIXI.utils.uid(), - x: 0, - y: 0, - width: 250, - height: 2, - container: null, - fill: theme.fill, - fillAlpha: theme.fillAlpha, - stroke: theme.stroke, - strokeWidth: theme.strokeWidth, - strokeAlpha: theme.strokeAlpha, - controlFill: theme.fill, - controlFillAlpha: .5, - controlStroke: theme.primaryColor, - controlStrokeWidth: 2, - controlStrokeAlpha: theme.strokeAlpha, - controlRadius: 16, - orientation: 'horizontal', - min: 0, - max: 100, - value: 0, - disabled: false, - onStart: null, - onUpdate: null, - onComplete: null, - tooltip: null, - visible: true - }, opts) - + this.opts = Object.assign( + {}, + { + id: PIXI.utils.uid(), + x: 0, + y: 0, + width: 250, + height: 2, + container: null, + fill: theme.fill, + fillAlpha: theme.fillAlpha, + stroke: theme.stroke, + strokeWidth: theme.strokeWidth, + strokeAlpha: theme.strokeAlpha, + controlFill: theme.fill, + controlFillAlpha: 0.5, + controlStroke: theme.primaryColor, + controlStrokeWidth: 2, + controlStrokeAlpha: theme.strokeAlpha, + controlRadius: 16, + orientation: 'horizontal', + min: 0, + max: 100, + value: 0, + disabled: false, + onStart: null, + onUpdate: null, + onComplete: null, + tooltip: null, + visible: true + }, + opts + ) + this.opts.container = this.opts.container || this // Validation @@ -149,7 +151,7 @@ export default class Slider extends PIXI.Container { this.sliderObj = null this.control = null this.tooltip = null - + this.visible = this.opts.visible // setup @@ -160,23 +162,26 @@ export default class Slider extends PIXI.Container { //----------------- this.layout() } - + /** * Creates children and instantiates everything. - * + * * @private * @return {Slider} A reference to the slider for chaining. */ setup() { - // Container events //----------------- const container = this.opts.container this.on('pointermove', e => { if (this.control.dragging) { - const moveX = this.control.event.data.getLocalPosition(this.control.parent).x - this._value = this.pixelToValue(moveX - this.control.delta - this.opts.controlRadius) + const moveX = this.control.event.data.getLocalPosition( + this.control.parent + ).x + this._value = this.pixelToValue( + moveX - this.control.delta - this.opts.controlRadius + ) let x = this.valueToPixel(this._value) + this.opts.controlRadius this.control.x = x @@ -188,8 +193,16 @@ export default class Slider extends PIXI.Container { if (container instanceof Element) { container.addEventListener('pointerup', e => this.onEnd(e), false) - container.addEventListener('pointercancel', e => this.onEnd(e), false) - container.addEventListener('pointerleave', e => this.onEnd(e), false) + container.addEventListener( + 'pointercancel', + e => this.onEnd(e), + false + ) + container.addEventListener( + 'pointerleave', + e => this.onEnd(e), + false + ) container.addEventListener('pointerout', e => this.onEnd(e), false) container.addEventListener('mouseup', e => this.onEnd(e), false) container.addEventListener('mousecancel', e => this.onEnd(e), false) @@ -220,7 +233,7 @@ export default class Slider extends PIXI.Container { control.event = e control.delta = e.data.getLocalPosition(this.control).x control.dragging = true - + if (this.opts.onStart) { this.opts.onStart.call(this, e, this) } @@ -229,20 +242,20 @@ export default class Slider extends PIXI.Container { this.control = control this.addChild(this.control) - + // interaction //----------------- this.sliderObj.on('pointerover', e => { - TweenLite.to(this.control, this.theme.fast, {alpha: .83}) + TweenLite.to(this.control, this.theme.fast, { alpha: 0.83 }) }) this.sliderObj.on('pointerout', e => { - TweenLite.to(this.control, this.theme.fast, {alpha: 1}) + TweenLite.to(this.control, this.theme.fast, { alpha: 1 }) }) this.sliderObj.on('pointerdown', e => { this.sliderObj.pointerdowned = true - TweenLite.to(this.control, this.theme.fast, {alpha: .7}) + TweenLite.to(this.control, this.theme.fast, { alpha: 0.7 }) }) // Click on the slider bar @@ -250,15 +263,17 @@ export default class Slider extends PIXI.Container { if (this.sliderObj.pointerdowned) { this.sliderObj.pointerdowned = false const position = e.data.getLocalPosition(this.control.parent) - this.value = this.pixelToValue(position.x - this.opts.controlRadius) - TweenLite.to(this.control, this.theme.fast, {alpha: .83}) + this.value = this.pixelToValue( + position.x - this.opts.controlRadius + ) + TweenLite.to(this.control, this.theme.fast, { alpha: 0.83 }) } }) // disabled //----------------- this.disabled = this.opts.disabled - + // tooltip //----------------- if (this.opts.tooltip) { @@ -275,14 +290,13 @@ export default class Slider extends PIXI.Container { return this } - + /** * Should be called to refresh the layout of the slider. Can be used after resizing. - * + * * @return {Slider} A reference to the slider for chaining. */ layout() { - // set position //----------------- this.position.set(this.opts.x, this.opts.y) @@ -293,15 +307,14 @@ export default class Slider extends PIXI.Container { return this } - + /** * Draws the slider to the canvas. - * + * * @private * @return {Slider} A reference to the slider for chaining. */ draw() { - const r = this.radius const cr = this.opts.controlRadius const w = this.opts.width @@ -312,12 +325,16 @@ export default class Slider extends PIXI.Container { this.sliderObj.clear() this.sliderObj.beginFill(0xffffff, 0) this.sliderObj.drawRect(0, 0, x + w + cr, cr * 2) - this.sliderObj.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha) + this.sliderObj.lineStyle( + this.opts.strokeWidth, + this.opts.stroke, + this.opts.strokeAlpha + ) this.sliderObj.beginFill(this.opts.fill, this.opts.fillAlpha) this.sliderObj.moveTo(x, y) this.sliderObj.lineTo(x + w, y) this.sliderObj.arcTo(x + w + r, y, x + w + r, y + r, r) - this.sliderObj.lineTo(x + w + r, y + r + 1) // BUGFIX: If not specified, there is a small area without a stroke. + this.sliderObj.lineTo(x + w + r, y + r + 1) // BUGFIX: If not specified, there is a small area without a stroke. this.sliderObj.arcTo(x + w + r, y + h, x + w, y + h, r) this.sliderObj.lineTo(x, y + h) this.sliderObj.arcTo(x - r, y + h, x - r, y + r, r) @@ -326,10 +343,20 @@ export default class Slider extends PIXI.Container { // Draw control this.control.clear() - this.control.lineStyle(this.opts.controlStrokeWidth, this.opts.controlStroke, this.opts.controlStrokeAlpha) - this.control.beginFill(this.opts.controlFill, this.opts.controlFillAlpha) + this.control.lineStyle( + this.opts.controlStrokeWidth, + this.opts.controlStroke, + this.opts.controlStrokeAlpha + ) + this.control.beginFill( + this.opts.controlFill, + this.opts.controlFillAlpha + ) this.control.drawCircle(0, 0, cr - 1) - this.control.beginFill(this.opts.controlStroke, this.opts.controlStrokeAlpha) + this.control.beginFill( + this.opts.controlStroke, + this.opts.controlStrokeAlpha + ) this.control.drawCircle(0, 0, cr / 6) this.control.endFill() @@ -338,12 +365,11 @@ export default class Slider extends PIXI.Container { /** * Executed, when the slider control movement ended. - * + * * @private * @return {Slider} A reference to the slider for chaining. */ onEnd(e) { - if (this.control.dragging) { this.control.event = null this.control.dragging = false @@ -357,9 +383,9 @@ export default class Slider extends PIXI.Container { /** * Calculates the value for a given pixel. - * + * * @private - * @param {number} value + * @param {number} value * @returns {number} The calucalted pixel. */ valueToPixel(value) { @@ -368,14 +394,17 @@ export default class Slider extends PIXI.Container { } else if (value > this.opts.max) { value = this.opts.max } - return this.opts.width * (value - this.opts.min) / (this.opts.max - this.opts.min) + return ( + (this.opts.width * (value - this.opts.min)) / + (this.opts.max - this.opts.min) + ) } /** * Calculates the pixel for a given value. - * + * * @private - * @param {number} pixel + * @param {number} pixel * @returns {number} The calucalted value. */ pixelToValue(pixel) { @@ -384,12 +413,15 @@ export default class Slider extends PIXI.Container { } else if (pixel > this.opts.width) { pixel = this.opts.width } - return this.opts.min + ((this.opts.max - this.opts.min) * pixel / this.opts.width) + return ( + this.opts.min + + ((this.opts.max - this.opts.min) * pixel) / this.opts.width + ) } - + /** * Gets or sets the value. - * + * * @member {number} */ get value() { @@ -405,27 +437,26 @@ export default class Slider extends PIXI.Container { const x = this.valueToPixel(value) + this.opts.controlRadius - TweenLite.to(this.control, this.theme.fast, {x}) + TweenLite.to(this.control, this.theme.fast, { x }) } - + /** * Gets or sets the disabled state. When disabled, the slider cannot be clicked. - * + * * @member {boolean} */ get disabled() { return this._disabled } set disabled(value) { - this._disabled = value - + if (this._disabled) { this.interactive = false this.sliderObj.interactive = false this.control.interactive = false this.control.buttonMode = false - this.alpha = .5 + this.alpha = 0.5 } else { this.interactive = true this.sliderObj.interactive = true @@ -437,11 +468,10 @@ export default class Slider extends PIXI.Container { /** * Shows the slider (sets his alpha values to 1). - * + * * @return {Slider} A reference to the slider for chaining. */ show() { - this.opts.strokeAlpha = 1 this.opts.fillAlpha = 1 this.opts.controlStrokeAlpha = 1 @@ -451,14 +481,13 @@ export default class Slider extends PIXI.Container { return this } - + /** * Hides the slider (sets his alpha values to 1). - * + * * @return {Slider} A reference to the slider for chaining. */ hide() { - this.opts.strokeAlpha = 0 this.opts.fillAlpha = 0 this.opts.controlStrokeAlpha = 0 diff --git a/lib/pixi/stylus.js b/lib/pixi/stylus.js index 95d38c9..3307155 100755 --- a/lib/pixi/stylus.js +++ b/lib/pixi/stylus.js @@ -4,7 +4,6 @@ import Events from '../events.js' import { Angle } from '../utils.js' class StylusCommand extends Object { - constructor() { super() } @@ -23,7 +22,6 @@ class StylusCommand extends Object { } class StrokeCommand extends StylusCommand { - constructor(stroke) { super() this.stroke = stroke @@ -50,7 +48,6 @@ class StrokeCommand extends StylusCommand { } class ClearCommand extends StylusCommand { - do(stylus) { // Clears the command stack stylus.commandStack = [] @@ -71,20 +68,20 @@ class ClearCommand extends StylusCommand { } } - export default class Stylus extends PIXI.Graphics { - - constructor({ width = window.innerWidth, + constructor({ + width = window.innerWidth, height = window.innerHeight, interactive = true, color = 0x000000, tiltX = 0, tiltY = 0, backgroundAlpha = 1, - backgroundFill = 0xFFFFFF, + backgroundFill = 0xffffff, colorAlpha = 1, captureEvents = true, - acceptMouseEvents = true } = {}) { + acceptMouseEvents = true + } = {}) { super() this.activePointers = 0 this.wantedWidth = width @@ -95,16 +92,15 @@ export default class Stylus extends PIXI.Graphics { this.color = color this.interactive = interactive this.debug = false - this.tiltX = tiltX // degrees -90 ... 90 - this.tiltY = tiltY // degrees -90 ... 90 + this.tiltX = tiltX // degrees -90 ... 90 + this.tiltY = tiltY // degrees -90 ... 90 this.captureEvents = captureEvents this.commandStack = [] this.undoCommandStack = [] this.strokes = [] this.stroke = [] this.minStrokeLength = 4 - if (captureEvents) - this.registerEventHandler(acceptMouseEvents) + if (captureEvents) this.registerEventHandler(acceptMouseEvents) this.drawBackground() } @@ -121,9 +117,12 @@ export default class Stylus extends PIXI.Graphics { isStylusPointer(event) { let identifier = event.data.identifier - if (typeof (event.data.originalEvent.changedTouches) !== 'undefined') { + if (typeof event.data.originalEvent.changedTouches !== 'undefined') { for (let touch of event.data.originalEvent.changedTouches) { - if (touch.identifier === identifier && touch.touchType === 'stylus') { + if ( + touch.identifier === identifier && + touch.touchType === 'stylus' + ) { this.tiltX = Angle.radian2degree(touch.azimuthAngle) this.tiltY = 90.0 - Angle.radian2degree(touch.altitudeAngle) return true @@ -141,9 +140,12 @@ export default class Stylus extends PIXI.Graphics { isStylusTouch(event) { let identifier = event.data.identifier - if (typeof (event.data.originalEvent.changedTouches) !== 'undefined') { + if (typeof event.data.originalEvent.changedTouches !== 'undefined') { for (let touch of event.data.originalEvent.changedTouches) { - if (touch.identifier === identifier && touch.pointerType === 'touch') { + if ( + touch.identifier === identifier && + touch.pointerType === 'touch' + ) { return true } } @@ -165,25 +167,26 @@ export default class Stylus extends PIXI.Graphics { } registerEventHandler() { - window.addEventListener('keydown', (e) => { + window.addEventListener('keydown', e => { switch (e.keyCode) { - case 38: // up arrow - this.tiltX += 5 - break - case 40: // down arrow - this.tiltX -= 5 - break - case 37: // left arrow - this.tiltY -= 5 - break - case 39: // right arrow - this.tiltY += 5 - break + case 38: // up arrow + this.tiltX += 5 + break + case 40: // down arrow + this.tiltX -= 5 + break + case 37: // left arrow + this.tiltY -= 5 + break + case 39: // right arrow + this.tiltY += 5 + break } - if (this.debug) console.log('keydown', e.keyCode, this.tiltX, this.tiltY) + if (this.debug) + console.log('keydown', e.keyCode, this.tiltX, this.tiltY) }) - this.on('pointerdown', (e) => { + this.on('pointerdown', e => { if (this.debug) console.log('pointerdown', e) if (this.eventInside(e)) { this.activePointers += 1 @@ -193,14 +196,19 @@ export default class Stylus extends PIXI.Graphics { } }) - this.on('pointermove', (e) => { - if (Events.isPointerDown(e.data.originalEvent) || this.isStylusPointer(e) || this.isStylusTouch(e)) { - if (this.debug) console.log('pointermove', e, this.eventInside(e)) + this.on('pointermove', e => { + if ( + Events.isPointerDown(e.data.originalEvent) || + this.isStylusPointer(e) || + this.isStylusTouch(e) + ) { + if (this.debug) + console.log('pointermove', e, this.eventInside(e)) if (this.eventInside(e) && this.singlePointer()) this.moveStroke(this.toStroke(e)) } }) - this.on('pointerup', (e) => { + this.on('pointerup', e => { if (this.eventInside(e)) { if (this.activePointers > 0) { this.activePointers -= 1 @@ -209,13 +217,13 @@ export default class Stylus extends PIXI.Graphics { } if (this.debug) console.log('pointerup', this.activePointers) }) - this.on('pointerleave', (e) => { + this.on('pointerleave', e => { if (this.activePointers > 0) { this.activePointers -= 1 } this.endStroke(this.toStroke(e)) }) - this.on('pointercancel', (e) => { + this.on('pointercancel', e => { if (this.activePointers > 0) { this.activePointers -= 1 } @@ -246,7 +254,6 @@ export default class Stylus extends PIXI.Graphics { } eventInside(event) { - let local = this.toLocal(event.data.global) for (let child of this.children) { let r = child.getBounds() @@ -255,10 +262,8 @@ export default class Stylus extends PIXI.Graphics { return false } } - if (local.x < 0 || local.x > this.wantedWidth) - return false - if (local.y < 0 || local.y > this.wantedHeight) - return false + if (local.x < 0 || local.x > this.wantedWidth) return false + if (local.y < 0 || local.y > this.wantedHeight) return false event.stopPropagation() // if (this.debug) console.log('stopPropagation', event) if (event.data.originalEvent.claimedByScatter) { @@ -276,9 +281,11 @@ export default class Stylus extends PIXI.Graphics { let x = Math.max(0, Math.min(local.x, this.wantedWidth)) let y = Math.max(0, Math.min(local.y, this.wantedHeight)) let desc = { - x, y, + x, + y, pressure: event.pressure || null, - tiltX: this.tiltX, tiltY: this.tiltY, + tiltX: this.tiltX, + tiltY: this.tiltY, color: this.color } return desc @@ -313,8 +320,11 @@ export default class Stylus extends PIXI.Graphics { this.moveTo(start.x, start.y) for (let i = 1; i < stroke.length; i++) { let info = stroke[i] - this.lineStyle(this.tiltToLineWidth(info.tiltY), - info.color, this.colorAlpha) + this.lineStyle( + this.tiltToLineWidth(info.tiltY), + info.color, + this.colorAlpha + ) this.lineTo(info.x, info.y) } this.endFill() @@ -329,7 +339,7 @@ export default class Stylus extends PIXI.Graphics { drawStrokes() { this.drawBackground() - this.lineStyle(1.0, 0xFF0000, 1) + this.lineStyle(1.0, 0xff0000, 1) for (let stroke of this.iterStrokes()) { this.drawStroke(stroke) } diff --git a/lib/pixi/switch.js b/lib/pixi/switch.js index 80ac66b..fcb3ecf 100644 --- a/lib/pixi/switch.js +++ b/lib/pixi/switch.js @@ -35,7 +35,7 @@ import Tooltip from './tooltip.js' /** * Class that represents a PixiJS Switch. - * + * * @example * // Create the app * const app = new PIXIApp({ @@ -43,7 +43,7 @@ import Tooltip from './tooltip.js' * width: 900, * height: 250 * }).setup().run() - * + * * // Create the switch * const switch1 = new Switch({ * x: 10, @@ -59,10 +59,9 @@ import Tooltip from './tooltip.js' * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/switch.html|DocTest} */ export default class Switch extends PIXI.Container { - /** * Creates an instance of a Switch. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the switch. * @param {number} [opts.id=auto generated] - The id of the switch. @@ -102,56 +101,61 @@ export default class Switch extends PIXI.Container { * @param {beforeActionCallback} [opts.beforeAction] - Executed before an action is triggered. * @param {afterActionCallback} [opts.afterAction] - Executed after an action was triggered. * @param {string|object} [opts.tooltip] - A string for the label of the tooltip or an object to configure the tooltip - * to display. + * to display. * @param {boolean} [opts.visible=true] - Is the switch initially visible (property visible)? */ constructor(opts = {}) { - super() - + const theme = Theme.fromString(opts.theme) this.theme = theme - this.opts = Object.assign({}, { - id: PIXI.utils.uid(), - x: 0, - y: 0, - width: 44, - height: 28, - fill: theme.fill, - fillAlpha: theme.fillAlpha, - fillActive: theme.primaryColor, - fillActiveAlpha: theme.fillActiveAlpha, - stroke: theme.stroke, - strokeWidth: theme.strokeWidth, - strokeAlpha: theme.strokeAlpha, - strokeActive: theme.primaryColor, - strokeActiveWidth: theme.strokeActiveWidth, - strokeActiveAlpha: theme.strokeActiveAlpha, - controlFill: theme.stroke, - controlFillAlpha: theme.strokeAlpha, - controlFillActive: theme.stroke, - controlFillActiveAlpha: theme.strokeAlpha, - controlStroke: theme.stroke, - controlStrokeWidth: theme.strokeWidth * .8, - controlStrokeAlpha: theme.strokeAlpha, - controlStrokeActive: theme.stroke, - controlStrokeActiveWidth: theme.strokeActiveWidth * .8, - controlStrokeActiveAlpha: theme.strokeActiveAlpha, - duration: theme.fast, - durationActive: theme.fast, - disabled: false, - active: false, - action: null, - actionActive: null, - beforeAction: null, - afterAction: null, - tooltip: null, - visible: true - }, opts) + this.opts = Object.assign( + {}, + { + id: PIXI.utils.uid(), + x: 0, + y: 0, + width: 44, + height: 28, + fill: theme.fill, + fillAlpha: theme.fillAlpha, + fillActive: theme.primaryColor, + fillActiveAlpha: theme.fillActiveAlpha, + stroke: theme.stroke, + strokeWidth: theme.strokeWidth, + strokeAlpha: theme.strokeAlpha, + strokeActive: theme.primaryColor, + strokeActiveWidth: theme.strokeActiveWidth, + strokeActiveAlpha: theme.strokeActiveAlpha, + controlFill: theme.stroke, + controlFillAlpha: theme.strokeAlpha, + controlFillActive: theme.stroke, + controlFillActiveAlpha: theme.strokeAlpha, + controlStroke: theme.stroke, + controlStrokeWidth: theme.strokeWidth * 0.8, + controlStrokeAlpha: theme.strokeAlpha, + controlStrokeActive: theme.stroke, + controlStrokeActiveWidth: theme.strokeActiveWidth * 0.8, + controlStrokeActiveAlpha: theme.strokeActiveAlpha, + duration: theme.fast, + durationActive: theme.fast, + disabled: false, + active: false, + action: null, + actionActive: null, + beforeAction: null, + afterAction: null, + tooltip: null, + visible: true + }, + opts + ) - this.opts.controlRadius = this.opts.controlRadius || (this.opts.height / 2) - this.opts.controlRadiusActive = this.opts.controlRadiusActive || this.opts.controlRadius + this.opts.controlRadius = + this.opts.controlRadius || this.opts.height / 2 + this.opts.controlRadiusActive = + this.opts.controlRadiusActive || this.opts.controlRadius // Validation //----------------- @@ -170,7 +174,7 @@ export default class Switch extends PIXI.Container { this.switchObj = null this.control = null this.tooltip = null - + this.visible = this.opts.visible // animated @@ -197,15 +201,14 @@ export default class Switch extends PIXI.Container { //----------------- this.layout() } - + /** * Creates children and instantiates everything. - * + * * @private * @return {Switch} A reference to the switch for chaining. */ setup() { - // Switch //----------------- let switchObj = new PIXI.Graphics() @@ -216,7 +219,7 @@ export default class Switch extends PIXI.Container { //----------------- this.xInactive = this.opts.controlRadius this.xActive = this.opts.width - this.opts.controlRadiusActive - + let control = new PIXI.Graphics() control.x = this.opts.active ? this.xActive : this.xInactive control.y = this.opts.height / 2 @@ -224,23 +227,22 @@ export default class Switch extends PIXI.Container { this.control = control this.addChild(this.control) - + // interaction //----------------- this.switchObj.on('pointerover', e => { - TweenLite.to(this.control, this.theme.fast, {alpha: .83}) + TweenLite.to(this.control, this.theme.fast, { alpha: 0.83 }) }) this.switchObj.on('pointerout', e => { - TweenLite.to(this.control, this.theme.fast, {alpha: 1}) + TweenLite.to(this.control, this.theme.fast, { alpha: 1 }) }) this.switchObj.on('pointerdown', e => { - TweenLite.to(this.control, this.theme.fast, {alpha: .7}) + TweenLite.to(this.control, this.theme.fast, { alpha: 0.7 }) }) this.switchObj.on('pointerup', e => { - if (this.opts.beforeAction) { this.opts.beforeAction.call(this, e, this) } @@ -257,7 +259,7 @@ export default class Switch extends PIXI.Container { } } - TweenLite.to(this.control, this.theme.fast, {alpha: .83}) + TweenLite.to(this.control, this.theme.fast, { alpha: 0.83 }) if (this.opts.afterAction) { this.opts.afterAction.call(this, e, this) @@ -271,7 +273,7 @@ export default class Switch extends PIXI.Container { // active //----------------- this.active = this.opts.active - + // tooltip //----------------- if (this.opts.tooltip) { @@ -288,14 +290,13 @@ export default class Switch extends PIXI.Container { return this } - + /** * Should be called to refresh the layout of the switch. Can be used after resizing. - * + * * @return {Switch} A reference to the switch for chaining. */ layout() { - // set position //----------------- this.position.set(this.opts.x, this.opts.y) @@ -306,28 +307,50 @@ export default class Switch extends PIXI.Container { return this } - + /** * Draws the switch to the canvas. - * + * * @private * @return {Switch} A reference to the switch for chaining. */ draw() { - this.switchObj.clear() if (this.active) { - this.switchObj.lineStyle(this.opts.strokeActiveWidth, this.opts.strokeActive, this.opts.strokeActiveAlpha) - this.switchObj.beginFill(this.opts.fillActive, this.opts.fillActiveAlpha) + this.switchObj.lineStyle( + this.opts.strokeActiveWidth, + this.opts.strokeActive, + this.opts.strokeActiveAlpha + ) + this.switchObj.beginFill( + this.opts.fillActive, + this.opts.fillActiveAlpha + ) } else { - this.switchObj.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha) + this.switchObj.lineStyle( + this.opts.strokeWidth, + this.opts.stroke, + this.opts.strokeAlpha + ) this.switchObj.beginFill(this.opts.fill, this.opts.fillAlpha) } this.switchObj.moveTo(this.radius, 0) this.switchObj.lineTo(this.opts.width - this.radius, 0) - this.switchObj.arcTo(this.opts.width, 0, this.opts.width, this.radius, this.radius) - this.switchObj.lineTo(this.opts.width, this.radius + 1) // BUGFIX: If not specified, there is a small area without a stroke. - this.switchObj.arcTo(this.opts.width, this.opts.height, this.opts.width - this.radius, this.opts.height, this.radius) + this.switchObj.arcTo( + this.opts.width, + 0, + this.opts.width, + this.radius, + this.radius + ) + this.switchObj.lineTo(this.opts.width, this.radius + 1) // BUGFIX: If not specified, there is a small area without a stroke. + this.switchObj.arcTo( + this.opts.width, + this.opts.height, + this.opts.width - this.radius, + this.opts.height, + this.radius + ) this.switchObj.lineTo(this.radius, this.opts.height) this.switchObj.arcTo(0, this.opts.height, 0, this.radius, this.radius) this.switchObj.arcTo(0, 0, this.radius, 0, this.radius) @@ -336,52 +359,91 @@ export default class Switch extends PIXI.Container { // Draw control this.control.clear() if (this.active) { - this.control.lineStyle(this.opts.controlStrokeActiveWidth, this.opts.controlStrokeActive, this.opts.controlStrokeActiveAlpha) - this.control.beginFill(this.opts.controlFillActive, this.opts.controlFillActiveAlpha) + this.control.lineStyle( + this.opts.controlStrokeActiveWidth, + this.opts.controlStrokeActive, + this.opts.controlStrokeActiveAlpha + ) + this.control.beginFill( + this.opts.controlFillActive, + this.opts.controlFillActiveAlpha + ) this.control.drawCircle(0, 0, this.opts.controlRadiusActive - 1) } else { - this.control.lineStyle(this.opts.controlStrokeWidth, this.opts.controlStroke, this.opts.controlStrokeAlpha) - this.control.beginFill(this.opts.controlFill, this.opts.controlFillAlpha) + this.control.lineStyle( + this.opts.controlStrokeWidth, + this.opts.controlStroke, + this.opts.controlStrokeAlpha + ) + this.control.beginFill( + this.opts.controlFill, + this.opts.controlFillAlpha + ) this.control.drawCircle(0, 0, this.opts.controlRadius - 1) } this.control.endFill() return this } - + /** * Draws the animation. - * + * * @private * @return {Switch} A reference to the switch for chaining. */ drawAnimated() { - this.switchObj.clear() - this.switchObj.lineStyle(this.tempAnimated.strokeWidth, this.tempAnimated.stroke, this.tempAnimated.strokeAlpha) - this.switchObj.beginFill(this.tempAnimated.fill, this.tempAnimated.fillAlpha) + this.switchObj.lineStyle( + this.tempAnimated.strokeWidth, + this.tempAnimated.stroke, + this.tempAnimated.strokeAlpha + ) + this.switchObj.beginFill( + this.tempAnimated.fill, + this.tempAnimated.fillAlpha + ) this.switchObj.moveTo(this.radius, 0) this.switchObj.lineTo(this.opts.width - this.radius, 0) - this.switchObj.arcTo(this.opts.width, 0, this.opts.width, this.radius, this.radius) - this.switchObj.lineTo(this.opts.width, this.radius + 1) // BUGFIX: If not specified, there is a small area without a stroke. - this.switchObj.arcTo(this.opts.width, this.opts.height, this.opts.width - this.radius, this.opts.height, this.radius) + this.switchObj.arcTo( + this.opts.width, + 0, + this.opts.width, + this.radius, + this.radius + ) + this.switchObj.lineTo(this.opts.width, this.radius + 1) // BUGFIX: If not specified, there is a small area without a stroke. + this.switchObj.arcTo( + this.opts.width, + this.opts.height, + this.opts.width - this.radius, + this.opts.height, + this.radius + ) this.switchObj.lineTo(this.radius, this.opts.height) this.switchObj.arcTo(0, this.opts.height, 0, this.radius, this.radius) this.switchObj.arcTo(0, 0, this.radius, 0, this.radius) this.switchObj.endFill() this.control.clear() - this.control.lineStyle(this.tempAnimated.controlStrokeWidth, this.tempAnimated.controlStroke, this.tempAnimated.controlStrokeAlpha) - this.control.beginFill(this.tempAnimated.controlFill, this.tempAnimated.controlFillAlpha) + this.control.lineStyle( + this.tempAnimated.controlStrokeWidth, + this.tempAnimated.controlStroke, + this.tempAnimated.controlStrokeAlpha + ) + this.control.beginFill( + this.tempAnimated.controlFill, + this.tempAnimated.controlFillAlpha + ) this.control.drawCircle(0, 0, this.tempAnimated.controlRadius - 1) this.control.endFill() return this } - + /** * Gets or sets the active state. - * + * * @member {boolean} */ get active() { @@ -389,12 +451,10 @@ export default class Switch extends PIXI.Container { } set active(value) { - this._active = value if (this._active) { - - TweenLite.to(this.control, this.opts.duration, {x: this.xActive}) + TweenLite.to(this.control, this.opts.duration, { x: this.xActive }) TweenLite.to(this.tempAnimated, this.opts.duration, { colorProps: { fill: this.opts.fillActive, @@ -413,10 +473,10 @@ export default class Switch extends PIXI.Container { onUpdate: () => this.drawAnimated(), onComplete: () => this.draw() }) - - } else { - TweenLite.to(this.control, this.opts.durationActive, {x: this.xInactive}) + TweenLite.to(this.control, this.opts.durationActive, { + x: this.xInactive + }) TweenLite.to(this.tempAnimated, this.opts.durationActive, { colorProps: { fill: this.opts.fill, @@ -437,10 +497,10 @@ export default class Switch extends PIXI.Container { }) } } - + /** * Gets or sets the disabled state. When disabled, the switch cannot be clicked. - * + * * @member {boolean} */ get disabled() { @@ -448,14 +508,13 @@ export default class Switch extends PIXI.Container { } set disabled(value) { - this._disabled = value - + if (this._disabled) { this.switchObj.interactive = false this.switchObj.buttonMode = false - this.switchObj.alpha = .5 - this.control.alpha = .5 + this.switchObj.alpha = 0.5 + this.control.alpha = 0.5 } else { this.switchObj.interactive = true this.switchObj.buttonMode = true @@ -466,11 +525,10 @@ export default class Switch extends PIXI.Container { /** * Shows the switch (sets his alpha values to 1). - * + * * @return {Switch} A reference to the switch for chaining. */ show() { - this.opts.strokeAlpha = 1 this.opts.strokeActiveAlpha = 1 this.opts.fillAlpha = 1 @@ -484,14 +542,13 @@ export default class Switch extends PIXI.Container { return this } - + /** * Hides the switch (sets his alpha values to 1). - * + * * @return {Switch} A reference to the switch for chaining. */ hide() { - this.opts.strokeAlpha = 0 this.opts.strokeActiveAlpha = 0 this.opts.fillAlpha = 0 diff --git a/lib/pixi/test.js b/lib/pixi/test.js index aeed5af..92198e8 100755 --- a/lib/pixi/test.js +++ b/lib/pixi/test.js @@ -15,12 +15,11 @@ export class Command extends PIXI.Graphics { this.setup() } - setup() { - } + setup() {} draw() { this.clear() - var color = (this.selected) ? this.selectedColor : 0xFFFFFF + var color = this.selected ? this.selectedColor : 0xffffff this.lineStyle(0) this.beginFill(color, 1) this.drawShape(this.shape) @@ -108,7 +107,6 @@ export class StopCommand extends Command { } export class RecorderTools extends PIXI.Container { - constructor(renderer) { super(renderer) this.renderer = renderer @@ -122,7 +120,9 @@ export class RecorderTools extends PIXI.Container { setup(container) { // Since this delegate might shadow another delegate, we mus avoid // capturing PointerEvents. - this.delegate = new InteractionMapper(container, this, { capturePointerEvents: false }) + this.delegate = new InteractionMapper(container, this, { + capturePointerEvents: false + }) } findTarget(event, local, global) { @@ -131,13 +131,21 @@ export class RecorderTools extends PIXI.Container { setupToolbar() { this.toolbar = new PIXI.Graphics() - this.record = new RecordCommand(this, 0xCC0000, new PIXI.Circle(0, 0, 16)) - this.play = new PlayCommand(this, 0x0000CC, new PIXI.Polygon(0, 16, - 32, 16 + 16, - 0, 16 + 32, - 0, 16)) - this.stop = new StopCommand(this, 0x0000CC, - new PIXI.Rectangle(0, 0, 32, 32)) + this.record = new RecordCommand( + this, + 0xcc0000, + new PIXI.Circle(0, 0, 16) + ) + this.play = new PlayCommand( + this, + 0x0000cc, + new PIXI.Polygon(0, 16, 32, 16 + 16, 0, 16 + 32, 0, 16) + ) + this.stop = new StopCommand( + this, + 0x0000cc, + new PIXI.Rectangle(0, 0, 32, 32) + ) this.toolbar.addChild(this.record).position.set(44, 48) this.toolbar.addChild(this.play).position.set(44 + 44, 16) this.toolbar.addChild(this.stop).position.set(44 + 44 + 44 + 16, 32) @@ -149,7 +157,7 @@ export class RecorderTools extends PIXI.Container { var graphics = this.toolbar graphics.clear() graphics.beginFill(0x000000, 0.5) - graphics.lineStyle(2, 0xFFFFFF, 1) + graphics.lineStyle(2, 0xffffff, 1) graphics.drawRoundedRect(16, 16, 44 * 4 + 8, 64, 8) graphics.endFill() } @@ -175,7 +183,11 @@ export class RecorderTools extends PIXI.Container { mapPositionToPoint(point) { let local = new PIXI.Point() - this.renderer.plugins.interaction.mapPositionToPoint(local, point.x, point.y) + this.renderer.plugins.interaction.mapPositionToPoint( + local, + point.x, + point.y + ) return local } @@ -184,8 +196,7 @@ export class RecorderTools extends PIXI.Container { } capture(event) { - if (typeof event.mouseDownSubstitute != 'undefined') - return false + if (typeof event.mouseDownSubstitute != 'undefined') return false return true } @@ -226,8 +237,7 @@ export class RecorderTools extends PIXI.Container { let local = this.extractLocal(event) if (this.toolbar.containsPoint(local)) { this.onPress(local) - } - else { + } else { this.recordEvent(event) this.updateTouchGraphics(interaction) } @@ -244,9 +254,9 @@ export class RecorderTools extends PIXI.Container { } let p = current.get(key) if (key == 'mouse') { - graphics.beginFill(0xCC0000, 0.5) + graphics.beginFill(0xcc0000, 0.5) } else { - graphics.beginFill(0xCCCCCC, 0.5) + graphics.beginFill(0xcccccc, 0.5) } graphics.drawCircle(p.x, p.y, 20) } @@ -256,7 +266,6 @@ export class RecorderTools extends PIXI.Container { } export class AppTest extends PIXIApp { - constructor(canvas, container) { super({ view: canvas, backgroundColor: 0x000000 }) this.container = container @@ -277,7 +286,3 @@ export class AppTest extends PIXIApp { return this } } - - - - diff --git a/lib/pixi/theme.js b/lib/pixi/theme.js index 4dc01ca..313e3c0 100644 --- a/lib/pixi/theme.js +++ b/lib/pixi/theme.js @@ -31,7 +31,6 @@ * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/theme.html|DocTest} */ export default class Theme { - /** * Creates an instance of a Theme. * @@ -81,52 +80,86 @@ export default class Theme { * is used for large actived text. */ constructor(opts = {}) { + const colorPrimary = + opts.primaryColor != null ? opts.primaryColor : 0x5ec7f8 // blue + const color1 = opts.color1 != null ? opts.color1 : 0x282828 // black + const color2 = opts.color2 != null ? opts.color2 : 0xf6f6f6 // white - const colorPrimary = opts.primaryColor != null ? opts.primaryColor : 0x5ec7f8 // blue - const color1 = opts.color1 != null ? opts.color1 : 0x282828 // black - const color2 = opts.color2 != null ? opts.color2 : 0xf6f6f6 // white - - this.opts = Object.assign({}, { - margin: 12, - padding: 12, - radius: 4, - fast: .25, - normal: .5, - slow: 1, - primaryColor: colorPrimary, - color1: color1, - color2: color2, - fill: color1, - fillAlpha: 1, - fillActive: color1, - fillActiveAlpha: 1, - stroke: color2, - strokeWidth: .6, - strokeAlpha: 1, - strokeActive: color2, - strokeActiveWidth: .6, - strokeActiveAlpha: 1, - iconColor: color2, - iconColorActive: colorPrimary, - background: color1 - }, opts) + this.opts = Object.assign( + {}, + { + margin: 12, + padding: 12, + radius: 4, + fast: 0.25, + normal: 0.5, + slow: 1, + primaryColor: colorPrimary, + color1: color1, + color2: color2, + fill: color1, + fillAlpha: 1, + fillActive: color1, + fillActiveAlpha: 1, + stroke: color2, + strokeWidth: 0.6, + strokeAlpha: 1, + strokeActive: color2, + strokeActiveWidth: 0.6, + strokeActiveAlpha: 1, + iconColor: color2, + iconColorActive: colorPrimary, + background: color1 + }, + opts + ) // Set textStyle and variants - this.opts.textStyle = Object.assign({}, { - fontFamily: '"Avenir Next", "Open Sans", "Segoe UI", "Roboto", "Helvetica Neue", -apple-system, system-ui, BlinkMacSystemFont, Arial, sans-serif !default', - fontWeight: '500', - fontSize: 18, - fill: color2, - stroke: color1, - strokeThickness: 0, - miterLimit: 1, - lineJoin: 'round' - }, this.opts.textStyle) - this.opts.textStyleSmall = Object.assign({}, this.opts.textStyle, {fontSize: this.opts.textStyle.fontSize - 3}, this.opts.textStyleSmall) - this.opts.textStyleLarge = Object.assign({}, this.opts.textStyle, {fontSize: this.opts.textStyle.fontSize + 3}, this.opts.textStyleLarge) - this.opts.textStyleActive = Object.assign({}, this.opts.textStyle, {fill: this.opts.primaryColor}, this.opts.textStyleActive) - this.opts.textStyleSmallActive = Object.assign({}, this.opts.textStyleSmall, {fill: this.opts.primaryColor}, this.opts.textStyleSmallActive) - this.opts.textStyleLargeActive = Object.assign({}, this.opts.textStyleLarge, {fill: this.opts.primaryColor}, this.opts.textStyleLargeActive) + this.opts.textStyle = Object.assign( + {}, + { + fontFamily: + '"Avenir Next", "Open Sans", "Segoe UI", "Roboto", "Helvetica Neue", -apple-system, system-ui, BlinkMacSystemFont, Arial, sans-serif !default', + fontWeight: '500', + fontSize: 18, + fill: color2, + stroke: color1, + strokeThickness: 0, + miterLimit: 1, + lineJoin: 'round' + }, + this.opts.textStyle + ) + this.opts.textStyleSmall = Object.assign( + {}, + this.opts.textStyle, + { fontSize: this.opts.textStyle.fontSize - 3 }, + this.opts.textStyleSmall + ) + this.opts.textStyleLarge = Object.assign( + {}, + this.opts.textStyle, + { fontSize: this.opts.textStyle.fontSize + 3 }, + this.opts.textStyleLarge + ) + this.opts.textStyleActive = Object.assign( + {}, + this.opts.textStyle, + { fill: this.opts.primaryColor }, + this.opts.textStyleActive + ) + this.opts.textStyleSmallActive = Object.assign( + {}, + this.opts.textStyleSmall, + { fill: this.opts.primaryColor }, + this.opts.textStyleSmallActive + ) + this.opts.textStyleLargeActive = Object.assign( + {}, + this.opts.textStyleLarge, + { fill: this.opts.primaryColor }, + this.opts.textStyleLargeActive + ) Object.assign(this, this.opts) } @@ -139,7 +172,6 @@ export default class Theme { * @return {Theme} Returns a newly created Theme object. */ static fromString(theme) { - if (theme && typeof theme === 'object') { return theme } @@ -171,9 +203,7 @@ export default class Theme { * @extends Theme * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/theme.html|DocTest} */ -export class ThemeDark extends Theme { - -} +export class ThemeDark extends Theme {} /** * Class that represents a PixiJS ThemeLight. @@ -193,15 +223,13 @@ export class ThemeDark extends Theme { * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/theme.html|DocTest} */ export class ThemeLight extends Theme { - /** * Creates an instance of a ThemeLight. * * @constructor */ constructor() { - - super({color1: 0xf6f6f6, color2: 0x282828}) + super({ color1: 0xf6f6f6, color2: 0x282828 }) } } @@ -223,14 +251,12 @@ export class ThemeLight extends Theme { * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/theme.html|DocTest} */ export class ThemeRed extends Theme { - /** * Creates an instance of a ThemeRed. * * @constructor */ constructor() { - - super({primaryColor: 0xd92f31}) + super({ primaryColor: 0xd92f31 }) } } diff --git a/lib/pixi/timeline.js b/lib/pixi/timeline.js index 4896091..5f9f854 100644 --- a/lib/pixi/timeline.js +++ b/lib/pixi/timeline.js @@ -2,9 +2,7 @@ import { Cycle, Colors, Dates, isEmpty } from '../utils.js' import { Capabilities } from '../capabilities.js' import { BitmapLabeledGraphics, FontInfo } from './labeledgraphics.js' - export class Ticks { - get reservedPrefixes() { return ['decade', 'year', 'month', 'day', 'hour', 'minute', 'second'] } @@ -70,15 +68,19 @@ export class Ticks { visibleLast = end } } - if (first == null) - return info - return { start: first, end: last, visibleStart: visibleFirst, visibleEnd: visibleLast, units: units } + if (first == null) return info + return { + start: first, + end: last, + visibleStart: visibleFirst, + visibleEnd: visibleLast, + units: units + } } drawTick(timeline, x, y, date) { let visible = date > timeline.start && date < timeline.end - if (!visible) - return false + if (!visible) return false timeline.drawTick(x) return true } @@ -87,13 +89,24 @@ export class Ticks { return date.toLocaleDateString('de', format) } - draw(timeline, range, width, height, available, format, nextFormat, level, extraTicks=false) { + draw( + timeline, + range, + width, + height, + available, + format, + nextFormat, + level, + extraTicks = false + ) { let first = null let last = null - let keyedFormat = (format) ? format[this.formatKey] : null - let keyedNextFormat = (nextFormat) ? nextFormat[this.formatKey] : null - let redundant = (nextFormat) ? this.formatKey in nextFormat : false - let fullyRedundant = keyedFormat != null && keyedFormat == keyedNextFormat + let keyedFormat = format ? format[this.formatKey] : null + let keyedNextFormat = nextFormat ? nextFormat[this.formatKey] : null + let redundant = nextFormat ? this.formatKey in nextFormat : false + let fullyRedundant = + keyedFormat != null && keyedFormat == keyedNextFormat let y = timeline.getY() for (let { start, end } of this.iterRanges(range)) { let x = timeline.toX(start) @@ -110,31 +123,29 @@ export class Ticks { let nextX = timeline.toX(end) - 100 if (x < 0 && nextX > -100 && !redundant) { xx = Math.min(4, nextX) - } - else { + } else { xx -= 2 } - } - else if (level > 0) { + } else if (level > 0) { xx = x + available / 2 } - + if (!fullyRedundant) { - timeline.ensureLabel(key, text, + timeline.ensureLabel( + key, + text, { x: xx, y: yy, align }, - FontInfo.small) + FontInfo.small + ) } - if (extraTicks) - timeline.drawTick(x, -level) + if (extraTicks) timeline.drawTick(x, -level) } if (timeline.visibleRange(start, end)) { - if (first == null) - first = start + if (first == null) first = start last = end } } - if (first == null) - return null + if (first == null) return null return { start: first, end: last } } @@ -149,7 +160,6 @@ export class Ticks { } export class DecadeTicks extends Ticks { - get milliseconds() { return 10 * 365 * 24 * 60 * 60 * 1000 } @@ -182,14 +192,12 @@ export class DecadeTicks extends Ticks { } export class YearTicks extends Ticks { - get milliseconds() { return 365 * 24 * 60 * 60 * 1000 } format(available) { - if (available < 44) - return { year: '2-digit', timeZone: 'UTC' } + if (available < 44) return { year: '2-digit', timeZone: 'UTC' } return { year: 'numeric', timeZone: 'UTC' } } @@ -211,17 +219,14 @@ export class YearTicks extends Ticks { } export class MonthTicks extends Ticks { - get milliseconds() { return (365 / 12) * 24 * 60 * 60 * 1000 } format(available) { let format = { month: 'narrow', timeZone: 'UTC' } - if (available > 44) - format.month = 'short' - if (available > 66) - format.year = '2-digit' + if (available > 44) format.month = 'short' + if (available > 66) format.year = '2-digit' if (available > 100) { format.month = 'long' format.year = 'numeric' @@ -251,15 +256,13 @@ export class MonthTicks extends Ticks { } export class DayTicks extends Ticks { - get milliseconds() { return 24 * 60 * 60 * 1000 } format(available) { let format = { day: 'numeric', timeZone: 'UTC' } - if (available > 44) - format.month = 'short' + if (available > 44) format.month = 'short' if (available > 100) { format.month = 'long' format.year = '2-digit' @@ -283,7 +286,11 @@ export class DayTicks extends Ticks { } iterStart(start) { - return Dates.create(start.getFullYear(), start.getMonth(), start.getDate()) + return Dates.create( + start.getFullYear(), + start.getMonth(), + start.getDate() + ) } next(date) { @@ -292,7 +299,6 @@ export class DayTicks extends Ticks { } export class HourTicks extends Ticks { - get milliseconds() { return 60 * 60 * 1000 } @@ -325,17 +331,22 @@ export class HourTicks extends Ticks { } dateKey(date) { - return this.key + date.getFullYear() - + date.getMonth() - + date.getDate() - + date.getHours() + return ( + this.key + + date.getFullYear() + + date.getMonth() + + date.getDate() + + date.getHours() + ) } iterStart(start) { - return Dates.create(start.getFullYear(), + return Dates.create( + start.getFullYear(), start.getMonth(), start.getDate(), - start.getHours()) + start.getHours() + ) } next(date) { @@ -348,7 +359,6 @@ export class HourTicks extends Ticks { } export class MinuteTicks extends Ticks { - get milliseconds() { return 60 * 1000 } @@ -378,19 +388,24 @@ export class MinuteTicks extends Ticks { } dateKey(date) { - return this.key + date.getFullYear() - + date.getMonth() - + date.getDate() - + date.getHours() - + date.getMinutes() + return ( + this.key + + date.getFullYear() + + date.getMonth() + + date.getDate() + + date.getHours() + + date.getMinutes() + ) } iterStart(start) { - return Dates.create(start.getFullYear(), + return Dates.create( + start.getFullYear(), start.getMonth(), start.getDate(), start.getHours(), - start.getMinutes()) + start.getMinutes() + ) } next(date) { @@ -403,7 +418,6 @@ export class MinuteTicks extends Ticks { } export class TimeTicks { - constructor(...ticks) { this.ticks = ticks } @@ -435,9 +449,11 @@ export class TimeTicks { let amount = ticks.milliseconds / duration let available = amount * size availables.set(ticks, available) - if (available < ticks.minWidth) - break - formats.set(ticks, (available < ticks.minLabelWidth) ? null : ticks.format(available)) + if (available < ticks.minWidth) break + formats.set( + ticks, + available < ticks.minLabelWidth ? null : ticks.format(available) + ) nextFormats.set(previous, formats.get(ticks)) previous = ticks visible.push(ticks) @@ -445,21 +461,26 @@ export class TimeTicks { let level = 0 let ranges = [] for (let ticks of visible) { - if (range == null) - continue - range = ticks.draw(timeline, range, width, height, + if (range == null) continue + range = ticks.draw( + timeline, + range, + width, + height, availables.get(ticks), formats.get(ticks), - nextFormats.get(ticks), level) + nextFormats.get(ticks), + level + ) if (range) { - ranges.push({ticks, range}) + ranges.push({ ticks, range }) } level += 1 } let extraLevel = ranges.length - 1 let extraStart = extraLevel - for(let {ticks, range} of ranges) { + for (let { ticks, range } of ranges) { ticks.drawExtra(timeline, range, extraLevel) extraLevel -= 1 if (extraLevel <= 0) { @@ -475,7 +496,6 @@ export class TimeTicks { } export class ColorRanges { - constructor(label, color, ranges) { this.label = label this.color = color @@ -502,9 +522,16 @@ export class ColorRanges { } export default class Timeline extends BitmapLabeledGraphics { - - constructor(width, height, { ticks = null, - baseLine = 0.5, showRange = true, throwDamping = 0.95 } = {}) { + constructor( + width, + height, + { + ticks = null, + baseLine = 0.5, + showRange = true, + throwDamping = 0.95 + } = {} + ) { super() this.wantedWidth = width this.wantedHeight = height @@ -521,10 +548,12 @@ export default class Timeline extends BitmapLabeledGraphics { this.deltas = [] this.labelDates = [] this.colorRanges = [] - this.rangeColors = new Cycle(Colors.eminence, + this.rangeColors = new Cycle( + Colors.eminence, Colors.steelblue, Colors.ochre, - Colors.turquoise) + Colors.turquoise + ) this.callbacks = [] this.onTapCallbacks = [] this.onDoubleTapCallbacks = [] @@ -536,18 +565,21 @@ export default class Timeline extends BitmapLabeledGraphics { this.autoScroll = false this.direction = -1 this.throwDamping = throwDamping - this.timeticks = ticks || new TimeTicks(new DecadeTicks(), - new YearTicks(), - new MonthTicks(), - new DayTicks()) + this.timeticks = + ticks || + new TimeTicks( + new DecadeTicks(), + new YearTicks(), + new MonthTicks(), + new DayTicks() + ) this.labelPrefix = '__' } updateSelection() { if (this.visibleDate(this.start) && this.visibleDate(this.end)) { this.selection = [this.start, this.end] - } - else { + } else { this.timeticks.selectedRange(this) } @@ -593,8 +625,12 @@ export default class Timeline extends BitmapLabeledGraphics { let cr = this.colorRanges[i] let label = cr.label cr.draw(this, w, h) - let current = this.ensureLabel('colorRange:' + label, label, - { x: xx, y: yy, align: 'right' }, FontInfo.small) + let current = this.ensureLabel( + 'colorRange:' + label, + label, + { x: xx, y: yy, align: 'right' }, + FontInfo.small + ) let r = current.getBounds() xx -= r.width + 16 @@ -623,7 +659,7 @@ export default class Timeline extends BitmapLabeledGraphics { this.prepareLabels() this.updateColorRanges(w, h) - this.lineStyle(2, 0xFFFFFF) + this.lineStyle(2, 0xffffff) if (this.start != null && this.end != null) { this.moveTo(this.toX(this.start), y) this.lineTo(this.toX(this.end), y) @@ -631,32 +667,30 @@ export default class Timeline extends BitmapLabeledGraphics { this.updateSelection() let selected = this.selection if (selected[0] != this.start && selected[1] != this.end) { - if (this.showRange) - this.drawSelectedRamge(selected) + if (this.showRange) this.drawSelectedRamge(selected) } for (let callback of this.callbacks) { callback(this.scroll, this.zoom, this.selection) } - } - else { + } else { this.moveTo(this.inset, y) this.lineTo(w - this.inset, y) } if (this.progress != null && this.progress < 1) { - this.lineStyle(2, 0xCCCCFF) + this.lineStyle(2, 0xccccff) this.moveTo(this.inset, y) this.lineTo((w - this.inset) * this.progress, y) } } totalWidth(bounded = false) { - let w = this.wantedWidth - (2 * this.inset) + let w = this.wantedWidth - 2 * this.inset return w * this.validZoom(this.zoom, bounded) } validZoom(zoom, bounded = true) { - let overshoot = (bounded) ? 1.0 : 2.0 + let overshoot = bounded ? 1.0 : 2.0 zoom = Math.max(zoom, this.minZoom / overshoot) zoom = Math.min(zoom, this.maxZoom * overshoot) return zoom @@ -690,7 +724,7 @@ export default class Timeline extends BitmapLabeledGraphics { y = this.getY() } this.moveTo(x, y) - this.lineTo(x, y - (this.tickHeight * direction * this.direction)) + this.lineTo(x, y - this.tickHeight * direction * this.direction) } prepareLabels() { @@ -710,24 +744,22 @@ export default class Timeline extends BitmapLabeledGraphics { visibleDate(date, offset = 0) { if (date >= this.start && date <= this.end) { let x = this.toX(date) + offset - return (x > 0 && x < this.wantedWidth) + return x > 0 && x < this.wantedWidth } return false } visibleRange(start, end) { let x = this.toX(start) - if (x > this.wantedWidth) - return false + if (x > this.wantedWidth) return false x = this.toX(end) - if (x < 0) - return false + if (x < 0) return false return true } tickLabelOffset(direction = 1, level = 0) { let fs = FontInfo.small.fontSize - let dh = fs + (level * (fs + 2)) + let dh = fs + level * (fs + 2) return this.direction * direction * dh } @@ -740,12 +772,16 @@ export default class Timeline extends BitmapLabeledGraphics { let [label, date] = this.labelDates[i] let align = 'center' // (last == null) ? 'right' : 'left' let x = this.toX(date) - let current = this.ensureLabel(this.labelPrefix + label, label, + let current = this.ensureLabel( + this.labelPrefix + label, + label, { - x: x, y: y, + x: x, + y: y, align }, - FontInfo.small) + FontInfo.small + ) let r = current.getBounds() current.visible = !(last != null && r.x + r.width > last.x) if (current.visible) { @@ -753,12 +789,26 @@ export default class Timeline extends BitmapLabeledGraphics { last = r } } - } - else { - let start = this.start.toLocaleDateString('de', { year: 'numeric', month: 'numeric', day: 'numeric' }) - let end = this.end.toLocaleDateString('de', { year: 'numeric', month: 'numeric', day: 'numeric' }) - this.ensureLabel(this.labelPrefix + 'start', start, { x: this.toX(this.start), y: h2 }) - this.ensureLabel(this.labelPrefix + 'end', end, { x: this.toX(this.end), y: h2, align: 'right' }) + } else { + let start = this.start.toLocaleDateString('de', { + year: 'numeric', + month: 'numeric', + day: 'numeric' + }) + let end = this.end.toLocaleDateString('de', { + year: 'numeric', + month: 'numeric', + day: 'numeric' + }) + this.ensureLabel(this.labelPrefix + 'start', start, { + x: this.toX(this.start), + y: h2 + }) + this.ensureLabel(this.labelPrefix + 'end', end, { + x: this.toX(this.end), + y: h2, + align: 'right' + }) } } @@ -774,7 +824,7 @@ export default class Timeline extends BitmapLabeledGraphics { this.killTweens() this.deltas = [] this.validScroll() - if (typeof ThrowPropsPlugin != "undefined") { + if (typeof ThrowPropsPlugin != 'undefined') { ThrowPropsPlugin.track(this, 'delta') } } @@ -796,8 +846,7 @@ export default class Timeline extends BitmapLabeledGraphics { } onEnd(event, interaction) { - - if (typeof ThrowPropsPlugin != "undefined") { + if (typeof ThrowPropsPlugin != 'undefined') { let vel = ThrowPropsPlugin.getVelocity(this, 'delta') ThrowPropsPlugin.untrack(this) } @@ -815,33 +864,31 @@ export default class Timeline extends BitmapLabeledGraphics { let anchor = interaction.current.mean() this.keepInBounds(delta, anchor) - for(let key of interaction.ended.keys()) { + for (let key of interaction.ended.keys()) { if (interaction.isDoubleTap(key)) { this.onDoubleTap(event, interaction, key) - } - else if (interaction.isTap(key)) { + } else if (interaction.isTap(key)) { this.onTap(event, interaction, key) - } - else if (interaction.isLongPress(key)) { + } else if (interaction.isLongPress(key)) { this.onLongPress(event, interaction, key) } } } onLongPress(event, interaction, key) { - for(let callback of this.onLongPressCallbacks) { + for (let callback of this.onLongPressCallbacks) { callback(event, interaction, key) } } onTap(event, interaction, key) { - for(let callback of this.onTapCallbacks) { + for (let callback of this.onTapCallbacks) { callback(event, interaction, key) } } onDoubleTap(event, interaction, key) { - for(let callback of this.onDoubleTapCallbacks) { + for (let callback of this.onDoubleTapCallbacks) { callback(event, interaction, key) } } @@ -854,8 +901,7 @@ export default class Timeline extends BitmapLabeledGraphics { _scrollMaximum(bounded) { let total = this.totalWidth(bounded) let limit = this.wantedWidth - if (total > limit) - return 0 + if (total > limit) return 0 let w = limit - 2 * this.inset return (w - total) / 2 } @@ -873,7 +919,6 @@ export default class Timeline extends BitmapLabeledGraphics { this.autoScroll = false } - validScroll(bounded = true) { let minimum = this.scrollMinimum(bounded) let maximum = this.scrollMaximum(bounded) @@ -898,8 +943,7 @@ export default class Timeline extends BitmapLabeledGraphics { let newX = this.toX(date) tweens.scroll = this.scroll + anchor.x - newX this.zoom = oldZoom - } - else { + } else { if (this.zoom < this.minZoom) { tweens.zoom = this.minZoom } @@ -911,7 +955,9 @@ export default class Timeline extends BitmapLabeledGraphics { } } if (!isEmpty(tweens)) { - tweens.onUpdate = () => { this.redraw() } + tweens.onUpdate = () => { + this.redraw() + } TweenLite.to(this, 0.5, tweens).delay(0.1) return } @@ -928,15 +974,14 @@ export default class Timeline extends BitmapLabeledGraphics { let direction = event.detail < 0 || event.wheelDelta > 0 let anchor = { x: event.clientX, y: event.clientY } const zoomFactor = 1.5 - this.onZoom((direction) ? zoomFactor : 1 / zoomFactor, anchor) + this.onZoom(direction ? zoomFactor : 1 / zoomFactor, anchor) this.redraw() this.keepInBounds(0, anchor) } - showRanges(ranges, label = "Untitled", color = null) { + showRanges(ranges, label = 'Untitled', color = null) { for (let cr of this.colorRanges) { - if (cr.label == label) - return + if (cr.label == label) return } while (this.colorRanges.length >= this.rangeColors.length) { this.colorRanges.shift() @@ -945,4 +990,3 @@ export default class Timeline extends BitmapLabeledGraphics { this.redraw() } } - diff --git a/lib/pixi/tooltip.js b/lib/pixi/tooltip.js index 8e7613c..8127d84 100644 --- a/lib/pixi/tooltip.js +++ b/lib/pixi/tooltip.js @@ -3,7 +3,7 @@ import AbstractPopup from './abstractpopup.js' /** * Class that represents a PixiJS Tooltip. - * + * * @example * // Create the app * const app = new PIXIApp({ @@ -11,13 +11,13 @@ import AbstractPopup from './abstractpopup.js' * width: 900, * height: 250 * }).setup().run() - * + * * // Add an DisplayObject to the app * const circle = new PIXI.Graphics() * circle.beginFill(0x5251a3) * circle.drawCircle(50, 50, 40) * app.scene.addChild(circle) - * + * * const tooltip = new Tooltip({ * object: circle, * container: app.scene, @@ -29,10 +29,9 @@ import AbstractPopup from './abstractpopup.js' * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/tooltip.html|DocTest} */ export default class Tooltip extends AbstractPopup { - /** * Creates an instance of a Tooltip. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the tooltip. * @param {number} [opts.minWidth=0] - The minimum width of the tooltip. @@ -45,19 +44,22 @@ export default class Tooltip extends AbstractPopup { * @param {number} [opts.delay=0] - A delay, after which the tooltip should be opened. */ constructor(opts = {}) { - const theme = Theme.fromString(opts.theme) - - opts = Object.assign({}, { - minWidth: 0, - minHeight: 0, - padding: theme.padding / 2, - object: null, - container: null, - offsetLeft: 8, - offsetTop: -8, - delay: 0 - }, opts) + + opts = Object.assign( + {}, + { + minWidth: 0, + minHeight: 0, + padding: theme.padding / 2, + object: null, + container: null, + offsetLeft: 8, + offsetTop: -8, + delay: 0 + }, + opts + ) opts.container = opts.container || opts.object @@ -71,15 +73,14 @@ export default class Tooltip extends AbstractPopup { //----------------- this.layout() } - + /** * Creates children and instantiates everything. - * + * * @private * @return {Tooltip} A reference to the tooltip for chaining. */ setup() { - super.setup() // bind events this @@ -87,7 +88,7 @@ export default class Tooltip extends AbstractPopup { this.interactive = true let mouseoverTooltip = false - + this.on('mouseover', e => { mouseoverTooltip = true }) @@ -100,7 +101,7 @@ export default class Tooltip extends AbstractPopup { }) } }) - + // bind events object //----------------- const object = this.opts.object @@ -109,7 +110,6 @@ export default class Tooltip extends AbstractPopup { let mouseoverObject = false object.on('mouseover', e => { - this.timeout = window.setTimeout(() => { mouseoverObject = true this.visible = true @@ -136,15 +136,14 @@ export default class Tooltip extends AbstractPopup { return this } - + /** * Calculates and sets the position of the tooltip. - * + * * @private * @return {Tooltip} A reference to the tooltip for chaining. */ setPosition(e) { - const position = e.data.getLocalPosition(this.opts.container) this.x = position.x + this.opts.offsetLeft diff --git a/lib/pixi/volatile.js b/lib/pixi/volatile.js index 0172d6e..0dae247 100644 --- a/lib/pixi/volatile.js +++ b/lib/pixi/volatile.js @@ -4,14 +4,14 @@ import Theme from './theme.js' /** * Class that represents a PixiJS Volatile. - * + * * @example * const app = new PIXIApp({ * view: canvas, * width: 900, * height: 250 * }).setup().run() - * + * * const button = new Button({ * label: 'Volatile!', * action: () => { @@ -22,17 +22,16 @@ import Theme from './theme.js' * }) * } * }) - * + * * app.scene.addChild(button) * * @class * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/volatile.html|DocTest} */ export default class Volatile { - /** * Creates an instance of a Volatile. - * + * * @constructor * @param {object} [opts] - An options object to specify to style and behaviour of the modal. * @param {number} [opts.id=auto generated] - The id of the tooltip. @@ -46,21 +45,24 @@ export default class Volatile { * @param {boolean} [opts.destroyOnComplete=true] - Should the object be destroyed after the volatile animation? */ constructor(opts = {}) { - const theme = Theme.fromString(opts.theme) this.theme = theme - this.opts = Object.assign({}, { - id: PIXI.utils.uid(), - object: null, - direction: 'top', // top, right, bottom, left - onStart: null, - onComplete: null, - distance: 160, - duration: 1.5, - ease: Quad.easeOut, - destroyOnComplete: true - }, opts) + this.opts = Object.assign( + {}, + { + id: PIXI.utils.uid(), + object: null, + direction: 'top', // top, right, bottom, left + onStart: null, + onComplete: null, + distance: 160, + duration: 1.5, + ease: Quad.easeOut, + destroyOnComplete: true + }, + opts + ) this.id = this.opts.id @@ -82,38 +84,34 @@ export default class Volatile { //----------------- this.run() } - + /** * Creates children and instantiates everything. - * + * * @private * @return {Volatile} A reference to the volatile for chaining. */ setup() { - return this } - + /** * Should be called to refresh the layout of the volatile. Can be used after resizing. - * + * * @return {Volatile} A reference to the volatile for chaining. */ layout() { - return this } - + /** * Starts the volatile animation. - * + * * @private * @return {Volatile} A reference to the volatile for chaining. */ run() { - for (let object of this.objects) { - let x = object.x let y = object.y @@ -144,13 +142,12 @@ export default class Volatile { } }, onComplete: () => { - if (this.opts.onComplete) { this.opts.onComplete.call(object, object) } if (this.opts.destroyOnComplete) { - object.destroy({children: true}) + object.destroy({ children: true }) } } }) diff --git a/lib/poppable.js b/lib/poppable.js index 0550eae..db6224c 100644 --- a/lib/poppable.js +++ b/lib/poppable.js @@ -2,9 +2,8 @@ * shown. */ export default class Poppable { - /** Register the poppable element in a context. Closes previously registered ones. - * @param {*} context + * @param {*} context */ register(context) { let registered = Poppable.get(context) @@ -16,7 +15,7 @@ export default class Poppable { /** * Unregister object from context - * @param {*} context + * @param {*} context */ unregister(context) { Poppable.delete(context) @@ -33,20 +32,20 @@ export default class Poppable { return Poppable.registrations.get(context) } - /** Sets the poppable in the given context - * @static - * @param {*} context - * @param {*} poppable - * @returns - * @memberof Poppable - */ + /** Sets the poppable in the given context + * @static + * @param {*} context + * @param {*} poppable + * @returns + * @memberof Poppable + */ static set(context, poppable) { return Poppable.registrations.set(context, poppable) } /** Test whether a poppable exists in the given context - * - * @param {*} context + * + * @param {*} context */ static has(context) { return Poppable.registrations.has(context) @@ -65,8 +64,8 @@ export default class Poppable { /** All poppable must implement a close method. */ close() { - console.error("Must be implemented") + console.error('Must be implemented') } } -Poppable.registrations = new Map() \ No newline at end of file +Poppable.registrations = new Map() diff --git a/lib/popup.js b/lib/popup.js index 9a3c43a..b80f04e 100644 --- a/lib/popup.js +++ b/lib/popup.js @@ -1,5 +1,5 @@ -import { Elements } from "./utils.js" -import Poppable from "./poppable.js" +import { Elements } from './utils.js' +import Poppable from './poppable.js' /** A Popup that shows text labels, images, or html */ @@ -36,16 +36,16 @@ export default class Popup extends Poppable { parent = null, content = null, context = window, - fontSize = "1em", - fontFamily = "Arial", + fontSize = '1em', + fontFamily = 'Arial', padding = 16, notchSize = 10, switchPos = false, minWidth = null, maxWidth = 800, - backgroundColor = "#EEE", - normalColor = "#444", - notchPosition = "bottomCenter", + backgroundColor = '#EEE', + normalColor = '#444', + notchPosition = 'bottomCenter', zIndex = 0, keepWithin = null, autoClose = true, @@ -60,7 +60,7 @@ export default class Popup extends Poppable { onResize = null, onMove = null, noStyle = false, - hideOnUp = true, + hideOnUp = true } = {}) { super() this.context = context @@ -108,38 +108,38 @@ export default class Popup extends Poppable { //console.log("Popup.setup", this.draggable) this.content = content this.items = {} - this.element = document.createElement("div") - this.element.classList.add("popup") + this.element = document.createElement('div') + this.element.classList.add('popup') this.setAlpha(this.element, 0) // this.element.style.opacity = 0 - Elements.addClass(this.element, "unselectable") - this.notch = document.createElement("div") + Elements.addClass(this.element, 'unselectable') + this.notch = document.createElement('div') Elements.setStyle(this.notch, this.notchStyle()) - this.notch.className = "notch" + this.notch.className = 'notch' this.setupDraggable() if (this.closeIcon) { - let img = document.createElement("img") - img.setAttribute("draggable", false) + let img = document.createElement('img') + img.setAttribute('draggable', false) img.src = this.closeIcon - img.style.position = "absolute" - img.style.right = "0px" - img.style.top = "0px" - img.style.width = "16px" - img.style.height = "16px" + img.style.position = 'absolute' + img.style.right = '0px' + img.style.top = '0px' + img.style.width = '16px' + img.style.height = '16px' img.onclick = e => { this.close() } this.element.appendChild(img) } if (this.resizeIcon) { - let img = document.createElement("img") - img.style.position = "absolute" - img.style.right = "0px" - img.style.bottom = "0px" - img.style.width = "16px" - img.style.height = "16px" + let img = document.createElement('img') + img.style.position = 'absolute' + img.style.right = '0px' + img.style.bottom = '0px' + img.style.width = '16px' + img.style.height = '16px' img.src = this.resizeIcon - img.setAttribute("draggable", true) + img.setAttribute('draggable', true) img.ondragstart = e => { this.currentPos = { x: e.clientX, y: e.clientY } return true @@ -147,27 +147,27 @@ export default class Popup extends Poppable { img.ondrag = e => { e.preventDefault() - let target = this.element.querySelector("iframe") || this.element + let target = + this.element.querySelector('iframe') || this.element let delta = { x: e.clientX - this.currentPos.x, y: e.clientY - this.currentPos.y } this.currentPos = { x: e.clientX, y: e.clientY } - if (delta.x == 0 && delta.y == 0) - return + if (delta.x == 0 && delta.y == 0) return let rect = target.getBoundingClientRect() let width = rect.width + delta.x let height = rect.height + delta.y - target.style.width = width + "px" - target.style.height = height + "px" + target.style.width = width + 'px' + target.style.height = height + 'px' switch (this.notchPosition) { - case "bottomLeft": - case "bottomCenter": + case 'bottomLeft': + case 'bottomCenter': let bottom = parseFloat(this.element.style.bottom) - this.element.style.bottom = bottom - delta.y + "px" + this.element.style.bottom = bottom - delta.y + 'px' break default: break @@ -177,31 +177,30 @@ export default class Popup extends Poppable { this.onResize({ target, delta, width, height }) } } - img.ondragend = e => { } + img.ondragend = e => {} this.element.appendChild(img) } - for (let key in content) { switch (key) { - case "selector": + case 'selector': break - case "text": - let text = document.createElement("span") + case 'text': + let text = document.createElement('span') this.element.appendChild(text) text.innerHTML = content[key] Elements.setStyle(text, { color: this.normalColor }) - Elements.addClass(text, "unselectable") - Elements.addClass(text, "PopupContent") + Elements.addClass(text, 'unselectable') + Elements.addClass(text, 'PopupContent') this.insertedNode = text this.loaded = true break - case "img": - alert("img to be implemented") + case 'img': + alert('img to be implemented') break - case "iframe": - let iframe = document.createElement("iframe") - iframe.setAttribute("frameBorder", 0) + case 'iframe': + let iframe = document.createElement('iframe') + iframe.setAttribute('frameBorder', 0) iframe.src = content[key] iframe.onload = e => { let body = iframe.contentWindow.document.body @@ -216,8 +215,8 @@ export default class Popup extends Poppable { }) let w = Math.max(body.scrollWidth, body.offsetWidth) let h = Math.max(body.scrollHeight, body.offsetHeight) - iframe.style.width = w + "px" - iframe.style.height = h + "px" + iframe.style.width = w + 'px' + iframe.style.height = h + 'px' this.layoutAfterInsert() if (this.onload != null) { this.onload() @@ -225,13 +224,13 @@ export default class Popup extends Poppable { this.loaded = true } this.element.appendChild(iframe) - Elements.addClass(iframe, "PopupContent") + Elements.addClass(iframe, 'PopupContent') this.insertIntoDOM() return - case "html": + case 'html': this.loaded = false - let div = document.createElement("div") - Elements.addClass(div, "PopupContent") + let div = document.createElement('div') + Elements.addClass(div, 'PopupContent') this.element.appendChild(div) div.innerHTML = content.html //console.log("insert", content) @@ -242,8 +241,7 @@ export default class Popup extends Poppable { div.innerHTML = `

Popup content not found. Missing ${selector}

` this.insertedNode = div.firstElementChild } - } - else { + } else { this.insertedNode = div.firstElementChild || div } this.setAlpha(this.insertedNode, 0) @@ -252,9 +250,12 @@ export default class Popup extends Poppable { if (images.length > 0) { let count = 0 for (let image of images) { - if (!image.complete && !image.src.startsWith('data:')) { + if ( + !image.complete && + !image.src.startsWith('data:') + ) { total += 1 - console.log("image not complete", image.src) + console.log('image not complete', image.src) image.onload = e => { count += 1 if (count == total) { @@ -271,15 +272,15 @@ export default class Popup extends Poppable { this.loaded = true } break - case "node": + case 'node': this.loaded = true - Elements.addClass(content.node, "PopupContent") + Elements.addClass(content.node, 'PopupContent') this.element.appendChild(content.node) this.insertedNode = content.node this.setAlpha(this.insertedNode, 0) break default: - alert("Unexpected content type: " + key) + alert('Unexpected content type: ' + key) break } } @@ -293,8 +294,7 @@ export default class Popup extends Poppable { let closing = this.closingEvent(e) if (closing) { this.close() - } - else { + } else { this.setupCloseHandler() } } @@ -303,18 +303,36 @@ export default class Popup extends Poppable { let close = this.handleClose if (this.hideOnUp) { if (window.PointerEvent) - this.parent.addEventListener("pointerup", close.bind(this), { capture: true, once: true }) + this.parent.addEventListener('pointerup', close.bind(this), { + capture: true, + once: true + }) else if (window.TouchEvent) - this.parent.addEventListener("touchend", close.bind(this), { capture: true, once: true }) + this.parent.addEventListener('touchend', close.bind(this), { + capture: true, + once: true + }) else - this.parent.addEventListener("mouseup", close.bind(this), { capture: true, once: true }) + this.parent.addEventListener('mouseup', close.bind(this), { + capture: true, + once: true + }) } else { if (window.PointerEvent) - this.parent.addEventListener("pointerdown", close.bind(this), { capture: true, once: true }) + this.parent.addEventListener('pointerdown', close.bind(this), { + capture: true, + once: true + }) else if (window.TouchEvent) - this.parent.addEventListener("touchstart", close.bind(this), { capture: true, once: true }) + this.parent.addEventListener('touchstart', close.bind(this), { + capture: true, + once: true + }) else - this.parent.addEventListener("mousedown", close.bind(this), { capture: true, once: true }) + this.parent.addEventListener('mousedown', close.bind(this), { + capture: true, + once: true + }) } } @@ -326,7 +344,7 @@ export default class Popup extends Poppable { closingEvent(e) { if (this.interactive) { - let node = e.target.closest(".PopupContent") + let node = e.target.closest('.PopupContent') return node == null } return true @@ -336,18 +354,19 @@ export default class Popup extends Poppable { let body = iframe.contentWindow.document.body let w = Math.max(body.scrollWidth, body.offsetWidth) let h = Math.max(body.scrollHeight, body.offsetHeight) - iframe.style.width = w + "px" - iframe.style.height = h + "px" + iframe.style.width = w + 'px' + iframe.style.height = h + 'px' } setupDraggable() { if (this.draggable) { let target = this.element - target.setAttribute("draggable", true) + target.setAttribute('draggable', true) target.ondragstart = e => { this.currentPos = { x: e.clientX, y: e.clientY } var img = document.createElement('img') - img.src = 'data:image/gifbase64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' + img.src = + 'data:image/gifbase64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' e.dataTransfer.setDragImage(img, 0, 0) } target.ondrag = e => { @@ -378,9 +397,7 @@ export default class Popup extends Poppable { } } - moveDragged(target) { - - } + moveDragged(target) {} insertIntoDOM(layout = true) { this.setAlpha(this.insertedNode, 0) @@ -396,8 +413,7 @@ export default class Popup extends Poppable { /** Layout the menu items. Needed only in the subclass. */ - layout() { } - + layout() {} remove() { if (this.parent.contains(this.element)) @@ -412,8 +428,7 @@ export default class Popup extends Poppable { this.unregister(this.context) if (this.closeCommand) { this.closeCommand(this, () => this.remove()) - } - else { + } else { this.remove() } } @@ -427,10 +442,10 @@ export default class Popup extends Poppable { * @memberof Popup */ setAlpha(targets, value) { - let objs = (targets instanceof Array) ? targets : [targets] + let objs = targets instanceof Array ? targets : [targets] for (let obj of objs) { if (value) { - obj.style.transition = "opacity 0.2s ease-in" + obj.style.transition = 'opacity 0.2s ease-in' } obj.style.opacity = value } @@ -459,12 +474,11 @@ export default class Popup extends Poppable { */ showAt(content, point) { this.setup(content) - console.log("showAt", this.loaded) + console.log('showAt', this.loaded) if (this.loaded) { this.placeAt(point) this.fadeIn() - } - else { + } else { this.setAlpha([this.element, this.insertedNode], 0) this.onload = () => { this.layoutAfterInsert() @@ -483,7 +497,7 @@ export default class Popup extends Poppable { * @memberof Popup */ placeOrigin(x, y) { - Elements.setStyle(this.element, { left: x + "px", top: y + "px" }) + Elements.setStyle(this.element, { left: x + 'px', top: y + 'px' }) } /** @@ -523,25 +537,24 @@ export default class Popup extends Poppable { * @memberof Popup */ notchPositionWithin(x, y) { - let horizontal = "Center" - let vertical = "center" + let horizontal = 'Center' + let vertical = 'center' let { width, height } = this.withinDimensions() let local = this.localPointWithin(x, y, width, height) if (local.y < height * 0.33) { - vertical = "top" + vertical = 'top' } if (local.y > height * 0.66) { - vertical = "bottom" + vertical = 'bottom' } if (local.x < width * 0.33) { - horizontal = "Left" + horizontal = 'Left' } if (local.x > width * 0.66) { - horizontal = "Right" + horizontal = 'Right' } let result = vertical + horizontal - if (result == "centerCenter") - return this.notchPosition + if (result == 'centerCenter') return this.notchPosition return result } @@ -553,37 +566,39 @@ export default class Popup extends Poppable { notchPosition = this.notchPositionWithin(x, y) } Elements.setStyle(this.notch, this.notchStyle(notchPosition)) - this.notch.className = "notch " + notchPosition + this.notch.className = 'notch ' + notchPosition let { width, height } = this.localDimensions() //if targetBoundingBox is set, popup is placed next to the rectangle if (this.targetBoundingBox) { let bbTop = this.targetBoundingBox.y - let bbBottom = this.targetBoundingBox.y + this.targetBoundingBox.height + let bbBottom = + this.targetBoundingBox.y + this.targetBoundingBox.height let bbLeft = this.targetBoundingBox.x - let bbRight = this.targetBoundingBox.x + this.targetBoundingBox.width + let bbRight = + this.targetBoundingBox.x + this.targetBoundingBox.width //console.log("place popup with bb set:", x, y, bbTop, bbBottom, bbLeft, bbRight) switch (notchPosition) { - case "bottomLeft": - case "bottomRight": - case "bottomCenter": + case 'bottomLeft': + case 'bottomRight': + case 'bottomCenter': y = bbTop if (!this.useEventPosWithBoundingBox) x = (bbLeft + bbRight) / 2 break - case "topLeft": - case "topRight": - case "topCenter": + case 'topLeft': + case 'topRight': + case 'topCenter': y = bbBottom if (!this.useEventPosWithBoundingBox) x = (bbLeft + bbRight) / 2 break - case "centerRight": + case 'centerRight': x = bbLeft if (!this.useEventPosWithBoundingBox) y = (bbTop + bbBottom) / 2 break - case "centerLeft": + case 'centerLeft': x = bbRight if (!this.useEventPosWithBoundingBox) y = (bbTop + bbBottom) / 2 @@ -595,14 +610,14 @@ export default class Popup extends Poppable { //calculate position depending on several (optional) parameters switch (notchPosition) { - case "bottomLeft": + case 'bottomLeft': x -= this.padding x -= this.notchSize y -= height y -= this.notchSize * 2 y -= this.posOffset break - case "bottomRight": + case 'bottomRight': x -= width x += this.padding x += this.notchSize @@ -610,36 +625,36 @@ export default class Popup extends Poppable { y -= this.notchSize * 2 y -= this.posOffset break - case "bottomCenter": + case 'bottomCenter': x -= width / 2 y -= height y -= this.notchSize * 2 y -= this.posOffset break - case "topLeft": + case 'topLeft': x -= this.padding x -= this.notchSize y += this.notchSize * 2 y += this.posOffset break - case "topRight": + case 'topRight': x -= width x += this.padding x += this.notchSize y += this.notchSize * 2 y += this.posOffset break - case "topCenter": + case 'topCenter': x -= width / 2 y += this.notchSize * 2 y += this.posOffset break - case "centerRight": + case 'centerRight': x -= width + this.notchSize * 2 x -= this.posOffset y -= height / 2 break - case "centerLeft": + case 'centerLeft': //console.log("height", height) y -= height / 2 x += this.notchSize * 2 @@ -667,23 +682,23 @@ export default class Popup extends Poppable { defaultStyle() { let padding = this.padding let style = { - maxWidth: this.maxWidth + "px", + maxWidth: this.maxWidth + 'px', zIndex: this.zIndex, - position: "absolute", + position: 'absolute' } if (this.minWidth) { - style.minWidth = this.minWidth + "px" + style.minWidth = this.minWidth + 'px' } if (!this.noStyle) { Object.assign(style, { - borderRadius: Math.round(this.padding / 2) + "px", + borderRadius: Math.round(this.padding / 2) + 'px', backgroundColor: this.backgroundColor, - padding: this.padding + "px", - boxShadow: "0 10px 15px rgba(0, 0, 0, 0.3)", + padding: this.padding + 'px', + boxShadow: '0 10px 15px rgba(0, 0, 0, 0.3)', fontFamily: this.fontFamily, fontSize: this.fontSize, - stroke: "black", - fill: "white" + stroke: 'black', + fill: 'white' }) } @@ -700,58 +715,58 @@ export default class Popup extends Poppable { let height = 0 let left = this.padding let size = this.localDimensions() - if (notchPosition.endsWith("Right")) { + if (notchPosition.endsWith('Right')) { left = size.width - this.padding - this.notchSize * 2 } - if (notchPosition.endsWith("Center")) { + if (notchPosition.endsWith('Center')) { left = size.width / 2 - this.notchSize } left = Math.round(left) + 'px' let borderBottom = 0 let borderTop = 0 - if (notchPosition.startsWith("bottom")) { + if (notchPosition.startsWith('bottom')) { if (this.noStyle) { return { width, height, left, - bottom: -this.notchSize + "px", - position: "absolute", - borderStyle: "solid", - borderTopWidth: this.notchSize + "px", - borderRight: this.notchSize + "px solid transparent", - borderLeft: this.notchSize + "px solid transparent", + bottom: -this.notchSize + 'px', + position: 'absolute', + borderStyle: 'solid', + borderTopWidth: this.notchSize + 'px', + borderRight: this.notchSize + 'px solid transparent', + borderLeft: this.notchSize + 'px solid transparent', borderBottom: 0 } - } else { return { width, height, left, - boxShadow: "0 12px 15px rgba(0, 0, 0, 0.1)", - bottom: -this.notchSize + "px", - position: "absolute", - borderTop: this.notchSize + "px solid " + this.backgroundColor, - borderRight: this.notchSize + "px solid transparent", - borderLeft: this.notchSize + "px solid transparent", + boxShadow: '0 12px 15px rgba(0, 0, 0, 0.1)', + bottom: -this.notchSize + 'px', + position: 'absolute', + borderTop: + this.notchSize + 'px solid ' + this.backgroundColor, + borderRight: this.notchSize + 'px solid transparent', + borderLeft: this.notchSize + 'px solid transparent', borderBottom: 0 } } } - if (notchPosition.startsWith("top")) { + if (notchPosition.startsWith('top')) { if (this.noStyle) { return { width, height, left, - top: -this.notchSize + "px", - position: "absolute", - borderStyle: "solid", - borderBottomWidth: this.notchSize + "px", - borderRight: this.notchSize + "px solid transparent", - borderLeft: this.notchSize + "px solid transparent", + top: -this.notchSize + 'px', + position: 'absolute', + borderStyle: 'solid', + borderBottomWidth: this.notchSize + 'px', + borderRight: this.notchSize + 'px solid transparent', + borderLeft: this.notchSize + 'px solid transparent', borderTop: 0 } } else { @@ -759,31 +774,29 @@ export default class Popup extends Poppable { width, height, left, - top: -this.notchSize + "px", - position: "absolute", - borderBottom: this.notchSize + "px solid " + this.backgroundColor, - borderRight: this.notchSize + "px solid transparent", - borderLeft: this.notchSize + "px solid transparent", + top: -this.notchSize + 'px', + position: 'absolute', + borderBottom: + this.notchSize + 'px solid ' + this.backgroundColor, + borderRight: this.notchSize + 'px solid transparent', + borderLeft: this.notchSize + 'px solid transparent', borderTop: 0 } } } if (this.noStyle) { - - if (notchPosition.endsWith("Left")) { - left = -this.notchSize * 2 + "px" + if (notchPosition.endsWith('Left')) { + left = -this.notchSize * 2 + 'px' } - if (notchPosition.endsWith("Right")) { - left = size.width + "px" + if (notchPosition.endsWith('Right')) { + left = size.width + 'px' } - let top = size.height / 2 - this.notchSize top = Math.round(top) + 'px' - return { width, height, @@ -791,29 +804,30 @@ export default class Popup extends Poppable { top, borderRightWidth: this.notchSize, borderLeftWidth: this.notchSize, - position: "absolute", - borderTop: this.notchSize + "px solid transparent", - borderBottom: this.notchSize + "px solid transparent" + position: 'absolute', + borderTop: this.notchSize + 'px solid transparent', + borderBottom: this.notchSize + 'px solid transparent' } - } else { - let borderRight = this.notchSize + "px solid transparent" - let borderLeft = this.notchSize + "px solid transparent" + let borderRight = this.notchSize + 'px solid transparent' + let borderLeft = this.notchSize + 'px solid transparent' let top = size.height / 2 - this.notchSize - if (notchPosition.endsWith("Left")) { - left = -this.notchSize * 2 + "px" - borderRight = this.notchSize + "px solid " + this.backgroundColor - this.element.style.boxShadow = "15px 10px 15px rgba(0, 0, 0, 0.3)" + if (notchPosition.endsWith('Left')) { + left = -this.notchSize * 2 + 'px' + borderRight = + this.notchSize + 'px solid ' + this.backgroundColor + this.element.style.boxShadow = + '15px 10px 15px rgba(0, 0, 0, 0.3)' } - if (notchPosition.endsWith("Right")) { - left = size.width + "px" - borderLeft = this.notchSize + "px solid " + this.backgroundColor - this.element.style.boxShadow = "15px 5px 15px rgba(0, 0, 0, 0.3)" + if (notchPosition.endsWith('Right')) { + left = size.width + 'px' + borderLeft = this.notchSize + 'px solid ' + this.backgroundColor + this.element.style.boxShadow = + '15px 5px 15px rgba(0, 0, 0, 0.3)' } top = Math.round(top) + 'px' - return { width, height, @@ -822,9 +836,9 @@ export default class Popup extends Poppable { borderRight, borderLeft, // boxShadow, - position: "absolute", - borderTop: this.notchSize + "px solid transparent", - borderBottom: this.notchSize + "px solid transparent" + position: 'absolute', + borderTop: this.notchSize + 'px solid transparent', + borderBottom: this.notchSize + 'px solid transparent' } } } @@ -842,16 +856,16 @@ export default class Popup extends Poppable { { parent = null, context = window, - fontSize = "1em", - fontFamily = "Arial", + fontSize = '1em', + fontFamily = 'Arial', padding = 16, notchSize = 10, switchPos = false, minWidth = null, maxWidth = 800, - backgroundColor = "#EEE", + backgroundColor = '#EEE', zIndex = 0, - normalColor = "#444", + normalColor = '#444', closeIcon = null, resizeIcon = null, closeCommand = null, @@ -866,9 +880,8 @@ export default class Popup extends Poppable { onMove = null } = {} ) { - - - let notchPosition = (switchPos && point.y < 50) ? "topCenter" : "bottomCenter" + let notchPosition = + switchPos && point.y < 50 ? 'topCenter' : 'bottomCenter' let popup = new Popup({ parent, context, diff --git a/lib/popupmenu.js b/lib/popupmenu.js index e373f0a..9c1f76f 100644 --- a/lib/popupmenu.js +++ b/lib/popupmenu.js @@ -6,21 +6,22 @@ import { Elements } from './utils.js' */ export default class PopupMenu extends Popup { /** - * The constructor. - * @constructor - * @param {DOM Element} parent - The DOM parent element. - * @param {Object} commands - A dict object with command label strings as keys - * and command functions as values. - * @param {string} fontSize - Describes the font size as CSS value - * @param {number || string} padding - Describes the padding as CSS value - * @param {number || string} notchSize - Describes the size of the notch (callout) as CSS value - * @param {string} highlightColor - The color of highlighted menu items as CSS value - * @param {string} backgroundColor - The color of the background as CSS value - * @param {string} normalColor - The color of normal menu items as CSS value - * @param {DOM Element} keepWithin - The container to stay within - * @param {boolean} autoClose - Autoclose the menu after selecting an item - */ - constructor({ parent = null, + * The constructor. + * @constructor + * @param {DOM Element} parent - The DOM parent element. + * @param {Object} commands - A dict object with command label strings as keys + * and command functions as values. + * @param {string} fontSize - Describes the font size as CSS value + * @param {number || string} padding - Describes the padding as CSS value + * @param {number || string} notchSize - Describes the size of the notch (callout) as CSS value + * @param {string} highlightColor - The color of highlighted menu items as CSS value + * @param {string} backgroundColor - The color of the background as CSS value + * @param {string} normalColor - The color of normal menu items as CSS value + * @param {DOM Element} keepWithin - The container to stay within + * @param {boolean} autoClose - Autoclose the menu after selecting an item + */ + constructor({ + parent = null, commands = null, fontSize = '1em', fontFamily = 'Arial', @@ -35,8 +36,20 @@ export default class PopupMenu extends Popup { highlightColor = 'black', notchPosition = 'bottomLeft', keepWithin = null, - autoClose = true } = {}) { - super({ parent, fontSize, fontFamily, padding, notchSize, notchPosition, backgroundColor, keepWithin, normalColor, autoClose }) + autoClose = true + } = {}) { + super({ + parent, + fontSize, + fontFamily, + padding, + notchSize, + notchPosition, + backgroundColor, + keepWithin, + normalColor, + autoClose + }) this.commands = commands this.zIndex = zIndex this.switchPos = switchPos @@ -50,7 +63,6 @@ export default class PopupMenu extends Popup { * @return {PopupMenu} this */ setup(commands) { - this.commands = commands this.items = {} this.element = document.createElement('div') @@ -63,14 +75,25 @@ export default class PopupMenu extends Popup { this.element.appendChild(item) item.innerHTML = key item.style.paddingBottom = item.style.paddingTop = this.spacing - Elements.setStyle(item, { color: this.normalColor, cursor: 'default' }) + Elements.setStyle(item, { + color: this.normalColor, + cursor: 'default' + }) Elements.addClass(item, 'unselectable') Elements.addClass(item, 'popupMenuItem') this.items[key] = item - item.onclick = (event) => { this.perform(key) } - item.ontap = (event) => { this.perform(key) } - item.onmouseover = (event) => { this.over(event, key) } - item.onmouseout = (event) => { this.out(event, key) } + item.onclick = event => { + this.perform(key) + } + item.ontap = event => { + this.perform(key) + } + item.onmouseover = event => { + this.over(event, key) + } + item.onmouseout = event => { + this.out(event, key) + } } this.element.appendChild(this.notch) @@ -100,7 +123,7 @@ export default class PopupMenu extends Popup { */ update(key, highlight = false) { let text = this.items[key] - text.style.color = (highlight) ? this.highlightColor : this.normalColor + text.style.color = highlight ? this.highlightColor : this.normalColor } /** Mouse over handöer. @@ -126,7 +149,7 @@ export default class PopupMenu extends Popup { * and command functions as values. * @param {Point} point - The position as x, y coordinates {px}. * @return {PopupMenu} this - */ + */ showAt(commands, point) { this.show(commands) this.placeAt(point) @@ -146,44 +169,71 @@ export default class PopupMenu extends Popup { * @param {string} normalColor - The color of normal menu items as CSS value * @param {boolean} autoClose - Autoclose the menu after selecting an item */ - static open(commands, point, { parent = null, - context = window, - fontSize = '1em', - fontFamily = 'Arial', - padding = 16, - zIndex = 1, - spacing = '0px', - switchPos = false, - notchSize = 10, - maxWidth = 800, - keepWithin = null, - backgroundColor = '#EEE', - normalColor = '#444', - autoClose = true } = {}) { - + static open( + commands, + point, + { + parent = null, + context = window, + fontSize = '1em', + fontFamily = 'Arial', + padding = 16, + zIndex = 1, + spacing = '0px', + switchPos = false, + notchSize = 10, + maxWidth = 800, + keepWithin = null, + backgroundColor = '#EEE', + normalColor = '#444', + autoClose = true + } = {} + ) { let registered = Poppable.get(context) if (registered) { this.closePopup() return } - console.log("open", point) - let notchPosition = (point.y < 50 && switchPos) ? 'topCenter' : 'bottomCenter' + console.log('open', point) + let notchPosition = + point.y < 50 && switchPos ? 'topCenter' : 'bottomCenter' let popup = new PopupMenu({ - parent, fontSize, padding, zIndex, spacing, switchPos, notchSize, + parent, + fontSize, + padding, + zIndex, + spacing, + switchPos, + notchSize, notchPosition, - maxWidth, backgroundColor, normalColor, - notchPosition, keepWithin, autoClose + maxWidth, + backgroundColor, + normalColor, + notchPosition, + keepWithin, + autoClose }) popup.showAt(commands, point) popup.register(context) - popup.closeEventListener = (e) => { - if (this.eventOutside(e)) - this.closePopup(context) + popup.closeEventListener = e => { + if (this.eventOutside(e)) this.closePopup(context) } if (autoClose) { - context.addEventListener('mousedown', popup.closeEventListener, true) - context.addEventListener('touchstart', popup.closeEventListener, true) - context.addEventListener('pointerdown', popup.closeEventListener, true) + context.addEventListener( + 'mousedown', + popup.closeEventListener, + true + ) + context.addEventListener( + 'touchstart', + popup.closeEventListener, + true + ) + context.addEventListener( + 'pointerdown', + popup.closeEventListener, + true + ) } } @@ -194,13 +244,22 @@ export default class PopupMenu extends Popup { /** Convenient static methods to close the PopupMenu implemented * as a class variable. */ - static closePopup(context=window) { + static closePopup(context = window) { let registered = Poppable.get(context) if (registered) { registered.close() - context.removeEventListener('mousedown', registered.closeEventListener) - context.removeEventListener('touchstart', registered.closeEventListener) - context.removeEventListener('pointerdown', registered.closeEventListener) + context.removeEventListener( + 'mousedown', + registered.closeEventListener + ) + context.removeEventListener( + 'touchstart', + registered.closeEventListener + ) + context.removeEventListener( + 'pointerdown', + registered.closeEventListener + ) } } } diff --git a/lib/scatter.js b/lib/scatter.js index 79c3cc8..c29c22a 100644 --- a/lib/scatter.js +++ b/lib/scatter.js @@ -9,16 +9,11 @@ import { Capabilities } from './capabilities.js' /** This interface allows scatters to delegate tap events to other objects. */ export class ITapDelegate extends Interface { - /** This method must be defined by the delegate. It handles the tap event. */ - tap(event) { - - } + tap(event) {} /** Tells the delegate that it should handle standard click events. */ - handleClicks() { - - } + handleClicks() {} } /** @@ -70,7 +65,7 @@ export class ScatterEvent extends BaseEvent { toString() { return ( - 'Event(\'scatterTransformed\', scale: ' + + "Event('scatterTransformed', scale: " + this.scale + ' about: ' + this.about.x + @@ -145,7 +140,12 @@ class Throwable { // Avoid division by zero errors later on // and consider the number of involved pointers sind addVelocity will be called by the // onMove events - let velocity = { t: t, dt: dt, dx: delta.x / delta.number, dy: delta.y / delta.number } + let velocity = { + t: t, + dt: dt, + dx: delta.x / delta.number, + dy: delta.y / delta.number + } this.velocities.push(velocity) while (this.velocities.length > buffer) { this.velocities.shift() @@ -241,8 +241,8 @@ class Throwable { // damping, collison detection, etc. here let next = Points.multiplyScalar(velocity, this.throwDamping) return { - x: (this.movableX) ? next.x : 0, - y: (this.movableY) ? next.y : 0 + x: this.movableX ? next.x : 0, + y: this.movableY ? next.y : 0 } } @@ -283,7 +283,7 @@ export class AbstractScatter extends Throwable { onClose = null, onThrowFinished = null, scaleAutoClose = false, - scaleCloseThreshold = 0.10, + scaleCloseThreshold = 0.1, scaleCloseBuffer = 0.05, maxRotation = Angle.degree2radian(5), useLowPassFilter = true @@ -305,7 +305,7 @@ export class AbstractScatter extends Throwable { }) /** - * Closes the card when the minScale is reached and the + * Closes the card when the minScale is reached and the * card is released. Card can be saved by scaling it up again. */ this.scaleAutoClose = scaleAutoClose @@ -387,7 +387,7 @@ export class AbstractScatter extends Throwable { if (this.useLowPassFilter) { rotate = this.rotateLPF.next(rotate) zoom = this.zoomLPF.next(zoom) - // console.log({rotate, zoom}) + // console.log({rotate, zoom}) } this.transform(delta, zoom, rotate, delta.about) if (zoom != 1) this.interactionAnchor = delta.about @@ -395,8 +395,8 @@ export class AbstractScatter extends Throwable { } get polygon() { - let w2 = this.width * this.scale / 2 - let h2 = this.height * this.scale / 2 + let w2 = (this.width * this.scale) / 2 + let h2 = (this.height * this.scale) / 2 let center = this.center let polygon = new Polygon(center) polygon.addPoint({ x: -w2, y: -h2 }) @@ -409,11 +409,9 @@ export class AbstractScatter extends Throwable { isOutside() { let stagePolygon = this.containerPolygon - if (stagePolygon == null) - return false + if (stagePolygon == null) return false let polygon = this.polygon - if (polygon == null) - return false + if (polygon == null) return false let result = stagePolygon.intersectsWith(polygon) return result === false || result.overlap < this.throwVisibility } @@ -456,7 +454,7 @@ export class AbstractScatter extends Throwable { keepOnStage(velocity, collision = 0.5) { let stagePolygon = this.containerPolygon - // UO: since keepOnStage is called in nextVelocity we need to + // UO: since keepOnStage is called in nextVelocity we need to // ensure a return value if (!stagePolygon) return { x: 0, y: 0 } let polygon = this.polygon @@ -498,10 +496,18 @@ export class AbstractScatter extends Throwable { _checkAutoClose() { if (this.scaleAutoClose) - if (this.scale < this.minScale + this.scaleCloseThreshold - this.scaleCloseBuffer) { - this.zoom(this.minScale, { animate: 0.2, onComplete: this.close.bind(this) }) + if ( + this.scale < + this.minScale + this.scaleCloseThreshold - this.scaleCloseBuffer + ) { + this.zoom(this.minScale, { + animate: 0.2, + onComplete: this.close.bind(this) + }) } else if (this.scale < this.minScale + this.scaleCloseThreshold) { - this.zoom(this.minScale + this.scaleCloseThreshold, { animate: 0.4 }) + this.zoom(this.minScale + this.scaleCloseThreshold, { + animate: 0.4 + }) } } @@ -600,7 +606,7 @@ export class AbstractScatter extends Throwable { fast: false, type: UPDATE }) - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event) }) } @@ -609,9 +615,15 @@ export class AbstractScatter extends Throwable { let origin = this.rotationOrigin let beta = Points.angle(origin, anchor) let distance = Points.distance(origin, anchor) - let { scale: newScale, zoom: thresholdedZoom } = this.calculateScale(zoom) + let { scale: newScale, zoom: thresholdedZoom } = this.calculateScale( + zoom + ) - let newOrigin = Points.arc(anchor, beta + rotate, distance * thresholdedZoom) + let newOrigin = Points.arc( + anchor, + beta + rotate, + distance * thresholdedZoom + ) let extra = Points.subtract(newOrigin, origin) let offset = Points.subtract(anchor, origin) this._move(offset) @@ -631,7 +643,7 @@ export class AbstractScatter extends Throwable { rotate: rotate, about: anchor }) - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event) }) } @@ -643,7 +655,7 @@ export class AbstractScatter extends Throwable { /** * For a given zoom, a new scale is calculated, taking * min and max scale into account. - * + * * @param {number} zoom - The zoom factor, to scale the object with. * @returns {object} - Returns an object containing the a value for a valid scale and the corrected zoom factor. */ @@ -661,8 +673,7 @@ export class AbstractScatter extends Throwable { zoom = scale / this.scale } - if (this.scaleAutoClose) - this._updateTransparency() + if (this.scaleAutoClose) this._updateTransparency() return { zoom, scale } } @@ -675,8 +686,10 @@ export class AbstractScatter extends Throwable { } calculateScaleTransparency() { - let transparency = (this.scale - this.minScale) / this.scaleCloseThreshold - transparency = (transparency > 1) ? 1 : (transparency < 0) ? 0 : transparency + let transparency = + (this.scale - this.minScale) / this.scaleCloseThreshold + transparency = + transparency > 1 ? 1 : transparency < 0 ? 0 : transparency return transparency } @@ -693,7 +706,7 @@ export class AbstractScatter extends Throwable { animateZoomBounce(dt = 1) { if (this.zoomAnchor != null) { let zoom = 1 - let amount = Math.min(0.01, 0.3 * dt / 100000.0) + let amount = Math.min(0.01, (0.3 * dt) / 100000.0) if (this.scale < this.minScale) zoom = 1 + amount if (this.scale > this.maxScale) zoom = 1 - amount if (zoom != 1) { @@ -734,8 +747,8 @@ export class AbstractScatter extends Throwable { if (this.scaleAutoClose) { if (this.scale <= this.minScale + this.scaleCloseThreshold) { - - if (this.scaleAutoCloseTimeout) clearTimeout(this.scaleAutoCloseTimeout) + if (this.scaleAutoCloseTimeout) + clearTimeout(this.scaleAutoCloseTimeout) this.scaleAutoCloseTimeout = setTimeout(() => { this._checkAutoClose() }, 600) @@ -745,7 +758,6 @@ export class AbstractScatter extends Throwable { } onStart(event, interaction) { - if (this.startGesture(interaction)) { this.dragging = true this.interactionAnchor = null @@ -759,7 +771,7 @@ export class AbstractScatter extends Throwable { fast: false, type: START }) - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event) }) } @@ -794,7 +806,7 @@ export class AbstractScatter extends Throwable { fast: false, type: END }) - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event) }) } @@ -805,7 +817,7 @@ export class AbstractScatter extends Throwable { } } - onTap(event, interaction, point) { } + onTap(event, interaction, point) {} onDragUpdate(delta) { if (this.onTransform != null) { @@ -816,7 +828,7 @@ export class AbstractScatter extends Throwable { about: this.currentAbout, type: null }) - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event) }) } @@ -830,7 +842,7 @@ export class AbstractScatter extends Throwable { fast: false, type: null }) - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event) }) } @@ -844,7 +856,7 @@ export class AbstractScatter extends Throwable { fast: true, type: null }) - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event) }) } @@ -857,16 +869,14 @@ export class AbstractScatter extends Throwable { fast: false, type: null }) - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event) }) } } onZoomed(about) { - - if (this.scaleAutoClose) - this._updateTransparency() + if (this.scaleAutoClose) this._updateTransparency() if (this.onTransform != null) { let event = new ScatterEvent(this, { @@ -875,7 +885,7 @@ export class AbstractScatter extends Throwable { fast: false, type: null }) - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event) }) } @@ -901,7 +911,13 @@ export class DOMScatterContainer { */ constructor( element, - { stopEvents = 'auto', claimEvents = true, useCapture = true, touchAction = 'none', debugCanvas = null } = {} + { + stopEvents = 'auto', + claimEvents = true, + useCapture = true, + touchAction = 'none', + debugCanvas = null + } = {} ) { this.onCapture = null this.element = element @@ -1015,7 +1031,10 @@ export class DOMScatterContainer { ***/ let found = document.elementFromPoint(global.x, global.y) for (let target of this.scatter.values()) { - if (target.interactive && this.isDescendant(target.element, found)) { + if ( + target.interactive && + this.isDescendant(target.element, found) + ) { if (this.stopEvents) Events.stop(event) if (this.claimEvents) event.claimedByScatter = target return target @@ -1049,8 +1068,6 @@ export class DOMScatterContainer { } } - - export class DOMScatter extends AbstractScatter { constructor( element, @@ -1074,7 +1091,7 @@ export class DOMScatter extends AbstractScatter { x = 0, y = 0, width = null, // required - height = null, // required + height = null, // required resizable = false, tapDelegate = null, triggerSVGClicks = false, @@ -1087,7 +1104,7 @@ export class DOMScatter extends AbstractScatter { autoThrow = true, scaleAutoClose = false, onClose = null, - scaleCloseThreshold = 0.10, + scaleCloseThreshold = 0.1, scaleCloseBuffer = 0.05, useLowPassFilter = true, maxRotation = Angle.degree2radian(15) @@ -1147,7 +1164,7 @@ export class DOMScatter extends AbstractScatter { transformOrigin: transformOrigin } this.tapNodes = new Map() - + // For tweenlite we need initial values in _gsTransform TweenLite.set(element, this.initialValues) this.onResize = onResize @@ -1166,15 +1183,15 @@ export class DOMScatter extends AbstractScatter { button.className = 'interactiveElement' this.element.appendChild(button) - button.addEventListener('pointerdown', (e) => { + button.addEventListener('pointerdown', e => { this.startResize(e) }) - button.addEventListener('pointermove', (e) => { + button.addEventListener('pointermove', e => { this.resize(e) }) - button.addEventListener('pointerup', (e) => { + button.addEventListener('pointerup', e => { this.stopResize(e) }) this.resizeButton = button @@ -1344,7 +1361,7 @@ export class DOMScatter extends AbstractScatter { onTap(event, interaction, point) { if (this.tapDelegate) { Events.stop(event) - this.tapDelegate.tap(event, "scatter") + this.tapDelegate.tap(event, 'scatter') } } @@ -1396,12 +1413,18 @@ export class DOMScatter extends AbstractScatter { e.preventDefault() let event = new CustomEvent('resizeStarted') - let oldPostition = { x: this.element.getBoundingClientRect().left, y: this.element.getBoundingClientRect().top } + let oldPostition = { + x: this.element.getBoundingClientRect().left, + y: this.element.getBoundingClientRect().top + } this.bringToFront() this.element.style.transformOrigin = '0% 0%' - let newPostition = { x: this.element.getBoundingClientRect().left, y: this.element.getBoundingClientRect().top } + let newPostition = { + x: this.element.getBoundingClientRect().left, + y: this.element.getBoundingClientRect().top + } let offset = Points.subtract(oldPostition, newPostition) @@ -1424,23 +1447,31 @@ export class DOMScatter extends AbstractScatter { rotation = (rotation + 360) % 360 let event = new CustomEvent('resized') if (e.target.getAttribute('resizing') == 'true') { - - let deltaX = (e.clientX - this.oldX) - let deltaY = (e.clientY - this.oldY) + let deltaX = e.clientX - this.oldX + let deltaY = e.clientY - this.oldY let r = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2)) let phi = Angle.radian2degree(Math.atan2(deltaX, deltaY)) - phi = ((phi) + 630) % 360 - let rot = ((rotation + 90) + 630) % 360 + phi = (phi + 630) % 360 + let rot = (rotation + 90 + 630) % 360 - let diffAngle = ((0 + rot) + 360) % 360 + let diffAngle = (0 + rot + 360) % 360 let phiCorrected = (phi + diffAngle + 360) % 360 let resizeW = r * Math.cos(Angle.degree2radian(phiCorrected)) let resizeH = -r * Math.sin(Angle.degree2radian(phiCorrected)) - if ((this.element.offsetWidth + resizeW) / this.scale > this.width * 0.5 / this.scale && (this.element.offsetHeight + resizeH) / this.scale > this.height * 0.3 / this.scale) TweenLite.to(this.element, 0, { width: this.element.offsetWidth + resizeW / this.scale, height: this.element.offsetHeight + resizeH / this.scale }) + if ( + (this.element.offsetWidth + resizeW) / this.scale > + (this.width * 0.5) / this.scale && + (this.element.offsetHeight + resizeH) / this.scale > + (this.height * 0.3) / this.scale + ) + TweenLite.to(this.element, 0, { + width: this.element.offsetWidth + resizeW / this.scale, + height: this.element.offsetHeight + resizeH / this.scale + }) this.oldX = e.clientX this.oldY = e.clientY @@ -1454,9 +1485,15 @@ export class DOMScatter extends AbstractScatter { e.preventDefault() let event = new CustomEvent('resizeEnded') - let oldPostition = { x: this.element.getBoundingClientRect().left, y: this.element.getBoundingClientRect().top } + let oldPostition = { + x: this.element.getBoundingClientRect().left, + y: this.element.getBoundingClientRect().top + } this.element.style.transformOrigin = '50% 50%' - let newPostition = { x: this.element.getBoundingClientRect().left, y: this.element.getBoundingClientRect().top } + let newPostition = { + x: this.element.getBoundingClientRect().left, + y: this.element.getBoundingClientRect().top + } let offset = Points.subtract(oldPostition, newPostition) TweenLite.to(this.element, 0, { css: { left: '+=' + offset.x + 'px' } }) diff --git a/lib/uitest.js b/lib/uitest.js index 342ab7e..573d0dd 100644 --- a/lib/uitest.js +++ b/lib/uitest.js @@ -16,7 +16,7 @@ * * // Add an action to the test case * test.tap(button, {eventType: 'click'}) - * + * * // Start the test case * test.start() * @@ -24,10 +24,9 @@ * @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/uitest.html|DocTest} */ export default class UITest { - /** * Creates an instance of an UITest. - * + * * In the background, the class UITest uses the Greensock TimelineMax class. The opts object is passed directly to the TimelineMax class, so it can use any key that uses the TimelineMax class. * * @constructor @@ -38,19 +37,28 @@ export default class UITest { * @param {number} [opts.defaultInterval] - The interval used when no action is specified for an action. */ constructor(opts = {}) { - - this.opts = Object.assign({}, { - timeScale: 1, - eventType: 'auto', - debug: false, - defaultInterval: null - }, opts) + this.opts = Object.assign( + {}, + { + timeScale: 1, + eventType: 'auto', + debug: false, + defaultInterval: null + }, + opts + ) // timeline //-------------------- - this._timeline = new TimelineMax(Object.assign({}, { - paused: true - }, this.opts)) + this._timeline = new TimelineMax( + Object.assign( + {}, + { + paused: true + }, + this.opts + ) + ) this._timeline.timeScale(this.opts.timeScale) // eventType @@ -118,7 +126,7 @@ export default class UITest { /** * Clears all instructions of the test case. - * + * * @return {UITest} A reference to the UITest for chaining. */ clear() { @@ -128,7 +136,7 @@ export default class UITest { /** * Restarts the test case. - * + * * @return {UITest} A reference to the UITest for chaining. */ restart() { @@ -138,7 +146,7 @@ export default class UITest { /** * Executes a tap event (pointerdown, pointerup) on a specific element. - * + * * @param {HTMLElement|string} element - The HTML element on which the event is to be executed, e.g. button, document, h2, canvas, etc. or an selector string. If a selector has been specified, it is evaluated immediately before the event is called using the querySelector method. * @param {number[]|object|PIXI.DisplayObject} [position=The center of the element.] - The local position of the event in the context of the specified HTML element. If no position is specified, the center of the HTML element is used. The position can be specified as an array of numbers, as an object with the two properties x and y, or as a PIXI.Display object. * @param {number} [timelinePosition=One second after the last action.] - The position in seconds when the event should be triggered, see shttps://greensock.com/docs/TimelineMax/addCallback(). @@ -152,91 +160,118 @@ export default class UITest { * @param {boolean} [opts.cancelable=true] - Events' cancelable property indicates if the event can be canceled, and therefore prevented as if the event never happened. If the event is not cancelable, then its cancelable property will be false and the event listener cannot stop the event from occurring. */ tap(element, position, timelinePosition, opts = {}) { - // arguments //-------------------- - [position, timelinePosition, opts] = this.reorderArguments(arguments) + ;[position, timelinePosition, opts] = this.reorderArguments(arguments) this._timelinePositions.push(timelinePosition) // debug //-------------------- - if (this.opts.debug) console.log('tap params', {element, position, timelinePosition, opts}) + if (this.opts.debug) + console.log('tap params', { + element, + position, + timelinePosition, + opts + }) // opts //-------------------- - opts = Object.assign({}, { - onStart: null, - onComplete: null, - eventTypes: this.resolveEvents(['down', 'up']), - eventType: null, - context: window, - bubbles: true, - cancelable: true - }, opts) + opts = Object.assign( + {}, + { + onStart: null, + onComplete: null, + eventTypes: this.resolveEvents(['down', 'up']), + eventType: null, + context: window, + bubbles: true, + cancelable: true + }, + opts + ) if (opts.eventType) { opts.eventTypes = opts.eventType } - opts.eventTypes = Array.isArray(opts.eventTypes) ? opts.eventTypes : [opts.eventTypes] + opts.eventTypes = Array.isArray(opts.eventTypes) + ? opts.eventTypes + : [opts.eventTypes] // timeline //-------------------- - this._timeline.addCallback(position => { + this._timeline.addCallback( + position => { + // element + //-------------------- + const elem = Util.extractElement(opts.context, element) - // element - //-------------------- - const elem = Util.extractElement(opts.context, element) + // position + //-------------------- + if (position === null) { + const rect = elem.getBoundingClientRect() + position = [rect.width / 2, rect.height / 2] + } - // position - //-------------------- - if (position === null) { - const rect = elem.getBoundingClientRect() - position = [rect.width / 2, rect.height / 2] - } + // coords + //-------------------- + const coords = Util.extractPosition(position) + if (this.opts.debug) console.log('local coords', coords) - // coords - //-------------------- - const coords = Util.extractPosition(position) - if (this.opts.debug) console.log('local coords', coords) + // eventTypes + //-------------------- + if (opts.eventTypes.length === 1) { + opts.eventTypes.unshift(null) + } - // eventTypes - //-------------------- - if (opts.eventTypes.length === 1) { - opts.eventTypes.unshift(null) - } + // event opts + //-------------------- + const eventOpts = { + bubbles: opts.bubbles, + cancelable: opts.cancelable + } - // event opts - //-------------------- - const eventOpts = {bubbles: opts.bubbles, cancelable: opts.cancelable} + if (opts.eventTypes[0]) { + // create and dispatch event + //-------------------- + const eventStart = Event.create( + elem, + coords, + opts.eventTypes[0], + eventOpts + ) + if (this.opts.debug) + console.log('dispatch event', eventStart) + elem.dispatchEvent(eventStart) - if (opts.eventTypes[0]) { + // onStart + //-------------------- + if (opts.onStart) { + opts.onStart.call(this, eventStart) + } + } // create and dispatch event //-------------------- - const eventStart = Event.create(elem, coords, opts.eventTypes[0], eventOpts) - if (this.opts.debug) console.log('dispatch event', eventStart) - elem.dispatchEvent(eventStart) + const eventComplete = Event.create( + elem, + coords, + opts.eventTypes[1], + eventOpts + ) + if (this.opts.debug) + console.log('dispatch event', eventComplete) + elem.dispatchEvent(eventComplete) - // onStart + // onComplete //-------------------- - if (opts.onStart) { - opts.onStart.call(this, eventStart) + if (opts.onComplete) { + opts.onComplete.call(this, eventComplete) } - } - - // create and dispatch event - //-------------------- - const eventComplete = Event.create(elem, coords, opts.eventTypes[1], eventOpts) - if (this.opts.debug) console.log('dispatch event', eventComplete) - elem.dispatchEvent(eventComplete) - - // onComplete - //-------------------- - if (opts.onComplete) { - opts.onComplete.call(this, eventComplete) - } - - }, timelinePosition, [position]) + }, + timelinePosition, + [position] + ) this._actions++ @@ -245,7 +280,7 @@ export default class UITest { /** * Executes a pan event (pointerdown, pointermove, pointerup) on a specific element. - * + * * @param {HTMLElement|string} element - The HTML element on which the event is to be executed, e.g. button, document, h2, canvas, etc. or an selector string. If a selector has been specified, it is evaluated immediately before the event is called using the querySelector method. * @param {number[]|object|PIXI.DisplayObject} [position=The center of the element.] - The local position of the event in the context of the specified HTML element. If no position is specified, the center of the HTML element is used. The position can be specified as an array of numbers, as an object with the two properties x and y, or as a PIXI.Display object. * @param {number} [timelinePosition=One second after the last action.] - The position in seconds when the event should be triggered, see shttps://greensock.com/docs/TimelineMax/addCallback(). @@ -262,104 +297,133 @@ export default class UITest { * @param {boolean} [opts.cancelable=true] - Events' cancelable property indicates if the event can be canceled, and therefore prevented as if the event never happened. If the event is not cancelable, then its cancelable property will be false and the event listener cannot stop the event from occurring. */ pan(element, position, timelinePosition, opts = {}) { - // arguments //-------------------- - [position, timelinePosition, opts] = this.reorderArguments(arguments) + ;[position, timelinePosition, opts] = this.reorderArguments(arguments) this._timelinePositions.push(timelinePosition) // debug //-------------------- - if (this.opts.debug) console.log('tap params', {element, position, timelinePosition, opts}) + if (this.opts.debug) + console.log('tap params', { + element, + position, + timelinePosition, + opts + }) // opts //-------------------- - opts = Object.assign({}, { - onStart: null, - onUpdate: null, - onComplete: null, - to: {x: 0, y: 0}, - duration: 1, - ease: Power0.easeNone, - eventTypes: this.resolveEvents(['down', 'move', 'up']), - context: window, - bubbles: true, - cancelable: true - }, opts) + opts = Object.assign( + {}, + { + onStart: null, + onUpdate: null, + onComplete: null, + to: { x: 0, y: 0 }, + duration: 1, + ease: Power0.easeNone, + eventTypes: this.resolveEvents(['down', 'move', 'up']), + context: window, + bubbles: true, + cancelable: true + }, + opts + ) // timeline //-------------------- - this._timeline.addCallback(position => { + this._timeline.addCallback( + position => { + // element + //-------------------- + const elem = Util.extractElement(opts.context, element) - // element - //-------------------- - const elem = Util.extractElement(opts.context, element) + // coords + //-------------------- + const from = Util.extractPosition(position) - // coords - //-------------------- - const from = Util.extractPosition(position) + // event opts + //-------------------- + const eventOpts = { + bubbles: opts.bubbles, + cancelable: opts.cancelable + } - // event opts - //-------------------- - const eventOpts = {bubbles: opts.bubbles, cancelable: opts.cancelable} + const gsOpts = { + ease: opts.ease, + onStart: () => { + // create and dispatch event + //-------------------- + const event = Event.create( + elem, + from, + opts.eventTypes[0], + eventOpts + ) + if (this.opts.debug) + console.log('dispatch event', event) + elem.dispatchEvent(event) - const gsOpts = { - ease: opts.ease, - onStart: () => { + // onStart + //-------------------- + if (opts.onStart) { + opts.onStart.call(this, event) + } + }, + onUpdate: () => { + // create and dispatch event + //-------------------- + const event = Event.create( + elem, + from, + opts.eventTypes[1], + eventOpts + ) + if (this.opts.debug) + console.log('dispatch event', event) + elem.dispatchEvent(event) - // create and dispatch event - //-------------------- - const event = Event.create(elem, from, opts.eventTypes[0], eventOpts) - if (this.opts.debug) console.log('dispatch event', event) - elem.dispatchEvent(event) + // onUpdate + //-------------------- + if (opts.onUpdate) { + opts.onUpdate.call(this, event) + } + }, + onComplete: () => { + // create and dispatch event + //-------------------- + const event = Event.create( + elem, + from, + opts.eventTypes[2], + eventOpts + ) + if (this.opts.debug) + console.log('dispatch event', event) + elem.dispatchEvent(event) - // onStart - //-------------------- - if (opts.onStart) { - opts.onStart.call(this, event) - } - }, - onUpdate: () => { - - // create and dispatch event - //-------------------- - const event = Event.create(elem, from, opts.eventTypes[1], eventOpts) - if (this.opts.debug) console.log('dispatch event', event) - elem.dispatchEvent(event) - - // onUpdate - //-------------------- - if (opts.onUpdate) { - opts.onUpdate.call(this, event) - } - }, - onComplete: () => { - - // create and dispatch event - //-------------------- - const event = Event.create(elem, from, opts.eventTypes[2], eventOpts) - if (this.opts.debug) console.log('dispatch event', event) - elem.dispatchEvent(event) - - // onComplete - //-------------------- - if (opts.onComplete) { - opts.onComplete.call(this, event) + // onComplete + //-------------------- + if (opts.onComplete) { + opts.onComplete.call(this, event) + } } } - } - // to - //-------------------- - const object = Util.extractTo(opts) - Object.assign(gsOpts, object) + // to + //-------------------- + const object = Util.extractTo(opts) + Object.assign(gsOpts, object) - // drag animation - //-------------------- - TweenLite.to(from, opts.duration, gsOpts) + // drag animation + //-------------------- + TweenLite.to(from, opts.duration, gsOpts) + }, + timelinePosition, + [position] + ) - }, timelinePosition, [position]) - this._actions++ return this @@ -367,7 +431,7 @@ export default class UITest { /** * Executes a pinch event (pointerdown, pointermove, pointerup) on a specific element with two "fingers" simultaneously. - * + * * @param {HTMLElement|string} element - The HTML element on which the event is to be executed, e.g. button, document, h2, canvas, etc. or an selector string. If a selector has been specified, it is evaluated immediately before the event is called using the querySelector method. * @param {number[]|object|PIXI.DisplayObject} [position=The center of the element.] - The local position of the event in the context of the specified HTML element. If no position is specified, the center of the HTML element is used. The position can be specified as an array of numbers, as an object with the two properties x and y, or as a PIXI.Display object. * @param {number} [timelinePosition=One second after the last action.] - The position in seconds when the event should be triggered, see shttps://greensock.com/docs/TimelineMax/addCallback(). @@ -387,145 +451,184 @@ export default class UITest { * @param {boolean} [opts.cancelable=true] - Events' cancelable property indicates if the event can be canceled, and therefore prevented as if the event never happened. If the event is not cancelable, then its cancelable property will be false and the event listener cannot stop the event from occurring. */ pinch(element, position, timelinePosition, opts = {}) { - // arguments //-------------------- - [position, timelinePosition, opts] = this.reorderArguments(arguments) + ;[position, timelinePosition, opts] = this.reorderArguments(arguments) this._timelinePositions.push(timelinePosition) // debug //-------------------- - if (this.opts.debug) console.log('tap params', {element, position, timelinePosition, opts}) + if (this.opts.debug) + console.log('tap params', { + element, + position, + timelinePosition, + opts + }) // opts //-------------------- - opts = Object.assign({}, { - onStart: null, - onUpdate: null, - onComplete: null, - doubleCallbacks: false, - duration: 1, - distance: 100, - to: null, - bezier: null, - ease: Power0.easeNone, - eventTypes: this.resolveEvents(['down', 'move', 'up']), - context: window, - bubbles: true, - cancelable: true - }, opts) + opts = Object.assign( + {}, + { + onStart: null, + onUpdate: null, + onComplete: null, + doubleCallbacks: false, + duration: 1, + distance: 100, + to: null, + bezier: null, + ease: Power0.easeNone, + eventTypes: this.resolveEvents(['down', 'move', 'up']), + context: window, + bubbles: true, + cancelable: true + }, + opts + ) // timeline //-------------------- - this._timeline.addCallback(position => { - - // element - //-------------------- - const elem = Util.extractElement(opts.context, element) - - // from - //-------------------- - let from1 = null - let from2 = null - - if (Array.isArray(position) && !Util.isNumber(position[0])) { - from1 = Util.extractPosition(position[0]) - from2 = Util.extractPosition(position[1]) - } else { - from1 = Util.extractPosition(position) - from2 = {x: from1.x, y: from1.y} - } - - // to - //-------------------- - let gsOpts1 = {} - let gsOpts2 = {} - - if (opts.to || opts.bezier) { - [gsOpts1, gsOpts2] = Util.extractMultiTo(opts) - } else { - const distance = opts.distance != null ? opts.distance : 100 - gsOpts1.x = from1.x - distance / 2 - gsOpts1.y = from1.y - gsOpts2.x = from2.x + distance / 2 - gsOpts2.y = from2.y - } - - // pointers - //-------------------- - const pointers = new Map() - pointers.set(0, {element: from1, gsOpts: gsOpts1}) - pointers.set(1, {element: from2, gsOpts: gsOpts2}) - - // loop - //-------------------- - pointers.forEach((value, key) => { + this._timeline.addCallback( + position => { + // element + //-------------------- + const elem = Util.extractElement(opts.context, element) // from //-------------------- - const from = value.element + let from1 = null + let from2 = null - // event opts - //-------------------- - const eventOpts = {bubbles: opts.bubbles, cancelable: opts.cancelable, pointerId: key, isPrimary: key === 0} - - const gsOpts = { - ease: opts.ease, - onStart: () => { - - // create and dispatch event - //-------------------- - const event = Event.create(elem, from, opts.eventTypes[0], eventOpts) - if (this.opts.debug) console.log('dispatch event', event) - elem.dispatchEvent(event) - - // onStart - //-------------------- - if (opts.onStart && (opts.doubleCallbacks || key === 0)) { - opts.onStart.call(this, event) - } - }, - onUpdate: () => { - - // create and dispatch event - //-------------------- - const event = Event.create(elem, from, opts.eventTypes[1], eventOpts) - if (this.opts.debug) console.log('dispatch event', event) - elem.dispatchEvent(event) - - // onUpdate - //-------------------- - if (opts.onUpdate && (opts.doubleCallbacks || key === 0)) { - opts.onUpdate.call(this, event) - } - }, - onComplete: () => { - - // create and dispatch event - //-------------------- - const event = Event.create(elem, from, opts.eventTypes[2], eventOpts) - if (this.opts.debug) console.log('dispatch event', event) - elem.dispatchEvent(event) - - // onComplete - //-------------------- - if (opts.onComplete && (opts.doubleCallbacks || key === 0)) { - opts.onComplete.call(this, event) - } - } + if (Array.isArray(position) && !Util.isNumber(position[0])) { + from1 = Util.extractPosition(position[0]) + from2 = Util.extractPosition(position[1]) + } else { + from1 = Util.extractPosition(position) + from2 = { x: from1.x, y: from1.y } } // to //-------------------- - Object.assign(gsOpts, value.gsOpts) + let gsOpts1 = {} + let gsOpts2 = {} - // drag animation + if (opts.to || opts.bezier) { + ;[gsOpts1, gsOpts2] = Util.extractMultiTo(opts) + } else { + const distance = opts.distance != null ? opts.distance : 100 + gsOpts1.x = from1.x - distance / 2 + gsOpts1.y = from1.y + gsOpts2.x = from2.x + distance / 2 + gsOpts2.y = from2.y + } + + // pointers //-------------------- - TweenLite.to(from, opts.duration, gsOpts) - }) + const pointers = new Map() + pointers.set(0, { element: from1, gsOpts: gsOpts1 }) + pointers.set(1, { element: from2, gsOpts: gsOpts2 }) + + // loop + //-------------------- + pointers.forEach((value, key) => { + // from + //-------------------- + const from = value.element + + // event opts + //-------------------- + const eventOpts = { + bubbles: opts.bubbles, + cancelable: opts.cancelable, + pointerId: key, + isPrimary: key === 0 + } + + const gsOpts = { + ease: opts.ease, + onStart: () => { + // create and dispatch event + //-------------------- + const event = Event.create( + elem, + from, + opts.eventTypes[0], + eventOpts + ) + if (this.opts.debug) + console.log('dispatch event', event) + elem.dispatchEvent(event) + + // onStart + //-------------------- + if ( + opts.onStart && + (opts.doubleCallbacks || key === 0) + ) { + opts.onStart.call(this, event) + } + }, + onUpdate: () => { + // create and dispatch event + //-------------------- + const event = Event.create( + elem, + from, + opts.eventTypes[1], + eventOpts + ) + if (this.opts.debug) + console.log('dispatch event', event) + elem.dispatchEvent(event) + + // onUpdate + //-------------------- + if ( + opts.onUpdate && + (opts.doubleCallbacks || key === 0) + ) { + opts.onUpdate.call(this, event) + } + }, + onComplete: () => { + // create and dispatch event + //-------------------- + const event = Event.create( + elem, + from, + opts.eventTypes[2], + eventOpts + ) + if (this.opts.debug) + console.log('dispatch event', event) + elem.dispatchEvent(event) + + // onComplete + //-------------------- + if ( + opts.onComplete && + (opts.doubleCallbacks || key === 0) + ) { + opts.onComplete.call(this, event) + } + } + } + + // to + //-------------------- + Object.assign(gsOpts, value.gsOpts) + + // drag animation + //-------------------- + TweenLite.to(from, opts.duration, gsOpts) + }) + }, + timelinePosition, + [position] + ) - }, timelinePosition, [position]) - this._actions++ return this @@ -569,13 +672,12 @@ export default class UITest { /** * Sorts the parameters so that the second, third, and fourth parameters can be optional (and possibly slip forward). - * + * * @private * @param {arguments} params - The arguments which were passed to the function. * @returns {array} - Returns an array of the position, the timelinePosition and the opts object. */ reorderArguments(params) { - // first parameter //-------------------- const element = params[0] @@ -585,12 +687,16 @@ export default class UITest { let position = null let timelinePosition = null let opts = null - + // second parameter //-------------------- if (Util.isNumber(params[1])) { timelinePosition = params[1] - } else if (Util.isObject(params[1]) && !Util.isPixiDisplayObject(params[1]) && (params[1].x == null || params[1].y == null)) { + } else if ( + Util.isObject(params[1]) && + !Util.isPixiDisplayObject(params[1]) && + (params[1].x == null || params[1].y == null) + ) { opts = params[1] } else if (params[1] != null) { position = params[1] @@ -618,9 +724,13 @@ export default class UITest { if (timelinePosition === null) { if (this.opts.defaultInterval === null && this._actions > 1) { - throw new Error('No execution time was specified for this action, and a default interval was not set in the class constructor!') + throw new Error( + 'No execution time was specified for this action, and a default interval was not set in the class constructor!' + ) } - timelinePosition = Math.max(...this._timelinePositions) + (this.opts.defaultInterval || 1) + timelinePosition = + Math.max(...this._timelinePositions) + + (this.opts.defaultInterval || 1) } if (opts === null) { @@ -632,12 +742,11 @@ export default class UITest { /** * Converts event type shortcuts to real event names. - * + * * @private * @param {string[]} events - An array of event types. */ resolveEvents(events) { - const data = [] if (this.opts.eventType === 'pointer') { @@ -688,34 +797,35 @@ export default class UITest { * @class */ class Util { - /** * Resolves the element from a specific context. - * + * * @static * @param {Window|Frame} context - The context within which the optionally specified element selector should be executed. * @return {HTMLElement|string} element - The HTML element on which the event is to be executed, e.g. button, document, h2, canvas, etc. or an selector string. If a selector has been specified, it is evaluated immediately before the event is called using the querySelector method. */ static extractElement(context, element) { - - const cont = Util.isFrame(context) ? context.contentDocument : context.document - const elem = Util.isString(element) ? cont.querySelector(element) : element + const cont = Util.isFrame(context) + ? context.contentDocument + : context.document + const elem = Util.isString(element) + ? cont.querySelector(element) + : element return elem } /** * Extracts the position of the second parameter. - * + * * @static * @param {object} object - Something were the coords should be extracted. * @return {object} - Returns an object with the keys x and y. */ static extractPosition(object) { - // event coords //-------------------- - const position = {x: 0, y: 0} + const position = { x: 0, y: 0 } // get the position //-------------------- @@ -739,17 +849,15 @@ class Util { /** * Extracts the to or bezier key. - * + * * @static * @param {object} opts - An options object where to or bezier should be extracted. * @return {object} - Returns an object with the to or bezier keys. */ static extractTo(opts) { - const object = {} if (opts.bezier) { - let bezier = null if (Array.isArray(opts.bezier)) { @@ -758,7 +866,9 @@ class Util { type: 'thru' } } else { - opts.bezier.values = opts.bezier.values.map(it => Util.extractPosition(it)) + opts.bezier.values = opts.bezier.values.map(it => + Util.extractPosition(it) + ) bezier = opts.bezier } @@ -774,19 +884,16 @@ class Util { /** * Extracts multiple to or bezier keys. - * + * * @static * @param {object} opts - An options object where to or bezier should be extracted. * @return {object[]} - Returns an array of objects with the keys x and y. */ static extractMultiTo(opts) { - const objects = [] if (opts.bezier) { - opts.bezier.forEach(it => { - let bezier = null if (Array.isArray(it)) { @@ -803,9 +910,7 @@ class Util { bezier }) }) - } else { - opts.to.forEach(it => { const to = Util.extractPosition(it) objects.push({ @@ -820,7 +925,7 @@ class Util { /** * Checks if a thing is a string. - * + * * @static * @param {object} object - The object to test for. * @return {boolean} - true if the thing is a string, otherwise false. @@ -831,7 +936,7 @@ class Util { /** * Checks if a thing is a number. - * + * * @static * @param {object} object - The object to test for. * @return {boolean} - true if the thing is a number, otherwise false. @@ -842,7 +947,7 @@ class Util { /** * Checks if a thing is an object. - * + * * @static * @param {object} object - The object to test for. * @return {boolean} - true if the thing is an object, otherwise false. @@ -853,18 +958,22 @@ class Util { /** * Checks if a thing is an PIXI.DisplayObject. - * + * * @static * @param {object} object - The object to test for. * @return {boolean} - true if the thing is a PIXI.DisplayObject, otherwise false. */ static isPixiDisplayObject(object) { - return typeof object.getBounds === 'function' && typeof object.renderWebGL === 'function' && typeof object.setTransform === 'function' + return ( + typeof object.getBounds === 'function' && + typeof object.renderWebGL === 'function' && + typeof object.setTransform === 'function' + ) } /** * Checks if a thing is a frame. - * + * * @static * @param {object} object - The object to test for. * @return {boolean} - true if the thing is a frame, otherwise false. @@ -886,19 +995,25 @@ class Util { * @class */ class Event { - /** * Creates an event object. - * + * * @static * @param {HTMLElement} target - The element on which the event should be executed. * @param {object} position - The local position of the event in relation to the target. The object must have the keys x and y. * @param {string} type - The type of the event, see https://developer.mozilla.org/de/docs/Web/Events * @param {object} opts - An options object. Every paramter of the event object can be overridden, see e.g. https://developer.mozilla.org/de/docs/Web/API/MouseEvent for all the properties. */ - static create(target, position = {x: 0, y: 0}, type = 'pointerup', opts = {}) { - - const rect = typeof target.getBoundingClientRect === 'function' ? target.getBoundingClientRect() : {x: 0, y: 0} + static create( + target, + position = { x: 0, y: 0 }, + type = 'pointerup', + opts = {} + ) { + const rect = + typeof target.getBoundingClientRect === 'function' + ? target.getBoundingClientRect() + : { x: 0, y: 0 } // EventInit const eventOpts = { @@ -955,11 +1070,27 @@ class Event { } if (type.startsWith('pointer')) { - return new PointerEvent(type, Object.assign({}, eventOpts, uiEventOpts, mouseEventOpts, pointerEventOpts, opts)) + return new PointerEvent( + type, + Object.assign( + {}, + eventOpts, + uiEventOpts, + mouseEventOpts, + pointerEventOpts, + opts + ) + ) } else if (type.startsWith('touch')) { - return new TouchEvent(type, Object.assign({}, eventOpts, uiEventOpts, touchEventOpts, opts)) + return new TouchEvent( + type, + Object.assign({}, eventOpts, uiEventOpts, touchEventOpts, opts) + ) } else { - return new MouseEvent(type, Object.assign({}, eventOpts, uiEventOpts, mouseEventOpts, opts)) + return new MouseEvent( + type, + Object.assign({}, eventOpts, uiEventOpts, mouseEventOpts, opts) + ) } } } diff --git a/lib/utils.js b/lib/utils.js index 27b2a8c..da184a6 100755 --- a/lib/utils.js +++ b/lib/utils.js @@ -61,31 +61,31 @@ export function sample(population, k) { */ if (!Array.isArray(population)) - throw new TypeError("Population must be an array.") + throw new TypeError('Population must be an array.') let n = population.length if (k < 0 || k > n) - throw new RangeError("Sample larger than population or is negative") + throw new RangeError('Sample larger than population or is negative') let result = new Array(k) - let setsize = 21 // size of a small set minus size of an empty list + let setsize = 21 // size of a small set minus size of an empty list - if (k > 5) - setsize += Math.pow(4, Math.ceil(Math.log(k * 3, 4))) + if (k > 5) setsize += Math.pow(4, Math.ceil(Math.log(k * 3, 4))) if (n <= setsize) { // An n-length list is smaller than a k-length set let pool = population.slice() - for (let i = 0; i < k; i++) { // inletiant: non-selected at [0,n-i) - let j = Math.random() * (n - i) | 0 + for (let i = 0; i < k; i++) { + // inletiant: non-selected at [0,n-i) + let j = (Math.random() * (n - i)) | 0 result[i] = pool[j] - pool[j] = pool[n - i - 1] // move non-selected item into vacancy + pool[j] = pool[n - i - 1] // move non-selected item into vacancy } } else { let selected = new Set() for (let i = 0; i < k; i++) { - let j = Math.random() * (n - i) | 0 + let j = (Math.random() * (n - i)) | 0 while (selected.has(j)) { - j = Math.random() * (n - i) | 0 + j = (Math.random() * (n - i)) | 0 } selected.add(j) result[i] = population[j] @@ -95,7 +95,6 @@ export function sample(population, k) { return result } - // Returns a function, that, as long as it continues to be invoked, will not // be triggered. The function will be called after it stops being called for // N milliseconds. If `immediate` is passed, trigger the function on the @@ -103,10 +102,10 @@ export function sample(population, k) { // Taken from: https://davidwalsh.name/essential-javascript-functions export function debounce(func, wait, immediate) { let timeout - return function () { + return function() { let context = this, args = arguments - let later = function () { + let later = function() { timeout = null if (!immediate) func.apply(context, args) } @@ -135,7 +134,6 @@ export function randomFloat(min = 0.0, max = 1.0) { } export class Dates { - static create(fullYear, month, day) { return new Date(Date.UTC(fullYear, month, day)) } @@ -145,7 +143,9 @@ export class Dates { } static startYearRange(date) { - return new Date(Date.UTC(date.getFullYear() - 1, 11, 31, 23, 59, 59, 999)) + return new Date( + Date.UTC(date.getFullYear() - 1, 11, 31, 23, 59, 59, 999) + ) } static endYearRange(date) { @@ -433,7 +433,6 @@ export class Points { * @class Sets */ export class Sets { - /** * Returns the intersection of all sets * https://stackoverflow.com/questions/31930894/javascript-set-data-structure-intersect @@ -444,12 +443,10 @@ export class Sets { */ static intersect(...sets) { if (!sets.length) return new Set() - const i = sets.reduce((m, s, i) => s.size < sets[m].size ? i : m, 0) + const i = sets.reduce((m, s, i) => (s.size < sets[m].size ? i : m), 0) const [smallest] = sets.splice(i, 1) const res = new Set() - for (let val of smallest) - if (sets.every(s => s.has(val))) - res.add(val) + for (let val of smallest) if (sets.every(s => s.has(val))) res.add(val) return res } @@ -497,7 +494,6 @@ export class Sets { /** Static methods to compute angles. */ export class Angle { - static normalize(angle) { let TAU = Math.PI * 2.0 while (angle > Math.PI) { @@ -544,11 +540,11 @@ export class Angle { } static degree2radian(degree) { - return Math.PI * degree / 180.0 + return (Math.PI * degree) / 180.0 } static radian2degree(rad) { - return 180.0 / Math.PI * rad + return (180.0 / Math.PI) * rad } } @@ -742,10 +738,9 @@ export class Polygon { if ( verty[i] > testy != verty[j] > testy && testx < - (vertx[j] - vertx[i]) * - (testy - verty[i]) / - (verty[j] - verty[i]) + - vertx[i] + ((vertx[j] - vertx[i]) * (testy - verty[i])) / + (verty[j] - verty[i]) + + vertx[i] ) c = !c } @@ -909,13 +904,10 @@ export class Polygon { } } - /** * Util functions to deal with DOMRects. */ export class Rect { - - /** * Test if a given point is contained by the provided Rect. * @@ -926,12 +918,14 @@ export class Rect { * @memberof Rect */ static contains(rect, point) { - return (point.x > rect.left && - point.x < rect.x + rect.right - && point.y > rect.top && point.y < rect.bottom) + return ( + point.x > rect.left && + point.x < rect.x + rect.right && + point.y > rect.top && + point.y < rect.bottom + ) } - /** *Returns the position of an rect as point object. * @@ -948,7 +942,6 @@ export class Rect { /** String utility functions */ export class Strings { - static toUpperCaseFirstChar(str) { return str.substr(0, 1).toUpperCase() + str.substr(1) } @@ -958,19 +951,22 @@ export class Strings { } static toUpperCaseEachWord(str, delim = ' ') { - return str.split(delim).map((v) => v.toUpperCaseFirstChar()).join(delim) + return str + .split(delim) + .map(v => v.toUpperCaseFirstChar()) + .join(delim) } static toLowerCaseEachWord(str, delim = ' ') { - return str.split(delim).map((v) => v.toLowerCaseFirstChar()).join(delim) + return str + .split(delim) + .map(v => v.toLowerCaseFirstChar()) + .join(delim) } - } - export class LowPassFilter { - - constructor(smoothing = 0.5, bufferMaxSize=10) { + constructor(smoothing = 0.5, bufferMaxSize = 10) { this.smoothing = smoothing // must be smaller than 1 this.buffer = [] // FIFO queue this.bufferMaxSize = bufferMaxSize @@ -978,7 +974,7 @@ export class LowPassFilter { /** * Setup buffer with array of values - * + * * @param {array} values * @returns {array} * @access public @@ -1007,9 +1003,8 @@ export class LowPassFilter { * @access private */ __push(value) { - let removed = (this.buffer.length === this.bufferMaxSize) - ? this.buffer.shift() - : 0 + let removed = + this.buffer.length === this.bufferMaxSize ? this.buffer.shift() : 0 this.buffer.push(value) return removed @@ -1023,7 +1018,6 @@ export class LowPassFilter { * @access public */ next(nextValue) { - // push new value to the end, and remove oldest one let removed = this.__push(nextValue) // smooth value using all values from buffer @@ -1052,5 +1046,3 @@ export class LowPassFilter { return values } } - - diff --git a/package-lock.json b/package-lock.json index 69ae12c..b5cbbb0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "iwmlib", - "version": "1.0.15", + "version": "1.0.16", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -465,6 +465,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "dev": true, "requires": { "es6-promisify": "^5.0.0" } @@ -758,7 +759,8 @@ "async-limiter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "dev": true }, "async-settle": { "version": "1.0.0", @@ -842,7 +844,8 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true }, "base": { "version": "0.11.2", @@ -938,6 +941,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1391,7 +1395,8 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "concat-stream": { "version": "1.6.2", @@ -1563,6 +1568,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "requires": { "ms": "2.0.0" } @@ -1910,12 +1916,14 @@ "es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "dev": true }, "es6-promisify": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "dev": true, "requires": { "es6-promise": "^4.0.3" } @@ -2348,6 +2356,7 @@ "version": "1.6.7", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz", "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=", + "dev": true, "requires": { "concat-stream": "1.6.2", "debug": "2.6.9", @@ -2433,6 +2442,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "dev": true, "requires": { "pend": "~1.2.0" } @@ -2601,6 +2611,7 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, "requires": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", @@ -2610,7 +2621,8 @@ "graceful-fs": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", - "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==" + "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==", + "dev": true } } }, @@ -2627,7 +2639,8 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true }, "fsevents": { "version": "1.2.9", @@ -3219,6 +3232,7 @@ "version": "7.1.4", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -3681,6 +3695,29 @@ "vinyl": "^2.0.0" } }, + "gulp-prettier": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/gulp-prettier/-/gulp-prettier-2.1.0.tgz", + "integrity": "sha512-6PvGPX+x0d1+PbP7tHF42o6zWzxCXqouTnpwZV1GjF47/wAgWBfPU1E6/6d4uAGM+NhmwWdKvIVumL3wMZZxDg==", + "dev": true, + "requires": { + "plugin-error": "^1.0.1", + "prettier": "^1.5.3", + "safe-buffer": "^5.1.2", + "through2": "^3.0.0" + }, + "dependencies": { + "through2": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", + "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", + "dev": true, + "requires": { + "readable-stream": "2 || 3" + } + } + } + }, "gulp-rename": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-1.4.0.tgz", @@ -3911,6 +3948,7 @@ "version": "2.2.2", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz", "integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==", + "dev": true, "requires": { "agent-base": "^4.3.0", "debug": "^3.1.0" @@ -3920,6 +3958,7 @@ "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, "requires": { "ms": "^2.1.1" } @@ -3927,7 +3966,8 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, @@ -3984,6 +4024,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -4577,6 +4618,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, "requires": { "graceful-fs": "^4.1.6" } @@ -5004,7 +5046,8 @@ "mime": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", + "dev": true }, "mime-db": { "version": "1.40.0", @@ -5036,6 +5079,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5080,6 +5124,7 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, "requires": { "minimist": "0.0.8" }, @@ -5087,14 +5132,16 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true } } }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true }, "murmurhash-js": { "version": "1.0.0", @@ -5338,6 +5385,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, "requires": { "wrappy": "1" } @@ -5538,7 +5586,8 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true }, "path-key": { "version": "2.0.1", @@ -5580,7 +5629,8 @@ "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true }, "performance-now": { "version": "2.1.0", @@ -5695,6 +5745,18 @@ "resource-loader": "^2.2.3" } }, + "plugin-error": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", + "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", + "dev": true, + "requires": { + "ansi-colors": "^1.0.1", + "arr-diff": "^4.0.0", + "arr-union": "^3.1.0", + "extend-shallow": "^3.0.2" + } + }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", @@ -5888,7 +5950,8 @@ "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true }, "propagating-hammerjs": { "version": "1.4.6", @@ -5901,7 +5964,8 @@ "proxy-from-env": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", - "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=" + "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=", + "dev": true }, "psl": { "version": "1.2.0", @@ -5940,6 +6004,7 @@ "version": "1.18.1", "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.18.1.tgz", "integrity": "sha512-luUy0HPSuWPsPZ1wAp6NinE0zgetWtudf5zwZ6dHjMWfYpTQcmKveFRox7VBNhQ98OjNA9PQ9PzQyX8k/KrxTg==", + "dev": true, "requires": { "debug": "^4.1.0", "extract-zip": "^1.6.6", @@ -5955,6 +6020,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, "requires": { "ms": "^2.1.1" } @@ -5962,7 +6028,8 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, @@ -6361,6 +6428,7 @@ "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, "requires": { "glob": "^7.1.3" } @@ -7594,7 +7662,8 @@ "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true }, "unset-value": { "version": "1.0.0", @@ -7857,6 +7926,7 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "dev": true, "requires": { "async-limiter": "~1.0.0" } @@ -7918,6 +7988,7 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "dev": true, "requires": { "fd-slicer": "~1.0.1" } diff --git a/package.json b/package.json index 2bfcd70..ba90bcb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "iwmlib", - "version": "1.0.15", + "version": "1.0.16", "description": "An Open Source library for multi-touch, WebGL powered applications.", "main": "index.js", "directories": { @@ -11,6 +11,7 @@ "build": "rollup --config ./rollup.config.js", "watch": "rollup --watch --config ./rollup.config.js", "3rdparty": "gulp", + "prettier": "gulp prettify", "jsdoc": "jsdoc -c ./doc/conf.json" }, "repository": { @@ -24,18 +25,20 @@ "eslint": "^6.0.1", "eslint-config-prettier": "^6.0.0", "eslint-plugin-prettier": "^3.1.0", + "fs-extra": "^8.0.1", "gulp": "^4.0.2", "gulp-concat": "^2.6.1", + "gulp-prettier": "^2.1.0", "gulp-rename": "^1.4.0", "gulp-replace": "^1.0.0", "gulp-uglify": "^3.0.2", "htmlhint": "^0.11.0", "prettier": "^1.18.2", + "puppeteer": "^1.18.1", "stylelint": "^10.1.0", "stylelint-config-standard": "^18.3.0" }, "dependencies": { - "fs-extra": "^8.0.1", "gsap": "^2.1.3", "hammerjs": "^2.0.8", "optimal-select": "^4.0.1", @@ -44,7 +47,6 @@ "pixi-particles": "^4.1.1", "pixi-projection": "^0.2.8", "pixi.js": "^4.8.8", - "propagating-hammerjs": "^1.4.6", - "puppeteer": "^1.18.1" + "propagating-hammerjs": "^1.4.6" } }