aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/dumbymap.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'src/dumbymap.mjs')
-rw-r--r--src/dumbymap.mjs76
1 files changed, 12 insertions, 64 deletions
diff --git a/src/dumbymap.mjs b/src/dumbymap.mjs
index 59c656c..b5afb6a 100644
--- a/src/dumbymap.mjs
+++ b/src/dumbymap.mjs
@@ -7,6 +7,7 @@ import LeaderLine from 'leader-line'
7import { renderWith, defaultAliases, parseConfigsFromYaml } from 'mapclay' 7import { renderWith, defaultAliases, parseConfigsFromYaml } from 'mapclay'
8import { onRemove, animateRectTransition, throttle } from './utils' 8import { onRemove, animateRectTransition, throttle } from './utils'
9import { Layout, SideBySide, Overlay } from './Layout' 9import { Layout, SideBySide, Overlay } from './Layout'
10import * as utils from './dumbyUtils'
10 11
11const docLinkSelector = 'a[href^="#"][title^="=>"]' 12const docLinkSelector = 'a[href^="#"][title^="=>"]'
12const geoLinkSelector = 'a[href^="geo:"]' 13const geoLinkSelector = 'a[href^="geo:"]'
@@ -140,64 +141,6 @@ export const markdown2HTML = (container, mdContent) => {
140 return container 141 return container
141 //}}} 142 //}}}
142} 143}
143// FIXME Don't use hard-coded CSS selector
144// TODO Use UI to switch layouts
145function focusNextMap(reverse = false) {
146 const renderedList = this.renderMaps
147 .map(render => render.target)
148 .filter(ele => ele.getAttribute('data-state') === 'rendered')
149 const mapNum = renderedList.length
150 if (mapNum === 0) return
151
152 // Get current focused map element
153 const currentFocus = this.container.querySelector('.map-container.focus')
154
155 // Remove class name of focus for ALL candidates
156 // This may trigger animation
157 renderedList.forEach(ele => ele.classList.remove('focus'))
158
159 // Get next existing map element
160 const padding = reverse ? -1 : 1
161 let nextIndex = currentFocus ? renderedList.indexOf(currentFocus) + padding : 0
162 nextIndex = (nextIndex + mapNum) % mapNum
163 const nextFocus = renderedList[nextIndex]
164 nextFocus.classList.add("focus")
165
166 return nextFocus
167}
168function focusDelay() {
169 return window.getComputedStyle(this.showcase).display === 'none' ? 50 : 300
170}
171
172function switchToNextLayout(reverse = false) {
173 const currentLayoutName = this.container.getAttribute('data-layout')
174 const currentIndex = layouts.map(l => l.name).indexOf(currentLayoutName)
175 const padding = reverse ? -1 : 1
176 const nextIndex = currentIndex === -1 ? 0 : (currentIndex + padding + layouts.length) % layouts.length
177 const nextLayout = layouts[nextIndex]
178 this.container.setAttribute("data-layout", nextLayout.name)
179}
180
181function focusNextBlock(reverse = false) {
182 const blocks = this.blocks.filter(b => b.checkVisibility({
183 contentVisibilityAuto: true,
184 opacityProperty: true,
185 visibilityProperty: true,
186 }))
187 const currentBlock = blocks.find(b => b.classList.contains('focus'))
188 const currentIndex = blocks.indexOf(currentBlock)
189 const padding = reverse ? -1 : 1
190 const nextIndex = currentIndex === -1 ? 0 : (currentIndex + padding + blocks.length) % blocks.length
191 const nextBlock = blocks[nextIndex]
192 blocks.forEach(b => b.classList.remove('focus'))
193 nextBlock?.classList?.add('focus')
194 nextBlock.scrollIntoView({ behavior: 'smooth', block: "nearest" })
195}
196
197function removeBlockFocus() {
198 this.blocks.forEach(b => b.classList.remove('focus'))
199}
200
201export const generateMaps = (container, callback) => { 144export const generateMaps = (container, callback) => {
202 container.classList.add('Dumby') 145 container.classList.add('Dumby')
203 const htmlHolder = container.querySelector('.SemanticHtml') ?? container 146 const htmlHolder = container.querySelector('.SemanticHtml') ?? container
@@ -208,18 +151,23 @@ export const generateMaps = (container, callback) => {
208 const renderMaps = [] 151 const renderMaps = []
209 152
210 const dumbymap = { 153 const dumbymap = {
154 layouts,
211 container, 155 container,
212 htmlHolder, 156 htmlHolder,
213 showcase, 157 showcase,
214 blocks, 158 blocks,
215 renderMaps: renderMaps, 159 renderMaps: renderMaps,
160 utils: {
161 focusNextMap: throttle(utils.focusNextMap, utils.focusDelay),
162 switchToNextLayout: throttle(utils.switchToNextLayout, 300),
163 focusNextBlock: utils.focusNextBlock,
164 removeBlockFocus: utils.removeBlockFocus,
165 }
216 } 166 }
217 dumbymap.utils = { 167 Object.entries(dumbymap.utils)
218 focusNextMap: throttle(focusNextMap.bind(dumbymap), focusDelay.bind(dumbymap)), 168 .forEach(([util, func]) => {
219 switchToNextLayout: throttle(switchToNextLayout.bind(dumbymap), 300), 169 dumbymap.utils[util] = func.bind(dumbymap)
220 focusNextBlock: focusNextBlock.bind(dumbymap), 170 })
221 removeBlockFocus: removeBlockFocus.bind(dumbymap),
222 }
223 171
224 // LeaderLine {{{ 172 // LeaderLine {{{
225 173