mirror of
https://github.com/pipipi-pikachu/PPTist.git
synced 2025-04-15 02:20:00 +08:00
refactor: 画笔工具重构,墨迹自适应屏幕缩放
This commit is contained in:
parent
e315518bec
commit
7ea0fd4286
@ -3,6 +3,10 @@
|
|||||||
<div class="blackboard" v-if="blackboard"></div>
|
<div class="blackboard" v-if="blackboard"></div>
|
||||||
|
|
||||||
<canvas class="canvas" ref="canvasRef"
|
<canvas class="canvas" ref="canvasRef"
|
||||||
|
:style="{
|
||||||
|
width: canvasWidth + 'px',
|
||||||
|
height: canvasHeight + 'px',
|
||||||
|
}"
|
||||||
@mousedown="$event => handleMousedown($event)"
|
@mousedown="$event => handleMousedown($event)"
|
||||||
@mousemove="$event => handleMousemove($event)"
|
@mousemove="$event => handleMousemove($event)"
|
||||||
@mouseup="handleMouseup()"
|
@mouseup="handleMouseup()"
|
||||||
@ -37,7 +41,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, onMounted, PropType, reactive, ref } from 'vue'
|
import { computed, defineComponent, onMounted, onUnmounted, PropType, reactive, ref } from 'vue'
|
||||||
|
|
||||||
const penSize = 6
|
const penSize = 6
|
||||||
const rubberSize = 80
|
const rubberSize = 80
|
||||||
@ -86,6 +90,25 @@ export default defineComponent({
|
|||||||
// 鼠标是否处在画布范围内:处在范围内才会显示画笔或橡皮
|
// 鼠标是否处在画布范围内:处在范围内才会显示画笔或橡皮
|
||||||
const mouseInCanvas = ref(false)
|
const mouseInCanvas = ref(false)
|
||||||
|
|
||||||
|
// 监听更新canvas尺寸
|
||||||
|
const canvasWidth = ref(0)
|
||||||
|
const canvasHeight = ref(0)
|
||||||
|
|
||||||
|
const widthScale = computed(() => canvasRef.value ? canvasWidth.value / canvasRef.value.width : 1)
|
||||||
|
const heightScale = computed(() => canvasRef.value ? canvasHeight.value / canvasRef.value.height : 1)
|
||||||
|
|
||||||
|
const updateCanvasSize = () => {
|
||||||
|
if (!writingBoardRef.value) return
|
||||||
|
canvasWidth.value = writingBoardRef.value.clientWidth
|
||||||
|
canvasHeight.value = writingBoardRef.value.clientHeight
|
||||||
|
}
|
||||||
|
const resizeObserver = new ResizeObserver(updateCanvasSize)
|
||||||
|
onMounted(() => {
|
||||||
|
if (writingBoardRef.value) resizeObserver.observe(writingBoardRef.value)
|
||||||
|
})
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (writingBoardRef.value) resizeObserver.unobserve(writingBoardRef.value)
|
||||||
|
})
|
||||||
|
|
||||||
// 初始化画布
|
// 初始化画布
|
||||||
const initCanvas = () => {
|
const initCanvas = () => {
|
||||||
@ -97,9 +120,6 @@ export default defineComponent({
|
|||||||
canvasRef.value.width = writingBoardRef.value.clientWidth
|
canvasRef.value.width = writingBoardRef.value.clientWidth
|
||||||
canvasRef.value.height = writingBoardRef.value.clientHeight
|
canvasRef.value.height = writingBoardRef.value.clientHeight
|
||||||
|
|
||||||
canvasRef.value.style.width = writingBoardRef.value.clientWidth + 'px'
|
|
||||||
canvasRef.value.style.height = writingBoardRef.value.clientHeight + 'px'
|
|
||||||
|
|
||||||
ctx.lineCap = 'round'
|
ctx.lineCap = 'round'
|
||||||
ctx.lineJoin = 'round'
|
ctx.lineJoin = 'round'
|
||||||
}
|
}
|
||||||
@ -197,28 +217,40 @@ export default defineComponent({
|
|||||||
lastTime = new Date().getTime()
|
lastTime = new Date().getTime()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取鼠标在canvas中的相对位置
|
||||||
|
const getMouseOffsetPosition = (e: MouseEvent | TouchEvent) => {
|
||||||
|
if (!canvasRef.value) return [0, 0]
|
||||||
|
const event = e instanceof MouseEvent ? e : e.changedTouches[0]
|
||||||
|
const canvasRect = canvasRef.value.getBoundingClientRect()
|
||||||
|
const x = event.pageX - canvasRect.x
|
||||||
|
const y = event.pageY - canvasRect.y
|
||||||
|
return [x, y]
|
||||||
|
}
|
||||||
|
|
||||||
// 处理鼠标(触摸)事件
|
// 处理鼠标(触摸)事件
|
||||||
// 准备开始绘制/擦除墨迹(落笔)
|
// 准备开始绘制/擦除墨迹(落笔)
|
||||||
const handleMousedown = (e: MouseEvent | TouchEvent) => {
|
const handleMousedown = (e: MouseEvent | TouchEvent) => {
|
||||||
const x = e instanceof MouseEvent ? e.offsetX : e.changedTouches[0].pageX
|
const [mouseX, mouseY] = getMouseOffsetPosition(e)
|
||||||
const y = e instanceof MouseEvent ? e.offsetY : e.changedTouches[0].pageY
|
const x = mouseX / widthScale.value
|
||||||
|
const y = mouseY / heightScale.value
|
||||||
|
|
||||||
isMouseDown = true
|
isMouseDown = true
|
||||||
lastPos = { x, y }
|
lastPos = { x, y }
|
||||||
lastTime = new Date().getTime()
|
lastTime = new Date().getTime()
|
||||||
|
|
||||||
if (e instanceof TouchEvent) {
|
if (e instanceof TouchEvent) {
|
||||||
updateMousePosition(x, y)
|
updateMousePosition(mouseX, mouseY)
|
||||||
mouseInCanvas.value = true
|
mouseInCanvas.value = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 开始绘制/擦除墨迹(移动)
|
// 开始绘制/擦除墨迹(移动)
|
||||||
const handleMousemove = (e: MouseEvent | TouchEvent) => {
|
const handleMousemove = (e: MouseEvent | TouchEvent) => {
|
||||||
const x = e instanceof MouseEvent ? e.offsetX : e.changedTouches[0].pageX
|
const [mouseX, mouseY] = getMouseOffsetPosition(e)
|
||||||
const y = e instanceof MouseEvent ? e.offsetY : e.changedTouches[0].pageY
|
const x = mouseX / widthScale.value
|
||||||
|
const y = mouseY / heightScale.value
|
||||||
|
|
||||||
updateMousePosition(x, y)
|
updateMousePosition(mouseX, mouseY)
|
||||||
|
|
||||||
if (isMouseDown) handleMove(x, y)
|
if (isMouseDown) handleMove(x, y)
|
||||||
}
|
}
|
||||||
@ -242,6 +274,8 @@ export default defineComponent({
|
|||||||
rubberSize,
|
rubberSize,
|
||||||
writingBoardRef,
|
writingBoardRef,
|
||||||
canvasRef,
|
canvasRef,
|
||||||
|
canvasWidth,
|
||||||
|
canvasHeight,
|
||||||
handleMousedown,
|
handleMousedown,
|
||||||
handleMousemove,
|
handleMousemove,
|
||||||
handleMouseup,
|
handleMouseup,
|
||||||
@ -253,13 +287,8 @@ export default defineComponent({
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.writing-board {
|
.writing-board {
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
z-index: 8;
|
|
||||||
cursor: none;
|
cursor: none;
|
||||||
|
@include absolute-0();
|
||||||
}
|
}
|
||||||
.blackboard {
|
.blackboard {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -267,11 +296,13 @@ export default defineComponent({
|
|||||||
background-color: #0f392b;
|
background-color: #0f392b;
|
||||||
}
|
}
|
||||||
.canvas {
|
.canvas {
|
||||||
@include absolute-0();
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
}
|
}
|
||||||
.eraser, .pen {
|
.eraser, .pen {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
position: fixed;
|
position: absolute;
|
||||||
z-index: 9;
|
z-index: 9;
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="writing-board-tool">
|
<div class="writing-board-tool">
|
||||||
<teleport to="body">
|
<div class="writing-board-wrap"
|
||||||
|
:style="{
|
||||||
|
width: slideWidth + 'px',
|
||||||
|
height: slideHeight + 'px',
|
||||||
|
}"
|
||||||
|
>
|
||||||
<WritingBoard
|
<WritingBoard
|
||||||
ref="writingBoardRef"
|
ref="writingBoardRef"
|
||||||
:color="writingBoardColor"
|
:color="writingBoardColor"
|
||||||
:blackboard="blackboard"
|
:blackboard="blackboard"
|
||||||
:model="writingBoardModel"
|
:model="writingBoardModel"
|
||||||
/>
|
/>
|
||||||
</teleport>
|
</div>
|
||||||
|
|
||||||
<div class="tools">
|
<div class="tools">
|
||||||
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.3" title="画笔">
|
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.3" title="画笔">
|
||||||
@ -51,6 +56,16 @@ export default defineComponent({
|
|||||||
components: {
|
components: {
|
||||||
WritingBoard,
|
WritingBoard,
|
||||||
},
|
},
|
||||||
|
props: {
|
||||||
|
slideWidth: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
slideHeight: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
const writingBoardRef = ref()
|
const writingBoardRef = ref()
|
||||||
const writingBoardColor = ref('#e2534d')
|
const writingBoardColor = ref('#e2534d')
|
||||||
@ -102,6 +117,15 @@ export default defineComponent({
|
|||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.writing-board-tool {
|
.writing-board-tool {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
z-index: 10;
|
||||||
|
@include absolute-0();
|
||||||
|
|
||||||
|
.writing-board-wrap {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
.tools {
|
.tools {
|
||||||
height: 50px;
|
height: 50px;
|
||||||
|
@ -45,7 +45,12 @@
|
|||||||
@close="slideThumbnailModelVisible = false"
|
@close="slideThumbnailModelVisible = false"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<WritingBoardTool v-if="writingBoardToolVisible" @close="writingBoardToolVisible = false" />
|
<WritingBoardTool
|
||||||
|
:slideWidth="slideWidth"
|
||||||
|
:slideHeight="slideHeight"
|
||||||
|
v-if="writingBoardToolVisible"
|
||||||
|
@close="writingBoardToolVisible = false"
|
||||||
|
/>
|
||||||
|
|
||||||
<div class="tools-left">
|
<div class="tools-left">
|
||||||
<IconLeftTwo class="tool-btn" theme="two-tone" :fill="['#111', '#fff']" @click="execPrev()" />
|
<IconLeftTwo class="tool-btn" theme="two-tone" :fill="['#111', '#fff']" @click="execPrev()" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user