Skip to content

Commit

Permalink
feat: floating drawing controls
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Sep 13, 2021
1 parent 2a9b5fb commit db87982
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 37 deletions.
56 changes: 56 additions & 0 deletions packages/client/internals/Draggable.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<script setup lang="ts">
import { computed, ref, onMounted } from 'vue'
import { useEventListener, useStorage } from '@vueuse/core'
const props = withDefaults(defineProps<{
storageKey: string
initialX?: number
initialY?: number
}>(), {
initialX: 0,
initialY: 0,
})
const point = useStorage(props.storageKey, { x: props.initialX, y: props.initialY })
const style = computed(() => {
return {
left: `${point.value.x}px`,
top: `${point.value.y}px`,
}
})
const el = ref<HTMLElement | null>(null)
onMounted(() => {
let start: {x: number; y: number} | undefined
useEventListener(el, 'pointerdown', (e: PointerEvent) => {
if (e.target !== el.value)
return
const react = el.value!.getBoundingClientRect()
start = {
x: e.pageX - react.left,
y: e.pageY - react.top,
}
})
useEventListener('pointermove', (e: PointerEvent) => {
if (!start)
return
point.value = {
x: e.pageX - start.x,
y: e.pageY - start.y,
}
})
useEventListener('pointerup', (e: PointerEvent) => {
start = undefined
})
// useEventListener('pointercancel', (e: PointerEvent) => {
// start = undefined
// })
})
</script>

<template>
<div ref="el" class="fixed" :style="style">
<slot />
</div>
</template>
87 changes: 57 additions & 30 deletions packages/client/internals/DrawingControls.vue
Original file line number Diff line number Diff line change
@@ -1,51 +1,70 @@
<script setup lang="ts">
import { drawingMode, drauu, brush, brushColors, drawingEnabled, canUndo, canRedo, canClear, clearDrauu } from '../logic/drawings'
import {
drawingMode, drauu, brush,
brushColors, drawingEnabled, drawingPinned,
canUndo, canRedo, canClear, clearDrauu,
} from '../logic/drawings'
import VerticalDivider from './VerticalDivider.vue'
import Draggable from './Draggable.vue'
function undo() {
drauu.undo()
}
function redo() {
drauu.redo()
}
function setDrawingMode(mode: typeof drawingMode.value) {
drawingMode.value = mode
drawingEnabled.value = true
}
function setBrushColor(color: typeof brush.color) {
brush.color = color
drawingEnabled.value = true
}
</script>

<template>
<div class="flex flex-wrap text-xl p-2 gap-1">
<Draggable
class="flex flex-wrap text-xl p-2 gap-1 rounded-md bg-main shadow transition-opacity duration-200 dark:(border border-gray-400 border-opacity-10)"
:class="drawingEnabled ? '' : drawingPinned ? 'opacity-30 hover:opacity-90' : 'opacity-0 pointer-events-none'"
storage-key="slidev:drawing-pos"
:initial-x="10"
:initial-y="10"
>
<button class="icon-btn" :class="{ shallow: drawingMode != 'stylus' }" @click="setDrawingMode('stylus')">
<carbon:pen />
</button>
<button class="icon-btn" :class="{ shallow: drawingMode != 'line' }" @click="setDrawingMode('line')">
<uil:line-alt />
</button>
<button class="icon-btn" :class="{ shallow: drawingMode != 'arrow' }" @click="setDrawingMode('arrow')">
<carbon:arrow-up-right />
</button>
<button class="icon-btn" :class="{ shallow: drawingMode != 'ellipse' }" @click="setDrawingMode('ellipse')">
<carbon:radio-button />
</button>
<button class="icon-btn" :class="{ shallow: drawingMode != 'rectangle' }" @click="setDrawingMode('rectangle')">
<carbon:checkbox />
</button>

<VerticalDivider />

<button
v-for="color of brushColors"
:key="color"
class="icon-btn"
:class="brush.color === color ? 'active' : 'shallow'"
@click="brush.color = color"
@click="setBrushColor(color)"
>
<div
class="w-6 h-6 transition-all transform border border-gray-400/50"
:class="brush.color !== color ? 'rounded-1/2 scale-85' : 'rounded'"
:style="{ background: color }"
:class="brush.color !== color ? 'rounded-1/2 scale-85' : 'rounded-md'"
:style="drawingEnabled? { background: color } : { borderColor: color }"
/>
</button>

<VerticalDivider />

