feat: 放映模式画板添加荧光笔

This commit is contained in:
pipipi-pikachu 2022-04-23 14:27:08 +08:00
parent b0a4c9dc22
commit 4bd8012425
3 changed files with 70 additions and 39 deletions

View File

@ -17,34 +17,49 @@
@mouseenter="mouseInCanvas = true" @mouseenter="mouseInCanvas = true"
></canvas> ></canvas>
<div <template v-if="mouseInCanvas">
class="pen" <div
:style="{ class="eraser"
left: mouse.x - penSize / 2 + 'px', :style="{
top: mouse.y - 36 + penSize / 2 + 'px', left: mouse.x - rubberSize / 2 + 'px',
color: color, top: mouse.y - rubberSize / 2 + 'px',
}" width: rubberSize + 'px',
v-if="mouseInCanvas && model === 'pen'" height: rubberSize + 'px',
><IconWrite class="icon" size="36" /></div> }"
v-if="model === 'eraser'"
<div ></div>
class="eraser" <div
:style="{ class="pen"
left: mouse.x - rubberSize / 2 + 'px', :style="{
top: mouse.y - rubberSize / 2 + 'px', left: mouse.x - penSize / 2 + 'px',
width: rubberSize + 'px', top: mouse.y - 36 + penSize / 2 + 'px',
height: rubberSize + 'px', color: color,
}" }"
v-if="mouseInCanvas && model === 'eraser'" v-if="model === 'pen'"
></div> >
<IconWrite class="icon" size="36" v-if="model === 'pen'" />
</div>
<div
class="pen"
:style="{
left: mouse.x - markSize / 2 + 'px',
top: mouse.y + 'px',
color: color,
}"
v-if="model === 'mark'"
>
<IconHighLight class="icon" size="36" v-if="model === 'mark'" />
</div>
</template>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, onMounted, onUnmounted, PropType, ref } from 'vue' import { computed, defineComponent, onMounted, onUnmounted, PropType, ref, watch } from 'vue'
const penSize = 6 const penSize = 6
const rubberSize = 80 const rubberSize = 80
const markSize = 25
export default defineComponent({ export default defineComponent({
name: 'writing-board', name: 'writing-board',
@ -54,7 +69,7 @@ export default defineComponent({
default: '#ffcc00', default: '#ffcc00',
}, },
model: { model: {
type: String as PropType<'pen' | 'eraser'>, type: String as PropType<'pen' | 'eraser' | 'mark'>,
default: 'pen', default: 'pen',
}, },
blackboard: { blackboard: {
@ -119,6 +134,20 @@ export default defineComponent({
} }
onMounted(initCanvas) onMounted(initCanvas)
// canvas ctx
const updateCtx = () => {
if (!ctx) return
if (props.model === 'mark') {
ctx.globalCompositeOperation = 'xor'
ctx.globalAlpha = 0.5
}
else if (props.model === 'pen') {
ctx.globalCompositeOperation = 'source-over'
ctx.globalAlpha = 1
}
}
watch(() => props.model, updateCtx)
// //
const draw = (posX: number, posY: number, lineWidth: number) => { const draw = (posX: number, posY: number, lineWidth: number) => {
if (!ctx) return if (!ctx) return
@ -205,9 +234,10 @@ export default defineComponent({
draw(x, y, lineWidth) draw(x, y, lineWidth)
lastLineWidth = lineWidth lastLineWidth = lineWidth
} }
else if (props.model === 'mark') draw(x, y, markSize)
else erase(x, y) else erase(x, y)
lastPos = {x, y} lastPos = { x, y }
lastTime = new Date().getTime() lastTime = new Date().getTime()
} }
@ -266,6 +296,7 @@ export default defineComponent({
mouseInCanvas, mouseInCanvas,
penSize, penSize,
rubberSize, rubberSize,
markSize,
writingBoardRef, writingBoardRef,
canvasRef, canvasRef,
canvasWidth, canvasWidth,

View File

@ -96,6 +96,7 @@ import {
Power, Power,
ListView, ListView,
Magic, Magic,
HighLight,
} from '@icon-park/vue-next' } from '@icon-park/vue-next'
export default { export default {
@ -215,6 +216,7 @@ export default {
app.component('IconPower', Power) app.component('IconPower', Power)
app.component('IconListView', ListView) app.component('IconListView', ListView)
app.component('IconMagic', Magic) app.component('IconMagic', Magic)
app.component('IconHighLight', HighLight)
// 视频播放器 // 视频播放器
app.component('IconPause', Pause) app.component('IconPause', Pause)

View File

@ -16,10 +16,13 @@
<div class="tools" :style="position"> <div class="tools" :style="position">
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.3" title="画笔"> <Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.3" title="画笔">
<div class="btn" :class="{ 'active': writingBoardModel === 'pen' }" @click="changePen()"><IconWrite class="icon" /></div> <div class="btn" :class="{ 'active': writingBoardModel === 'pen' }" @click="changeModel('pen')"><IconWrite class="icon" /></div>
</Tooltip>
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.3" title="荧光笔">
<div class="btn" :class="{ 'active': writingBoardModel === 'mark' }" @click="changeModel('mark')"><IconHighLight class="icon" /></div>
</Tooltip> </Tooltip>
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.3" title="橡皮擦"> <Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.3" title="橡皮擦">
<div class="btn" :class="{ 'active': writingBoardModel === 'eraser' }" @click="changeEraser()"><IconErase class="icon" /></div> <div class="btn" :class="{ 'active': writingBoardModel === 'eraser' }" @click="changeModel('eraser')"><IconErase class="icon" /></div>
</Tooltip> </Tooltip>
<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>
@ -48,7 +51,7 @@
import { defineComponent, PropType, ref } from 'vue' import { defineComponent, PropType, ref } from 'vue'
import WritingBoard from '@/components/WritingBoard.vue' import WritingBoard from '@/components/WritingBoard.vue'
const writingBoardColors = ['#000000', '#ffffff', '#1e497b', '#4e81bb', '#e2534d', '#9aba60', '#8165a0', '#47acc5', '#f9974c'] const writingBoardColors = ['#000000', '#ffffff', '#1e497b', '#4e81bb', '#e2534d', '#9aba60', '#8165a0', '#47acc5', '#f9974c', '#ffff3a']
interface Position { interface Position {
left?: number | string; left?: number | string;
@ -57,6 +60,8 @@ interface Position {
bottom?: number | string; bottom?: number | string;
} }
type WritingBoardModel = 'pen' | 'mark' | 'eraser'
export default defineComponent({ export default defineComponent({
name: 'writing-board-tool', name: 'writing-board-tool',
emits: ['close'], emits: ['close'],
@ -83,17 +88,11 @@ export default defineComponent({
setup(props, { emit }) { setup(props, { emit }) {
const writingBoardRef = ref() const writingBoardRef = ref()
const writingBoardColor = ref('#e2534d') const writingBoardColor = ref('#e2534d')
const writingBoardModel = ref<'pen' | 'eraser'>('pen') const writingBoardModel = ref<WritingBoardModel>('pen')
const blackboard = ref(false) const blackboard = ref(false)
// const changeModel = (model: WritingBoardModel) => {
const changePen = () => { writingBoardModel.value = model
writingBoardModel.value = 'pen'
}
//
const changeEraser = () => {
writingBoardModel.value = 'eraser'
} }
// //
@ -101,9 +100,9 @@ export default defineComponent({
writingBoardRef.value.clearCanvas() writingBoardRef.value.clearCanvas()
} }
// //
const changeColor = (color: string) => { const changeColor = (color: string) => {
if (writingBoardModel.value !== 'pen') writingBoardModel.value = 'pen' if (writingBoardModel.value === 'eraser') writingBoardModel.value = 'pen'
writingBoardColor.value = color writingBoardColor.value = color
} }
@ -118,8 +117,7 @@ export default defineComponent({
writingBoardColor, writingBoardColor,
writingBoardModel, writingBoardModel,
blackboard, blackboard,
changePen, changeModel,
changeEraser,
clearCanvas, clearCanvas,
changeColor, changeColor,
closeWritingBoard, closeWritingBoard,