<template>
<div class="correction-wrap">
<div class="header" />
<div class="main">
<div class="left-wrap" />
<div class="center-wrap">
<!-- <canvas-container :img-url="imgUrl" />-->
<div ref="canvasContRef" class="canvas-container">
<div v-show="imgIsLoad" ref="canvasWrapRef" class="canvas-wrap" :style="canvasStyle">
<canvas ref="canvasRef"/>
</div>
<button v-for="tool in tools" @click="changeTool(tool.code)"
style="padding: 2rem;font-size: 2rem;background: pink;margin: 2rem;">{{ tool.name }}
</button>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "",
data(){
return {
imgUrl: 'http://t15.baidu.com/it/u=1890820641,1283345175&fm=224&app=112&f=JPEG?w=500&h=500',
canvas: null,
canvasX:100,//x补偿
canvasY:100,//y补偿
ctx: null,
imgIsLoad: false,
// 所使用的工具名称 drag draw
toolName: '',
// 画布的属性值
canvasValue: {
width: 0,
height: 0,
left: 0,
top: 0,
scale: 1,
rotate: 0,
cursor: 'default'
},
// 拖拽的元素列表
dragList: [],
// 记录每一步操作
preDrawAry: [],
tools: [
{
code: 'draw',
name: '画笔'
},
{
code: 'eraser',
name: '橡皮'
},
{
code: 'clean',
name: '清空'
}
]
}
},
computed: {
canvasStyle() {
const {width, height, left, top, scale, rotate, cursor} = this.canvasValue
return {
width: `${width}px`,
height: `${height}px`,
left: `${left}px`,
top: `${top}px`,
transform: `rotate(${rotate}deg) scale(${scale})`,
cursor: cursor
}
},
},
mounted() {
const canvas = this.$refs.canvasRef
const ctx = canvas.getContext('2d')
this.loadImg(canvas, ctx)
},
methods: {
// 加载图片
loadImg(canvas) {
const img = new Image()
// 图片加载成功
img.onload = () => {
this.imgIsLoad = true
canvas.width = img.width
canvas.height = img.height
this.$set(this.canvasValue, 'width', img.width)
this.$set(this.canvasValue, 'height', img.height)
canvas.style.backgroundImage = `url(${this.imgUrl})`
}
// 图片加载失败
img.onerror = () => {
}
img.src = this.imgUrl
},
// 切换工具
changeTool(name) {
console.log(name)
const wrapRef = this.$refs.canvasWrapRef
wrapRef.ontouchstart = null
const canvas = this.$refs.canvasRef
const ctx = canvas.getContext('2d')
switch (name) {
case 'draw':
this.drawPaint(canvas, ctx)
break
case 'eraser':
this.eraser(canvas, ctx)
break
case 'clean':
this.drawClear(canvas,ctx)
break
default:
break
}
},
// 画笔
drawPaintMouse(canvas, ctx) {
canvas.onmousedown = (e) => {
this.$set(this.canvasValue, 'cursor', 'crosshair')
this.imgData = ctx.getImageData(0, 0, canvas.width, canvas.height)
this.preDrawAry.push(this.imgData)
ctx.beginPath()
ctx.lineWidth = 2
ctx.strokeStyle = 'red'
ctx.moveTo(e.offsetX, e.offsetY)
canvas.onmousemove = (e) => {
ctx.lineTo(e.offsetX, e.offsetY)
ctx.stroke()
}
}
console.log(canvas.onmousedown)
// 鼠标抬起取消鼠标移动的事件
document.onmouseup = (e) => {
canvas.onmousemove = null
ctx.closePath()
this.$set(this.canvasValue, 'cursor', 'default')
}
},
drawPaint(canvas, ctx) {
canvas.ontouchstart = (e) => {
this.$set(this.canvasValue, 'cursor', 'crosshair')
this.imgData = ctx.getImageData(0, 0, canvas.width, canvas.height)
this.preDrawAry.push(this.imgData)
e.preventDefault();
ctx.beginPath()
ctx.lineWidth = 2
ctx.strokeStyle = 'red'
ctx.moveTo(e.changedTouches[0].pageX-this.canvasX, e.changedTouches[0].pageY-this.canvasY)
canvas.ontouchmove = (e) => {
ctx.lineTo(e.changedTouches[0].pageX-this.canvasX, e.changedTouches[0].pageY-this.canvasY)
ctx.stroke()
}
}
console.log(canvas.onmousedown)
// 鼠标抬起取消鼠标移动的事件
document.ontouchend = (e) => {
canvas.ontouchmove = null
ctx.closePath()
this.$set(this.canvasValue, 'cursor', 'default')
}
},
drawClear(canvas, ctx){
ctx.clearRect(0,0,canvas.offsetWidth,canvas.offsetHeight)//重置画笔
},
// 橡皮擦
eraser(canvas, ctx, r = 10) {
canvas.ontouchstart = (e) => {
this.imgData = ctx.getImageData(0, 0, canvas.width, canvas.height)
this.preDrawAry.push(this.imgData)
let x1 = e.changedTouches[0].pageX-this.canvasX
let y1 = e.changedTouches[0].pageY-this.canvasY
// 鼠标第一次点下的时候擦除一个圆形区域,同时记录第一个坐标点
ctx.save()
e.preventDefault();
ctx.beginPath()
ctx.arc(x1, y1, r, 0, 2 * Math.PI)
ctx.clip()
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.restore()
canvas.ontouchmove = (e) => {
const x2 = e.changedTouches[0].pageX-this.canvasX
const y2 = e.changedTouches[0].pageY-this.canvasY
// 获取两个点之间的剪辑区域四个端点
const asin = r * Math.sin(Math.atan((y2 - y1) / (x2 - x1)))
const acos = r * Math.cos(Math.atan((y2 - y1) / (x2 - x1)))
// 保证线条的连贯,所以在矩形一端画圆
ctx.save()
ctx.beginPath()
ctx.arc(x2, y2, r, 0, 2 * Math.PI)
ctx.clip()
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.restore()
// 清除矩形剪辑区域里的像素
ctx.save()
ctx.beginPath()
ctx.moveTo(x1 + asin, y1 - acos)
ctx.lineTo(x2 + asin, y2 - acos)
ctx.lineTo(x2 - asin, y2 + acos)
ctx.lineTo(x1 - asin, y1 + acos)
ctx.closePath()
ctx.clip()
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.restore()
// 记录最后坐标
x1 = x2
y1 = y2
}
}
},
}
}
</script>