Skip to content

Commit

Permalink
feat: support enabling drawings in build
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Sep 13, 2021
1 parent 38f2128 commit 74077a4
Show file tree
Hide file tree
Showing 20 changed files with 206 additions and 151 deletions.
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"cypress/globals": true
},
"globals": {
"__DEV__": true
"__DEV__": true,
"__SLIDEV_FEATURE_DRAWINGS__": true
},
"extends": "@antfu",
"plugins": ["jest", "cypress"],
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ packages/slidev/README.md
packages/create-app/template/slides.md
composable-vue-cn
components.d.ts
.slidev
25 changes: 13 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,18 @@ Status: <b>Public Beta 🎉</b><br>

- 📝 [**Markdown-based**](https://sli.dev/guide/syntax.html) - use your favorite editors and workflow
- 🧑‍💻 [**Developer Friendly**](https://sli.dev/guide/syntax.html#code-blocks) - built-in syntax highlighting, live coding, etc.
- 🎨 [**Themable**](https://sli.dev/themes/gallery.html) - theme can be shared and used with npm packages
- 🌈 [**Stylish**](https://sli.dev/guide/syntax.html#embedded-styles) - [Windi CSS](https://windicss.org/) on-demand utilities, easy-to-use embedded stylesheets
- 🤹 [**Interactive**](https://sli.dev/custom/directory-structure.html#components) - embedding Vue components seamlessly
- 🎙 [**Presenter Mode**](https://sli.dev/guide/presenter-mode.html) - use another window, or even your phone to control your slides
- 🧮 [**LaTeX**](https://sli.dev/guide/syntax.html#latex) - Built-in LaTeX math equations support
- 📰 [**Diagrams**](https://sli.dev/guide/syntax.html#diagrams) - Creates diagrams with textual descriptions
- 🌟 [**Icons**](https://sli.dev/guide/syntax.html#icons) - Access to icons from any iconset directly
- 💻 [**Editors**](https://sli.dev/guide/editors.html) - Integrated editor, or [extension for VS Code](https://github.com/slidevjs/slidev-vscode)
- 🎥 [**Recording**](https://sli.dev/guide/recording.html) - built-in recording and camera view
- 📤 [**Portable**](https://sli.dev/guide/exporting.html) - export into PDF, PNGs, or even a hostable SPA
- ⚡️ [**Fast**](https://vitejs.dev) - instant reloading powered by [Vite](https://vitejs.dev)
- 🛠 [**Hackable**](https://sli.dev/custom/config-vite.html) - using Vite plugins, Vue components, or any npm packages
- 🎨 [**Themable**](https://sli.dev/themes/gallery.html) - theme can be shared and used with npm packages.
- 🌈 [**Stylish**](https://sli.dev/guide/syntax.html#embedded-styles) - [Windi CSS](https://windicss.org/) on-demand utilities, easy-to-use embedded stylesheets.
- 🤹 [**Interactive**](https://sli.dev/custom/directory-structure.html#components) - embedding Vue components seamlessly.
- 🎙 [**Presenter Mode**](https://sli.dev/guide/presenter-mode.html) - use another window, or even your phone to control your slides.
- 🧮 [**LaTeX**](https://sli.dev/guide/syntax.html#latex) - built-in LaTeX math equations support.
- 📰 [**Diagrams**](https://sli.dev/guide/syntax.html#diagrams) - creates diagrams with textual descriptions
- 🌟 [**Icons**](https://sli.dev/guide/syntax.html#icons) - access to icons from any iconset directly.
- 💻 [**Editors**](https://sli.dev/guide/editors.html) - integrated editor, or [extension for VS Code](https://github.com/slidevjs/slidev-vscode)
- 🎥 [**Recording**](https://sli.dev/guide/recording.html) - built-in recording and camera view.
- 📤 [**Portable**](https://sli.dev/guide/exporting.html) - export into PDF, PNGs, or even a hostable SPA.
- ⚡️ [**Fast**](https://vitejs.dev) - instant reloading powered by [Vite](https://vitejs.dev).
- 🛠 [**Hackable**](https://sli.dev/custom/config-vite.html) - using Vite plugins, Vue components, or any npm packages.

## Getting Started

Expand All @@ -76,6 +76,7 @@ For a full example, you can check the [demo](https://github.com/slidevjs/slidev/
- [RecordRTC](https://recordrtc.org) - Built-in recording and camera view
- [VueUse](https://vueuse.org) family - [`@vueuse/core`](https://github.com/vueuse/vueuse), [`@vueuse/head`](https://github.com/vueuse/head), [`@vueuse/motion`](https://github.com/vueuse/motion), etc.
- [Iconify](https://iconify.design/) - Iconsets collection.
- [Drauu](https://github.com/antfu/drauu) - Drawing and annotations support
- [KaTeX](https://katex.org/) - LaTeX math rendering.
- [Mermaid](https://mermaid-js.github.io/mermaid) - Textual Diagrams.

Expand Down
2 changes: 2 additions & 0 deletions demo/starter/slides.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ info: |
Learn more at [Sli.dev](https://sli.dev)
title: Welcome to Slidev
drawings:
persist: true
---

# Welcome to Slidev
Expand Down
6 changes: 4 additions & 2 deletions demo/starter/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { defineConfig } from 'vite'

export default defineConfig({
plugins: [
Inspect()
]
Inspect({
enabled: true,
}),
],
})
5 changes: 2 additions & 3 deletions packages/client/internals/Draggable.vue
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
<script setup lang="ts">
import { ref } from 'vue'
import { useStorage, useDraggable } from '@vueuse/core'
import type { Position } from '@vueuse/core'
const props = defineProps<{
storageKey?: string
initial?: Position
initial?: {x: number; y: number}
}>()
const el = ref<HTMLElement | null>(null)
const initial = props.initial ?? { x: 0, y: 0 }
const point = props.storageKey
? useStorage(props.storageKey, initial)
: ref(initial)
const { style } = useDraggable(el, { initial: point })
const { style } = useDraggable(el, { initialValue: point })
</script>

<template>
Expand Down
10 changes: 6 additions & 4 deletions packages/client/internals/NavControls.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@ const barStyle = computed(() => props.persist
)
const RecordingControls = shallowRef<any>()
const DrawingControls = shallowRef<any>()
if (__DEV__) {
if (__DEV__)
import('./RecordingControls.vue').then(v => RecordingControls.value = v.default)
const DrawingControls = shallowRef<any>()
if (__SLIDEV_FEATURE_DRAWINGS__)
import('./DrawingControls.vue').then(v => DrawingControls.value = v.default)
}
</script>

<template>
Expand Down Expand Up @@ -87,7 +88,8 @@ if (__DEV__) {
<ph:cursor-fill v-if="showPresenterCursor" />
<ph:cursor-duotone v-else class="opacity-50" />
</button>

</template>
<template v-if="__SLIDEV_FEATURE_DRAWINGS__ && !isEmbedded">
<template v-if="DrawingControls">
<button
class="icon-btn relative"
Expand Down
9 changes: 5 additions & 4 deletions packages/client/internals/Play.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ useSwipeControls(root)
const presistNav = computed(() => isScreenVertical.value || showEditor.value)
const Editor = shallowRef<any>()
const DrawingControls = shallowRef<any>()
if (__DEV__) {
if (__DEV__)
import('./Editor.vue').then(v => Editor.value = v.default)
const DrawingControls = shallowRef<any>()
if (__SLIDEV_FEATURE_DRAWINGS__)
import('./DrawingControls.vue').then(v => DrawingControls.value = v.default)
}
</script>

<template>
Expand All @@ -60,7 +61,7 @@ if (__DEV__) {
>
<NavControls class="m-auto" :persist="presistNav" />
</div>
<template v-if="__DEV__ && !isEmbedded && DrawingControls">
<template v-if="__SLIDEV_FEATURE_DRAWINGS__ && !isEmbedded && DrawingControls">
<DrawingControls class="ml-0" />
</template>
</template>
Expand Down
2 changes: 1 addition & 1 deletion packages/client/internals/Presenter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ onMounted(() => {
<div class="grid-section bottom">
<NavControls :persist="true" />
</div>
<DrawingControls />
<DrawingControls v-if="__SLIDEV_FEATURE_DRAWINGS__" />
</div>
<div class="progress-bar">
<div
Expand Down
4 changes: 2 additions & 2 deletions packages/client/internals/SlidesShow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ watch(currentRoute, () => {
}, { immediate: true })
const DrawingLayer = shallowRef<any>()
if (__DEV__)
if (__SLIDEV_FEATURE_DRAWINGS__ || __SLIDEV_FEATURE_DRAWINGS_PERSIST__)
import('./DrawingLayer.vue').then(v => DrawingLayer.value = v.default)
</script>

Expand All @@ -42,7 +42,7 @@ if (__DEV__)
<!-- Global Top -->
<GlobalTop />
<template v-if="__DEV__ && DrawingLayer">
<template v-if="(__SLIDEV_FEATURE_DRAWINGS__ || __SLIDEV_FEATURE_DRAWINGS_PERSIST__) && DrawingLayer">
<DrawingLayer />
</template>
<PresenterMouse v-if="!isPresenter" />
Expand Down
5 changes: 2 additions & 3 deletions packages/client/internals/WebCamera.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
<script setup lang="ts">
import { useEventListener, useStorage } from '@vueuse/core'
import { useEventListener, useStorage, useDraggable } from '@vueuse/core'
import { computed, onMounted, ref, watchEffect } from 'vue'
import { currentCamera } from '../state'
import { recorder } from '../logic/recording'
import { useDraggable } from '../logic/utils'
const size = useStorage('slidev-webcam-size', Math.round(Math.min(window.innerHeight, (window.innerWidth) / 8)))
const position = useStorage('slidev-webcam-pos', {
Expand All @@ -17,7 +16,7 @@ const video = ref<HTMLVideoElement | undefined>()
const { streamCamera, showAvatar } = recorder
const { style: containerStyle } = useDraggable(frame, { initial: position })
const { style: containerStyle } = useDraggable(frame, { initialValue: position })
const { isDragging: handlerDown } = useDraggable(handler, {
onMove({ x, y }) {
size.value = Math.max(10, Math.min(x - position.value.x, y - position.value.y) / 0.8536)
Expand Down
104 changes: 101 additions & 3 deletions packages/parser/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ResolvedFontOptions, SlidevConfig, SlidevThemeMeta } from '@slidev/types'
import { toArray, uniq } from '@antfu/utils'
import { DrawingsOptions, FontOptions, ResolvedDrawingsOptions, ResolvedFontOptions, SlidevConfig, SlidevThemeMeta } from '@slidev/types'
import { parseAspectRatio } from './utils'
import { resolveFonts } from './core'

export function resolveConfig(headmatter: any, themeMeta: SlidevThemeMeta = {}) {
const themeHightlighter = ['prism', 'shiki'].includes(themeMeta.highlighter || '') ? themeMeta.highlighter as 'prism' | 'shiki' : undefined
Expand All @@ -23,7 +23,7 @@ export function resolveConfig(headmatter: any, themeMeta: SlidevThemeMeta = {})
selectable: false,
themeConfig: {},
fonts: {} as ResolvedFontOptions,
persistDrawings: false,
drawings: {} as ResolvedDrawingsOptions,
}
const config: SlidevConfig = {
...defaultConfig,
Expand All @@ -35,6 +35,7 @@ export function resolveConfig(headmatter: any, themeMeta: SlidevThemeMeta = {})
...headmatter.config?.fonts,
...headmatter?.fonts,
}),
drawings: resolveDarwings(headmatter.drawings),
}

if (config.colorSchema !== 'dark' && config.colorSchema !== 'light')
Expand All @@ -52,3 +53,100 @@ export function resolveConfig(headmatter: any, themeMeta: SlidevThemeMeta = {})

return config
}

export function resolveFonts(fonts: FontOptions = {}): ResolvedFontOptions {
const {
fallbacks = true,
italic = false,
provider = 'google',
} = fonts
let sans = toArray(fonts.sans).flatMap(i => i.split(/,\s*/g)).map(i => i.trim())
let serif = toArray(fonts.serif).flatMap(i => i.split(/,\s*/g)).map(i => i.trim())
let mono = toArray(fonts.mono).flatMap(i => i.split(/,\s*/g)).map(i => i.trim())
const weights = toArray(fonts.weights || '200,400,600').flatMap(i => i.toString().split(/,\s*/g)).map(i => i.trim())
const custom = toArray(fonts.custom).flatMap(i => i.split(/,\s*/g)).map(i => i.trim())

const local = toArray(fonts.local).flatMap(i => i.split(/,\s*/g)).map(i => i.trim())
const webfonts = fonts.webfonts
? fonts.webfonts
: fallbacks
? uniq([...sans, ...serif, ...mono, ...custom])
: []

webfonts.filter(i => local.includes(i))

function toQuoted(font: string) {
if (/^(['"]).*\1$/.test(font))
return font
return `"${font}"`
}

if (fallbacks) {
sans = uniq([
...sans.map(toQuoted),
'ui-sans-serif',
'system-ui',
'-apple-system',
'BlinkMacSystemFont',
'"Segoe UI"',
'Roboto',
'"Helvetica Neue"',
'Arial',
'"Noto Sans"',
'sans-serif',
'"Apple Color Emoji"',
'"Segoe UI Emoji"',
'"Segoe UI Symbol"',
'"Noto Color Emoji"',
])
serif = uniq([
...serif.map(toQuoted),
'ui-serif',
'Georgia',
'Cambria',
'"Times New Roman"',
'Times',
'serif',
])
mono = uniq([
...mono.map(toQuoted),
'ui-monospace',
'SFMono-Regular',
'Menlo',
'Monaco',
'Consolas',
'"Liberation Mono"',
'"Courier New"',
'monospace',
])
}

return {
sans,
serif,
mono,
webfonts,
provider,
local,
italic,
weights,
}
}

function resolveDarwings(options: DrawingsOptions = {}): ResolvedDrawingsOptions {
const {
enabled = true,
persist = false,
} = options

const persistPath = typeof persist === 'string'
? persist
: persist
? '.slidev/drawings'
: false

return {
enabled,
persist: persistPath,
}
}

0 comments on commit 74077a4

Please sign in to comment.