一、什么是uniapp呢?
1. uni-app简介
uni-app 是一个基于 Vue.js 的跨平台开发框架,允许开发者使用一套代码同时发布到 iOS、Android、Web、各类小程序及快应用等多个平台。它采用 Vue 语法,支持组件化开发,封装了各平台的原生能力,极大降低了开发与维护成本。使用 UniApp 开发的主要优势包括“一次编写,多端运行”,适合快速迭代和覆盖多端的项目需求;基于 Vue.js,学习成本低,便于现有前端开发者上手;拥有完善的开发工具和生态支持,如 HBuilderX、插件市场等;性能接近原生,尤其在主流平台表现优秀;开发效率高,特别适合中小型团队和初创公司快速推出产品。
二、实现基本的画图功能
接下来,我将手把手教会你使用uniapp开发画图软件
1. 实现的效果展示
目前实现了以下的功能:
- (1)可以进行绘画
- (2)选择画笔的颜色
- (3)选择画笔的粗细程度
- (4)清空画布
- (5)保存画布
2. 实现功能核心代码讲解
在实现画画功能之前,应该明白画布是如何创建的
创建画布
ctx.value = uni.createCanvasContext('drawCanvas')
画布配置
ctx.value.setStrokeStyle('#000000') // 默认黑色
ctx.value.setLineWidth(5) // 默认线宽
ctx.value.setLineCap('round') // 圆角线头
ctx.value.setLineJoin('round') // 圆角连接
未处理画布尺寸的,需要动态获取屏幕尺寸并设置画布宽高
const systemInfo = uni.getSystemInfoSync()
canvasWidth.value = systemInfo.windowWidth
canvasHeight.value = systemInfo.windowHeight * 0.8
画布区域
<canvas
canvas-id="drawCanvas"
class="draw-canvas"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
disable-scroll="true"
:style="{width: canvasWidth + 'px', height: canvasHeight + 'px'}"
></canvas>
2.2.1 画画的功能实现
画画无法就是触摸,触摸移动,触摸后三个状态
画布区域的三个方法就是对应着这三个状态的触发。
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
2.2.1.1 触摸开始
如何实现绘画呢?一条黑色的线,就是无数条黑色的点连接而成的,所以我们使用将存储点来组合成我们所画的线,我们将点使用points数组进行存储绘画路过的无数的点,当我们触摸开始的时候就记录当前的点位置,所以points.value = [point],后续我们移动时就会添加其他的点进入该数组中。
// 触摸开始
const handleTouchStart = async (e) => {
if (!ensureContext()) return
isDrawing.value = true
const point = {
x: e.touches[0].x,
y: e.touches[0].y
}
points.value = [point] // 重置点数组
ctx.value.beginPath() // 开始新的绘制路径
ctx.value.moveTo(point.x, point.y) // 移动画笔到起点
ctx.value.stroke() // 执行描边(绘制第一个点)
ctx.value.draw(true) // 立即渲染到画布
}
2.2.1.2 触摸移动
// 触摸移动
const handleTouchMove = async (e) => {
if (!isDrawing.value || !ensureContext()) return
const point = {
x: e.touches[0].x,
y: e.touches[0].y
}
points.value.push(point)
if (points.value.length >= 2) {
const lastPoint = points.value[points.value.length - 2]
const currentPoint = points.value[points.value.length - 1]
ctx.value.moveTo(lastPoint.x, lastPoint.y) // 移动到上一个点
ctx.value.lineTo(currentPoint.x, currentPoint.y) // 画线到当前点
ctx.value.stroke() // 执行描边
ctx.value.draw(true) // 立即渲染
}
}
至少需要2个点才能形成线段(所以判断points.value.length >= 2)
2.2.1.3 触摸结束
将绘画的状态设置为false,表示不在继续绘画了,同时将points用于存储绘画的点设置为空,方便下次绘画时使用。
// 触摸结束
const handleTouchEnd = () => {
isDrawing.value = false
points.value = []
}
2.2.2 选择画笔的颜色
ctx.value.setStrokeStyle('#000000') // 默认黑色
2.2.3 选择画笔的粗细程度
ctx.value.setLineWidth(5) // 默认线宽
2.2.4 清空画布
ctx.value.clearRect(0, 0, canvasWidth.value, canvasHeight.value)
ctx.value.draw(true)
clearRect(x, y, width, height) 清除指定矩形区域内的像素,其中:
- (0, 0):从画布左上角开始
- (canvasWidth, canvasHeight):覆盖整个画布
2.2.5 保存画布
使用了uni.canvasToTempFilePath和uni.saveImageToPhotosAlbum
uni.canvasToTempFilePath- 生成临时文件(将 Canvas 内容导出为临时图片文件)
uni.saveImageToPhotosAlbum- 保存到相册(将临时文件保存至系统相册。)
uni.canvasToTempFilePath({
canvasId: 'drawCanvas',
success: (res) => {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: () => {
uni.showToast({
title: '保存成功',
icon: 'success'
})
},
fail: () => {
uni.showToast({
title: '保存失败,请检查权限',
icon: 'none'
})
}
})
},
fail: (err) => {
console.error('保存失败:', err)
uni.showToast({
title: '生成图片失败',
icon: 'none'
})
}
})