需求
通过canvas来实现触摸板来写下一些题目的解题步骤,然后使用设备是手机跟pad
代码
vue
<template>
<canvas id="canvas" @touchstart="touchstart" @touchend="touchend" @touchmove="touchmove"></canvas>
</template>
js
export default {
data() {
return {
ctx: '',
point: {
x: 0,
y: 0
}
}
},
mounted() {
this.init()
},
methods: {
/**
* @description: canvas 初始化
* @param {type}
* @return:
*/
init() {
const canvas = document.getElementById('canvas')
this.ctx = canvas.getContext('2d')
this.ctx.strokeStyle = '#474E60'
this.ctx.lineWidth = 1
},
/**
* @description: 获取相对坐标
* @param {type}
* @return:
*/
absolutePoint(event) {
const touch = event.targetTouches[0]
const canvas = document.getElementById('canvas')
const react = canvas.getBoundingClientRect()
this.point = { x: touch.pageX - react.left, y: touch.pageY - react.top }
},
/**
* @description: 绘制
* @param {type}
* @return:
*/
draw(event) {
this.ctx.lineTo(this.point.x, this.point.y)
this.ctx.stroke()
},
/**
* @description: 开始触摸
* @param {type}
* @return:
*/
touchstart(event) {
this.absolutePoint(event)
this.ctx.moveTo(this.point.x, this.point.y)
},
/**
* @description: 触摸结束
* @param {type}
* @return:
*/
touchend(event) {},
/**
* @description: 触摸移动
* @param {type}
* @return:
*/
touchmove(event) {
this.absolutePoint(event)
this.draw(event)
}
}
}
效果图
问题
触摸坐标跟画图坐标不符,然后线条模糊
解决方案
在init方法里边重置canvas的高宽
/**
* @description: canvas 初始化
* @param {type}
* @return:
*/
init() {
const canvas = document.getElementById('canvas')
const width = canvas.offsetWidth // ++
const height = canvas.offsetHeight // ++
this.ctx = canvas.getContext('2d')
canvas.width = width // ++
canvas.height = height // ++
this.ctx.strokeStyle = '#474E60'
this.ctx.lineWidth = 1
},
问题原因
canvas 的宽高属性是必须通过属性设置的,因为需求原因,我的canvas通过父元素进行100%设置,通过重置canvas高宽可以解决问题。
完整实例
完整代码
<template>
<canvas id="canvas" @touchstart="touchstart" @touchend="touchend" @touchmove="touchmove"></canvas>
</template>
<script>
export default {
data() {
return {
ctx: '',
point: {
x: 0,
y: 0
}
}
},
mounted() {
this.init()
},
methods: {
/**
* @description: canvas 初始化
* @param {type}
* @return:
*/
init() {
const canvas = document.getElementById('canvas')
const width = canvas.offsetWidth
const height = canvas.offsetHeight
this.ctx = canvas.getContext('2d')
canvas.width = width
canvas.height = height
this.ctx.strokeStyle = '#474E60'
this.ctx.lineWidth = 1
},
/**
* @description: 获取相对坐标
* @param {type}
* @return:
*/
absolutePoint(event) {
const touch = event.targetTouches[0]
const canvas = document.getElementById('canvas')
const react = canvas.getBoundingClientRect()
this.point = { x: touch.pageX - react.left, y: touch.pageY - react.top }
},
/**
* @description: 绘制
* @param {type}
* @return:
*/
draw(event) {
this.ctx.lineTo(this.point.x, this.point.y)
this.ctx.stroke()
},
/**
* @description: 开始触摸
* @param {type}
* @return:
*/
touchstart(event) {
this.absolutePoint(event)
this.ctx.moveTo(this.point.x, this.point.y)
},
/**
* @description: 触摸结束
* @param {type}
* @return:
*/
touchend(event) {},
/**
* @description: 触摸移动
* @param {type}
* @return:
*/
touchmove(event) {
this.absolutePoint(event)
this.draw(event)
}
}
}
</script>
ps: 实例是以组件形式存在