1. Vue介绍
Vue 是一套用于构建用户界面的渐进式框架。Vue 的核心库只关注视图层。
在本文将讲解如何利用 Vue 和一些其他的库来实现图片的马赛克和涂鸦功能。
2. 马赛克功能实现
2.1. 获取图片信息
首先,接下来要使用的几个库 。我们将使用以下库:
vue
vue-croppie
vue-easy-crop
js-image-mosaic
其中,vue-croppie 和 vue-easy-crop 用于截取图片,而 js-image-mosaic 用于处理马赛克效果。
在 Vue 的 data 上存储选择的图片信息:
data() {
return {
selectedImg: null,
mosaicImg: null,
mosaicSize: 25,
mosaicOpacity: 1,
};
},
在模板中,使用 file input 元素来选择图片:
<template>
<div class="mosaic-demo">
<input type="file" @change="onSelectImg"/>
<div v-if="selectedImg">
<vue-croppie
ref="croppie"
:img="selectedImg"
:viewport="{ width: 200, height: 200, type: 'circle' }"
:boundary="{ width: 300, height: 300 }"
/>
<button type="button" class="mosaic-button" @click="applyMosaic">
Apply Mosaic
</button>
</div>
</div>
</template>
使用 @change 事件在文件选择器中选择图像,然后使用 vue-croppie 组件来确保图像在可见区域内。我们将 onSubmit 方法定义如下:
methods: {
onSelectImg(event) {
this.selectedImg = event.target.files[0];
},
applyMosaic() {
const image = this.$refs.croppie.get().toDataURL();
const img = new Image();
img.onload = () => {
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
canvas.getContext('2d').drawImage(img, 0, 0);
this.mosaicImg = new JSMosaic(canvas, { size: this.mosaicSize, alpha: this.mosaicOpacity })
.generate();
};
img.src = image;
},
},
在 applyMosaic 方法中,我们拿到之前在 vue-croppie 组件上截取的图像。我们创建了一个新图像标签并将数据 url 设置为图像源。一旦图像加载完毕,我们将其绘制到画布上,并使用 JSMosaic 库创建蒙版图像。
2.2. 显示马赛克效果
在模板中,我们使用 vue-easy-crop 创造一个容器来显示马赛克<img>
<template>
<div class="mosaic-demo">
<input type="file" @change="onSelectImg"/>
<div v-if="selectedImg">
<vue-croppie
ref="croppie"
:img="selectedImg"
:viewport="{ width: 200, height: 200, type: 'circle' }"
:boundary="{ width: 300, height: 300 }"
/>
<button type="button" class="mosaic-button" @click="applyMosaic">
Apply Mosaic
</button>
<div class="mosaic-result" v-if="mosaicImg">
<vue-easy-crop :image="mosaicImg">
<span aria-hidden="true">{{ $t('scratchArea.label') }}</span>
</vue-easy-crop>
</div>
</div>
</div>
</template>
现在,我们已经使用 vue-croppie 组件截取选择的图像,并使用 JSMosaic 库创建马赛克效果。使用 vue-easy-crop 库可以方便地和美观地显示那幅马赛克图像。
3. 涂鸦功能实现
3.1. 编写样式表
在样式表中,我们编写用于在画布上绘制图形的 CSS 代码。下面是我们的样式表:
.canvas-container::before {
content: "";
display: block;
background-color: rgba(255, 255, 255, 0.5);
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1;
}
.canvas {
display: block;
position: relative;
z-index: 2;
}
3.2. 创建涂鸦组件
在我们的组件模板中,我们创建了一个图像输入,并将其包装在一个在页面上点击后呈现涂鸦图像的容器中。
<template>
<div class="draw-container">
<input type="file" @change="onSelectImg" />
<div class="canvas-container" @mousedown="handleMouseDown" @mouseup="handleMouseUp" @mousemove="handleMouseMove">
<canvas ref="canvas" class="canvas" width="600" height="400" />
</div>
</div>
</template>
在 data 中,我们存储希望绘制的图形,在这里放置了一个空对象:
data() {
return {
drawingObject: {},
isMousePressed: false,
image: null
};
},
在处理鼠标活动事件的方法中,我们地几个地方才是相关的件。首先,在 handleMouseDown 方法中,我们设置 isMousePressed 布尔值为 true。
handleMouseDown(e) {
this.isMousePressed = true;
this.drawingObject.color = '#'+Math.floor(Math.random()*16777215).toString(16);
this.drawingObject.size = 2;
this.drawingObject.points = [
{
x: e.offsetX,
y: e.offsetY
}
];
},
然后,在 handleMouseMove中,我们开始绘制选择颜色和大小的方格图形:
handleMouseMove(e) {
if (this.isMousePressed) {
this.drawingObject.points.push({
x: e.offsetX,
y: e.offsetY
});
}
this.draw();
},
在 handleMouseUp 处理程序中,我们将当前建立的图形添加到 drawings 数组中,并将 drawingObject 重置为空对象:
handleMouseUp() {
if (this.isMousePressed) {
this.drawings.push(this.drawingObject);
this.drawingObject = {};
this.isMousePressed = false;
}
},
我们还需要在 mounted 钩子中编写一个方法来将图像加载到画布中:
mounted() {
this.loadImage();
},
methods: {
loadImage() {
if (!this.image) {
return;
}
const canvas = this.$refs.canvas;
const context = canvas.getContext('2d');
const img = new Image();
img.onload = () => {
context.drawImage(img, 0, 0, canvas.width, canvas.height);
};
img.src = this.image;
},
...
},
在 loadImage 方法中,我们检查图像是否存在,如果存在,则将其绘制到画布上,这样就可以在涂鸦之上显示它。
3.3. 绘制图案
最后,我们通过将所有在 drawings 数组中的图形渲染到画布上来完成绘制图案功能。
draw() {
const canvas = this.$refs.canvas;
const context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
this.loadImage();
this.drawings.forEach((drawing) => {
context.beginPath();
context.strokeStyle = drawing.color;
context.lineWidth = drawing.size;
context.moveTo(drawing.points[0].x, drawing.points[0].y);
drawing.points.forEach((point) => {
context.lineTo(point.x, point.y);
});
context.stroke();
context.closePath();
});
},
在绘制函数中,我们使用 canvas 清除画布,然后使用 context.beginPath 确保没有先前的绘图对象残留。接着,我们使用 context.strokeStyle 和 context.lineWidth 设置绘图颜色和线宽。此后,我们使用 moveTo 和 lineTo 将每个点连接到下一个点,并使用 context.stroke 将绘制图案渲染到屏幕上。
4. 结论
在本文中,我们探讨了如何通过使用一些 Vue 库(vue-croppie,vue-easy-crop 和 js-image-mosaic)以及使用 vanilla JavaScript 能快速达到实现图片的马赛克和涂鸦的方式。我希望你能按照这些步骤,完成这个应用,并且能改善它或者利用它来完成自己的项目。