feat: 优化放映模式画笔笔触尺寸调整方式(#162)

This commit is contained in:
pipipi-pikachu 2022-10-16 15:30:12 +08:00
parent 1fa355a170
commit 54d45c6982
5 changed files with 86 additions and 39 deletions

View File

@ -49,6 +49,10 @@ const props = defineProps({
type: String, type: String,
default: '', default: '',
}, },
moveable: {
type: Boolean,
default: true,
},
}) })
const emit = defineEmits<{ const emit = defineEmits<{
@ -67,6 +71,8 @@ onMounted(() => {
}) })
const startMove = (e: MouseEvent) => { const startMove = (e: MouseEvent) => {
if (!props.moveable) return
let isMouseDown = true let isMouseDown = true
const windowWidth = document.body.clientWidth const windowWidth = document.body.clientWidth

View File

@ -15,7 +15,6 @@
@touchend="handleMouseup(); mouseInCanvas = false" @touchend="handleMouseup(); mouseInCanvas = false"
@mouseleave="handleMouseup(); mouseInCanvas = false" @mouseleave="handleMouseup(); mouseInCanvas = false"
@mouseenter="mouseInCanvas = true" @mouseenter="mouseInCanvas = true"
@wheel="$event => mousewheelListener($event)"
></canvas> ></canvas>
<template v-if="mouseInCanvas"> <template v-if="mouseInCanvas">
@ -57,7 +56,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, onMounted, onUnmounted, PropType, ref, watch } from 'vue' import { computed, onMounted, onUnmounted, PropType, ref, watch } from 'vue'
import { throttle } from 'lodash'
const props = defineProps({ const props = defineProps({
color: { color: {
@ -72,6 +70,18 @@ const props = defineProps({
type: Boolean, type: Boolean,
default: false, default: false,
}, },
penSize: {
type: Number,
default: 6,
},
markSize: {
type: Number,
default: 24,
},
rubberSize: {
type: Number,
default: 80,
},
}) })
const emit = defineEmits<{ const emit = defineEmits<{
@ -82,10 +92,6 @@ let ctx: CanvasRenderingContext2D | null = null
const writingBoardRef = ref<HTMLElement>() const writingBoardRef = ref<HTMLElement>()
const canvasRef = ref<HTMLCanvasElement>() const canvasRef = ref<HTMLCanvasElement>()
const penSize = ref(6)
const rubberSize = ref(80)
const markSize = ref(24)
let lastPos = { let lastPos = {
x: 0, x: 0,
y: 0, y: 0,
@ -174,7 +180,7 @@ const erase = (posX: number, posY: number) => {
const lastPosX = lastPos.x const lastPosX = lastPos.x
const lastPosY = lastPos.y const lastPosY = lastPos.y
const radius = rubberSize.value / 2 const radius = props.rubberSize / 2
const sinRadius = radius * Math.sin(Math.atan((posY - lastPosY) / (posX - lastPosX))) const sinRadius = radius * Math.sin(Math.atan((posY - lastPosY) / (posX - lastPosX)))
const cosRadius = radius * Math.cos(Math.atan((posY - lastPosY) / (posX - lastPosX))) const cosRadius = radius * Math.cos(Math.atan((posY - lastPosY) / (posX - lastPosX)))
@ -213,7 +219,7 @@ const getDistance = (posX: number, posY: number) => {
const getLineWidth = (s: number, t: number) => { const getLineWidth = (s: number, t: number) => {
const maxV = 10 const maxV = 10
const minV = 0.1 const minV = 0.1
const maxWidth = penSize.value const maxWidth = props.penSize
const minWidth = 3 const minWidth = 3
const v = s / t const v = s / t
let lineWidth let lineWidth
@ -238,7 +244,7 @@ const handleMove = (x: number, y: number) => {
draw(x, y, lineWidth) draw(x, y, lineWidth)
lastLineWidth = lineWidth lastLineWidth = lineWidth
} }
else if (props.model === 'mark') draw(x, y, markSize.value) else if (props.model === 'mark') draw(x, y, props.markSize)
else erase(x, y) else erase(x, y)
lastPos = { x, y } lastPos = { x, y }
@ -321,22 +327,6 @@ const setImageDataURL = (imageDataURL: string) => {
} }
} }
//
const mousewheelListener = throttle(function(e: WheelEvent) {
if (props.model === 'eraser') {
if (e.deltaY < 0 && rubberSize.value < 200) rubberSize.value += 20
else if (e.deltaY > 0 && rubberSize.value > 20) rubberSize.value -= 20
}
if (props.model === 'pen') {
if (e.deltaY < 0 && penSize.value < 10) penSize.value += 2
else if (e.deltaY > 0 && penSize.value > 4) penSize.value -= 2
}
if (props.model === 'mark') {
if (e.deltaY < 0 && markSize.value < 40) markSize.value += 4
else if (e.deltaY > 0 && markSize.value > 16) markSize.value -= 4
}
}, 300, { leading: true, trailing: false })
defineExpose({ defineExpose({
clearCanvas, clearCanvas,
getImageDataURL, getImageDataURL,

View File

@ -54,7 +54,6 @@ export const HOTKEY_DOC = [
{ label: '切换下一页', value: '↓ / → / PgDown' }, { label: '切换下一页', value: '↓ / → / PgDown' },
{ label: '切换下一页', value: 'Enter / Space' }, { label: '切换下一页', value: 'Enter / Space' },
{ label: '退出放映', value: 'ESC' }, { label: '退出放映', value: 'ESC' },
{ label: '调整画笔笔触大小', value: '鼠标滚轮' },
], ],
}, },
{ {

View File

@ -34,8 +34,8 @@
<WritingBoardTool <WritingBoardTool
:slideWidth="slideWidth" :slideWidth="slideWidth"
:slideHeight="slideHeight" :slideHeight="slideHeight"
:left="75" :left="-365"
:top="5" :top="-155"
v-if="writingBoardToolVisible" v-if="writingBoardToolVisible"
@close="writingBoardToolVisible = false" @close="writingBoardToolVisible = false"
/> />

View File

@ -11,6 +11,9 @@
:color="writingBoardColor" :color="writingBoardColor"
:blackboard="blackboard" :blackboard="blackboard"
:model="writingBoardModel" :model="writingBoardModel"
:penSize="penSize"
:markSize="markSize"
:rubberSize="rubberSize"
@end="hanldeWritingEnd()" @end="hanldeWritingEnd()"
/> />
</div> </div>
@ -21,18 +24,43 @@
:height="50" :height="50"
:left="left" :left="left"
:top="top" :top="top"
:moveable="sizePopoverType === ''"
> >
<div class="tools"> <div class="tools" @mousedown.stop>
<div class="tool-content"> <div class="tool-content">
<Popover trigger="click" :visible="sizePopoverType === 'pen'">
<template #content>
<div class="size">
<div class="label">墨迹粗细</div>
<Slider class="size-slider" :min="4" :max="10" :step="2" v-model:value="penSize" />
</div>
</template>
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.3" title="画笔"> <Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.3" title="画笔">
<div class="btn" :class="{ 'active': writingBoardModel === 'pen' }" @click="changeModel('pen')"><IconWrite class="icon" /></div> <div class="btn" :class="{ 'active': writingBoardModel === 'pen' }" @click="changeModel('pen')"><IconWrite class="icon" /></div>
</Tooltip> </Tooltip>
</Popover>
<Popover trigger="click" :visible="sizePopoverType === 'mark'">
<template #content>
<div class="size">
<div class="label">墨迹粗细</div>
<Slider class="size-slider" :min="16" :max="40" :step="4" v-model:value="markSize" />
</div>
</template>
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.3" title="荧光笔"> <Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.3" title="荧光笔">
<div class="btn" :class="{ 'active': writingBoardModel === 'mark' }" @click="changeModel('mark')"><IconHighLight class="icon" /></div> <div class="btn" :class="{ 'active': writingBoardModel === 'mark' }" @click="changeModel('mark')"><IconHighLight class="icon" /></div>
</Tooltip> </Tooltip>
</Popover>
<Popover trigger="click" :visible="sizePopoverType === 'eraser'">
<template #content>
<div class="size">
<div class="label">橡皮大小</div>
<Slider class="size-slider" :min="20" :max="200" :step="20" v-model:value="rubberSize" />
</div>
</template>
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.3" title="橡皮擦"> <Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.3" title="橡皮擦">
<div class="btn" :class="{ 'active': writingBoardModel === 'eraser' }" @click="changeModel('eraser')"><IconErase class="icon" /></div> <div class="btn" :class="{ 'active': writingBoardModel === 'eraser' }" @click="changeModel('eraser')"><IconErase class="icon" /></div>
</Tooltip> </Tooltip>
</Popover>
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.3" title="清除墨迹"> <Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.3" title="清除墨迹">
<div class="btn" @click="clearCanvas()"><IconClear class="icon" /></div> <div class="btn" @click="clearCanvas()"><IconClear class="icon" /></div>
</Tooltip> </Tooltip>
@ -98,10 +126,21 @@ const writingBoardRef = ref<typeof WritingBoard>()
const writingBoardColor = ref('#e2534d') const writingBoardColor = ref('#e2534d')
const writingBoardModel = ref<WritingBoardModel>('pen') const writingBoardModel = ref<WritingBoardModel>('pen')
const blackboard = ref(false) const blackboard = ref(false)
const sizePopoverType = ref<'' | WritingBoardModel>('')
const penSize = ref(6)
const markSize = ref(24)
const rubberSize = ref(80)
const changeModel = (model: WritingBoardModel) => { const changeModel = (model: WritingBoardModel) => {
if (writingBoardModel.value === model) {
sizePopoverType.value = sizePopoverType.value === model ? '' : model
}
else {
if (sizePopoverType.value) sizePopoverType.value = ''
writingBoardModel.value = model writingBoardModel.value = model
} }
}
// //
const clearCanvas = () => { const clearCanvas = () => {
@ -199,4 +238,17 @@ const hanldeWritingEnd = () => {
} }
} }
} }
.size {
width: 200px;
display: flex;
align-items: center;
user-select: none;
.label {
width: 70px;
}
.size-slider {
flex: 1;
}
}
</style> </style>