From dcd9fdc7cfc278ecd363400ac267e785e5b26296 Mon Sep 17 00:00:00 2001 From: Marvin Danig Date: Tue, 25 Sep 2018 11:35:33 -0400 Subject: [PATCH] Update bookiza.js resources --- crust/index-template.html | 1 + crust/scripts/bookiza.js | 578 ++++++++++++++++++++++++++++---------- crust/scripts/invoker.js | 2 +- crust/style/book.css | 66 +---- package-lock.json | 2 +- package.json | 2 +- 6 files changed, 442 insertions(+), 209 deletions(-) diff --git a/crust/index-template.html b/crust/index-template.html index 9afb034..73df65e 100644 --- a/crust/index-template.html +++ b/crust/index-template.html @@ -33,6 +33,7 @@ + {{{ CONTENT }}} diff --git a/crust/scripts/bookiza.js b/crust/scripts/bookiza.js index a72f086..e904b71 100644 --- a/crust/scripts/bookiza.js +++ b/crust/scripts/bookiza.js @@ -9,15 +9,15 @@ this.node = d.getElementById('book') this.delegator = d.getElementById('plotter') this.state = { - direction: 'forward', + direction: _forward, isInitialized: false, isTurning: false, // 'isPeelable': false, // 'isZoomed': false, // 'isPeeled': false, // 'toTurnOrNotToTurn': false, - // 'eventsCache': [], - mode: _viewer.getMatch('(orientation: landscape)') ? 'landscape' : 'portrait' + mode: _viewer.getMatch('(orientation: landscape)') ? 'landscape' : 'portrait', + animations: {} } /****************************************************** @@ -44,10 +44,13 @@ this.frames = this.elements.map((page, index) => _addPageWrappersAndBaseClasses(page, index)) /****************************************************** - * @range is set of printable frames for the viewport: // this.range = [] * + * @range is set of printable frames for the viewport: + * this.range = [] * TODO: Use [ p, q, r, s, t, u, v ] standard snapshots * *******************************************************/ + this.eventsCache = [] this.tick = 0 /* Count the number of pages ticked before book goes to isTurning: false state again */ + this.Ω = (paintTime = 100) => paintTime * Math.pow(0.9, this.tick) /* Apply paintTime cushion for multipage turns via wheel events */ /* Turn events */ this.turned = new Event('turned') @@ -79,15 +82,13 @@ return !!index.between(0, _book.frames.length) } - addEvents(eventName, callback) { - _book.node.addEventListener(eventName, callback, false) - } - } - /************************************ - ******** Geometry listeners ******** - ************************************/ + /******************************* + * + * Geometric system listeners * + * + ********************************/ const _setGeometricalPremise = (node) => node.getBoundingClientRect() @@ -104,38 +105,36 @@ w.addEventListener('resize', _resetGeometricalOrigin) // Re-calibrate geometrical origin. - /**************************************** + /************************************************************************************** * One time @superbook initialization. * The minimum length of a book is 4 pages. (options.length) * Pages could be provided to Bookiza via DOM or be synthesized * using length value passed as an object property for initialization. * Force the book length to always be an even number: https://bubblin.io/docs/concept - ************************************/ + ***************************************************************************************/ const _initializeSuperBook = ({ options = { duration: 300, peel: true, zoom: true, startPage: 1, length: 4 } }) => { _removeChildren(_book.node) delete _book.elements /* Clear object property from { _book } after a mandatory DOM lookup. */ - _book.options = options /* Save options to the book */ + _book.options = options /* Save options to { book } */ let size = _book.frames.length === 0 ? Number.isInteger(options.length) ? options.length >= 4 ? _isOdd(options.length) ? options.length + 1 : options.length : 4 : 4 : _isOdd(_book.frames.length) ? _book.frames.length + 1 : _book.frames.length - if (_book.frames.length === 0) _book.frames = _reifyPages(size) + if (_book.frames.length === 0) _book.frames = _reifyFrames(size) if (_isOdd(_book.frames.length)) _book.frames.push(_createFrame(_book.frames.length)) - _applyEventListenersOnBook(_setCurrentPage(options.startPage)) // Event delegation via #plotter node. - - - _printElementsToDOM('buttons', _book.buttons) - _printElementsToDOM('view', _setViewIndices(_getCurrentPage(_book.currentPage), _book.state.mode).map((index) => _book.frames[`${index}`]), _book.tick) + /******************************************************** + * Set up mutationObserver & performanceObservers to * + * handle state. * + * Buttons will mutate DOM to set off _openTheBook() * + * or _turnTheBook() via MutatationObserver() * + ********************************************************/ - _book.state.isInitialized = true - - - // console.log('Second') // To prove that the book is printed before DOMContentLoaded event is fired. + _setUpMutationObservers([_setUpPerformanceObservers, _buttons, _oneTimePrint]) // Pass array of callbacks } @@ -220,10 +219,12 @@ w.addEventListener('mouseover', _applyBookEvents) w.addEventListener('mouseout', _removeBookEvents) - /* Listen to @touch events only when capable of Touch. - * Some Windows/Chrome will return true even when the - * screen isn't touch capable. Do not use this to !listen - * keyboard/mouse events. Plain and simple. */ + /*********************************************************** + * Listen to @touch events only when capable of Touch. * + * Some Windows/Chrome will return true even when the * + * screen isn't touch capable. Do not use this to !listen * + * keyboard/mouse events. Plain and simple. * + ************************************************************/ if (_isTouch()) { touchEvents.map((event) => { @@ -231,51 +232,22 @@ }) } - const mutationConfiguration = { attributes: false, childList: true, subtree: false } - - const mutator = mutations => { - - mutations.map((mutation, index) => { - // console.log(Array.from(mutation.addedNodes).includes('a#next.arrow-controls.next-page.flex'), index) - // Array.from(mutation.addedNodes).map(each => { console.log(each)}) - }) - - // for (const mutation of mutations) { - - // console.log(mutation.addedNodes) - - // // console.log(mutation.addedNodes) - - if (mutations.length !== 1) return - - if (_book.state.isInitialized) { - // _raiseAnimatablePages(_book.targetPage, _book.tick) - // _animateLeaf(_book.targetPage) - } - - - // } - } - - const observer = new MutationObserver(mutator) - - observer.observe(_book.node, mutationConfiguration) - - // observer.disconnect() // TODO: If we decide on close to cover functionality. - if (callback && typeof callback === 'function') callback() + } - /****************************************/ - /** *********** Event handlers ***********/ - /****************************************/ + /*************************************** + * Event handlers + ****************************************/ const _handleMouseOver = (event) => { switch (event.target.nodeName) { case 'A': - // console.log('Anchor over', event.target.id) + _book.state.direction = _direction(event.target.id) + break case 'DIV': + // console.log(_book.state.direction) break default: } @@ -293,22 +265,34 @@ } } - const _handleMouseMove = (event) => { - _updateGeometricalPlotValues(event) - } + const _handleMouseMove = (event) => { _updateGeometricalPlotValues(event) } const _handleMouseDown = (event) => { - _book.plotter.side === 'right' - ? _book.state.direction = 'forward' - : _book.state.direction = 'backward' + _book.state.direction = _direction() switch (event.target.nodeName) { case 'A': // console.log('Execute half turn') + + // _book.state.direction === _forward + // ? _printElementsToDOM('rightPages', _getRangeIndices(_getCurrentPage(_book.targetPage), _book.state.mode).rightPageIndices.map((index) => _book.frames[`${index}`]), _book.tick) + // : _printElementsToDOM('leftPages', _getRangeIndices(_getCurrentPage(_book.targetPage), _book.state.mode).leftPageIndices.map((index) => _book.frames[`${index}`]), _book.tick) + + break case 'DIV': // console.log('Page picked, execute curl') // console.log('down', event.pageX) + // console.log(_book.state.direction) + _book.plotter.start = { + x: event.pageX, + y: event.pageY + } + + // _book.state.direction === _forward + // ? _printElementsToDOM('rightPages', _getRangeIndices(_getCurrentPage(_book.targetPage), _book.state.mode).rightPageIndices.map((index) => _book.frames[`${index}`]), _book.tick) + // : _printElementsToDOM('leftPages', _getRangeIndices(_getCurrentPage(_book.targetPage), _book.state.mode).leftPageIndices.map((index) => _book.frames[`${index}`]), _book.tick) + break default: } @@ -321,6 +305,15 @@ break case 'DIV': // console.log('up', event.pageX) // Calculate x-shift, y-shift. + + _book.plotter.end = { + x: event.pageX, + y: event.pageY + } + + console.log(_sign(_book.plotter.start.x - _book.plotter.end.x)) + + break default: } @@ -329,18 +322,14 @@ const _handleMouseClicks = (event) => { switch (event.target.nodeName) { case 'A': - _book.state.direction = event.target.id === 'next' ? 'forward' : 'backward' - + _book.state.direction = _direction(event.target.id) _book.state.isTurning ? _book.tick += 1 : _book.tick = 1 + _book.eventsCache.push({ tick: _book.tick, page: _book.targetPage }) // Pop via DOM mutations - _book.state.direction === 'forward' + _book.state.direction === _forward ? _printElementsToDOM('rightPages', _getRangeIndices(_getCurrentPage(_book.targetPage), _book.state.mode).rightPageIndices.map((index) => _book.frames[`${index}`]), _book.tick) : _printElementsToDOM('leftPages', _getRangeIndices(_getCurrentPage(_book.targetPage), _book.state.mode).leftPageIndices.map((index) => _book.frames[`${index}`]), _book.tick) - - _raiseAnimatablePages(_book.targetPage, _book.tick) - _animateLeaf(_book.targetPage) - _book.targetPage = _target(_book.state.direction) break @@ -363,19 +352,20 @@ const _handleWheelEvent = (event) => { switch (event.target.nodeName) { case 'A': - _book.state.direction = event.deltaY < 0 ? 'backward' : 'forward' - // _book.state.isTurning ? _book.tick += 1 : _book.tick = 1 + _book.state.direction = event.target.id === 'next' ? event.deltaY < 0 ? _backward : _forward : event.deltaY < 0 ? _forward : _backward - // _book.state.direction === 'forward' - // ? _printElementsToDOM('rightPages', _getRangeIndices(_getCurrentPage(_book.targetPage), _book.state.mode).rightPageIndices.map((index) => _book.frames[`${index}`]), _book.tick) - // : _printElementsToDOM('leftPages', _getRangeIndices(_getCurrentPage(_book.targetPage), _book.state.mode).leftPageIndices.map((index) => _book.frames[`${index}`]), _book.tick) + _book.state.isTurning ? _book.tick += 1 : _book.tick = 1 + + _book.eventsCache.push({ tick: _book.tick, page: _book.targetPage }) // Pop via DOM mutations - // _raiseAnimatablePages(_book.targetPage, _book.tick) + _book.state.isTurning = true - // _animateLeaf(_book.targetPage) + _book.state.direction === _forward + ? _printElementsToDOM('rightPages', _getRangeIndices(_getCurrentPage(_book.targetPage), _book.state.mode).rightPageIndices.map((index) => _book.frames[`${index}`]), _book.tick) + : _printElementsToDOM('leftPages', _getRangeIndices(_getCurrentPage(_book.targetPage), _book.state.mode).leftPageIndices.map((index) => _book.frames[`${index}`]), _book.tick) - // _book.targetPage = _target(_book.state.direction) + _book.targetPage = _target(_book.state.direction) break case 'DIV': @@ -397,56 +387,247 @@ } const _handleTouchStart = (event) => { - if (event.touches.length === 2) { + switch (event.touches.length) { + case '1': + _book.plotter.startPoint = { + x: event.pageX, + y: event.pageY + } + break + case '2': + + break + default: + break } - console.log(event.touches.length) - } - const _handleTouchMove = (event) => { - _updateGeometricalPlotValues(event) + + } + const _handleTouchMove = (event) => { _updateGeometricalPlotValues(event) } + const _handleTouchEnd = (event) => { console.log('Touch stopped') + + switch (event.touches.length) { + case '1': + _book.plotter.startPoint = { + x: event.pageX, + y: event.pageY + } + break + case '2': + + break + default: + break + } + + } - /**********************************/ - /** ****** Animation methods *******/ - /**********************************/ + /********************************************** + * Conio-tubular math + web animation objects * + **********************************************/ const _kf1 = () => [ { transform: 'rotateY(0deg)', transformOrigin: 'left center 0' }, { transform: 'rotateY(-180deg)', transformOrigin: 'left center 0' } ] - const _kf2 = () => [ - { transform: 'rotateY(180deg)', transformOrigin: 'right center 0' }, - { transform: 'rotateY(0deg)', transformOrigin: 'right center 0' } - ] - const _kf3 = () => [ { transform: 'rotateY(0deg)', transformOrigin: 'right center 0' }, { transform: 'rotateY(180deg)', transformOrigin: 'right center 0' } ] + const _kf2 = () => [ + { transform: 'rotateY(180deg)', transformOrigin: 'right center 0' }, + { transform: 'rotateY(0deg)', transformOrigin: 'right center 0' } + ] + + // transform: translate3d(0, 0, 0) rotateY(-180deg) skewY(0deg); transform-origin: left center 0; const _kf4 = () => [ - { transform: 'rotateY(-180deg)', transformOrigin: 'left center 0' }, + { transform: `rotateY(${_book.state.direction() * 180}deg)`, transformOrigin: 'left center 0' }, { transform: 'rotateY(0deg)', transformOrigin: 'left center 0' } ] - const _options = ({ duration = _book.options.duration, bezierCurvature = 'ease-in' }) => ({ + const _kf5 = () => [ + { transform: 'translate3d(0px, 0px, 0px) rotateY(0deg)', transformOrigin: 'left center 0' }, + { transform: `translate3d(${_book.state.direction() * _book.plotter.bounds.width / 4}px, 0px, 0px) rotateY(0deg)`, transformOrigin: 'left center 0' } + ] + + const _opacity = () => [ + { opacity: 1 }, + { opacity: 0 } + ] + + const _flutter = () => [ + { transform: 'translate3d(0px, 0px, 0px)' }, + { transform: `translate3d(${_book.state.direction() * -1 * 0.3}vw, 0px, 0px)` }, + { transform: 'translate3d(0px, 0px, 0px)' }, + ] + + const _options = ({ duration = _book.options.duration, bezierCurvature = 'ease-in-out', direction = 'normal', iterations = 1 }) => ({ currentTime: 0, duration: duration, easing: bezierCurvature, - fill: 'forwards', - iterations: 1, - direction: 'normal' + fill: 'both', + iterations: iterations, + direction: direction }) + const _openTheBook = () => { + + switch (_getCurrentPage(_book.targetPage)) { + case 1: + + _book.state.animations.book = _book.node.animate(_kf5(), _options({})) + + _book.state.animations.buttonOpacity = _book.buttons[1].animate(_opacity(), _options({ duration: _book.options.duration / 2 })) + + let animation1 = _book.frames[_setViewIndices(_getCurrentPage(_book.currentPage), _book.state.mode)[0]].childNodes[0].animate(_kf3(), _options({})) + + _book.frames[_getRangeIndices(_getCurrentPage(_book.currentPage), _book.state.mode).leftPageIndices[1]].childNodes[0].animate(_kf4(), _options({})) + + _book.frames[_getRangeIndices(_getCurrentPage(_book.currentPage), _book.state.mode).leftPageIndices[0]].childNodes[0].animate(_kf2(), _options({})).reverse() + + animation1.onfinish = (event) => { + _book.state.animations.buttonFlutter = _book.buttons[0].animate(_flutter(), _options({ iterations: Infinity, duration: 600, bezierCurvature: 'cubic-bezier(0.42, 0, 0.58, 1)' })) + _setCurrentPage(_book.targetPage) + _applyEventListenersOnBook(_isInitialized) + } + break + case _book.frames.length: + + _book.state.animations.book = _book.node.animate(_kf5(), _options({})) + + _book.state.animations.buttonOpacity = _book.buttons[0].animate(_opacity(), _options({ duration: _book.options.duration / 2 })) + + let animation2 = _book.frames[_setViewIndices(_getCurrentPage(_book.currentPage), _book.state.mode)[1]].childNodes[0].animate(_kf1(), _options({})) + + _book.frames[_getRangeIndices(_getCurrentPage(_book.currentPage), _book.state.mode).rightPageIndices[0]].childNodes[0].animate(_kf2(), _options({})) + + _book.frames[_getRangeIndices(_getCurrentPage(_book.currentPage), _book.state.mode).rightPageIndices[1]].childNodes[0].animate(_kf4(), _options({})).reverse() + + animation2.onfinish = (event) => { + _book.state.animations.buttonFlutter = _book.buttons[1].animate(_flutter(), _options({ iterations: Infinity, duration: 1000, bezierCurvature: 'cubic-bezier(0.42, 0, 0.58, 1)' })) + _setCurrentPage(_book.targetPage) + _applyEventListenersOnBook(_isInitialized) + } + break + default: + + + _applyEventListenersOnBook(_isInitialized) + + break + } + } + + const _oneTimePrint = () => { + switch (_getCurrentPage(_book.options.startPage)) { + case 1: + + _book.currentPage = _getCurrentPage(_book.options.startPage + 1) // 2 + _book.targetPage = _getCurrentPage(_book.options.startPage) // 1 + + _book.state.direction = _backward + + _printElementsToDOM('view', _setViewIndices(_getCurrentPage(_book.currentPage), _book.state.mode).map((index) => _book.frames[`${index}`]), _book.tick) + + _book.state.isTurning ? _book.tick += 1 : _book.tick = 1 + + _printElementsToDOM('leftPages', _getRangeIndices(_getCurrentPage(_book.currentPage), _book.state.mode).leftPageIndices.map((index) => _book.frames[`${index}`]), _book.tick) + + break + case _book.frames.length: + + _book.currentPage = _getCurrentPage(_book.options.startPage - 1) // last but one + _book.targetPage = _getCurrentPage(_book.options.startPage) // last + _book.state.direction = _forward + + _printElementsToDOM('view', _setViewIndices(_getCurrentPage(_book.currentPage), _book.state.mode).map((index) => _book.frames[`${index}`]), _book.tick) + + _book.state.isTurning ? _book.tick += 1 : _book.tick = 1 + + _printElementsToDOM('rightPages', _getRangeIndices(_getCurrentPage(_book.currentPage), _book.state.mode).rightPageIndices.map((index) => _book.frames[`${index}`]), _book.tick) + + break + default: + + _book.currentPage = _isEven(_getCurrentPage(_book.options.startPage)) ? 1 : _book.frames.length + _book.targetPage = _getCurrentPage(_book.options.startPage) + _book.state.direction = _isEven(_getCurrentPage(_book.options.startPage)) ? _backward : _forward + + console.log(_getCurrentPage(_book.targetPage + 1)) + + _isEven(_getCurrentPage(_book.options.startPage)) + ? _printElementsToDOM('rightPages', _getRangeIndices(_getCurrentPage(_book.targetPage - 1), _book.state.mode).rightPageIndices.map((index) => _book.frames[`${index}`]), _book.tick) + : _printElementsToDOM('leftPages', _getRangeIndices(_getCurrentPage(_book.targetPage + 1), _book.state.mode).leftPageIndices.map((index) => _book.frames[`${index}`]), _book.tick) + + _isEven(_getCurrentPage(_book.options.startPage)) + ? _printElementsToDOM('first', [_book.frames[0]], _book.tick) + : _printElementsToDOM('last', [_book.frames[_book.frames.length - 1]], _book.tick) + + break + + } + } + + + const _turnTheBook = () => { + /******************************************** + * Check if eventsCache has an event * + * queued up for this (addNode) mutation * + *******************************************/ + + + let turnable = _book.eventsCache.shift() + if (turnable !== undefined) { + + // console.log(_book.state.animations) + + if (_book.state.direction === _forward && _book.targetPage === 2) { + _book.state.animations.book.reverse() + _book.state.animations.buttonOpacity.reverse() + _book.state.animations.buttonFlutter.cancel() + } + + if (_book.state.direction === _backward && _book.targetPage === 1) { + _book.state.animations.book.reverse() + _book.state.animations.buttonOpacity.reverse() + _book.state.animations.buttonFlutter.cancel() + } + + + if (_book.state.direction === _backward && _book.targetPage === _book.frames.length - 1) { + _book.state.animations.book.reverse() + _book.state.animations.buttonOpacity.reverse() + _book.state.animations.buttonFlutter.cancel() + } + + if (_book.state.direction === _forward && _book.targetPage === _book.frames.length) { + _book.state.animations.book.reverse() + _book.state.animations.buttonOpacity.reverse() + _book.state.animations.buttonFlutter.cancel() + } + + + // console.log('Ω', _book.Ω()) + + + _raiseAnimatablePages(turnable.page, turnable.tick) + _animateLeaf(turnable.page) + + + } + } + const _raiseAnimatablePages = (pageNo, tick) => { switch (_book.state.direction) { - case 'forward': + case _forward: switch (_book.state.mode) { case 'portrait': break @@ -458,7 +639,7 @@ break } break - case 'backward': + case _backward: switch (_book.state.mode) { case 'portrait': break @@ -473,10 +654,7 @@ } } - - const _animateLeaf = (pageNo) => { - _book.state.isTurning = true _book.turning.page = _getCurrentPage(pageNo) _book.turning.view = _setViewIndices(_getCurrentPage(pageNo), _book.state.mode).map((i) => i + 1) // Array of page numbers in the [View]. @@ -489,7 +667,7 @@ break case 'landscape': switch (_book.state.direction) { - case 'forward': + case _forward: let animation1 = _book.frames[_setViewIndices(_getCurrentPage(pageNo), _book.state.mode)[1]].childNodes[0].animate(_kf1(), _options({})) let animation2 = _book.frames[_getRangeIndices(_getCurrentPage(pageNo), _book.state.mode).rightPageIndices[0]].childNodes[0].animate(_kf2(), _options({})) @@ -508,9 +686,11 @@ _book.turned.view = _setViewIndices(_getCurrentPage(pageNo), _book.state.mode).map((i) => i + 1) // Array of page numbers in the [View]. _book.node.dispatchEvent(_book.turned) + // console.log(_book.currentPage) + } break - case 'backward': + case _backward: let animation3 = _book.frames[_setViewIndices(_getCurrentPage(pageNo), _book.state.mode)[0]].childNodes[0].animate(_kf3(), _options({})) @@ -539,9 +719,8 @@ } } - - /********************************** - ********** @Helper methods ******** + /********************************* + * @Helper methods * ***********************************/ const _isTouch = () => 'ontouchstart' in w || n.MaxTouchPoints > 0 || n.msMaxTouchPoints > 0 @@ -550,7 +729,7 @@ const _isOdd = (number) => Math.abs(number % 2) === 1 - // const _sign = (x) => (typeof x === 'number' ? (x ? (x < 0 ? -1 : 1) : x === x ? 1 : NaN) : NaN) + const _sign = (x) => (typeof x === 'number' ? (x ? (x < 0 ? -1 : 1) : x === x ? 1 : NaN) : NaN) const _leftCircularIndex = (currentIndex, index) => parseInt(currentIndex) - parseInt(index) < 0 @@ -562,7 +741,6 @@ ? parseInt(currentIndex) + parseInt(index) - parseInt(_book.frames.length) : parseInt(currentIndex) + parseInt(index) - const _stepper = (mode) => (mode === 'portrait' ? 1 : 2) const π = Math.PI @@ -574,17 +752,93 @@ const λ = (angle) => { } // Cone angle - // const _setFlippingDirection = () => (_book.plotter.side === 'right') ? 'forward' : 'backward' + // Definitions: + // μ = Mu = `x-distance` in pixels from origin of the book. (for mousePosition/touchPoint) + // ε = Epsilon = `y-distance` in pixels from origin of the book. + // let Δ, θ, ω, Ω, α, β, δ = 0 + + // Cone Angle λ (= ) + // const λ = (angle) => { + + + + const _direction = (id) => id === undefined + ? _book.plotter.side === 'right' ? _forward : _backward + : id === 'next' ? _forward : _backward + + const _forward = () => 1 + + const _backward = () => -1 + + const _isInitialized = () => { _book.state.isInitialized = true } // w.requestAnimationFrame = (() => w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.mozRequestAnimationFrame || w.oRequestAnimationFrame || w.msRequestAnimationFrame || function (callback) { w.setTimeout(callback, 1E3 / 60) })() + const _setUpMutationObservers = (callbacks) => { + + const mutationConfig = { attributes: false, childList: true, subtree: false } + const mutator = mutations => { + + let isNodeAdded = false + + mutations.map(mutation => { + if (mutation.type === 'childList' && mutation.addedNodes.length) isNodeAdded = true + }) + if (isNodeAdded) + _book.state.isInitialized === true ? _turnTheBook() : _openTheBook() + + } + const observer = new MutationObserver(mutator) + observer.observe(_book.node, mutationConfig) + + // observer.disconnect() // TODO: If we decide on closeBook functionality. + + callbacks.map(callback => { if (callback && typeof callback === 'function') callback() }) + } + + const _setUpPerformanceObservers = () => { + /******************************************** + * Performance matters! * + * Returns Ω values of the browser * + ********************************************/ + if (!w.performance) return + + // const performance = w.performance + + // const performanceEntries = performance.getEntriesByType('paint') + + // const Ω = performanceEntries.find(({ name }) => name === 'first-contentful-paint') + + + // console.log(Ω.startTime) + + // performanceEntries.forEach((performanceEntry, i, entries) => { + // console.log("The time to " + performanceEntry.name + " was " + performanceEntry.startTime + " milliseconds." + performanceEntry.duration + "duration") + // // let Ω = performanceEntry.startTime + // }) + + + // const perfObserver = new PerformanceObserver((list) => { + // for (const entry of list.getEntries()) { + // // `entry` is a PerformanceEntry instance. + // console.log(entry.entryType, entry.startTime, entry.duration) + // } + // }) + + // // // Start observing the entry types you care about. + // perfObserver.observe({ entryTypes: ['resource', 'paint'] }) + + } + + const _stepper = (mode) => (mode === 'portrait' ? 1 : 2) + const _step = () => - _book.state.direction === 'forward' + _book.state.direction === _forward ? _isEven(_book.targetPage) ? _stepper(_book.state.mode) : 1 : _isOdd(_book.targetPage) ? _stepper(_book.state.mode) : 1 const _target = (direction) => - direction === 'forward' + direction === _forward ? _getCurrentPage(_book.targetPage + _step()) : _getCurrentPage(_book.targetPage - _step()) @@ -686,25 +940,26 @@ const _removeElementFromDOMById = (id) => { if (d.getElementById(id) !== null) d.getElementById(id).remove() } - const _reifyPages = size => [...d.createRange() + const _reifyFrames = size => [...d.createRange() .createContextualFragment(new String(new Array(size) .fill() - .map((v, i) => `
`))) + .map((v, i) => `
`))) .querySelectorAll('div') ].map((page, index) => _addPageWrappersAndBaseClasses(page, index)) const _createFrame = (index, html) => html === undefined - ? _addPageWrappersAndBaseClasses(d.createRange().createContextualFragment(`
`).firstChild, index) + ? _addPageWrappersAndBaseClasses(d.createRange().createContextualFragment(`
`).firstChild, index) : _addPageWrappersAndBaseClasses(html, index) + const _buttons = () => { _printElementsToDOM('buttons', _book.buttons) } const _printElementsToDOM = (type, elements, tick = _book.frames.length) => { const docfrag = d.createDocumentFragment() switch (type) { case 'buttons': - elements.forEach((elem) => { + elements.forEach(elem => { docfrag.appendChild(elem) }) break @@ -720,7 +975,7 @@ let rightPages = elements.map((page, currentIndex) => { return _applyStyles(page, currentIndex, type, tick) }) - rightPages.forEach((page) => { + rightPages.forEach(page => { docfrag.appendChild(page) }) break @@ -728,10 +983,19 @@ let leftPages = elements.map((page, currentIndex) => { return _applyStyles(page, currentIndex, type, tick) }) - leftPages.forEach((page) => { + leftPages.forEach(page => { docfrag.appendChild(page) }) break + // case 'first': + // let first = _applyStyles(elements[0], 0, type, tick) + // docfrag.appendChild(first) + // break + // case 'last': + // let last = _applyStyles(elements[0], 0, type, tick) + // docfrag.appendChild(last) + // break + } _book.node.appendChild(docfrag) } @@ -743,8 +1007,7 @@ switch (type) { case 'view': // inner - cssString = - 'transform: translate3d(0, 0, 0) rotateY(0deg) skewY(0deg); transform-origin: 0 center 0;' + cssString = 'transform: translate3d(0, 0, 0) rotateY(0deg) skewY(0deg); transform-origin: 0 center 0;' pageObj.childNodes[0].style = cssString // wrapper cssString = 'z-index: 2; float: left; left: 0;' @@ -770,6 +1033,10 @@ cssString += _isEven(currentIndex) ? 'z-index: 0; ' : 'z-index: 1;' pageObj.style.cssText = cssString break + // case 'first': + // break + // case 'last': + // break } break case 'landscape': @@ -808,12 +1075,37 @@ // wrapper cssString = 'pointer-events:none;' - pageObj.style.cssText = cssString + // pageObj.style.cssText = cssString cssString += _isEven(currentIndex) - ? `z-index: ${tick}; float: left; left: 0;` - : `z-index: ${tick - _book.frames.length}; float: right; right: 0; ` + ? `z-index: ${tick - _book.frames.length}; float: left; left: 0;` + : `z-index: ${tick}; float: right; right: 0; ` pageObj.style.cssText = cssString break + // case 'first': + // // inner + // // cssString = 'pointer-events:none; transitions: none; transform: translate3d(0, 0, 0) rotateY(-180deg) skewY(0deg); transform-origin: left center 0px;' + // cssString = 'pointer-events: none; transitions: none;' + // pageObj.childNodes[0].style = cssString + + // // wrapper + // cssString = `pointer-events: none; z-index: ${tick}; float: right; right: 0;` + // pageObj.style.cssText = cssString + + // break + // case 'last': + // // inner + // cssString = 'pointer-events:none; transitions: none; transform: translate3d(0, 0, 0) rotateY(-180deg) skewY(0deg); transform-origin: right center 0px;' + // pageObj.childNodes[0].style = cssString + + // // wrapper + // cssString = `pointer-events:none; z-index: ${tick}; float: left; left: 0;` + // pageObj.style.cssText = cssString + + + // break + + + } } @@ -849,15 +1141,12 @@ _book.plotter.side === 'right' ? _book.plotter.region === 'upper' ? 'I' : 'IV' : _book.plotter.region === 'upper' ? 'II' : 'III' - _book.plotter.currentPointerPosition = JSON.parse( - `{ "x": "${event.pageX - _book.plotter.origin.x}", "y": "${_book.plotter.origin.y - event.pageY}" }` - ) - _book.plotter.θ = Math.acos( - parseInt(_book.plotter.currentPointerPosition.x) * 2 / parseInt(_book.plotter.bounds.width) - ) // θ in radians + _book.plotter.currentPointerPosition = JSON.parse(`{ "x": "${event.pageX - _book.plotter.origin.x}", "y": "${_book.plotter.origin.y - event.pageY}" }`) + _book.plotter.θ = Math.acos(parseInt(_book.plotter.currentPointerPosition.x) * 2 / parseInt(_book.plotter.bounds.width)) // θ in radians _book.plotter.μ = parseInt(_book.plotter.currentPointerPosition.x) // x-coord from origin. _book.plotter.ε = parseInt(_book.plotter.currentPointerPosition.y) // y-coord from origin. + // console.log(_book.plotter.μ) // console.log(_sign(_book.plotter.μ)) // _printCursorPosition(event) // delete this method call alongwith its function @@ -882,9 +1171,9 @@ d.getElementById('yaxis').textContent = _book.plotter.ε } - /********************************** - ************* Polyfills *********** - **********************************/ + /********************************* + * Polyfills * + **********************************/ DOMTokenList.prototype.addmany = function (classes) { let classArr = classes.split(' ') @@ -958,7 +1247,14 @@ // console.log(_book) - const _addEventListeners = (eventName, callback) => { _book.node.addEventListener(eventName, callback, false) } + /****************** + * Add `turned`, `turning` listeners to + * allow callback execution with context + * of the book, page & whatever is in view. + * We'll call these TurnListeners. + */ + const _addTurnListeners = (eventName, callback) => { _book.node.addEventListener(eventName, callback, false) } + class Superbook { execute(methodName, ...theArgs) { switch (methodName) { @@ -980,9 +1276,9 @@ on(methodName, ...args) { switch (methodName) { case 'turning': - return _addEventListeners('turning', args[0]) + return _addTurnListeners('turning', args[0]) case 'turned': - return _addEventListeners('turned', args[0]) + return _addTurnListeners('turned', args[0]) default: return new Error('Event not found') } diff --git a/crust/scripts/invoker.js b/crust/scripts/invoker.js index 8d392e7..e870a47 100644 --- a/crust/scripts/invoker.js +++ b/crust/scripts/invoker.js @@ -1,4 +1,4 @@ -const options = { duration: 300, peel: true, zoom: true, startPage: 1 } +const options = { duration: 600, peel: true, zoom: false, startPage: 1, build: 'long' } // length: 2000 // document.addEventListener('DOMContentLoaded', (event) => { console.log('First') }) diff --git a/crust/style/book.css b/crust/style/book.css index 66914c8..b7875ac 100644 --- a/crust/style/book.css +++ b/crust/style/book.css @@ -242,70 +242,6 @@ svg { opacity: 1; } -.first-page .previous-page { - opacity: 0; -} - -.last-page .next-page { - opacity: 0; -} - -.first-page .next-page { - -webkit-animation: next-page 1s; - -webkit-animation-iteration-count: infinite; - -webkit-animation-timing-function: ease-in-out; - -moz-animation: next-page 1s; - -moz-animation-iteration-count: infinite; - -moz-animation-timing-function: ease-in-out; - -o-animation: next-page 1s; - -o-animation-iteration-count: infinite; - -o-animation-timing-function: ease-in-out; - -ms-animation: next-page 1s; - -ms-animation-iteration-count: infinite; - -ms-animation-timing-function: ease-in-out; - -webkit-animation: next-page 1s; - animation: next-page 1s; - -webkit-animation-iteration-count: infinite; - animation-iteration-count: infinite; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; -} - -@-webkit-keyframes next-page { - 0% { - -webkit-transform: translateX(0px); - -ms-transform: translateX(0px); - transform: translateX(0px); - } - 50% { - -webkit-transform: translateX(6px); - -ms-transform: translateX(6px); - transform: translateX(6px); - } - 100% { - -webkit-transform: translateX(0px); - -ms-transform: translateX(0px); - transform: translateX(0px); - } -} - -@keyframes next-page { - 0% { - -webkit-transform: translateX(0px); - -ms-transform: translateX(0px); - transform: translateX(0px); - } - 50% { - -webkit-transform: translateX(6px); - -ms-transform: translateX(6px); - transform: translateX(6px); - } - 100% { - -webkit-transform: translateX(0px); - -ms-transform: translateX(0px); - transform: translateX(0px); - } -} .grabbable { cursor: move; @@ -327,4 +263,4 @@ svg { /* To be removed eventually */ -@import './plotter.css'; \ No newline at end of file +@import './plotter.css'; diff --git a/package-lock.json b/package-lock.json index 05d6b97..eab77e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "bookiza", - "version": "1.0.0-beta.1", + "version": "1.0.0-beta.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 86073e9..d2b4248 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bookiza", - "version": "1.0.0-beta.1", + "version": "1.0.0-beta.2", "description": "A book baking tool", "logo": { "file": "./assets/images/bookiza.png"