Feature/lightbox (#309)

add Lightbox
This commit is contained in:
Ilya Y 2023-11-13 11:05:05 +03:00 committed by GitHub
parent 2c7e98acdf
commit 4121d99a73
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 131 additions and 7 deletions

View File

@ -36,6 +36,7 @@ img {
img {
display: block;
margin-bottom: 0.5em;
cursor: zoom-in;
}
blockquote,

View File

@ -27,6 +27,7 @@ import { createPopper } from '@popperjs/core'
import { AuthorBadge } from '../Author/AuthorBadge'
import { getImageUrl } from '../../utils/getImageUrl'
import { FeedArticlePopup } from '../Feed/FeedArticlePopup'
import { Lightbox } from '../_shared/Lightbox'
type Props = {
article: Shout
@ -49,6 +50,8 @@ const scrollTo = (el: HTMLElement) => {
}
export const FullArticle = (props: Props) => {
const [selectedImage, setSelectedImage] = createSignal('')
const { t, formatDate } = useLocalize()
const {
user,
@ -169,7 +172,7 @@ export const FullArticle = (props: Props) => {
document.body.appendChild(tooltip)
if (element.hasAttribute('href')) {
element.setAttribute('href', 'javascript: void(0);')
element.setAttribute('href', 'javascript: void(0)')
}
const popperInstance = createPopper(element, tooltip, {
@ -230,7 +233,19 @@ export const FullArticle = (props: Props) => {
})
})
const [isActionPopupActive, setIsActionPopupActive] = createSignal(false)
const openLightbox = (image) => {
setSelectedImage(image)
}
const handleLightboxClose = () => {
setSelectedImage()
}
const handleArticleBodyClick = (event) => {
if (event.target.tagName === 'IMG') {
const src = event.target.src
openLightbox(getImageUrl(src))
}
}
return (
<>
@ -313,7 +328,7 @@ export const FullArticle = (props: Props) => {
</Show>
<Show when={body()}>
<div id="shoutBody" class={styles.shoutBody}>
<div id="shoutBody" class={styles.shoutBody} onClick={handleArticleBodyClick}>
<Show when={!body().startsWith('<')} fallback={<div innerHTML={body()} />}>
<MD body={body()} />
</Show>
@ -433,7 +448,6 @@ export const FullArticle = (props: Props) => {
description={getDescription(props.article.body)}
imageUrl={props.article.cover}
shareUrl={getShareUrl({ pathname: `/${props.article.slug}` })}
isVisible={(value) => setIsActionPopupActive(value)}
trigger={
<button>
<Icon name="ellipsis" class={clsx(styles.icon)} />
@ -490,6 +504,9 @@ export const FullArticle = (props: Props) => {
</div>
</div>
</div>
<Show when={selectedImage()}>
<Lightbox image={selectedImage()} onClose={handleLightboxClose} />
</Show>
</>
)
}

View File

@ -0,0 +1,52 @@
.Lightbox {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgb(0 0 0 / 80%);
display: flex;
align-items: center;
justify-content: center;
z-index: 10000;
.image {
max-width: 90%;
max-height: 80%;
cursor: pointer;
}
.close {
position: absolute;
top: 20px;
right: 40px;
font-size: 30px;
color: white;
cursor: pointer;
width: 20px;
height: 20px;
}
.zoomControls {
display: flex;
position: absolute;
bottom: 16px;
left: 50%;
height: 24px;
gap: 1rem;
transform: translateX(-50%);
.control {
border-radius: 50%;
width: 24px;
height: 24px;
font-size: 20px;
line-height: 1;
display: flex;
align-items: center;
justify-content: center;
border: 2px solid #fff;
color: #fff;
}
}
}

View File

@ -0,0 +1,56 @@
import { clsx } from 'clsx'
import styles from './Lightbox.module.scss'
import { createSignal } from 'solid-js'
import { Icon } from '../Icon'
type Props = {
class?: string
image: string
onClose: () => void
}
const ZOOM_STEP = 1.08
export const Lightbox = (props: Props) => {
const [zoomLevel, setZoomLevel] = createSignal(1)
const closeLightbox = () => {
props.onClose()
}
const zoomIn = (event) => {
event.stopPropagation()
setZoomLevel(zoomLevel() * ZOOM_STEP)
}
const zoomOut = (event) => {
event.stopPropagation()
setZoomLevel(zoomLevel() / ZOOM_STEP)
}
const lightboxStyle = () => ({
transform: `scale(${zoomLevel()})`,
transition: 'transform 0.3s ease'
})
return (
<div class={clsx(styles.Lightbox, props.class)} onClick={closeLightbox}>
<span class={styles.close} onClick={closeLightbox}>
<Icon name="close-white" />
</span>
<div class={styles.zoomControls}>
<button class={styles.control} onClick={(event) => zoomOut(event)}>
<b>-</b>
</button>
<button class={styles.control} onClick={(event) => zoomIn(event)}>
<b>+</b>
</button>
</div>
<img
class={styles.image}
src={props.image}
style={lightboxStyle()}
alt={''}
onClick={(event) => event.stopPropagation()}
/>
</div>
)
}

View File

@ -0,0 +1 @@
export { Lightbox } from './Lightbox'

View File

@ -69,9 +69,6 @@ const useProfileForm = () => {
})
}
}
createEffect(() => {
console.log('!!! FL:', form.links)
})
return { form, submit, updateFormField, slugError }
}