vue实现画布编辑
Vue 实现画布编辑
使用 HTML5 Canvas 和 Vue 结合
在 Vue 中可以通过封装 HTML5 Canvas 实现画布编辑功能。创建一个 Vue 组件,在 mounted 钩子中初始化画布,并通过事件监听实现绘图交互。
<template>
<canvas ref="canvas" @mousedown="startDrawing" @mousemove="draw" @mouseup="stopDrawing"></canvas>
</template>
<script>
export default {
data() {
return {
isDrawing: false,
ctx: null,
};
},
mounted() {
const canvas = this.$refs.canvas;
canvas.width = 800;
canvas.height = 600;
this.ctx = canvas.getContext('2d');
},
methods: {
startDrawing(e) {
this.isDrawing = true;
this.ctx.beginPath();
this.ctx.moveTo(e.offsetX, e.offsetY);
},
draw(e) {
if (!this.isDrawing) return;
this.ctx.lineTo(e.offsetX, e.offsetY);
this.ctx.stroke();
},
stopDrawing() {
this.isDrawing = false;
},
},
};
</script>
使用第三方库 Fabric.js
Fabric.js 是一个功能强大的 Canvas 库,支持对象操作、缩放、旋转等高级功能。在 Vue 中集成 Fabric.js 可以快速实现复杂的画布编辑功能。

<template>
<canvas ref="canvas"></canvas>
</template>
<script>
import { fabric } from 'fabric';
export default {
mounted() {
const canvas = new fabric.Canvas(this.$refs.canvas, {
width: 800,
height: 600,
});
// 添加矩形
const rect = new fabric.Rect({
left: 100,
top: 100,
width: 50,
height: 50,
fill: 'red',
});
canvas.add(rect);
// 支持拖拽和缩放
canvas.set('selection', true);
},
};
</script>
使用 SVG 和 Vue 结合
如果不需要像素级操作,可以使用 SVG 实现画布编辑。SVG 是矢量图形,适合实现缩放、平移等操作。

<template>
<svg ref="svg" width="800" height="600" @mousedown="startDrawing" @mousemove="draw" @mouseup="stopDrawing">
<path :d="pathData" stroke="black" fill="none" />
</svg>
</template>
<script>
export default {
data() {
return {
isDrawing: false,
pathData: '',
};
},
methods: {
startDrawing(e) {
this.isDrawing = true;
const { offsetX, offsetY } = e;
this.pathData = `M ${offsetX} ${offsetY}`;
},
draw(e) {
if (!this.isDrawing) return;
const { offsetX, offsetY } = e;
this.pathData += ` L ${offsetX} ${offsetY}`;
},
stopDrawing() {
this.isDrawing = false;
},
},
};
</script>
实现撤销和重做功能
通过记录操作历史实现撤销和重做功能。可以使用栈结构存储每一步操作的状态。
<template>
<canvas ref="canvas" @mousedown="startDrawing" @mousemove="draw" @mouseup="stopDrawing"></canvas>
<button @click="undo">撤销</button>
<button @click="redo">重做</button>
</template>
<script>
export default {
data() {
return {
isDrawing: false,
ctx: null,
history: [],
historyIndex: -1,
};
},
mounted() {
const canvas = this.$refs.canvas;
canvas.width = 800;
canvas.height = 600;
this.ctx = canvas.getContext('2d');
this.saveState();
},
methods: {
saveState() {
const canvas = this.$refs.canvas;
const imageData = this.ctx.getImageData(0, 0, canvas.width, canvas.height);
this.history = this.history.slice(0, this.historyIndex + 1);
this.history.push(imageData);
this.historyIndex++;
},
undo() {
if (this.historyIndex <= 0) return;
this.historyIndex--;
this.ctx.putImageData(this.history[this.historyIndex], 0, 0);
},
redo() {
if (this.historyIndex >= this.history.length - 1) return;
this.historyIndex++;
this.ctx.putImageData(this.history[this.historyIndex], 0, 0);
},
startDrawing(e) {
this.isDrawing = true;
this.ctx.beginPath();
this.ctx.moveTo(e.offsetX, e.offsetY);
},
draw(e) {
if (!this.isDrawing) return;
this.ctx.lineTo(e.offsetX, e.offsetY);
this.ctx.stroke();
},
stopDrawing() {
this.isDrawing = false;
this.saveState();
},
},
};
</script>
实现元素选择和拖拽
在 Fabric.js 中可以通过监听事件实现元素的选择和拖拽。
<template>
<canvas ref="canvas"></canvas>
</template>
<script>
import { fabric } from 'fabric';
export default {
mounted() {
const canvas = new fabric.Canvas(this.$refs.canvas, {
width: 800,
height: 600,
});
const rect = new fabric.Rect({
left: 100,
top: 100,
width: 50,
height: 50,
fill: 'red',
});
canvas.add(rect);
canvas.on('object:selected', (e) => {
console.log('选中元素:', e.target);
});
canvas.on('object:moving', (e) => {
console.log('移动元素:', e.target);
});
},
};
</script>
通过以上方法,可以在 Vue 中实现基础的画布编辑功能,包括绘图、撤销、重做、元素选择和拖拽等操作。






