Skip to content

Commit

Permalink
feat(plugin-photo-swipe): support download and fullscreen option, close
Browse files Browse the repository at this point in the history
  • Loading branch information
Mister-Hope committed Jun 4, 2024
1 parent 421fece commit 260f9be
Show file tree
Hide file tree
Showing 11 changed files with 135 additions and 59 deletions.
12 changes: 12 additions & 0 deletions docs/plugins/features/photo-swipe.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ In preview mode, you can:
- Default: `".theme-default-content :not(a) > img:not([no-view])"`
- Details: Image selector

### download

- Type: `boolean`
- Default: `true`
- Details: Whether to show the download button.

### fullscreen

- Type: `boolean`
- Default: `true`
- Details: Whether to show the fullscreen button.

### scrollToClose

- Type: `boolean`
Expand Down
12 changes: 12 additions & 0 deletions docs/zh/plugins/features/photo-swipe.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ export default {
- 默认值:`".theme-default-content :not(a) > img:not([no-view])"`
- 详情:图片选择器

### download

- 类型:`boolean`
- 默认值:`true`
- 详情:是否显示下载按钮。

### fullscreen

- 类型:`boolean`
- 默认值:`true`
- 详情:是否显示全屏按钮。

### scrollToClose

- 类型:`boolean`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,27 @@ import { usePageData, usePageFrontmatter } from 'vuepress/client'
import type { PhotoSwipePluginLocaleData } from '../../shared/index.js'
import { usePhotoSwipeOptions } from '../helpers/index.js'
import { getImages, registerPhotoSwipe } from '../utils/index.js'
import type { PhotoSwipeBehaviorOptions } from '../utils/index.js'

import 'photoswipe/dist/photoswipe.css'
import '../styles/photo-swipe.css'

export interface UsePhotoSwipeOptions {
export interface UsePhotoSwipeOptions extends PhotoSwipeBehaviorOptions {
selector: string | string[]
locales: Record<
string,
Record<`${keyof PhotoSwipePluginLocaleData}Title`, string>
>
/** @default 500 */
delay?: number
/** @default true */
scrollToClose?: boolean
}

export const usePhotoSwipe = ({
selector,
locales,
delay = 500,
download = true,
fullscreen = true,
scrollToClose = true,
}: UsePhotoSwipeOptions): void => {
const photoSwipeOptions = usePhotoSwipeOptions()
Expand All @@ -42,14 +43,13 @@ export const usePhotoSwipe = ({
.then(async () => {
const imageSelector = isString(photoSwipe) ? photoSwipe : selector

destroy = await registerPhotoSwipe(
getImages(imageSelector),
{
...photoSwipeOptions.value,
...locale.value,
},
destroy = await registerPhotoSwipe(getImages(imageSelector), {
...photoSwipeOptions.value,
...locale.value,
download,
fullscreen,
scrollToClose,
)
})
})
}

Expand Down
6 changes: 6 additions & 0 deletions plugins/features/plugin-photo-swipe/src/client/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@ declare const __PS_LOCALES__: Record<
string,
Record<`${keyof PhotoSwipePluginLocaleData}Title`, string>
>
declare const __PS_DOWNLOAD__: boolean
declare const __PS_FULLSCREEN__: boolean
declare const __PS_SCROLL_TO_CLOSE__: boolean

const selector = __PS_SELECTOR__
const locales = __PS_LOCALES__
const delay = __PS_DELAY__
const download = __PS_DOWNLOAD__
const fullscreen = __PS_FULLSCREEN__
const scrollToClose = __PS_SCROLL_TO_CLOSE__

// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
Expand All @@ -29,6 +33,8 @@ export default defineClientConfig({
selector,
delay,
locales,
download,
fullscreen,
scrollToClose,
})
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { PhotoSwipeOptions } from '../helpers/index.js'
import { LOADING_ICON } from './icon.js'
import { getImageUrlInfo } from './images.js'
import { initPhotoSwipe } from './initPhotoSwipe.js'
import type { PhotoSwipeBehaviorOptions } from './typings.js'

export interface PhotoSwipeState {
open: (index: number) => void
Expand All @@ -14,8 +15,12 @@ export interface PhotoSwipeState {

export const createPhotoSwipe = (
images: string[],
photoSwipeOptions: PhotoSwipeOptions,
scrollToClose = true,
{
scrollToClose = true,
download = true,
fullscreen = true,
...photoSwipeOptions
}: PhotoSwipeOptions & PhotoSwipeBehaviorOptions,
): Promise<PhotoSwipeState> =>
import(/* webpackChunkName: "photo-swipe" */ 'photoswipe').then(
({ default: PhotoSwipe }) => {
Expand Down Expand Up @@ -52,7 +57,7 @@ export const createPhotoSwipe = (
: {}),
})

initPhotoSwipe(currentPhotoSwipe)
initPhotoSwipe(currentPhotoSwipe, { download, fullscreen })

currentPhotoSwipe.addFilter('placeholderSrc', () => images[index])
currentPhotoSwipe.init()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './createPhotoSwipe.js'
export * from './images.js'
export * from './usePhotoSwipe.js'
export * from './typings.js'
Original file line number Diff line number Diff line change
@@ -1,50 +1,14 @@
import { useFullscreen } from '@vueuse/core'
import type PhotoSwipe from 'photoswipe'

export const initPhotoSwipe = (photoSwipe: PhotoSwipe): void => {
const { isSupported, toggle } = useFullscreen()

export const initPhotoSwipe = (
photoSwipe: PhotoSwipe,
{
download = true,
fullscreen = true,
}: { download?: boolean; fullscreen?: boolean } = {},
): void => {
photoSwipe.on('uiRegister', () => {
if (isSupported.value)
// add fullscreen button
photoSwipe.ui!.registerElement({
name: 'fullscreen',
order: 7,
isButton: true,

html: '<svg class="pswp__icn" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path d="M249.5 270.833H437v-75H212a37.5 37.5 0 0 0-37.5 37.5v225h75v-187.5zm-37.5 600h225v-75H249.5v-187.5h-75v225a37.5 37.5 0 0 0 37.5 37.5zm637.5-37.5v-225h-75v187.5H587v75h225a37.5 37.5 0 0 0 37.5-37.5zM587 270.833h187.5v187.5h75v-225a37.5 37.5 0 0 0-37.5-37.5H587v75z"/></svg>',

onClick: () => {
toggle()
},
})

// add download button
photoSwipe.ui!.registerElement({
name: 'download',
order: 8,
isButton: true,
tagName: 'a',

// SVG with outline
html: {
isCustomSVG: true,
inner:
'<path d="M20.5 14.3 17.1 18V10h-2.2v7.9l-3.4-3.6L10 16l6 6.1 6-6.1-1.5-1.6ZM23 23H9v2h14" id="pswp__icn-download"/>',
outlineID: 'pswp__icn-download',
},

onInit: (el, photoSwipe) => {
el.setAttribute('download', '')
el.setAttribute('target', '_blank')
el.setAttribute('rel', 'noopener')

photoSwipe.on('change', () => {
el.setAttribute('href', photoSwipe.currSlide!.data.src!)
})
},
})

// add bullets indicator
photoSwipe.ui!.registerElement({
name: 'bulletsIndicator',
Expand Down Expand Up @@ -73,5 +37,51 @@ export const initPhotoSwipe = (photoSwipe: PhotoSwipe): void => {
})
},
})

// add fullscreen button if supported
if (fullscreen) {
const { isSupported, toggle } = useFullscreen()

if (isSupported.value)
photoSwipe.ui!.registerElement({
name: 'fullscreen',
order: 7,
isButton: true,

html: '<svg class="pswp__icn" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path d="M249.5 270.833H437v-75H212a37.5 37.5 0 0 0-37.5 37.5v225h75v-187.5zm-37.5 600h225v-75H249.5v-187.5h-75v225a37.5 37.5 0 0 0 37.5 37.5zm637.5-37.5v-225h-75v187.5H587v75h225a37.5 37.5 0 0 0 37.5-37.5zM587 270.833h187.5v187.5h75v-225a37.5 37.5 0 0 0-37.5-37.5H587v75z"/></svg>',

onClick: () => {
toggle()
},
})
}

if (download) {
// add download button
photoSwipe.ui!.registerElement({
name: 'download',
order: 8,
isButton: true,
tagName: 'a',

// SVG with outline
html: {
isCustomSVG: true,
inner:
'<path d="M20.5 14.3 17.1 18V10h-2.2v7.9l-3.4-3.6L10 16l6 6.1 6-6.1-1.5-1.6ZM23 23H9v2h14" id="pswp__icn-download"/>',
outlineID: 'pswp__icn-download',
},

onInit: (el, photoSwipe) => {
el.setAttribute('download', '')
el.setAttribute('target', '_blank')
el.setAttribute('rel', 'noopener')

photoSwipe.on('change', () => {
el.setAttribute('href', photoSwipe.currSlide!.data.src!)
})
},
})
}
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface PhotoSwipeBehaviorOptions {
download?: boolean
fullscreen?: boolean
scrollToClose?: boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@ import type { PhotoSwipeOptions } from '../helpers/index.js'
import { LOADING_ICON } from './icon.js'
import { getImageElementInfo } from './images.js'
import { initPhotoSwipe } from './initPhotoSwipe.js'
import type { PhotoSwipeBehaviorOptions } from './typings.js'

export const registerPhotoSwipe = (
images: HTMLImageElement[],
photoSwipeOptions: PhotoSwipeOptions,
scrollToClose = true,
{
scrollToClose = true,
download = true,
fullscreen = true,
...photoSwipeOptions
}: PhotoSwipeOptions & PhotoSwipeBehaviorOptions,
): Promise<() => void> =>
import(/* webpackChunkName: "photo-swipe" */ 'photoswipe').then(
({ default: PhotoSwipe }) => {
Expand All @@ -35,7 +40,7 @@ export const registerPhotoSwipe = (
: {}),
})

initPhotoSwipe(currentPhotoSwipe)
initPhotoSwipe(currentPhotoSwipe, { download, fullscreen })

currentPhotoSwipe.addFilter('thumbEl', () => image)
currentPhotoSwipe.addFilter('placeholderSrc', () => image.src)
Expand Down
18 changes: 18 additions & 0 deletions plugins/features/plugin-photo-swipe/src/node/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,24 @@ export interface PhotoSwipePluginOptions {
*/
selector?: string | string[]

/**
* Whether to enable the download button
*
* 是否启用下载按钮
*
* @default true
*/
download?: boolean

/**
* Whether to enable the fullscreen button
*
* 是否启用全屏按钮
*
* @default true
*/
fullscreen?: boolean

/**
* Whether close the current image when scrolling.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export const photoSwipePlugin =
options.selector ||
'.theme-default-content :not(a) > img:not([no-view])',
__PS_DELAY__: options.delay || 800,
__PS_DOWNLOAD__: options.download ?? true,
__PS_FULLSCREEN__: options.fullscreen ?? true,
__PS_SCROLL_TO_CLOSE__: options.scrollToClose ?? true,
__PS_LOCALES__: fromEntries(
entries(
Expand Down

0 comments on commit 260f9be

Please sign in to comment.