肆拾肆- 微信小程序 canvas 解锁及弹簧物理效应动画
1. 效果
在微信小程序
内做基于弹簧物理效应
的动画
。
2. 关于响应事件设置
微信
现在好像只提供 H5
的 Canvas
接口,然后关于拖动
、点击
的事件
接口如下:
Page({onLoad: function () {// ......},// 这里是拖动响应onTouchMove: function (e) {cleanLine(false);gbobjPoint.isTouch = true;let tmPoint = e.touches[0];if (tmPoint.x < 0) {gbobjPoint.touchX = 0;} else if (tmPoint.x > gbobjPoint.canW) {gbobjPoint.touchX = gbobjPoint.canW;} else {gbobjPoint.touchX = tmPoint.x;};if (tmPoint.y < 0) {gbobjPoint.touchY = 0;} else if (tmPoint.y > gbobjPoint.canH) {gbobjPoint.touchY = gbobjPoint.canH;} else {gbobjPoint.touchY = tmPoint.y;};for (let intI = 0; intI < gbobjPoint.intPoint; intI++) {if (!gbobjPoint.arrPoint[intI].clicked) {let dblFarFTouchX = tmPoint.x - gbobjPoint.arrPoint[intI].nowx;let dblFarFTouchY = tmPoint.y - gbobjPoint.arrPoint[intI].nowy;if ((dblFarFTouchX * dblFarFTouchX + dblFarFTouchY * dblFarFTouchY) < (gbobjPoint.R * gbobjPoint.R)) {gbobjPoint.arrPoint[intI].clicked = true;gbobjPoint.lineP[gbobjPoint.numOfP] = intI;gbobjPoint.numOfP++;if (gbobjPoint.numOfP == gbobjPoint.pwNum) {let bolRight = true;for (let intI = 0; intI < gbobjPoint.pwNum; intI++) {if (gbobjPoint.lineP[intI] != gbobjPoint.pw[intI]) {bolRight = false;};};if (bolRight) {gbobjPoint.fading = true;};};};};};},// 这里是手指离开的响应事件onTouchEnd: function (e) {gbobjPoint.isTouch = false;if (gbobjPoint.lineInv) {cleanLine(true);};gbobjPoint.lineInv = setInterval(invLine, 50);},
);
3. 关于力效应
1 ) 弹簧效应
主要公式为:
F(x)=−mxF(x) = -mx F(x)=−mx
所以其实纯粹是物体越远
,受的力越大
。
2 ) 当点击时,相当于也给一个力作用
于所有点
:
这里我给予两个力
- 当位于圆圈两倍半径内,给与
弹簧力
- 当位于圆圈两倍半径外,给与小一点的
弹簧力
if (gbobjPoint.isTouch) {if (dblFarT < (gbobjPoint.R * 2) * (gbobjPoint.R * 2)) {gbobjPoint.arrPoint[intI].vx += dblGapTX / 18;gbobjPoint.arrPoint[intI].vy += dblGapTY / 18;} else {if (dblGapTX > 0) {gbobjPoint.arrPoint[intI].vx += Math.sqrt(dblFarT - (dblGapTY) * (dblGapTY)) / 85;} else {gbobjPoint.arrPoint[intI].vx += -Math.sqrt(dblFarT - (dblGapTY) * (dblGapTY)) / 85;};if (dblGapTY > 0) {gbobjPoint.arrPoint[intI].vy += Math.sqrt(dblFarT - (dblGapTX) * (dblGapTX)) / 85;} else {gbobjPoint.arrPoint[intI].vy += -Math.sqrt(dblFarT - (dblGapTX) * (dblGapTX)) / 85;};};};
3 ) 为了体现阻尼
效果我还给了一个阻尼力
F(v)=−mvF(v) = -mv F(v)=−mv
4. 关于力的体现
纯粹是用一个定时器
对所有点的状态以及位置计算出各点现在的位置
以及力的方向
,代码如下:
function funRoundInv() {gbobjPoint.ctx.fillStyle = gbobjPoint.backColor + "1)";gbobjPoint.ctx.fillRect(0, 0, gbobjPoint.canW, gbobjPoint.canH);if (gbobjPoint.numOfP > 0) {gbobjPoint.ctx.lineWidth = gbobjPoint.R / 8;gbobjPoint.ctx.strokeStyle = gbobjPoint.lineColor + (gbobjPoint.lineTime / 10).toString() + ")";gbobjPoint.ctx.beginPath();gbobjPoint.ctx.moveTo(gbobjPoint.arrPoint[gbobjPoint.lineP[0]].nowx, gbobjPoint.arrPoint[gbobjPoint.lineP[0]].nowy);if (gbobjPoint.numOfP > 1) {for (let intI = 1; intI < gbobjPoint.numOfP; intI++) {gbobjPoint.ctx.lineTo(gbobjPoint.arrPoint[gbobjPoint.lineP[intI]].nowx, gbobjPoint.arrPoint[gbobjPoint.lineP[intI]].nowy);};};if (gbobjPoint.isTouch) {gbobjPoint.ctx.lineTo(gbobjPoint.touchX, gbobjPoint.touchY);};gbobjPoint.ctx.stroke();};gbobjPoint.ctx.lineWidth = 0;for (let intI = 0; intI < gbobjPoint.intPoint; intI++) {gbobjPoint.ctx.fillStyle = gbobjPoint.arrPoint[intI].color;let dblGapX = (gbobjPoint.arrPoint[intI].nowx - gbobjPoint.arrPoint[intI].orgx);let dblGapY = (gbobjPoint.arrPoint[intI].nowy - gbobjPoint.arrPoint[intI].orgy);let dblGapTX = gbobjPoint.touchX - gbobjPoint.arrPoint[intI].nowx;let dblGapTY = gbobjPoint.touchY - gbobjPoint.arrPoint[intI].nowy;let dblFarT = (dblGapTX) * (dblGapTX) + (dblGapTY) * (dblGapTY);if (gbobjPoint.isTouch) {if (dblFarT < (gbobjPoint.R * 2) * (gbobjPoint.R * 2)) {gbobjPoint.arrPoint[intI].vx += dblGapTX / 18;gbobjPoint.arrPoint[intI].vy += dblGapTY / 18;} else {if (dblGapTX > 0) {gbobjPoint.arrPoint[intI].vx += Math.sqrt(dblFarT - (dblGapTY) * (dblGapTY)) / 85;} else {gbobjPoint.arrPoint[intI].vx += -Math.sqrt(dblFarT - (dblGapTY) * (dblGapTY)) / 85;};if (dblGapTY > 0) {gbobjPoint.arrPoint[intI].vy += Math.sqrt(dblFarT - (dblGapTX) * (dblGapTX)) / 85;} else {gbobjPoint.arrPoint[intI].vy += -Math.sqrt(dblFarT - (dblGapTX) * (dblGapTX)) / 85;};};};gbobjPoint.arrPoint[intI].vx += -dblGapX / 5;gbobjPoint.arrPoint[intI].vy += -dblGapY / 5;gbobjPoint.arrPoint[intI].vx += -gbobjPoint.arrPoint[intI].vx / 16;gbobjPoint.arrPoint[intI].vy += -gbobjPoint.arrPoint[intI].vy / 16;gbobjPoint.arrPoint[intI].nowx += gbobjPoint.arrPoint[intI].vx;gbobjPoint.arrPoint[intI].nowy += gbobjPoint.arrPoint[intI].vy;gbobjPoint.ctx.beginPath();gbobjPoint.ctx.arc(gbobjPoint.arrPoint[intI].nowx, gbobjPoint.arrPoint[intI].nowy, gbobjPoint.R, 0, 2 * Math.PI);gbobjPoint.ctx.closePath();gbobjPoint.ctx.fill();};if (gbobjPoint.fading) {gbobjPoint.ctx.fillStyle = gbobjPoint.backColor + (gbobjPoint.fadeTime / 10).toString() + ")";gbobjPoint.ctx.fillRect(0, 0, gbobjPoint.canW, gbobjPoint.canH);if (gbobjPoint.fadeIn) {gbobjPoint.fadeTime -= 0.3;if (gbobjPoint.fadeTime < 0) {gbobjPoint.fading = false;gbobjPoint.fadeIn = false;};} else {gbobjPoint.fadeTime += 0.3;if (gbobjPoint.fadeTime >= 10.5) {gbobjPoint.fading = false;clearInterval(gbobjPoint.roundInv);gbobjPoint.roundInv=null;gbobjPoint.wordInv=setInterval( funWordInv,30);};};};
};
5. 全代码
const app = getApp();
let arrColor = ["#FF9D9D", "#E9FD78", "#6BFFAD", "#6BB0FF", "#E16BFF", "#FF6B7F", "#31ECDD", "#9BEC31", "#ECBA31"];
let gbobjPoint = {};
gbobjPoint.intPoint = 9;
gbobjPoint.arrPoint = [];
gbobjPoint.R = 9;
gbobjPoint.ctx = 0;
gbobjPoint.canW = 0;
gbobjPoint.canH = 0;
gbobjPoint.backColor = "rgba(255, 240, 255,";
gbobjPoint.roundInv = 0;
gbobjPoint.isTouch = false;
gbobjPoint.touchX = 0;
gbobjPoint.touchY = 0;
gbobjPoint.dpr = 0;
gbobjPoint.lineP = [];
gbobjPoint.numOfP = 0;
gbobjPoint.lineColor = "rgba(200,160,200,";
gbobjPoint.lineInv = null;
gbobjPoint.lineTime = 10;
gbobjPoint.fadeIn = true;
gbobjPoint.fadeTime = 10;
gbobjPoint.fading = true;
gbobjPoint.pw = [1, 3, 6, 4, 8, 5, 1, 1, 1];
gbobjPoint.pwNum = 6;
gbobjPoint.wordInv = null;
gbobjPoint.wordNum = 3;
gbobjPoint.wordContent = ["我","爱","丹尼尔"];
gbobjPoint.wordNow = 0;
gbobjPoint.wordMaxTime =10;
gbobjPoint.wordTime =0;
gbobjPoint.wordColor ="rgba(128, 0, 128,"class claPoint {constructor() {this.color = "";this.orgx = 0;this.orgy = 0;this.nowx = 0;this.nowy = 0;this.vx = Math.random() * 5 - 2.5;this.vy = Math.random() * 5 - 2.5;this.clicked = false;};
};function cleanLine(bolReal) {if (bolReal) {for (let intI = 0; intI < gbobjPoint.intPoint; intI++) {gbobjPoint.arrPoint[intI].clicked = false;gbobjPoint.lineP[intI] = -1;};gbobjPoint.numOfP = 0;};gbobjPoint.lineTime = 10;clearInterval(gbobjPoint.lineInv);gbobjPoint.lineInv = null;
};function invLine() {gbobjPoint.lineTime--;if (gbobjPoint.lineTime == 0) {cleanLine(true);};
};
function funWordInv(){gbobjPoint.ctx.fillStyle = gbobjPoint.backColor + "1)";gbobjPoint.ctx.fillRect(0, 0, gbobjPoint.canW, gbobjPoint.canH);gbobjPoint.ctx.fillStyle = gbobjPoint.wordColor+(1-gbobjPoint.wordTime/gbobjPoint.wordMaxTime).toString()+")";gbobjPoint.ctx.font = (gbobjPoint.wordTime/gbobjPoint.wordMaxTime*150).toString()+"px '微软雅黑'";gbobjPoint.ctx.textAlign = "center"; gbobjPoint.ctx.textBaseline = "middle";gbobjPoint.ctx.fillText(gbobjPoint.wordContent[gbobjPoint.wordNow], gbobjPoint.canW/2, gbobjPoint.canH/2);gbobjPoint.wordTime+=0.1;if(gbobjPoint.wordTime>gbobjPoint.wordMaxTime){gbobjPoint.wordTime=0;gbobjPoint.wordNow++;if(gbobjPoint.wordNow>=gbobjPoint.wordNum){clearInterval(gbobjPoint.wordInv);gbobjPoint.wordInv=null;};};
};function funRoundInv() {gbobjPoint.ctx.fillStyle = gbobjPoint.backColor + "1)";gbobjPoint.ctx.fillRect(0, 0, gbobjPoint.canW, gbobjPoint.canH);if (gbobjPoint.numOfP > 0) {gbobjPoint.ctx.lineWidth = gbobjPoint.R / 8;gbobjPoint.ctx.strokeStyle = gbobjPoint.lineColor + (gbobjPoint.lineTime / 10).toString() + ")";gbobjPoint.ctx.beginPath();gbobjPoint.ctx.moveTo(gbobjPoint.arrPoint[gbobjPoint.lineP[0]].nowx, gbobjPoint.arrPoint[gbobjPoint.lineP[0]].nowy);if (gbobjPoint.numOfP > 1) {for (let intI = 1; intI < gbobjPoint.numOfP; intI++) {gbobjPoint.ctx.lineTo(gbobjPoint.arrPoint[gbobjPoint.lineP[intI]].nowx, gbobjPoint.arrPoint[gbobjPoint.lineP[intI]].nowy);};};if (gbobjPoint.isTouch) {gbobjPoint.ctx.lineTo(gbobjPoint.touchX, gbobjPoint.touchY);};// gbobjPoint.ctx.closePath();// gbobjPoint.ctx.closePath(); gbobjPoint.ctx.stroke();};gbobjPoint.ctx.lineWidth = 0;for (let intI = 0; intI < gbobjPoint.intPoint; intI++) {gbobjPoint.ctx.fillStyle = gbobjPoint.arrPoint[intI].color;let dblGapX = (gbobjPoint.arrPoint[intI].nowx - gbobjPoint.arrPoint[intI].orgx);let dblGapY = (gbobjPoint.arrPoint[intI].nowy - gbobjPoint.arrPoint[intI].orgy);let dblGapTX = gbobjPoint.touchX - gbobjPoint.arrPoint[intI].nowx;let dblGapTY = gbobjPoint.touchY - gbobjPoint.arrPoint[intI].nowy;let dblFarT = (dblGapTX) * (dblGapTX) + (dblGapTY) * (dblGapTY);if (gbobjPoint.isTouch) {if (dblFarT < (gbobjPoint.R * 2) * (gbobjPoint.R * 2)) {gbobjPoint.arrPoint[intI].vx += dblGapTX / 18;gbobjPoint.arrPoint[intI].vy += dblGapTY / 18;} else {if (dblGapTX > 0) {// gbobjPoint.arrPoint[intI].vx += (gbobjPoint.R * 2) / 13 + (dblGapTX-gbobjPoint.R* 2) / 39;// gbobjPoint.arrPoint[intI].vx += Math.sqrt(dblFarT - (dblGapTY) * (dblGapTY)) / 50;gbobjPoint.arrPoint[intI].vx += Math.sqrt(dblFarT - (dblGapTY) * (dblGapTY)) / 85;} else {gbobjPoint.arrPoint[intI].vx += -Math.sqrt(dblFarT - (dblGapTY) * (dblGapTY)) / 85;};if (dblGapTY > 0) {gbobjPoint.arrPoint[intI].vy += Math.sqrt(dblFarT - (dblGapTX) * (dblGapTX)) / 85;} else {gbobjPoint.arrPoint[intI].vy += -Math.sqrt(dblFarT - (dblGapTX) * (dblGapTX)) / 85;};};};gbobjPoint.arrPoint[intI].vx += -dblGapX / 5;gbobjPoint.arrPoint[intI].vy += -dblGapY / 5;// gbobjPoint.arrPoint[intI].vx += Math.random() ;// gbobjPoint.arrPoint[intI].vy += Math.random();gbobjPoint.arrPoint[intI].vx += -gbobjPoint.arrPoint[intI].vx / 16;gbobjPoint.arrPoint[intI].vy += -gbobjPoint.arrPoint[intI].vy / 16;// if (dblGapX>0){// gbobjPoint.arrPoint[intI].vx+=1/(Math.pow( dblGapX+6,2))/3;// }else{// gbobjPoint.arrPoint[intI].vx+=-1/(Math.pow( -dblGapX-6,2))/3;// }; // if (dblGapY>0){// gbobjPoint.arrPoint[intI].vy+=1/(Math.pow( dblGapY+6,2))/3;// }else{// gbobjPoint.arrPoint[intI].vy+=-1/(Math.pow( -dblGapY-6,2))/3;// };gbobjPoint.arrPoint[intI].nowx += gbobjPoint.arrPoint[intI].vx;gbobjPoint.arrPoint[intI].nowy += gbobjPoint.arrPoint[intI].vy;gbobjPoint.ctx.beginPath();gbobjPoint.ctx.arc(gbobjPoint.arrPoint[intI].nowx, gbobjPoint.arrPoint[intI].nowy, gbobjPoint.R, 0, 2 * Math.PI);gbobjPoint.ctx.closePath();gbobjPoint.ctx.fill();};if (gbobjPoint.fading) {gbobjPoint.ctx.fillStyle = gbobjPoint.backColor + (gbobjPoint.fadeTime / 10).toString() + ")";gbobjPoint.ctx.fillRect(0, 0, gbobjPoint.canW, gbobjPoint.canH);if (gbobjPoint.fadeIn) {gbobjPoint.fadeTime -= 0.3;if (gbobjPoint.fadeTime < 0) {gbobjPoint.fading = false;gbobjPoint.fadeIn = false;};} else {gbobjPoint.fadeTime += 0.3;if (gbobjPoint.fadeTime >= 10.5) {gbobjPoint.fading = false;clearInterval(gbobjPoint.roundInv);gbobjPoint.roundInv=null;gbobjPoint.wordInv=setInterval( funWordInv,30);};};};
};Page({onPullDownRefresh() {wx.stopPullDownRefresh()},data: {motto: 'Hello World',userInfo: {},hasUserInfo: false,canIUse: wx.canIUse('button.open-type.getUserInfo')},onLoad: function () {},onTouchMove: function (e) {cleanLine(false);gbobjPoint.isTouch = true;let tmPoint = e.touches[0];if (tmPoint.x < 0) {gbobjPoint.touchX = 0;} else if (tmPoint.x > gbobjPoint.canW) {gbobjPoint.touchX = gbobjPoint.canW;} else {gbobjPoint.touchX = tmPoint.x;};if (tmPoint.y < 0) {gbobjPoint.touchY = 0;} else if (tmPoint.y > gbobjPoint.canH) {gbobjPoint.touchY = gbobjPoint.canH;} else {gbobjPoint.touchY = tmPoint.y;};for (let intI = 0; intI < gbobjPoint.intPoint; intI++) {if (!gbobjPoint.arrPoint[intI].clicked) {let dblFarFTouchX = tmPoint.x - gbobjPoint.arrPoint[intI].nowx;let dblFarFTouchY = tmPoint.y - gbobjPoint.arrPoint[intI].nowy;if ((dblFarFTouchX * dblFarFTouchX + dblFarFTouchY * dblFarFTouchY) < (gbobjPoint.R * gbobjPoint.R)) {gbobjPoint.arrPoint[intI].clicked = true;gbobjPoint.lineP[gbobjPoint.numOfP] = intI;gbobjPoint.numOfP++;if (gbobjPoint.numOfP == gbobjPoint.pwNum) {let bolRight = true;for (let intI = 0; intI < gbobjPoint.pwNum; intI++) {if (gbobjPoint.lineP[intI] != gbobjPoint.pw[intI]) {bolRight = false;};};if (bolRight) {gbobjPoint.fading = true;};};};};};},onTouchEnd: function (e) {gbobjPoint.isTouch = false;if (gbobjPoint.lineInv) {cleanLine(true);};gbobjPoint.lineInv = setInterval(invLine, 50);},onReady: function () {const query = wx.createSelectorQuery()query.select('#canDrawPoint').fields({node: true,size: true}).exec((res) => {const canvas = res[0].node;const ctx = canvas.getContext('2d');gbobjPoint.ctx = ctx;gbobjPoint.dpr = wx.getSystemInfoSync().pixelRatio;const dpr =gbobjPoint.dpr;canvas.width = res[0].width * gbobjPoint.dpr;canvas.height = res[0].height * gbobjPoint.dpr;ctx.scale(gbobjPoint.dpr , gbobjPoint.dpr );gbobjPoint.canW = canvas.width/gbobjPoint.dpr;gbobjPoint.canH = canvas.height/gbobjPoint.dpr;let dblR = Math.min(gbobjPoint.canW/ 13.2, gbobjPoint.canH / 16.2);gbobjPoint.R = dblR;console.log(gbobjPoint);// for (let intI = 0; intI < gbobjPoint.intPoint; intI++) {for (let intJ = 0; intJ < 3; intJ++) {for (let intK = 0; intK < 3; intK++) {let objTmpPoint = new claPoint();objTmpPoint.color = arrColor[(intK + intJ * 3) % 10];let bolOverlap = false;let intTmp = 0;// do {// bolOverlap = false;// objTmpPoint.orgx = (Math.random() * 6 + 1) * canvas.width / 8;// objTmpPoint.orgy = (Math.random() * 8 + 1) * canvas.height / 10;// for (let intJ = 0; intJ < intI; intJ++) {// if (Math.sqrt(Math.pow(objTmpPoint.orgx - gbobjPoint.arrPoint[intJ].orgx, 2) + Math.pow(objTmpPoint.orgy - gbobjPoint.arrPoint[intJ].orgy, 2)) < (dblR * 2.5)) {// bolOverlap = true;// // console.log(Math.sqrt(Math.pow(objTmpPoint.x - gbobjPoint.arrPoint[intJ].x, 2) + Math.pow(objTmpPoint.y - gbobjPoint.arrPoint[intJ].y, 2)));// };// };// intTmp++;// } while (bolOverlap && intTmp < 100);objTmpPoint.orgx = (intK + 1) * gbobjPoint.canW / 4;objTmpPoint.orgy = (intJ + 1) * gbobjPoint.canH / 4;objTmpPoint.nowx = objTmpPoint.orgx + dblR * (Math.random() * 2 - 1);objTmpPoint.nowy = objTmpPoint.orgy + dblR * (Math.random() * 2 - 1);// 速度的没有再根据画布大小随机gbobjPoint.arrPoint.push(objTmpPoint);gbobjPoint.lineP.push(-1);};};// };gbobjPoint.roundInv = setInterval(funRoundInv, 30);});}
})
6. 真正走心的内容
其实我想了好久都没想出到底怎么写这东西比较好,说是深的内容其实也不算,但我也怕以后我忘了代码。
还有因为我妈霸占了厕所我没办法睡觉所以写上来而已。
我一开始本来打算做复杂一点的动画,但后来想着想着还是算了,以后接着做吧,最近工作也很忙,公司压力也大,一直暗示着不乖点干活就要炒人,所以还是得用心工作的呀。
肆拾肆- 微信小程序 canvas 解锁及弹簧物理效应动画相关推荐
- 微信小程序canvas绘制环形图(含动画)
页面版 效果图 思路 1.使用一个canvas绘制(带动画): 2.通过画弧线,设置线宽,来实现圆环效果: 3.计算每段圆弧的起始角度和终止角度,用递归做动画: 绘制完第一段圆弧块–>再绘制下一 ...
- 【微信小程序canvas】实现小程序手写板用户签名(附代码)
[微信小程序canvas]实现小程序手写板用户签名(附代码) 工作中公司业务需要的微信小程序用户签字功能 先看效果图: wxml <view class="wrapper"& ...
- 微信小程序-canvas绘制文字实现自动换行
微信小程序-canvas绘制文字实现自动换行 在使用微信小程序canvas绘制文字时,时常会遇到这样的问题:因为canvasContext.fillText参数为 我们只能设置文本的最大宽度,这就产生 ...
- 微信小程序 canvas type = 2d 绘制海报心得(包括怎么绘制图片和圆角图片和圆角矩形等)
微信小程序 canvas type=2d 使用心得 为了方便这里我封装成了一个component 然后说说怎么使用最新的方法(使用方法类似于html中的canvas可以进行参考)获取--canvas ...
- 微信小程序canvas画布新接口type为2D时drawImage方法的使用以及注意事项
微信小程序canvas画布自2.9.0 起支持一套新 Canvas 2D 接口(需指定 type 属性),但文档不全,从原canvas的api转变到新的api时遇到不少问题,现将新版与旧版的画布载入图 ...
- 微信小程序详解 php,微信小程序canvas基础详解
canvas 元素用于在网页上绘制图形.HTML5 的 canvas 元素使用 JavaScript 在网页上绘制2D图像.本文主要和大家分享微信小程序canvas基础详解,希望能帮助到大家. 一.了 ...
- 微信小程序canvas简单使用
微信小程序canvas简单使用 index.wxml文件 index.js文件 效果图 index.wxml文件 <canvas type="2d" id="can ...
- 微信小程序canvas实现签名功能
微信小程序canvas实现签名功能 在微信小程序项目中,开发模块涉及到手写签名功能,微信小程序canvas闪亮登场 文章目录 微信小程序canvas实现签名功能 前言 一.微信小程序canvas实现签 ...
- 微信小程序Canvas实现手写签名
微信小程序Canvas实现手写签名 功能描述 点击按钮显示弹窗,弹窗主体为签名板,底部两个按钮为清除和保存. 清除按钮:清空签名板 保存按钮:保存签名为图片,并关闭弹窗 关键点分析 Canvas实现手 ...
最新文章
- buffer转int python_Python学习教程第23天numpy库(上)
- 第十七章 大规模机器学习-机器学习老师板书-斯坦福吴恩达教授
- java如何解决高并发问题_java怎么处理高并发?
- 深圳当代艺术家的一次聚会
- 用vector实现二维向量
- Spring+Quartz实现定时任务的配置步骤
- 层层递进——宽度优先搜索(BFS)
- U盘/硬盘/移动硬盘专家
- 古文构词之法、造词之法
- Linux进程间通信
- QAM调制原理_锁相环(PLL)基本原理 PLL电路常见构建模块
- php易语言互交_易语言php编码转换 易语言与php数据交互
- MYSQL 安装时出现的问题error: Failed dependencies
- 【用来参考】AndroidQ SystemUI之锁屏加载(上)滑动锁屏
- 刚入行的软件测试工程师如何自学软件测试?
- aptana安装python库_使用Aptana搭建Python开发环境
- 百度云重置服务器密码,单台或多台腾讯云服务器 CVM 重置实例密码教程
- 艾美捷SequENZ测序级改造型胰蛋白酶用途和技术说明
- 901.freeswitch常用命令
- RAC 网络心跳 磁盘心跳 本地心跳 控制文件磁盘心跳