本插件是基于zwp-draw-pad插件来实现的
首先第一步封装插件
<template>
<canvas canvas-id="myCanvas" disable-scroll :style="drawPadStyles" @touchstart="onTouchStart"
@touchmove="onTouchMove" @touchend="onTouchEnd" />
</template>
<script>
function deepClone(data) {
return JSON.parse(JSON.stringify(data))
}
export default {
props: {
width: {
type: Number,
required: true
},
height: {
type: Number,
required: true
},
color: {
type: String,
default: '#000'
},
size: {
type: Number,
default: 3
},
disabled: {
type: Boolean,
default: false
}
},
computed: {
drawPadStyles({
width,
height
}) {
return `width: ${width}px;height: ${height}px`
}
},
methods: {
onTouchStart(e) {
const {
disabled,
points,
originData
} = this
if (disabled) return
const {
x,
y
} = e.changedTouches[0]
points.push([x, y])
originData.push([
[x, y]
])
},
onTouchMove(e) {
const {
disabled,
points,
originData,
draw
} = this
if (disabled) return
const {
x,
y
} = e.changedTouches[0]
points.push([x, y])
originData[originData.length - 1].push([x, y])
draw()
},
onTouchEnd() {
this.points = []
},
draw() {
const {
ctx,
points
} = this
if (points.length < 2) return
ctx.moveTo(...points.shift())
ctx.lineTo(...points[0])
ctx.stroke()
ctx.draw(true)
},
/**
* 清空画布
*/
init() {
const {
ctx,
width,
height
} = this
ctx.clearRect(0, 0, width, height)
ctx.draw()
this.originData = []
},
/**
* 回退到上一笔
*/
back() {
const {
originData,
drawByData
} = this
originData.pop()
drawByData(originData)
},
/**
* 根据传入的数据绘制
* @param {Array} data
*/
drawByData(data) {
const {
init,
ctx
} = this
if (!data || !data.length) return init()
const tempData = deepClone(data)
while (!!tempData.length) {
const lineData = tempData.shift()
ctx.moveTo(...lineData.shift())
while (!!lineData.length) ctx.lineTo(...lineData.shift())
}
ctx.stroke()
ctx.draw()
},
/**
* 临时保存画布上的数据
* @param {Any} key 用于访问的key
* @param {Boolean} isInit 保存完毕后是否清空画布,默认为true
*/
saveCache(key, isInit = true) {
const {
cache,
originData,
init
} = this
const temp = deepClone(originData)
cache.set(key, temp)
if (isInit) init()
},
/**
* 用缓存的key恢复画布
* @param {Any} key 用于访问的key
*/
restoreCache(key) {
const {
drawByData,
cache
} = this
this.originData = cache.get(key)
drawByData(this.originData)
},
/**
* 清空缓存数据
*/
clearCache() {
this.cache.clear()
},
save(options) {
return new Promise((success, fail) => {
const {
width,
height,
canvasId
} = this
uni.canvasToTempFilePath({
x: 0,
y: 0,
width,
height,
...options,
canvasId: 'myCanvas',
success,
fail
},
this
)
})
}
},
created() {
const {
color,
size
} = this
const ctx = uni.createCanvasContext('myCanvas', this)
ctx.setStrokeStyle(color)
ctx.setLineWidth(size)
ctx.setLineCap('round')
ctx.setLineJoin('round')
this.ctx = ctx
this.points = []
this.originData = []
this.cache = new Map()
}
}
</script>
封装好插件以后我们把他放到公共文件夹
然后在需要使用的页面script引入
import QM from "@/common/qianming.vue" //具体名字,路径根据自己创建的来
然后在template标签内引入
<template>
<view class="qmb">
<QM ref="drawview" :width="600" :height="300" />
<view class="button">
<view class="clearbtn" @click="padinit()">清除</view>
<view class="surebtn" @click="padsave()">确定</view>
</view>
</view>
</template>
在method执行方法,下面列举一部分有需要可以根据自身情况来自己添加
具体用法参考清除按钮,在上面封装的文件里都有标注
// 清除按钮
padinit() {
this.$refs.drawview.init()
},
// 保存手写内容为图片(base64)
padsave() {
var that = this;
this.$refs.drawview.save().then(res => {
console.log('保存图片的地址', res.tempFilePath)
},
下面是样式,根据自己需求更改
<style lang="less">
.button {
width: 100%;
height: 60px;
color: #27408B;
position: fixed;
bottom: 0px;
left: 0;
}
.clearbtn {
background-color: #FFFFFF;
width: 50%;
height: 40px;
color: #27408B;
float: left;
border: 2px solid #0390ff;
font-size: 15px;
font-family: '黑体';
line-height: 40px;
text-align: center;
}
.surebtn {
background-color: #0390ff;
width: 50%;
height: 40px;
color: #fff;
float: left;
font-size: 15px;
font-family: '黑体';
line-height: 40px;
text-align: center;
}
.clearbtn:hover {
background-color: #D8D8D8;
}
.surebtn:hover {
background-color: #D8D8D8;
}
</style>
有不明白或者更好的建议欢迎在下方评论