Skip to content

Commit

Permalink
feat: drauu menu
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Sep 13, 2021
1 parent 9bf22dc commit a44ddfc
Show file tree
Hide file tree
Showing 11 changed files with 169 additions and 50 deletions.
71 changes: 71 additions & 0 deletions packages/client/internals/DrauuControls.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<script setup lang="ts">
import { drauuMode, drauu, drauuBrush, brushColors, drauuEnabled, canUndo, canRedo } from '../logic/drauu'
import VerticalDivider from './VerticalDivider.vue'
function clear() {
if (confirm('Clear the drawing?'))
drauu.clear()
}
function undo() {
drauu.undo()
}
function redo() {
drauu.redo()
}
</script>

<template>
<div class="m-auto rounded-md bg-main shadow dark:(border border-gray-400 border-opacity-10)">
<div class="flex text-xl p-2 gap-1">
<button
v-for="color of brushColors"
:key="color"
class="icon-btn"
:class="drauuBrush.color === color ? 'active' : 'shallow'"
@click="drauuBrush.color = color"
>
<div
class="w-5 h-5 transition-all border border-gray-400/50"
:class="drauuBrush.color !== color ? 'rounded-full' : 'rounded'"
:style="{ background: color }"
/>
</button>

<VerticalDivider />

<button class="icon-btn" :class="{ shallow: drauuMode != 'draw' }" @click="drauuMode = 'draw'">
<carbon:draw />
</button>
<button class="icon-btn" :class="{ shallow: drauuMode != 'line' }" @click="drauuMode = 'line'">
<carbon:scalpel />
</button>
<button class="icon-btn" :class="{ shallow: drauuMode != 'ellipse' }" @click="drauuMode = 'ellipse'">
<carbon:radio-button />
</button>
<button class="icon-btn" :class="{ shallow: drauuMode != 'rectangle' }" @click="drauuMode = 'rectangle'">
<carbon:checkbox />
</button>

<VerticalDivider />

<button class="icon-btn" @click="clear()">
<carbon:clean />
</button>
<button class="icon-btn" :class="{ disabled: !canUndo }" @click="undo()">
<carbon:undo />
</button>
<button class="icon-btn" :class="{ disabled: !canRedo }" @click="redo()">
<carbon:redo />
</button>

<template v-if="drauuEnabled">
<VerticalDivider />
<button class="icon-btn" @click="drauuEnabled = false">
<carbon:close />
</button>
</template>
</div>
</div>
</template>
26 changes: 12 additions & 14 deletions packages/client/internals/DrauuLayer.vue
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
<script setup lang="ts">
import { onMounted, ref, watch, inject } from 'vue'
import { createDrauu } from 'drauu'
import { drauuBrush, drauuMode } from '../state/drauu'
import { onMounted, ref, watch, inject, onBeforeUnmount } from 'vue'
import { drauuEnabled, drauu } from '../logic/drauu'
import { injectionSlideScale } from '../constants'
defineProps<{ enabled?: boolean }>()
const scale = inject(injectionSlideScale)!
const svg = ref<SVGSVGElement>()
onMounted(() => {
const drauu = createDrauu({
el: svg.value,
brush: drauuBrush,
mode: drauuMode.value,
corrdinateScale: 1 / scale.value,
})
drauu.mount(svg.value!)
watch(scale, scale => drauu.options.corrdinateScale = 1 / scale, { immediate: true })
})
watch(drauuMode, mode => drauu.mode = mode)
watch(scale, scale => drauu.options.corrdinateScale = 1 / scale)
onBeforeUnmount(() => {
drauu.unmount()
})
</script>

