<template>
<div class="test">
<canvas
id="mycanvas"
width="800"
height="600"
ref="canvas"
@mousedown="canvasDown($event)"
@mouseup="canvasUp($event)"
@mousemove="canvasMove($event)"
></canvas>
<img :src="signSrc" alt="" />
<el-button type="danger" @click="penClick">画笔</el-button>
<el-button type="danger" @click="rectangleClick">矩形</el-button>
<el-button type="danger" @click="roundClick">圆形</el-button>
<el-button type="danger" @click="resetCanvas">清空画布</el-button>
<el-button type="danger" @click="revoke">撤销</el-button>
<el-button type="danger" @click="saveImg">保存图片</el-button>
</div>
</template>
<script>
export default {
components: {},
data () {
return {
flag: false, // 是否绘制
imgUrl:
'https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg',
img: new Image(), // 背景图片缓存
context: {}, // canvas对象
oldX: 0, // 第一次点击X轴
oldY: 0, // 第一次点击Y轴
penDraw: false, // 画笔工具是否启用
rectangleDraw: false, // 矩形工具是否启用
roundDraw: false, // 圆形工具是否启用
history: [], // 存储每次操作
signSrc: '' // 保存的图片地址
}
},
mounted () {
this.initDraw()
},
methods: {
initDraw () {
// 初始化画布
const canvas = this.$refs.mycanvas//document.getElementById('mycanvas')
var a = setInterval(() => {
canvas = document.getElementById('mycanvas')
if(!canvas){
return false
}else{
clearInterval(a)
this.context = canvas.getContext('2d')
this.img.src = this.imgUrl
this.img.onload = () => {
if(this.img.complete){
//根据图像重新设定canvas宽高
canvas.setAttribute("width",img.width)
canvas.setAttribute("height",this.img.height)
//绘制图片
this.context.drawImage(this.img, 0, 0, this.img.width, this.img.height)
this.context.lineWidth = 3 // 画笔粗细
this.context.strokeStyle = '#FF0000' // 画笔颜色
}
}
}
},1)
},
// 点击画笔
penClick () {
this.penDraw = true
this.rectangleDraw = false
this.roundDraw = false
},
// 点击矩形
rectangleClick () {
this.penDraw = false
this.rectangleDraw = true
this.roundDraw = false
},
// 点击圆形
roundClick () {
this.penDraw = false
this.rectangleDraw = false
this.roundDraw = true
},
// 保存图片
saveImg () {
// location.href = this.$refs.canvas.toDataURL().replace('image/png', 'image/stream')
const imgBase64 = this.$refs.canvas.toDataURL('image/png')
this.signSrc = imgBase64
},
resetCanvas () {
// 清空画布
this.context.clearRect(0, 0, 800, 600) // 清空
this.flag = false
this.history.length = 0 // 清空记录
this.initDraw()
},
// 撤销
revoke () {
this.history.pop()
if (this.history.length > 0) {
// 从存入的记录里删除
this.context.putImageData(this.history[this.history.length - 1], 0, 0)
}
},
// 绘制铅笔
pencil (e) {
const newx = e.offsetX //e.pageX
const newy = e.offsetY //e.pageY
this.context.lineTo(newx, newy)
this.context.stroke()
},
// 绘制矩形
rectangle (e) {
const newX = e.offsetX //e.pageX
const newY = e.offsetY // e.pageY
this.context.beginPath()
this.context.rect(this.oldX, this.oldY, newX - this.oldX, newY - this.oldY)
this.context.stroke()
},
// 绘制圆形
round (e) {
const newX = e.offsetX // e.pageX
const newY = e.offsetY //e.pageY
this.context.beginPath()
var r = Math.sqrt(Math.pow(newX - this.oldX, 2), Math.pow(newY - this.oldY), 2)
/**
ctx.arc(x, y, radius, startAngle, endAngle, Boolean)
圆心坐标: (x, y)
半径: radius
起始角度: startAngle
结束角度: endAngle
是否逆时针旋转: false 代表顺时针旋转
*/
this.context.arc(this.oldX, this.oldY, r, 0, 2 * Math.PI)
this.context.closePath()
this.context.stroke()
},
// 鼠标落下
canvasDown (e) {
this.context.beginPath() // 分开路径,开始一个新的路径
this.flag = true // 开始绘制
// 获取鼠标起始位置
this.oldX = e.offsetX // e.pageX
this.oldY = e.offsetY // e.pageY
},
// 鼠标滑动
canvasMove (e) {
if (this.flag === true) {
if (this.history.length > 0) {
// history数组的长度大于0,才可以putImageData()
this.context.putImageData(
this.history[this.history.length - 1],
0,
0
)
} else {
this.history.push(this.context.getImageData(0, 0, 800, 600))
}
// 执行画笔
if (this.flag === true && this.penDraw === true) {
this.pencil(e)
}
// 执行矩形
if (this.flag === true && this.rectangleDraw === true) {
this.rectangle(e)
}
// 执行圆形
if (this.flag === true && this.roundDraw === true) {
this.round(e)
}
}
},
// 鼠标抬起
canvasUp (e) {
console.log(e)
// getImageData() 方法返回 ImageData 对象,该对象拷贝了画布指定矩形的像素数据。
this.history.push(this.context.getImageData(0, 0, 800, 600))
this.flag = false
}
}
}
</script>
<style lang="less" scoped></style>
