Skip to content

Commit 619aabf

Browse files
committed
Implement simple lightbox
Signed-off-by: Yukai Huang <[email protected]>
1 parent b142c02 commit 619aabf

File tree

3 files changed

+166
-0
lines changed

3 files changed

+166
-0
lines changed

public/js/extra.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
deserializeParamAttributeFromElement
2222
} from './lib/markdown/utils'
2323
import { renderFretBoard } from './lib/renderer/fretboard/fretboard'
24+
import './lib/renderer/lightbox'
2425

2526
import markdownit from 'markdown-it'
2627
import markdownitContainer from 'markdown-it-container'
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import './lightbox.css'
2+
3+
let images = []
4+
let currentImage = null
5+
let currentIndexIndex = 0
6+
7+
function findOrCreateLightboxContainer () {
8+
const lightboxContainerSelector = '.lightbox-container'
9+
10+
let lightBoxContainer = document.querySelector(lightboxContainerSelector)
11+
if (!lightBoxContainer) {
12+
lightBoxContainer = document.createElement('div')
13+
lightBoxContainer.className = 'lightbox-container'
14+
15+
lightBoxContainer.innerHTML = `
16+
<i class="fa fa-chevron-left lightbox-control-previous" aria-hidden="true"></i>
17+
<i class="fa fa-chevron-right lightbox-control-next" aria-hidden="true"></i>
18+
<i class="fa fa-close lightbox-control-close" aria-hidden="true"></i>
19+
20+
<div class="lightbox-inner">
21+
</div>
22+
`
23+
24+
const hideContainer = (e) => {
25+
e.stopPropagation()
26+
lightBoxContainer.classList.remove('show')
27+
}
28+
29+
lightBoxContainer.querySelector('.lightbox-control-previous').addEventListener('click', (e) => {
30+
e.stopPropagation()
31+
switchImage(-1)
32+
})
33+
lightBoxContainer.querySelector('.lightbox-control-next').addEventListener('click', (e) => {
34+
e.stopPropagation()
35+
switchImage(1)
36+
})
37+
lightBoxContainer.querySelector('.lightbox-control-close').addEventListener('click', hideContainer)
38+
lightBoxContainer.addEventListener('click', hideContainer)
39+
40+
document.body.appendChild(lightBoxContainer)
41+
}
42+
43+
return lightBoxContainer
44+
}
45+
46+
function switchImage (dir) {
47+
const lightBoxContainer = findOrCreateLightboxContainer()
48+
49+
currentIndexIndex += dir
50+
if (currentIndexIndex >= images.length) {
51+
currentIndexIndex = 0
52+
} else if (currentIndexIndex < 0) {
53+
currentIndexIndex = images.length - 1
54+
}
55+
56+
const img = images[currentIndexIndex]
57+
58+
setImageInner(img, lightBoxContainer)
59+
}
60+
61+
function setImageInner (img, lightBoxContainer) {
62+
const src = img.getAttribute('src')
63+
const alt = img.getAttribute('alt')
64+
65+
lightBoxContainer.querySelector('.lightbox-inner').innerHTML = `<img src="${src}" alt="${alt}">`
66+
}
67+
68+
function onClickImage (img) {
69+
const lightBoxContainer = findOrCreateLightboxContainer()
70+
71+
setImageInner(img, lightBoxContainer)
72+
73+
lightBoxContainer.classList.add('show')
74+
75+
currentImage = img
76+
updateLightboxImages()
77+
}
78+
79+
function updateLightboxImages () {
80+
images = [...document.querySelectorAll('.markdown-body img:not(.emoji)')]
81+
82+
if (currentImage) {
83+
currentIndexIndex = images.findIndex(image => image === currentImage)
84+
}
85+
}
86+
87+
const init = () => {
88+
const markdownBody = document.querySelector('.markdown-body')
89+
if (!markdownBody) {
90+
return
91+
}
92+
93+
markdownBody.addEventListener('click', function (e) {
94+
if (e.target.nodeName === 'IMG' && !e.target.classList.contains('emoji')) {
95+
onClickImage(e.target)
96+
e.stopPropagation()
97+
}
98+
})
99+
}
100+
101+
init()
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
.lightbox-container.show {
2+
display: flex !important;
3+
}
4+
5+
.lightbox-container {
6+
display: none;
7+
8+
position: fixed;
9+
z-index: 99999;
10+
background-color: rgba(255, 255, 255, 0.8);
11+
top: 0;
12+
left: 0;
13+
width: 100%;
14+
height: 100%;
15+
16+
justify-content: center;
17+
align-items: center;
18+
padding: 0px 40px;
19+
}
20+
21+
.lightbox-container .lightbox-control-previous,
22+
.lightbox-container .lightbox-control-next,
23+
.lightbox-container .lightbox-control-close {
24+
position: absolute;
25+
width: 40px;
26+
height: 40px;
27+
color: rgba(65, 65, 65, 0.8);
28+
text-align: center;
29+
cursor: pointer;
30+
user-select: none;
31+
font-size: 25px;
32+
}
33+
34+
.lightbox-container .lightbox-control-previous:hover,
35+
.lightbox-container .lightbox-control-next:hover,
36+
.lightbox-container .lightbox-control-close:hover {
37+
cursor: rgba(130, 130, 130, 0.78);
38+
}
39+
40+
.lightbox-container .lightbox-control-next,
41+
.lightbox-container .lightbox-control-previous {
42+
top: calc(50% - 10px);
43+
}
44+
45+
.lightbox-container .lightbox-control-previous {
46+
left: 0;
47+
}
48+
49+
.lightbox-container .lightbox-control-next {
50+
right: 0;
51+
}
52+
53+
.lightbox-container .lightbox-control-close {
54+
top: 10px;
55+
right: 10px;
56+
}
57+
58+
.lightbox-container .lightbox-inner img {
59+
max-width: 100%;
60+
}
61+
62+
.markdown-body img:not(.emoji) {
63+
cursor: zoom-in;
64+
}

0 commit comments

Comments
 (0)