市面上的其它组件都是直接用白色来覆盖,实现了橡皮擦功能,但是有缺陷,就是遇到不是白底的,例如其它颜色或者透明色,就用白色覆盖不掉了,而且白色还容易给别的地方涂改成白色了,很鸡肋。我这个方法是消除法,把黑色的内容用白色的抵消掉,只对画笔画过的内容起作用,其它地方不会覆盖,也不会消除。
1.下载组件
npm install --save-dev vue-drawing-canvas**
页面使用
<template>
<vue-drawing-canvas ref="VueCanvasDrawing" />
</template>
<script>
import VueDrawingCanvas from "vue-drawing-canvas";
export default {
name: "MyComponent",
components: {
VueDrawingCanvas,
},
};
我的页面使用,和上面一样,只不过用了一些属性
<vue-drawing-canvas
v-if="isShowCanvas"
class="esign-atra"
ref="VueCanvasDrawing"
:image.sync="image"
:width="esignWidth"
:height="esignHeight"
:stroke-type="strokeType"
:line-cap="lineCap"
:line-join="lineJoin"
:fill-shape="fillShape"
:eraser="eraser"
:lineWidth="line"
:color="color"
:background-color="backgroundColor"
:background-image="backgroundImage"
:watermark="watermark"
:initialImage="initialImage"
saveAs="png"
:styles="{
}"
:lock="disabled"
@mousemove.native="getCoordinate($event)"
:additional-images="additionalImages"
/>
页面展现,我这边是后台返回的图片,所以用img展现
<img v-for="(item,index) in esignImageList"
:key="index"
:src="item.bs64"
:style="[{
position:'absolute',
marginLeft: '20px',
zIndex: 9,
width: esignWidth + 'px',
height:esignHeight+ 'px',
}]">
2.重点
修改的地方:node_modules
找到vue_drawing_canvas.esm.js这个文件
其实我们在画布上画的黑色的区域都是由无数个点构成,每个点都有(x,y)
要想实现橡皮擦功能,分两步
第一步,将画笔变成白色。
在startDraw这个方法中判断切换到橡皮擦的属性eraser,然后将笔的颜色变成白色。
startDraw(event) {
if (!this.lock) {
this.drawing = true;
let coordinate = this.getCoordinates(event);
this.strokes = {
type: this.eraser ? 'eraser' : this.strokeType,
from: coordinate,
coordinates: [],
///////////// 判断切换到橡皮擦的属性eraser,然后将笔的颜色变成白色
color: this.eraser ? '#fff' : this.color,
////////////
width: this.lineWidth,
fill: this.eraser || this.strokeType === 'dash' || this.strokeType === 'line' ? false : this.fillShape,
lineCap: this.lineCap,
lineJoin: this.lineJoin
};
this.guides = [];
}
},
第二步,将白色笔画过的区域从黑色的区域的数组中筛选出来
在stopDraw方法中,计算白色笔画过的区域的最近和最远的点。然后从黑色笔画过的区域中减去这些白色重合的点,是不是就达到了橡皮擦的作用。
// 获取画笔在画布上x轴延伸最左边的点,y轴最上面的点,也就是x最小,y最小的点
getMin(arr, type) {
var min = arr.length === 0 ? arr[0] : arr[0][type];
for(var i = 1, ilen = arr.length; i < ilen; i+=1) {
if(arr[i][type] < min) {
min = arr[i][type];
}
}
return min;
},
// 获取画笔在画布上x轴延伸最右边的点,y轴最下面的点,也就是x最大,y最大
getMax(arr, type) {
var max = arr.length === 0 ? arr[0] : arr[0][type];
for(var i = 1,ilen = arr.length; i < ilen; i++) {
if(arr[i][type] > max) {
max = arr[i][type];
}
}
return max;
},
// 在画笔停下的时候,计算橡皮擦擦过的线经过的最远和最近的点,然后将其从黑色笔的数组中去掉。
stopDraw() {
if (this.drawing) {
this.strokes.coordinates = this.guides.length > 0 ? this.guides : this.strokes.coordinates;
// 判断是否点开橡皮擦,橡皮擦时执行下列逻辑
if (this.strokes.type === 'eraser') {
// images就是那个最终生效的数组
const imagesCopy = JSON.parse(JSON.stringify(this.images))
imagesCopy.forEach((item) => {
if (item.type === 'dash') {
const minX = this.getMin(item.coordinates, 'x')
const maxX = this.getMax(item.coordinates, 'x')
const minY = this.getMin(item.coordinates, 'y')
const maxY = this.getMax(item.coordinates, 'y')
// 这一步,将黑色区域的数组this.strokes.coordinates与白色区域的数组重合的地方筛选出来,然后重新往最终展现的数组里push,也就是images
let arr = this.strokes.coordinates.filter(_item => _item.x < maxX + 1 && _item.x > minX - 1 && _item.y < maxY + 1 && _item.y > minY - 1)
this.images.push({
color: this.strokes.color,
fill: this.strokes.fill,
from: this.strokes.from,
lineCap:this.strokes.lineCap,
lineJoin: this.strokes.lineJoin,
type: this.strokes.type,
width: this.strokes.width,
coordinates: arr
});
}
})
} else {
// 不是橡皮擦的正常push
this.images.push(this.strokes);
}
this.redraw(true);
this.drawing = false;
this.trash = [];
}
},