vue实现画板
Vue 实现画板功能
在 Vue 中实现画板功能可以通过 HTML5 的 Canvas API 实现。以下是一个完整的实现方案:
创建 Vue 组件
新建一个 Vue 单文件组件(SFC),命名为 DrawingBoard.vue:
<template>
<div class="drawing-board">
<canvas
ref="canvas"
@mousedown="startDrawing"
@mousemove="draw"
@mouseup="stopDrawing"
@mouseleave="stopDrawing"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
></canvas>
<div class="controls">
<input type="color" v-model="selectedColor">
<input type="range" v-model="brushSize" min="1" max="50">
<button @click="clearCanvas">清除</button>
</div>
</div>
</template>
<script>
export default {
data() {
return {
isDrawing: false,
selectedColor: '#000000',
brushSize: 5,
lastX: 0,
lastY: 0
}
},
mounted() {
this.setupCanvas()
},
methods: {
setupCanvas() {
const canvas = this.$refs.canvas
canvas.width = canvas.offsetWidth
canvas.height = canvas.offsetHeight
},
startDrawing(e) {
this.isDrawing = true
const canvas = this.$refs.canvas
const rect = canvas.getBoundingClientRect()
this.lastX = e.clientX - rect.left
this.lastY = e.clientY - rect.top
},
draw(e) {
if (!this.isDrawing) return
const canvas = this.$refs.canvas
const ctx = canvas.getContext('2d')
const rect = canvas.getBoundingClientRect()
const currentX = e.clientX - rect.left
const currentY = e.clientY - rect.top
ctx.beginPath()
ctx.moveTo(this.lastX, this.lastY)
ctx.lineTo(currentX, currentY)
ctx.strokeStyle = this.selectedColor
ctx.lineWidth = this.brushSize
ctx.lineCap = 'round'
ctx.lineJoin = 'round'
ctx.stroke()
this.lastX = currentX
this.lastY = currentY
},
stopDrawing() {
this.isDrawing = false
},
clearCanvas() {
const canvas = this.$refs.canvas
const ctx = canvas.getContext('2d')
ctx.clearRect(0, 0, canvas.width, canvas.height)
},
handleTouchStart(e) {
e.preventDefault()
const touch = e.touches[0]
const mouseEvent = new MouseEvent('mousedown', {
clientX: touch.clientX,
clientY: touch.clientY
})
this.startDrawing(mouseEvent)
},
handleTouchMove(e) {
e.preventDefault()
const touch = e.touches[0]
const mouseEvent = new MouseEvent('mousemove', {
clientX: touch.clientX,
clientY: touch.clientY
})
this.draw(mouseEvent)
},
handleTouchEnd() {
this.stopDrawing()
}
}
}
</script>
<style scoped>
.drawing-board {
width: 100%;
height: 500px;
border: 1px solid #ccc;
position: relative;
}
canvas {
width: 100%;
height: 100%;
background-color: white;
cursor: crosshair;
}
.controls {
margin-top: 10px;
display: flex;
gap: 10px;
align-items: center;
}
</style>
功能说明
-
画布设置:在
mounted生命周期钩子中初始化画布尺寸,使其填充父容器。 -
绘图功能:通过鼠标事件监听实现绘图功能:

mousedown开始绘制mousemove持续绘制mouseup和mouseleave停止绘制
-
触摸支持:添加触摸事件处理,使画板在移动设备上也能使用。
-
控制面板:
- 颜色选择器:修改画笔颜色
- 滑块:调整画笔粗细
- 清除按钮:清空画布
-
绘制样式:设置
lineCap和lineJoin为round使线条更平滑。
使用组件
在父组件中引入并使用:
<template>
<div>
<DrawingBoard />
</div>
</template>
<script>
import DrawingBoard from './DrawingBoard.vue'
export default {
components: {
DrawingBoard
}
}
</script>
进阶功能
如需保存绘图结果,可以添加以下方法:
methods: {
saveAsImage() {
const canvas = this.$refs.canvas
const dataURL = canvas.toDataURL('image/png')
const link = document.createElement('a')
link.download = 'drawing.png'
link.href = dataURL
link.click()
}
}
然后在模板中添加保存按钮:
<button @click="saveAsImage">保存为图片</button>
这个实现提供了基础的画板功能,可以根据需要进一步扩展,如添加橡皮擦、撤销/重做等功能。






