|
| 1 | +<div id="image-modal" class="image-modal"> |
| 2 | + <button type="button" class="close" title="Minimize this image" aria-label="Minimize this image"> |
| 3 | + <svg width="60" height="60" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M35.97 25.37L38.6 28H32v-6.6l2.63 2.63L38.67 20 40 21.33l-4.03 4.04zM24.03 34.63L21.4 32H28v6.6l-2.63-2.63L21.33 40 20 38.67l4.03-4.04z" fill="#000"/></svg> |
| 4 | + </button> |
| 5 | + <div class="img-wrapper"> |
| 6 | + <img class="modal-image" id="img1" /> |
| 7 | + </div> |
| 8 | + <!-- expandIconSvg svg inlined, will be used in image overlay and removed from here on document load. JS in footer.ejs does this--> |
| 9 | + <svg id="expandIconSvg" width="60" height="60" fill="#fff"><circle cx="30" cy="30" r="30" fill="#000" fill-opacity=".5"/><path fill-rule="evenodd" clip-rule="evenodd" d="M23.97 37.37L26.6 40H20v-6.6l2.63 2.63L26.67 32 28 33.33l-4.03 4.04zM36.03 22.63L33.4 20H40v6.6l-2.63-2.63L33.33 28 32 26.67l4.03-4.04z"/></svg> |
| 10 | +</div> |
| 11 | + |
| 12 | +<script> |
| 13 | + var imgWrapper |
| 14 | + function createImageOverlayWrapper() { |
| 15 | + if (imgWrapper) { // cache hit |
| 16 | + return imgWrapper |
| 17 | + } |
| 18 | +
|
| 19 | + // read expandIcon from image-modal where its inlined so that we |
| 20 | + // can read it here. then remove it and strip the id since it'll be used multiple times |
| 21 | + const expandIconSvg = document.getElementById('expandIconSvg') |
| 22 | + expandIconSvg.remove() |
| 23 | + expandIconSvg.id = "" |
| 24 | +
|
| 25 | +
|
| 26 | + let wrapperDiv = document.createElement('div') |
| 27 | + wrapperDiv.className = 'image-wrapper' |
| 28 | +
|
| 29 | + let expandBtn = document.createElement('button') |
| 30 | + expandBtn.setAttribute('aria-label', 'expand this image') |
| 31 | + expandBtn.title = 'expand this image' |
| 32 | + expandBtn.className='expand-image-btn' |
| 33 | + expandBtn.appendChild(expandIconSvg) |
| 34 | +
|
| 35 | + wrapperDiv.appendChild(expandBtn) |
| 36 | +
|
| 37 | + imgWrapper = wrapperDiv // add to cache |
| 38 | +
|
| 39 | + return wrapperDiv |
| 40 | + } |
| 41 | +
|
| 42 | + function wrapImageInOverlay(imgElement) { |
| 43 | + // clone the wrapper so the original isn't mutated and we can reuse it |
| 44 | + const overlayWrapper = createImageOverlayWrapper().cloneNode(true) |
| 45 | +
|
| 46 | + imgElement.parentNode.insertBefore(overlayWrapper, imgElement) |
| 47 | + overlayWrapper.appendChild(imgElement) |
| 48 | + } |
| 49 | +
|
| 50 | + window.onload = () => { |
| 51 | + const imgs = document.querySelectorAll('.g-main-content img'); // get all images |
| 52 | +
|
| 53 | + // for each image - add overlay allowing for expand btn and click handler for expansion |
| 54 | + imgs.forEach((img, idx) => { |
| 55 | + wrapImageInOverlay(img); |
| 56 | + img.addEventListener('click', () => expandImage(img.src)); |
| 57 | + }); |
| 58 | + } |
| 59 | +
|
| 60 | + var imgModal = document.querySelector('.image-modal') |
| 61 | + var imgModalImg = document.querySelector('.image-modal .modal-image'); |
| 62 | +
|
| 63 | + function expandImage(imgSrc) { |
| 64 | + imgModal.style.display = 'block'; |
| 65 | + imgModalImg.src = imgSrc; |
| 66 | +
|
| 67 | + window.addEventListener('scroll', function onScroll() { |
| 68 | + window.removeEventListener('scroll', onScroll); |
| 69 | + imgModal.style.display='none'; |
| 70 | + }); |
| 71 | + }; |
| 72 | +
|
| 73 | + var modalCloseBtn = document.querySelector('.image-modal .close'); |
| 74 | + modalCloseBtn.addEventListener('click', () => { |
| 75 | + imgModal.style.display = 'none'; |
| 76 | + }); |
| 77 | +
|
| 78 | + /* keydown listener so img modal can be closed with Esc key */ |
| 79 | + document.addEventListener('keydown', (event) => { |
| 80 | + if (event.key === 'Escape' && imgModal.style.display === 'block') { |
| 81 | + imgModal.style.display = 'none'; |
| 82 | + } |
| 83 | + }); |
| 84 | +</script> |
0 commit comments