mirror of
https://github.com/pipipi-pikachu/PPTist.git
synced 2025-04-15 02:20:00 +08:00
feat: 优化放映模式画笔笔触尺寸调整方式(#162)
This commit is contained in:
parent
1fa355a170
commit
54d45c6982
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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: '鼠标滚轮' },
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -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"
|
||||||
/>
|
/>
|
||||||
|
@ -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>
|
Loading…
x
Reference in New Issue
Block a user