携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情
前言
本文主要记录了我在学习
uni-app
和uniClound
实战课程 的过程
并记录下实现代码过程中的遇到的问题、以及对应的解决方法,也记录下我对此的思考总结
具体的课程是 大帅老师的 付费课程
目前我已经学完,确实非常的不错
此项目集合已经发布到了线上,大家可以搜索小程序鱼爸爸
体验一下
小程序刚上线,主要是把学习东西体现出来;
可能存在很多bug
,大家可以反馈给我,谢谢!
系列文章
第一篇:《一个简易的绘画板功能?别小看它,知识点可不少!| 【uni-app】【uniCloud】实战系列 | 猿创营》
第二篇:《github 中国区大佬排名都有谁?每天凌晨1点定时更新给你看 | 【uni-app】【uniCloud】实战系列 | 猿创营》
第三篇:《更多实用小demo,迈向独立程序员的起点 | 【uni-app】【uniCloud】实战系列 | 猿创营》
前置知识点
- canvas 的基本使用 传送门
- uni-app 中 canvas 传送门
- uniCloud 的基础知识 传送门
- uniCloud 文件上传 传送门
- uni-app 传送门 通过 uniCloud 调用传送门 获取数据库数据
效果展示
线上小程序体验
分析功能
这个demo
其实是非常简单的,总共的功能主要如下:
点击绘画板,进入绘画板页面,然后就可以作画了
其中作画的里面可以选择 画笔 的颜色,也可以调整 画笔 的半径大小,画完之后,便可以提交画作
提交完了之后,可以在绘画板作品里面看到自己的画作,会按照时间顺序排列
具体实现步骤
绘画功能
思路
绘画主要通过 canvas
来实现
在移动端,我们主要 通过 touchStartHandler
和 touchMoverHandler
这两个方法来不断的获取 画笔 的坐标点
获取坐标点之后,将坐标点连成线,这样就可以得到一个连贯的 每一条线
关于设置半径大小和画笔也比较简单,只需要 通过一个全局变量来控制 canvas
的参数即可
具体代码如下
页面部分
<view>
<canvas
@touchstart="touchStartHandler"
@touchmove="touchMoverHandler"
canvas-id="myCanvas">
</canvas>
<slider value="20" @change="sliderChange" min="5" max="80" show-value />
<scroll-view class="scroll-view_H" scroll-x="true" scroll-left="120">
<view v-for="(item,index) in listColor" @click="handleColor(item)"
class="scroll-view-item_H" :class="[item.color === currentColor.color ? item.color : '', item.className]" :key="index">
<!-- {{item.label}} -->
</view>
</scroll-view>
<button @click="btnPostCanvas">提交画作</button>
</view>
touch事件部分
/**
* 当开始触摸屏的时候的事件
* @param {Object} e
*/
touchStartHandler(e){
console.log('touchStartHandler ---',e)
// 用来接收所有的触控点,后面会有用
this.listPoint = []
//移动端设备通常是支持多点触摸的,这里我们不需要处理多个点,取第一个触摸点即可
const touchPoint = e.changedTouches[0];
this.listPoint.push({x:touchPoint.x,y:touchPoint.y})
const context = uni.createCanvasContext('myCanvas');
// 设置颜色:此处颜色是一个变量,可以提供用户修改【实现设置画笔的颜色的功能】
context.fillStyle = this.currentColor.color || "red";
//在手指的触摸位置绘制一个圆形
// 此处的 this.radius 也是个变量 【实现设置画笔的粗细的功能】
context.arc(touchPoint.x,touchPoint.y,this.radius,0, Math.PI * 2);
context.fill();
// true 不清除 canvas 之前的内容
context.draw(true);
},
/**
* 手指在触摸屏上移动时候 的回调方法
* 频率会比较高,在实际用的时候,如果觉得卡的话,可以做一个 “防抖” 的处理
* @param {Object} e
*/
touchMoverHandler(e){
console.log('touchMoverHandler ===',e)
//获取到移动中的触摸点
const touchPoint = e.changedTouches[0];
this.listPoint.push({x:touchPoint.x,y:touchPoint.y})
const context = uni.createCanvasContext('myCanvas');
context.fillStyle = this.currentColor.color || "red";
//在手指的触摸位置绘制一个圆形
context.arc(touchPoint.x,touchPoint.y,this.radius,0, Math.PI * 2);
context.fill();
// 注意:此处 this.listPoint 就是把所有的点 都存起来的变量
// 1. 取最后两次的点
// 2. 将最后两次的点 连成一条直线
let last = this.listPoint[this.listPoint.length-2]
let next = this.listPoint[this.listPoint.length-1]
context.beginPath();
context.strokeStyle = this.currentColor.color || "red";;
context.lineWidth = this.radius*2;
context.moveTo(last.x,last.y);
context.lineTo(next.x,next.y);
context.closePath();
context.stroke();
context.draw(true);
},
上传绘画
思路
上传绘画的功能实现:
先将canvas
转换成图片
再用uniClound
的 云存储 功能将图片存到服务器上,得到一个fileID
最后将此 fileID
与 该用户(此处为小程序的openid
)关联起来形成一条数据库的记录
代码如下
uni-app
代码
/**
* 点击提交画作
*/
btnPostCanvas(){
// 将 url 与 openid 关联
let openid = getApp().globalData.openid
if(!openid) return uni.showToast({title: '未获取到openid,请稍后再试',duration: 2000});
//显示加载框
uni.showLoading({title: '正在加载...'});
//1.将指定canvas的内容生成png图片文件
uni.canvasToTempFilePath({
canvasId:"myCanvas",
success: (res) => {
//图片文件的路径
const imagefile = res.tempFilePath;
//2.调用uniCloud上传的方法
uniCloud.uploadFile({
cloudPath:Date.now()+".png",//文件名,可重复,阿里云云存储不支持子目录
filePath:imagefile,//要上传的文件路径
success: (res) => {
//3.从函数中获得上传后的云端路径fileID
const cloudfile = res.fileID;
console.log('上传后的ID===',cloudfile)
// 4. 将用户的 openid 与 此文件的 fileID 作为一条记录存在数据库中
uniCloud.callFunction({
name:'postpainting',
data:{openid,url:cloudfile},
success:(res)=>{
// 保存成功,返回上一层
uni.showModal({content:'保存成功',showCancel:true,success:(res)=>{uni.navigateBack()}})
},
complete:()=>{uni.hideLoading()}
})
},
fail:(err)=>{ uni.hideLoading();uni.showToast({title: '网络请求出错,请稍后再试',duration: 2000})
}
})
},
fail: (err) => {uni.hideLoading();uni.showToast({title: '网络请求出错,请稍后再试',duration: 2000})
},
},
)
},
uniClound
服务端代码 【postpainting接口】
exports.main = async (event, context) => {
//event为客户端上传的参数
console.log('event : ', event)
const {openid,url} = event
// 获取数据库对象
const db = uniCloud.database()
// 增加一条记录
let res = await db.collection('paintings').add({url,openid,createtime:Date.now()})
return res
};
列表展示
思路
查看本人的绘画作品,相比上面的功能就更简单了 【主要就是服务端的查询接口】
只需要在服务端将此用户的所有画作获取到,再返回给前端即可
代码如下
exports.main = async (event, context) => {
//event为客户端上传的参数
console.log('event : ', event)
const {openid,url} = event
let db = uniCloud.database()
let dbRes = await db.collection('paintings').where({openid}).orderBy("createtime","desc").get()
//返回数据给客户端
return dbRes.data
};
总结
虽然只是一个很小的demo
而已,但是 麻雀虽小,五脏俱全,通过 uni-app
和 uniClound
的配合使用,自己一个人就实现了所有的前后端的工作
后期还可以增加很多功能:比如 可以撤销每一步,等等
回头再看,以后简单的小活,全部都可以自己搞定,而不需要后端同学的配合。自己平时的一些好的想法和构思就能马上实现
最后推荐下大帅老师,确实很厉害,干货多多;
在公众号里搜 大帅老猿
,在他这里可以学到很多东西