<button class="icon-btn" :class="{ shallow: drawingMode != 'stylus' }" @click="drawingMode = 'stylus'">
<carbon:draw />
</button>
<button class="icon-btn" :class="{ shallow: drawingMode != 'line' }" @click="drawingMode = 'line'">
<uil:line-alt />
</button>
<button class="icon-btn" :class="{ shallow: drawingMode != 'arrow' }" @click="drawingMode = 'arrow'">
<carbon:arrow-up-right />
</button>
<button class="icon-btn" :class="{ shallow: drawingMode != 'ellipse' }" @click="drawingMode = 'ellipse'">
<carbon:radio-button />
</button>
<button class="icon-btn" :class="{ shallow: drawingMode != 'rectangle' }" @click="drawingMode = 'rectangle'">
<carbon:checkbox />
</button>

<VerticalDivider />

<button class="icon-btn" :class="{ disabled: !canUndo }" @click="undo()">
<carbon:undo />
</button>
Expand All @@ -56,11 +75,19 @@ function redo() {
<carbon:delete />
</button>

<template v-if="drawingEnabled">
<VerticalDivider />
<button class="icon-btn" @click="drawingEnabled = false">
<carbon:close />
</button>
</template>
</div>
<VerticalDivider />
<button class="icon-btn" :class="{ shallow: !drawingPinned }" @click="drawingPinned = !drawingPinned">
<carbon:pin-filled v-show="drawingPinned" />
<carbon:pin v-show="!drawingPinned" />
</button>
<button
v-if="drawingEnabled"
class="icon-btn"
:class="{ shallow: !drawingEnabled }"
@click="drawingEnabled = !drawingEnabled"
>
<carbon:error v-show="drawingPinned" />
<carbon:close-outline v-show="!drawingPinned" />
</button>
</Draggable>
</template>
6 changes: 1 addition & 5 deletions packages/client/internals/NavControls.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ if (__DEV__) {

<template>
<nav ref="root" class="flex flex-col">
<template v-if="__DEV__ && !isEmbedded && DrawingControls && drawingEnabled">
<DrawingControls class="ml-0" :class="barStyle" />
<div :class="persist ? 'border-b border-gray-400/20' : 'pt-1'"></div>
</template>
<div class="flex flex-wrap-reverse text-xl p-2 gap-1" :class="barStyle" @mouseleave="onMouseLeave">
<button v-if="!isEmbedded" class="icon-btn" @click="toggleFullscreen">
<carbon:minimize v-if="isFullscreen" />
Expand Down Expand Up @@ -98,7 +94,7 @@ if (__DEV__) {
title="Drawing"
@click="drawingEnabled = !drawingEnabled"
>
<carbon:draw />
<carbon:pen />
<div
v-if="drawingEnabled"
class="absolute left-1 right-1 bottom-0 h-0.7 rounded-full"
Expand Down
10 changes: 8 additions & 2 deletions packages/client/internals/Play.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { ref, computed, shallowRef } from 'vue'
import { showEditor, windowSize, isScreenVertical, slideScale } from '../state'
import { isPrintMode, next, prev, useSwipeControls } from '../logic/nav'
import { isPrintMode, next, prev, useSwipeControls, isEmbedded } from '../logic/nav'
import { isDrawing } from '../logic/drawings'
import { registerShortcuts } from '../logic/shortcuts'
import { themeVars } from '../env'
Expand Down Expand Up @@ -31,8 +31,11 @@ useSwipeControls(root)
const presistNav = computed(() => isScreenVertical.value || showEditor.value)
const Editor = shallowRef<any>()
if (__DEV__)
const DrawingControls = shallowRef<any>()
if (__DEV__) {
import('./Editor.vue').then(v => Editor.value = v.default)
import('./DrawingControls.vue').then(v => DrawingControls.value = v.default)
}
</script>

<template>
Expand All @@ -57,6 +60,9 @@ if (__DEV__)
>
<NavControls class="m-auto" :persist="presistNav" />
</div>
<template v-if="__DEV__ && !isEmbedded && DrawingControls">
<DrawingControls class="ml-0" />
</template>
</template>
</SlideContainer>

Expand Down
2 changes: 2 additions & 0 deletions packages/client/internals/Presenter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import NoteEditor from './NoteEditor.vue'
import Goto from './Goto.vue'
import SlidesShow from './SlidesShow.vue'
import SlideWrapper from './SlideWrapper'
import DrawingControls from './DrawingControls.vue'
const main = ref<HTMLDivElement>()
Expand Down Expand Up @@ -126,6 +127,7 @@ onMounted(() => {
<div class="grid-section bottom">
<NavControls :persist="true" />
</div>
<DrawingControls />
</div>
<div class="progress-bar">
<div
Expand Down
1 change: 1 addition & 0 deletions packages/client/logic/drawings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export const drawingMode = computed({
})

export const drawingEnabled = ref(false)
export const drawingPinned = ref(false)
export const canUndo = ref(false)
export const canRedo = ref(false)
export const canClear = ref(false)
Expand Down

0 comments on commit db87982

Please sign in to comment.