<template>
<svg ref="svg" :class="{ 'pointer-events-none': !enabled }"></svg>
<svg
ref="svg"
class="w-full h-full absolute top-0"
:class="{ 'pointer-events-none': !drauuEnabled }"
></svg>
</template>
38 changes: 27 additions & 11 deletions packages/client/internals/NavControls.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import { computed, ref, shallowRef } from 'vue'
import { isDark, toggleDark, isColorSchemaConfigured } from '../logic/dark'
import { hasNext, hasPrev, prev, next, total, isPresenter, currentPage, downloadPDF, isEmbedded } from '../logic/nav'
import { toggleOverview, showEditor, showInfoDialog, fullscreen, breakpoints, activeElement } from '../state'
import { drauuEnabled, drauuMode, drauuBrush } from '../logic/drauu'
import { configs } from '../env'
import Settings from './Settings.vue'
import MenuButton from './MenuButton.vue'
import VerticalDivider from './VerticalDivider.vue'
defineProps({
mode: {
Expand All @@ -26,8 +28,11 @@ const onMouseLeave = () => {
}
const RecordingControls = shallowRef<any>()
if (__DEV__)
const DrauuControls = shallowRef<any>()
if (__DEV__) {
import('./RecordingControls.vue').then(v => RecordingControls.value = v.default)
import('./DrauuControls.vue').then(v => DrauuControls.value = v.default)
}
</script>

<template>
Expand All @@ -45,34 +50,45 @@ if (__DEV__)
<carbon:arrow-right />
</button>

<button v-if="!isEmbedded" class="icon-btn" title="Slides overview" @click="toggleOverview">
<button v-if="!isEmbedded" class="icon-btn" title="Slides overview" @click="toggleOverview()">
<carbon:apps />
</button>

<button v-if="!isColorSchemaConfigured" class="icon-btn" title="Toggle dark mode" @click="toggleDark">
<button v-if="!isColorSchemaConfigured" class="icon-btn" title="Toggle dark mode" @click="toggleDark()">
<carbon-moon v-if="isDark" />
<carbon-sun v-else />
</button>

<div class="w-1px m-2 opacity-10 bg-current"></div>
<VerticalDivider />

<template v-if="__DEV__ && !isEmbedded">
<RouterLink v-if="isPresenter" :to="nonPresenterLink" class="icon-btn" title="Play Mode">
<carbon:presentation-file />
</RouterLink>

<template v-if="!isPresenter && !md && RecordingControls">
<RecordingControls />
<VerticalDivider />
</template>

<div class="w-1px m-2 opacity-10 bg-current"></div>
<template v-if="!isPresenter && DrauuControls">
<button class="icon-btn relative" @click="drauuEnabled = !drauuEnabled">
<carbon:draw />
<div
v-if="drauuEnabled"
class="absolute left-1 right-1 bottom-0 h-0.7 rounded-full"
:style="{ background: drauuBrush.color }"
></div>
</button>
<DrauuControls v-if="drauuEnabled" class="absolute bottom-17 left-2" />
<VerticalDivider />
</template>

<RouterLink v-if="isPresenter" :to="nonPresenterLink" class="icon-btn" title="Play Mode">
<carbon:presentation-file />
</RouterLink>
<RouterLink v-if="!isPresenter" :to="presenterLink" class="icon-btn" title="Presenter Mode">
<carbon:user-speaker />
</RouterLink>

<button v-if="!isPresenter" class="icon-btn <md:hidden" @click="showEditor = !showEditor">
<carbon:edit />
<carbon:text-annotation-toggle />
</button>
</template>
<template v-else>
Expand All @@ -98,7 +114,7 @@ if (__DEV__)
</MenuButton>
</template>

<div v-if="!isEmbedded" class="w-1px m-2 opacity-10 bg-current"></div>
<VerticalDivider v-if="!isEmbedded" />

<div class="h-40px flex" p="l-1 t-0.5 r-2" text="sm leading-2">
<div class="my-auto">
Expand Down
11 changes: 8 additions & 3 deletions packages/client/internals/SlidesShow.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
<script setup lang="ts">
import { watch } from 'vue'
import { shallowRef, watch } from 'vue'
import { currentRoute, clicks, rawRoutes, nextRoute } from '../logic/nav'
import { getSlideClass } from '../utils'
import DrauuLayer from './DrauuLayer.vue'
import SlideWrapper from './SlideWrapper'
// @ts-ignore
import GlobalTop from '/@slidev/global-components/top'
Expand All @@ -16,6 +15,10 @@ watch(currentRoute, () => {
if (nextRoute.value?.meta && nextRoute.value.meta.preload !== false)
nextRoute.value.meta.__preloaded = true
}, { immediate: true })
const DrauuLayer = shallowRef<any>()
if (__DEV__)
import('./DrauuLayer.vue').then(v => DrauuLayer.value = v.default)
</script>

<template>
Expand All @@ -38,5 +41,7 @@ watch(currentRoute, () => {
<!-- Global Top -->
<GlobalTop />
<DrauuLayer class="w-full h-full absolute top-0" :enabled="true" />
<template v-if="__DEV__ && DrauuLayer">
<DrauuLayer />
</template>
</template>
3 changes: 3 additions & 0 deletions packages/client/internals/VerticalDivider.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template>
<div class="w-1px m-2 opacity-10 bg-current" />
</template>
30 changes: 30 additions & 0 deletions packages/client/logic/drauu.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { markRaw, reactive, ref, watch } from 'vue'
import { Brush, createDrauu, DrawingMode } from 'drauu'

export const brushColors = [
'#ff595e',
'#ffca3a',
'#8ac926',
'#1982c4',
'#6a4c93',
'#ffffff',
'#000000',
]

export const drauuBrush = reactive<Brush>({ color: brushColors[0], size: 4 })
export const drauuMode = ref<DrawingMode>('draw')
export const drauuEnabled = ref(false)
export const canUndo = ref(false)
export const canRedo = ref(false)

export const drauu = markRaw(createDrauu({
brush: drauuBrush,
mode: drauuMode.value,
}))

drauu.on('changed', () => {
canRedo.value = drauu.canRedo()
canUndo.value = drauu.canUndo()
})

watch(drauuMode, mode => drauu.mode = mode)
2 changes: 1 addition & 1 deletion packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"@vueuse/head": "^0.6.0",
"@vueuse/motion": "^1.5.6",
"codemirror": "^5.62.2",
"drauu": "^0.0.4",
"drauu": "^0.0.7",
"file-saver": "^2.0.5",
"js-base64": "^3.6.1",
"js-yaml": "^4.1.0",
Expand Down
5 changes: 0 additions & 5 deletions packages/client/state/drauu.ts

This file was deleted.

8 changes: 8 additions & 0 deletions packages/client/styles/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ html {
@apply hover:(opacity-100 bg-gray-400 bg-opacity-10);
}

.icon-btn.shallow {
@apply opacity-30
}

.icon-btn.active {
@apply opacity-100
}

.icon-btn.disabled {
@apply opacity-25 pointer-events-none;
}
Expand Down
11 changes: 2 additions & 9 deletions packages/create-app/template/slides.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
---
# try also 'default' to start simple
theme: seriph
# random image from a curated Unsplash collection by Anthony
# like them? see https://unsplash.com/collections/94734566/slidev
background: https://source.unsplash.com/collection/94734566/1920x1080
# apply any windi css classes to the current slide
class: 'text-center'
# https://sli.dev/custom/highlighters.html
class: text-center
highlighter: shiki
# show line numbers in code blocks
lineNumbers: false
# some information about the slides, markdown enabled
info: |
## Slidev Starter Template
Presentation slides for developers.
Learn more at [Sli.dev](https://sli.dev)
title: Welcome to Slidev
---

# Welcome to Slidev
Expand All @@ -38,7 +32,6 @@ Presentation slides for developers
</a>
</div>


<!--
The last comment block of each slide will be treated as slide notes. It will be visible and editable in Presenter Mode along with the slide. [Read more in the docs](https://sli.dev/guide/syntax.html#notes)
-->
Expand Down
14 changes: 7 additions & 7 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit a44ddfc

Please sign in to comment.