PageSourceSearch

https://earl2021-aru.netlify.app/libs/tile-view/tile-view.js

js earl2021-aru.netlify.app collected 2026-10-03 10:40:28 UTC 5,553 bytes, 177 lines download raw bytes

1/*
2 *  Tile View for remark.js Slides
3 *
4 *  Garrick Aden-Buie
5 *
6 *  Inspired and converted to Vanilla JS from
7 *  https://github.com/StephenHesperus/remark-hook/
8 *
9 *  Include after remarkjs slides are initialized.
10 *
11 */
12
13/* global slideshow */
14(function () {
15  const ready = function (fn) {
16    /* MIT License Copyright (c) 2016 Nuclei */
17    /* https://github.com/nuclei/readyjs */
18    const completed = () => {
19      document.removeEventListener('DOMContentLoaded', completed)
20      window.removeEventListener('load', completed)
21      fn()
22    }
23    if (document.readyState !== 'loading') {
24      setTimeout(fn)
25    } else {
26      document.addEventListener('DOMContentLoaded', completed)
27      window.addEventListener('load', completed)
28    }
29  }
30
31  ready(function () {
32    const launchKey = 79 // keycode for O, used to enable tile view
33
34    // Slides container
35    const remarkSlideShow = document.querySelector('div.remark-slides-area')
36
37    let tileView = document.querySelector('div.remark__tile-view')
38    if (!tileView) {
39      tileView = document.createElement('div')
40      tileView.className = 'remark__tile-view'
41    }
42
43    const toggleElement = el => {
44      el.style.display = el.style.display === 'none' ? '' : 'none'
45    }
46
47    function slideshowResize () {
48      window.dispatchEvent(new Event('resize'))
49    }
50
51    const toggleTileView = function () {
52      toggleElement(tileView)
53      toggleElement(remarkSlideShow)
54
55      if (tileView.style.display === 'none') {
56        // tileView is now hidden, go to current slide
57        slideshow.gotoSlide(tileVars.currentSlideIdx + 1)
58
59        slideshow.resume()
60        slideshowResize()
61      } else {
62        // store current slide index prior to launching tile-view
63        tileVars.currentSlideIdx = slideshow.getCurrentSlideIndex()
64
65        // set class on seen and current slide and scroll into view
66        const tiles = tileView.querySelectorAll('.remark__tile-view__tile');
67        [...tiles].forEach((tile, idx) => {
68          tile.classList.toggle(
69            'remark__tile-view__tile--seen',
70            idx < tileVars.currentSlideIdx
71          )
72          tile.classList.toggle(
73            'remark__tile-view__tile--current',
74            idx === tileVars.currentSlideIdx
75          )
76        })
77        tiles[tileVars.currentSlideIdx].scrollIntoView({
78          behavior: 'smooth',
79          block: 'center'
80        })
81
82        slideshow.pause()
83      }
84    }
85
86    const createTileView = ({ minSize = 250, title = document.title } = {}) => {
87      // Tile view header
88      const h1 = document.createElement('h1')
89      h1.className = 'remark__tile-view__header'
90      h1.innerHTML = title
91
92      tileView.appendChild(h1)
93      const tiles = document.createElement('div')
94      tiles.className = 'remark__tile-view__tiles'
95      tileView.appendChild(tiles)
96
97      // Clone slideshow
98      const slidesArea = remarkSlideShow.cloneNode(true)
99
100      // Calculate slide scale and tile container size
101      const slideScaler = slidesArea.querySelector('.remark-slide-scaler')
102      const slideWidth = parseFloat(slideScaler.style.width.replace('px', ''))
103      const slideHeight = parseFloat(
104        slideScaler.style.height.replace('px', '')
105      )
106      const scale = minSize / Math.min(slideWidth, slideHeight)
107      let tileWidth = Math.round(slideWidth * scale)
108      let tileHeight = Math.round(slideHeight * scale)
109
110      // convert tileWidth/Height to em relative to base 18px (set in CSS)
111      tileWidth = tileWidth / 18
112      tileHeight = tileHeight / 18
113
114      tiles.style.gridTemplateColumns = `repeat(auto-fill, minmax(${tileWidth}em, 1fr))`
115
116      const slides = slidesArea.querySelectorAll('.remark-slide-container')
117
118      slides.forEach((slide, slideIndex) => {
119        let tile = document.createElement('template')
120        tile.innerHTML = `<div class="remark__tile-view__tile">
121            <div class="remark__tile-view__slide-container">
122            </div></div>`
123        tile = tile.content.firstChild
124
125        const tileContainer = tile.querySelector(
126          '.remark__tile-view__slide-container'
127        )
128        tileContainer.style.width = `${tileWidth}em`
129        tileContainer.style.height = `${tileHeight}em`
130
131        const thisSlideScaler = slide.querySelector('.remark-slide-scaler')
132        thisSlideScaler.style.top = '0px'
133        thisSlideScaler.style.left = '0px'
134        thisSlideScaler.style.transform = `scale(${scale})`
135        thisSlideScaler.parentElement.classList.add('remark-visible')
136
137        slide.addEventListener('click', () => {
138          tileVars.currentSlideIdx = slideIndex
139          toggleTileView()
140        })
141
142        tileContainer.appendChild(slide)
143        tiles.appendChild(tile)
144      })
145
146      document.body.appendChild(tileView)
147    }
148
149    const tileVars = {}
150
151    document.addEventListener('keydown', ev => {
152      if (ev.keyCode === launchKey) {
153        toggleTileView()
154      }
155    })
156
157    const addTileViewHelpText = () => {
158      const helpTable = document.querySelector(
159        '.remark-help-content table.light-keys'
160      )
161      if (!helpTable) {
162        console.error(
163          'Could not find remark help table, has remark been initialized?'
164        )
165        return
166      }
167      const newRow = document.createElement('tr')
168      newRow.innerHTML += '<td><span class="key">o</span></td>'
169      newRow.innerHTML += '<td>Tile View: Overview of Slides</td>'
170      helpTable.append(newRow)
171    }
172
173    createTileView({ minSize: 200 })
174    toggleElement(tileView)
175    addTileViewHelpText()
176  })
177})()

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.