📢 博客主页:星辰丶xing-CSDN博客
🎥 本文由星辰丶xing原创,首发于CSDN
🏅 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
⭐ 以梦为马🦄,不负韶华❗
✨⭐🌟✨💫✨🌟⭐🌙
目录
Canvas是HTML5中的新元素,它是一个图形容器,可以使用脚本来绘制图形、路径、字符以及添加图像。在Unity等游戏开发环境中,Canvas是游戏中所有UI组件的“容器”,用于容纳和展示游戏界面中的UI元素,如按钮、图片、文本等。它还可以用于处理图片,如加载、显示、缩放、旋转、翻转和裁剪图片。此外,Canvas还可以用来创建动画、模拟物理效果、进行数据可视化、构建虚拟现实等等
一,实现效果
二,实现流程
1,页面文件
a,首先需要在用到此功能的地方填写对应的canvas组件;
b,设置好相关的样式,以及绑定需要用到的事件,如手指刚触摸屏幕事件:bindtouchstart,手指在屏幕上滑动事件:bindtouchmove,手指离开屏幕事件:bindtouchend;
c,给canvas添加canvas-id,方便对应的js使用;
d,如果在真机预览或者调试的时候发现界面滚动导致无法滑动,可以给canvas组件外面加一个view标签写上catchtouchmove="true",即可解决问题。
<canvas canvas-id="myCanvas" bindtouchstart="touchStart" bindtouchmove="touchMove" bindtouchend="touchEnd" style="width: {{canvasWidth}}px; height: {{canvasHeight}}px;border: 6rpx dashed #ccc;margin: 20rpx auto;"></canvas>
<!-- bindtouchstart 手指刚接触屏幕 -->
<!-- bindtouchmove 手指在屏幕上滑动 -->
<!-- bindtouchend 手指离开屏幕 -->
<view style="display:flex">
<button bindtap="saveImage" type="primary">保存图片</button>
<button bindtap="clearCanvas" type="primary">清空画布</button>
</view>
2,逻辑文件
a,考虑到每个设备屏幕尺寸不一样,所以动态给canvas组件设置宽高;
b,根据组件中的canvas-id初始化canvas,绘制想要的背景,连接线等内容,然后进行绘制;
c,在手指点击屏幕以及手指在屏幕滑动的时候创建线条,然后进行绘制;
d,清除方法就是重新绘制一遍上面的代码。
Page({
// 存储当前手指的位置以及画布的宽高
data: {
x: 0,
y: 0,
canvasWidth: 0,
canvasHeight: 0,
},
onLoad() {
// 获取设备的信息
const systemInfo = wx.getSystemInfoSync()
// 根据设备设置画布宽高
this.setData({
canvasWidth: systemInfo.windowWidth * 3 / 4,
canvasHeight: systemInfo.windowHeight * 4 / 5,
})
this.drawAxis()
},
// 初始化画布
drawAxis() {
// 创建获取 Canvas 绘图上下文的方法 这里需要写canvas组件的canvas-id
const ctx = wx.createCanvasContext('myCanvas')
// 绘制白色背景
ctx.fillStyle = '#FFFFFF'
// 填充一个矩形(矩形路径左上角的横坐标,矩形路径左上角的纵坐标,矩形路径的宽度,矩形路径的高度)
ctx.fillRect(0, 0, this.data.canvasWidth, this.data.canvasHeight)
// 设置线条宽度(画的线,以及横线和竖线的宽度)
ctx.lineWidth = 2
// 设置线条颜色为灰色
ctx.strokeStyle = '#888888'
// 画纵向的线
ctx.setLineDash([5, 10], 0) // 虚线 [5,10] 5表示每段虚线的宽度 10代表虚线之间的距离
// ctx.setLineDash([], 0) // 实线
//画纵向的线
// 将绘图的当前点移动到Canvas的水平中心(this.data.canvasWidth / 2)和顶部(0)的位置。这定义了第一条垂直线的起点
ctx.moveTo(this.data.canvasWidth / 2, 0)
// 从当前点(Canvas的水平中心和顶部)绘制一条直线到 Canvas 的水平中心和底部(this.data.canvasHeight)。这定义了第一条垂直线的终点
ctx.lineTo(this.data.canvasWidth / 2, this.data.canvasHeight)
//画横向的线
// 将绘图的当前点移动到 Canvas 的左侧(0)和垂直中心(this.data.canvasHeight / 2)的位置。这定义了第二条水平线的起点
ctx.moveTo(0, this.data.canvasHeight / 2)
// 从当前点(Canvas 的左侧和垂直中心)绘制一条直线到 Canvas 的右侧和垂直中心(this.data.canvasWidth)。这定义了第二条水平线的终点
ctx.lineTo(this.data.canvasWidth, this.data.canvasHeight / 2)
//调用stroke方法进行描边--使用当前设置的线条样式(如颜色、线宽等)来绘制之前通过 moveTo 和 lineTo 方法定义的线条。这会同时绘制第一条垂直线和第二条水平线
ctx.stroke()
//调用draw方法进行绘制将之前在绘图上下文中的描述(路径、变形、样式)画到 canvas 中
ctx.draw(true)
},
// 手指接触屏幕--把手指刚接触屏幕的坐标点存储起来
touchStart(e) {
console.log(e)
this.setData({
x: e.touches[0].x,
y: e.touches[0].y
})
},
// 手指在屏幕上滑动
touchMove(e) {
const ctx = wx.createCanvasContext('myCanvas')
// 这里因为是需要签字 所以需要取消虚线
ctx.setLineDash([], 0)
// 设置线条颜色为黑色
ctx.strokeStyle = '#000000'
// 设置线条宽度
ctx.lineWidth = 8
// 定义线条的起点和终点
ctx.moveTo(this.data.x, this.data.y)
ctx.lineTo(event.touches[0].x, event.touches[0].y)
ctx.lineCap = 'round' // 线条的端点样式为圆形
ctx.lineJoin = 'round' // 连接样式为圆形
ctx.stroke() //调用stroke方法进行描边
ctx.draw(true) // 传入true表示保留之前的绘制内容
// 更新触摸点的位置
this.setData({
x: e.touches[0].x,
y: e.touches[0].y
})
},
// 手指离开屏幕
touchEnd(e) {
// 在手指离开屏幕可以做一些事情,例如提示 一笔画手离开就结束等功能
console.log(e)
},
// 清除按钮
clearCanvas() {
// 这里就是重新调用初始绘画的方法
this.drawAxis()
},
})
3,以图片的形式把画布内容保存到相册
a,保存相册就会出现权限问题,用户同意才可以保存,不同意就无法保存到相册。
b,在点击保存按钮的时候先看是否有同意保存图片的权限。
c,如果首次保存图片就会如图1所示弹出授权窗口提示,如果点击允许就可以保存图片且以后都可以直接保存,除非小程序在微信app中删除,重新进入才会再次弹授权窗口。
d,点击拒绝就会弹出弹窗如图2所示,告知需要给权限,实际使用可以更改提示语或者添加取消按钮。
e,如果不添加检查权限的话小程序也会弹出如图1所示的授权窗口,但是拒绝之后就没有引导了,所以还是建议添加检查权限的代码。
- 保存图片到相册代码
// 保存当前canvas的内容为图片--图片权限的问题
saveImage(){
wx.authorize({
scope: 'scope.writePhotosAlbum',
success() {
console.log('用户同意添加相册权限');
wx.canvasToTempFilePath({ // 调用把当前画布指定区域的内容导出生成指定大小的图片的Api
canvasId: 'myCanvas', // canvas的id
success(res) {
wx.saveImageToPhotosAlbum({ // 保存图片到相册
filePath: res.tempFilePath,
success() {
wx.showToast({
title: '保存成功',
icon: 'success',
duration: 2000
})
}
})
}
})
},
fail() {
// 用户拒绝授权录音权限
console.log('用户拒绝添加相册权限');
wx.showModal({
title: '权限请求',
content: '图片保存需要您的授权,请前往设置页面打开授权',
confirmColor:'#A083FF',
showCancel: false,
success(modalRes) {
if (modalRes.confirm) {
wx.openSetting({
withSubscriptions: false,
success(settingRes) {
if (settingRes.authSetting['scope.writePhotosAlbum']) {
} else {
wx.showToast({
title: '相册权限未打开',
icon: 'none',
duration:2500
});
}
},
fail(err) {
console.error('打开设置页面失败', err);
}
});
}
}
});
}
});
}