Mini PS小程序——集成打开画报 墨迹电子签名 图片拖拽可单独食用
个人制作。本文主要讲解了最近编写的一个基于uni-app框架的小程序的制作思路和实现代码,该程序集成了多向编辑、墨迹电子签名和开放海报。
目录
1.完整的源代码链接
2.实施思路
3.核心代码
3-1.图形和文本的多方向编辑
3-2.墨水的电子签名
3-3.公开海报
3-4.摘要
4.效果展示和体验
1、完整源码链接:
完整代码:https://github.com/TensionMax/mini-ps
其中演示的文字编辑、图片编辑、墨迹电子签名、公开海报可以单独食用,包括文档描述。
2、实现思路
该工具主要由五个不同的组件模块组成:文本编辑、图片编辑、墨迹电子签名、控件和打开海报。
1.文本编辑模块设置的文本参数对象被插入到文本队列中。
2.图片编辑模块设置的图片参数对象被插入到图片队列中。
3.墨迹电子签名模块完成绘制后,由canvasToTempFilePath转换为临时图片,获取参数后可插入图片队列或直接导出。
4.使用控制模块调整/文本队列和图片队列的参数。
5.打开海报模块,利用控制台的参数将PS画板上的效果绘制到画布上实现效果,然后使用canvasToTempFilePath将效果转换成图片导出。
3、核心代码
3-1、文字/图片编辑模块
文字/图片编辑模块主要用于实现移动/缩放功能,其他配件为甜品。
由于两个模块功能相似,本文只对图片编辑模块进行说明。
HTML
img style=' position : absolute ' : style=' { left : item . x ' px ',top: item.y 'px ',width: item.w 'px ',height: item.h 'px ',} ' @ touch start=' touch start($ event,item,Index)' @ long press=' long press($ event,item,Index)' @ touch move stop。
touch :[{ client x 3360 14//距显示区域左上角的水平距离(不包括顶部栏)client : 16//距显示区域左上角的垂直距离(不包括顶部栏)页面X: 14 //距整个页面左上角的水平距离(不包括顶部栏)页面y3360 16//距整个页面左上角的垂直距离(不包括顶部栏)}, { client x : 14 client y 3360 16 page x 3360 14 page y : 16 }]长度为2的触摸代表双指触摸,通过确定双指触摸点的变化方向,可以实现双指缩放效果。 因为每个标签都设置为style='position: absolute ',所以只需要根据位置参数更新X、Y、W、H即可。
题外话-性能问题
一次移动和多次操作DOM会影响性能。
3354虚拟DOM,看一下
为什么不用事件委托?
3354是不必要的,Vue已经为我们进行了优化,在对性能影响较大的时候我们会考虑。
编辑图片演示
3-2、油墨电子签名板
小程序真实机器中touchmove事件的触发频率和精度
确度很迷,不太好根据速度来判定绘制的线宽,我只好用其他方式去实现,虽然效果不完美。其实现思路是通过多次的循环绘制以达到油墨效果,每次循环绘制的长度和宽度都不相同。
HTML
<canvas canvas-id="canvas" @touchstart.stop="touchStart" @touchmove.stop="touchMove"@touchend.stop="touchEnd"></canvas>
JAVASCRIPT
export default {data() { return { lineWidth0: 5, //初始线宽 建议1~5 ctx: null, x0: 0, //初始横坐标或上一段touchmove事件中触摸点的横坐标 y0: 0, //初始纵坐标或上一段touchmove事件中触摸点的纵坐标 t0: 0, //初始时间或上一段touchmove事件发生时间 v0: 0, //初始速率或touchmove事件间发生速率 lineWidth: 0, //动态线宽 keenness: 5, //油墨程度 建议0~5 k: 0.3, //油墨因子,即每次绘制线条时线宽的变化程度 }},onReady() { this.ctx = uni.createCanvasContext('canvas', this); this.ctx.setLineCap('round')},methods: { //设置初始值 touchStart(e) { this.lineWidth = this.lineWidth0 this.t0 = new Date().getTime() this.v0 = 0 this.x0 = e.touches[0].clientX this.y0 = e.touches[0].clientY }, touchMove(e) { let dx = e.touches[0].clientX - this.x0, dy = e.touches[0].clientY - this.y0, ds = Math.pow(dx * dx + dy * dy, 0.5), dt = (new Date().getTime()) - this.t0, v1 = ds / dt; //同 this.v0 初始速率或touchmove事件间发生速率 if (this.keenness === 0) { //油墨为0时 this.ctx.moveTo(this.x0, this.y0) this.ctx.lineTo(this.x0 + dx, this.y0 + dy) this.ctx.setLineWidth(this.lineWidth) this.ctx.stroke() this.ctx.draw(true) } else { //由于touchMove的触发频率问题,这里采用for循环绘制,原理如图所示 //这里的k因为 let a = this.keenness if (this.keenness > 5) { a = 5 } for (let i = 0; i < a; i++) { this.ctx.moveTo(this.x0 + dx * i / a, this.y0 + dy * i / a) this.ctx.lineTo(this.x0 + dx * (i + 1) / a, this.y0 + dy * (i + 1) / a) //此时touchmove事件间发生与上一个事件的发生的速率比较 if (v1 < this.v0) { this.lineWidth -= this.k if (this.lineWidth < this.lineWidth * 0.25) this.lineWidth = this.lineWidth * 0.25 } else { this.lineWidth += this.k if (this.lineWidth > this.lineWidth * 1.5) this.lineWidth = this.lineWidth * 1.5 } this.ctx.setLineWidth(this.lineWidth) this.ctx.stroke() this.ctx.draw(true) } } this.x0 = e.touches[0].clientX this.y0 = e.touches[0].clientY this.t0 = new Date().getTime() this.v0 = v1 }, touchEnd(e) { this.x0 = 0 this.y0 = 0 this.t0 = 0 this.v0 = 0 }}}
使用的大部分是canvas的基础api,注意绘制单位都为px。
油墨电子签名Demo
3-3、开放式海报模块
如果说微信小程序是银色金滩,那么截至2020年1月6日或者未来,小程序的canvas就是金滩上充斥着未知数个的玻璃块的那一片 ——
鲁迅版权声明:Mini PS小程序——集成打开画报 墨迹电子签名 图片拖拽可单独食用是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。