From 65b383cd83d3435e67b9d8ec0f88ec60a29aef03 Mon Sep 17 00:00:00 2001 From: grahamhannington Date: Fri, 1 Nov 2024 16:51:39 +0800 Subject: [PATCH] Introduce paused mode (tap or press the space bar to pause/restart automated page flipping) --- README.md | 41 +++++++++++++++++++++++++----------- bigas.js | 55 +++++++++++++++++++++++++++++++++++++++++------- modules/state.js | 4 +++- style.css | 4 ++++ 4 files changed, 83 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 1450d43..e12ae45 100644 --- a/README.md +++ b/README.md @@ -14,17 +14,16 @@ Two consecutive slashes (//) represent a *page break*: https://grahamhannington.github.io/bigas?text=Basement//Medicine//Pavement//Government//Trench/Coat -You can flip between pages manually using touch gestures or a keyboard: - -| Action | Touch gesture | Key | -| ------------ | ------------- | --- | -| Page forward | Swipe left | Enter
Page Down
Down arrow (↓)
Right arrow (→) | -| Page back | Swipe right | Page Up
Up arrow (↑)
Left arrow (←) | - -or you can use the `interval` parameter to specify the interval in seconds between automated page flips: +You can flip between pages manually using touch gestures or a keyboard, or you can use the `interval` parameter to automatically flip to the next page after a number of seconds: https://grahamhannington.github.io/bigas?interval=2&text=Basement//Medicine//Pavement//Government//Trench/Coat +| Action | Touch gesture | Key | +| ---------------------------------------- | ------------- | --- | +| Page forward | Swipe left | Enter
Page Down
Down arrow (↓)
Right arrow (→) | +| Page back | Swipe right | Page Up
Up arrow (↑)
Left arrow (←) | +| Pause/restart
automated page flipping | Tap | Space bar | + You can also specify other [parameters](#parameters) such as the background color or image, or the name of a Google font to use. **Tip:** Big As is best displayed in your browser's full-screen mode (for example, in a desktop browser, press F11). @@ -233,13 +232,29 @@ Margin around the SVG element (that contains the text) within its parent (contai Default: `2vh` +### `paused` + +Start in paused mode. The text will appear dimmed. + +Only relevant for multipage text with automated page flipping (`interval` greater than 0). + +To start automated page flipping, tap the text or press the space bar. + +Allowed values: `true` or `false` + +Default: `false` + +**Tip:** Specifying `paused` (the parameter name by itself, with no trailing equal sign or value) has the same effect as `paused=true`. + ### `random` Show a random page. Paging forward or background shows a different random page. -Only works for text that consists of multiple "pages" (where each "page" is separated by `//`). +Only relevant for multipage text. + +Allowed values: `true` or `false` -Allowed values: `true` or `false`. +Default: `false` **Tip:** Specifying `random` (the parameter name by itself, with no trailing equal sign or value) has the same effect as `random=true`. @@ -249,7 +264,9 @@ Reverse the page order. Only works for text that consists of multiple "pages" (where each "page" is separated by `//`). -Allowed values: `true` or `false`. +Allowed values: `true` or `false` + +Default: `false` **Tip:** Specifying `reverse` (the parameter name by itself, with no trailing equal sign or value) has the same effect as `reverse=true`. @@ -348,7 +365,7 @@ See also: [`height`](#height) ## Developer notes Big As is tiny. -Essentially all Big As does is insert text in an SVG element, and then "shrinkwrap" the `viewBox` attribute of that SVG element to match the bounding box of the text. +Essentially all Big As does is insert text in an SVG element, and then "shrinkwrap" the `viewBox` attribute of that SVG element to fit the bounding box of the text. For an overview of this technique, see [my answer in Stack Overflow](https://stackoverflow.com/a/79065021/1334619). ### Tricky parts diff --git a/bigas.js b/bigas.js index 03846f0..5cc5bcb 100644 --- a/bigas.js +++ b/bigas.js @@ -71,7 +71,8 @@ function formatSVGElementById (svgElementId) { 'ArrowUp': prevPage, 'ArrowLeft': prevPage, 'ArrowUp': prevPage, - 'PageUp': prevPage + 'PageUp': prevPage, + ' ': togglePause }[event.key] keyHandler?.(svgElement) }) @@ -89,20 +90,52 @@ function formatSVGElementById (svgElementId) { svgElement.parentElement.addEventListener('touchend', function(event) { touchendX = event.changedTouches[0].screenX touchendY = event.changedTouches[0].screenY - handleSwipe(svgElement) + handleTouchGesture(svgElement) }, {passive: true}) - function handleSwipe (svgElement) { + function handleTouchGesture (svgElement) { if (touchendX < touchstartX) { - nextPage (svgElement) + nextPage(svgElement) } - if (touchendX > touchstartX) { - prevPage (svgElement) + prevPage(svgElement) + } + if (touchendX == touchstartX) { + togglePause(svgElement) + } + } +} + +// Toggle between pause and automated page flipping +// (only relevant if interval parameter is greater than 0) +function togglePause (svgElement) { + const state = getState() + if (state.interval > 0) { + if (state.paused) { + // Restart automated page flipping + let intervalID = setInterval(nextPage, state.interval * 1000, svgElement) + svgElement.style.transition = 'none' + svgElement.classList.add('show') + svgElement.classList.remove('dim') + setStateProperty('_intervalID', intervalID) + setStateProperty('paused', false) + } else { + // Pause automated page flipping + clearInterval(state._intervalID) + setStateProperty('_intervalID', null) + setStateProperty('paused', true) + setPauseStyle(svgElement) } } } +function setPauseStyle (svgElement) { + const state = getState() + svgElement.style.transition = 'opacity ' + state.fadeIn + 's' + svgElement.classList.add('dim') + svgElement.classList.remove('show') +} + function nextPage (svgElement) { var newPage const state = getState() @@ -221,7 +254,14 @@ function styleText (svgElement) { // fadeIn is in seconds, setInterval delay is in milliseconds. if (state._initialPage) { if (state.interval > 0) { - setTimeout(() => {setInterval(nextPage, state.interval * 1000, svgElement)}, state.fadeIn * 1000) + if (state.paused) { + setPauseStyle (svgElement) + } else { + setTimeout(() => { + let intervalID = setInterval(nextPage, state.interval * 1000, svgElement) + setStateProperty('_intervalID', intervalID) + }, state.fadeIn * 1000) + } } setStateProperty('_initialPage', false) } @@ -315,7 +355,6 @@ function getRandomPageNumber () { function getStatePages () { return getStateProperty('text').split(pageSeparator).length // Number of pages - } export { formatSVGElementById, formatSVGElementsByClassName, setStateFromURLParams } \ No newline at end of file diff --git a/modules/state.js b/modules/state.js index 5f83130..f1f1ae8 100644 --- a/modules/state.js +++ b/modules/state.js @@ -14,6 +14,7 @@ let state = { interval: 0, lineHeight: 16, margin: null, + paused: false, random: false, reverse: false, text: 'Big As/Possible', @@ -25,7 +26,8 @@ let state = { trimBottom: 0, trimTop: 0, width: null, - _initialPage: true + _initialPage: true, + _intervalID: false } // Return the state object diff --git a/style.css b/style.css index eabe564..1a0a794 100644 --- a/style.css +++ b/style.css @@ -30,6 +30,10 @@ body { visibility: visible; opacity: 1; } +#svg.dim { + visibility: visible; + opacity: 0.7; +} text { fill: #FFFFFF; paint-order: stroke;