feat: support internal medium-zoom by site.config.ts/frontmatter

This commit is contained in:
YunYouJun 2023-01-29 21:22:21 +08:00
parent 7e598c625d
commit c2bed243f6
12 changed files with 133 additions and 39 deletions

View File

@ -100,6 +100,8 @@ export default defineSiteConfig({
enable: true,
},
mediumZoom: { enable: true },
sponsor: {
enable: true,
methods: [

View File

@ -58,6 +58,37 @@ Algolia 是一个在线第三方搜索服务,您需要自行申请相关 ID
Valaxy 提供了一个快速集成插件 [valaxy-addon-algolia](https://github.com/YunYouJun/valaxy/tree/main/packages/valaxy-addon-algolia)(目前仅支持 DocSearch
## 图片预览Medium Zoom
Valaxy 内置了 [medium-zoom](https://github.com/francoischalifour/medium-zoom) 进行图片预览,默认关闭。
> [Medium Zoom Demo](https://medium-zoom.francoischalifour.com/)
- mediumZoom
- `enable`: 是否开启
- `selector`: 可自定义传入选择器
- `options`: 与 [options | medium-zoom](https://github.com/francoischalifour/medium-zoom#options) 一致
譬如开启 Medium Zoom
```ts
// site.config.ts
import { defineSiteConfig } from 'valaxy'
export default defineSiteConfig({
mediumZoom: { enable: true }
})
```
除此之外,你也可以单独控制是否在某篇文章中开启。
```md
---
title: Test Medium Zoom
medium_zoom: true
---
```
## 音乐播放器
> 基于 [Aplayer](https://github.com/DIYgod/APlayer) 与 [MetingJS](https://github.com/metowolf/MetingJS) 实现

View File

@ -24,7 +24,7 @@ export const defaultThemeConfig: ThemeConfig = {
say: {
enable: true,
api: 'https://el-bot-api.vercel.app/api/words/young',
api: 'https://el-bot-api.elpsy.cn/api/words/young',
hitokoto: {
enable: false,
api: 'https://v1.hitokoto.cn',

View File

@ -2,8 +2,8 @@
import type { Ref } from 'vue'
import { inject, onMounted, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { useAplayer, useCodePen, useCopyCode, wrapTable } from '..'
import type { Post } from '../..'
import { useAplayer, useCodePen, useCopyCode, useMediumZoom, wrapTable } from 'valaxy'
import type { Post } from 'valaxy'
const props = defineProps<{
frontmatter: Post
@ -32,6 +32,9 @@ if (props.frontmatter.codepen)
useCodePen()
useCopyCode()
if (typeof props.frontmatter.medium_zoom === 'undefined' || props.frontmatter.medium_zoom)
useMediumZoom()
</script>
<template>
@ -64,3 +67,10 @@ useCopyCode()
</article>
</Transition>
</template>
<style>
.medium-zoom-overlay,
.medium-zoom-image--opened {
z-index: 999;
}
</style>

View File

@ -1 +1,2 @@
export * from './copy-code'
export * from './medium-zoom'

View File

@ -0,0 +1,23 @@
import mediumZoom from 'medium-zoom'
import { useSiteConfig } from 'valaxy'
import { onMounted } from 'vue'
/**
* @description image preview by medium-zoom
*/
export const useMediumZoom = () => {
const siteConfig = useSiteConfig()
const mediumZoomConfig = siteConfig.value.mediumZoom
onMounted(() => {
if (mediumZoomConfig.enable) {
mediumZoom(
mediumZoomConfig.selector || '.markdown-body img',
{
background: 'var(--medium-zoom-c-bg, rgba(0, 0, 0, 0.8))',
...mediumZoomConfig.options,
},
)
}
})
}

View File

@ -6,29 +6,6 @@ export function random(min: number, max: number) {
return Math.random() * (max - min) + min
}
/**
* wrap node
* @param className
*/
export function wrap(el: HTMLElement, className: string) {
const wrapper = document.createElement('div')
wrapper.className = className
el.parentNode!.insertBefore(wrapper, el)
el.parentNode!.removeChild(el)
wrapper.appendChild(el)
}
/**
* class table
*/
export const wrapTable = (container: HTMLElement | Document = document) => {
container.querySelectorAll('table').forEach((el) => {
const container = document.createElement('div')
container.className = 'table-container'
wrap(el, 'table-container')
})
}
export function throttleAndDebounce(fn: () => void, delay: number): () => void {
let timeout: number
let called = false

View File

@ -1,3 +1,4 @@
export * from './cdn'
export * from './helper'
export * from './time'
export * from './wrap'

View File

@ -0,0 +1,22 @@
/**
* wrap node
* @param className
*/
export function wrap(el: HTMLElement, className: string) {
const wrapper = document.createElement('div')
wrapper.className = className
el.parentNode!.insertBefore(wrapper, el)
el.parentNode!.removeChild(el)
wrapper.appendChild(el)
}
/**
* class table
*/
export const wrapTable = (container: HTMLElement | Document = document) => {
container.querySelectorAll('table').forEach((el) => {
const container = document.createElement('div')
container.className = 'table-container'
wrap(el, 'table-container')
})
}

View File

@ -76,6 +76,12 @@ export const defaultSiteConfig: SiteConfig = {
cdn: {
prefix: 'https://unpkg.com/',
},
mediumZoom: {
enable: false,
selector: '',
options: {},
},
}
export const defaultValaxyConfig: ValaxyNodeConfig = {

View File

@ -1,3 +1,4 @@
import type { ZoomOptions } from 'medium-zoom'
import type { ValaxyAddon } from '../types'
export type DefaultThemeConfig = {
@ -184,6 +185,20 @@ export interface SiteConfig {
icon: string
}[]
}
/**
* image preview by medium-zoom
* @url https://github.com/francoischalifour/medium-zoom
*/
mediumZoom: {
enable: boolean
/**
* For example: '.markdown-body img'
* @default '' content.value querySelectorAll('img')
*/
selector: string | HTMLElement | HTMLElement[]
options: ZoomOptions
}
}
export type PartialDeep<T> = {

View File

@ -100,19 +100,6 @@ export interface Post extends Record<string, any> {
*/
end?: boolean
/**
* use aplayer
*/
aplayer?: boolean
/**
* use katex
*/
katex?: boolean
/**
* use codepen
*/
codepen?: boolean
/**
*
*/
@ -145,4 +132,23 @@ export interface Post extends Record<string, any> {
* @description markdown
*/
markdown?: boolean
// third-party features
/**
* use aplayer
*/
aplayer?: boolean
/**
* use katex
*/
katex?: boolean
/**
* use codepen
*/
codepen?: boolean
/**
* use medium-zoom
* @url https://github.com/francoischalifour/medium-zoom
*/
medium_zoom: boolean
}