<!--Canvas鼠标画线组件-->
<template>
<canvas @mousedown="handlerMousedown" @mouseup="handlerMoseUp" id="canvas-line" :width="width" :height="height"
>您的浏览器暂不支持Canvas,请切换浏览器!</canvas
>
<!--这边放置你需要放置的内容-->
<div :style="{ zIndex: printFlag ? -99 : 100 }" class="content"><slot>请放置你需要放置的内容!</slot></div>
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue'
const width = ref<number>(1920)
const height = ref<number>(1080)
// 是否允许进行画线
let printFlag = ref<boolean>(false)
// 当前画布对象
let canvasLineDom: any = null
// 当前画布容器对象
let context: any = null
// 是否允许在canvas上进行描线
let allowPrintLine = ref<boolean>(false)
// 画布宽高自适应
onMounted(() => {
// 第一次加载时获取当前宽高,赋值给画布
const dom = document.getElementsByTagName('body')
width.value = dom[0].clientWidth
height.value = dom[0].clientHeight
//当窗口大小改变时更改画布宽高
window.addEventListener('resize', () => {
width.value = window.innerWidth
height.value = window.innerHeight - 80
})
// 监听键盘enter事件,当用户按下enter时,清空线
window.addEventListener('keydown', () => {
printFlag.value = !printFlag.value
if (canvasValid()) {
context.reset()
}
})
})
// 获取画布对象
onMounted(() => {
canvasLineDom = document.querySelector('#canvas-line')
if (canvasValid()) {
context = canvasLineDom.getContext('2d')
allowPrintLine.value = true
}
})
/**
* 获取鼠标在canvas上的具体坐标
* @param canvas canvas对象
* @param x 原x点
* @param y 原y点
*/
const windowToCanvas = (canvas: any, x: number, y: number) => {
let rect = canvas.getBoundingClientRect()
return {
x: x - rect.left * (canvas.width / rect.width),
y: y - rect.top * (canvas.height / rect.height)
}
}
/**
* 鼠标按下
* @param e 事件
*/
function handlerMousedown(e: any) {
allowPrintLine.value = true
if (canvasValid()) {
let ele = windowToCanvas(canvasLineDom, e.clientX, e.clientY)
let { x, y } = ele
context.moveTo(x, y)
canvasLineDom.onmousemove = handlerMouseMove
}
}
/**
* 鼠标移动
* @param e 事件
*/
const handlerMouseMove = (e: any) => {
if (canvasValid() && allowPrintLine.value) {
let ele = windowToCanvas(canvasLineDom, e.clientX, e.clientY)
let { x, y } = ele
context.lineTo(x, y)
context.lineWidth = '5'
context.strokeStyle = 'rgba(255,0,0,0.87)'
context.stroke()
}
}
/**
* 鼠标松开
* @param e 事件
*/
function handlerMoseUp(e: Event) {
if (canvasValid()) {
allowPrintLine.value = false
}
}
/**
* 是否支持canvas
*/
function canvasValid(): boolean {
return !canvasLineDom || !canvasLineDom.getContext ? false : true
}
</script>
<style scoped lang="scss">
#canvas-line {
overflow: hidden;
// 将canvas容器背景设为透明
background-color: rgba(0, 0, 0, 0);
margin: 0px;
padding: 0px;
}
.content {
overflow: hidden;
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
}
</style>
在页面画线(Canvans组件 vue3+Ts)
于 2022-07-11 11:08:32 首次发布