在微信小程序的画布绘制多张图片,很简单,只需要调用drawImage就可以,但是如果要做一个图片编辑的小程序,肯定要对绘制上去的图片、文字等等进行操作,比如移动一下,旋转一下或者缩放等等。但普通的画布并没有对象记忆功能,它最终输出的只是一张图片,因此我们需要自己编写代码去保存绘制的对象,今天就跟大家简单说一下具体怎么实现。大家可以先看一下最终效果,可以对每个对象进行删除及旋转缩放操作。

一、绘制对象的信息

要对多个绘制的对象进行操作,肯定要知道该对象的信息。对象的属性可以定义如下:

{type:'image' ,  px:0, py:0 , width: 10 ,height: 10 ,ox: 5 ,oy: 5,degree:90}

type是绘制的对象的类型,比如图片、文字。为节省篇幅,本文将以图片为例。px,py是图片左上角顶点距离画布左上角顶点分别在x轴和y轴的距离;ox,oy是旋转原点的坐标。

二、绘制对象

 for(var ti in t_icon){//遍历要绘制的对象var obj=t_icon[ti];var px = obj.px, py = obj.py, index = obj.cap_index,size = obj.size, degree = obj.degree;var wid = this.getCapWidth(size)//图片的宽高,为方便,本例中默认图片为正方形var tmp = this.data.iconTmp[index];//角度需转换为弧度制degree = degree * Math.PI / 180;var ox = px + (wid / 2), oy = py + (wid / 2)ctx.translate(ox,oy);ctx.rotate(degree );ctx.translate(-wid / 2, -wid / 2);ctx.drawImage(tmp, 0, 0, wid, wid);//为当前选择对象 绘制虚线框if (ti == this.data.current&&!save) {ctx.setStrokeStyle('#FF6A6A');ctx.setLineWidth(3)ctx.setLineDash([10, 7], 8);ctx.rect(0, 0, wid, wid)ctx.stroke();ctx.drawImage('/images/delete.png', -iconSize / 2, -iconSize/2, iconSize, iconSize);ctx.drawImage('/images/rotate.png', wid - iconSize/2, wid - iconSize/2, iconSize, iconSize);}ctx.rotate(-degree);//计算当前原点绕图片中心旋转后的坐标var rx0=wid/2,ry0=wid/2,
x=0,y=0,
pos=this.getRotatePosition(x,y,rx0,ry0,degree);var x0=pos[0],y0=pos[1];//将原点恢复为 0,0ctx.translate(-px-x0, -py-y0);//保存旋转原点的坐标obj.ox=ox;obj.oy=oy;this.data.targetIcon[ti]=obj;}
getRotatePosition(x,y,rx0,ry0,degree){//点x,y绕点(rx0,ry0)旋转degree后的坐标var x0 = (x - rx0) * Math.cos(degree) - (y - ry0) * Math.sin(degree) + rx0,y0 = (x - rx0) * Math.sin(degree) + (y - ry0) * Math.cos(degree) + ry0;return [Number(x0),Number(y0)];
},

三、画布事件监听

触摸画布时

start: function ({ changedTouches: [touches] }) {//变量解构赋值var [sx, sy] = [touches.x, touches.y],//按住画布时的坐标t_icon=[...this.data.targetIcon];//对象数组this.data.current = t_icon.length - 1;
this.data.startX=sx;
this.data.startY =sy;
//防止同时作用于多个图片
if (this.data.scaleMode)return; for(var i=t_icon.length-1;i>=0;i--){//倒序读取,因为后添加的会覆盖在之前添加的上面var obj=t_icon[i],wid=Number(this.getCapWidth(obj.size)),px=Number(obj.px),py=Number(obj.py),degree=obj.degree*Math.PI/180;var pos=this.getRotatePosition(0,0,(wid/2),(wid/2),degree);//图片左上角的坐标px,py;右下角的rx,rypx+=pos[0];py+=pos[1];//console.log(px+' '+py+' '+sx+' '+sy);pos=this.getRotatePosition(wid,wid,wid/2,wid/2,degree);var rx=pos[0],ry=pos[1];//删除动作var off=iconSize/2;//图标大小的一半if (sx >= px - off && sx <= px + off && sy >= py - off && sy <= py + off) {this.data.targetIcon.splice(i, 1);this.drawCap();return;}//旋转缩放动作px = Number(obj.px); py = Number(obj.py);//恢复到旋转前的坐标if (sx >= px+rx - off && sx <= px+rx + off && sy >= py+ry - off && sy <= py+ry + off) {this.data.scaleMode=1;//按住了缩放return;//防止同时作用于多个帽子}if(sx>=px&&sy>=py&&sx<=(px+wid)&&sy<=(py+wid)){//交换位置,把选中的移到最后面,这样才能让其显示在最上面[t_icon[i], t_icon[this.data.current]] = [t_icon[this.data.current], t_icon[i]]break;}
}
},

在画布上移动时,我们要保证右下角那个旋转的图标始终跟随我们的手指移动,

画张图帮助大家理解一下,画功拙劣,勿喷。。

move: function ({ changedTouches:[touches]}) {//变量解构赋值var [nx ,ny]= [ touches.x ,  touches.y],//滑动时的坐标[ sx, sy] = [ this.data.startX, this.data.startY];var ti=[...this.data.targetIcon],current=this.data.current;if(!this.data.scaleMode){var obj = ti[current];if(!obj)return;var wid = Number(this.getCapWidth(obj.size)), px = Number(obj.px), py = Number(obj.py);//触摸到图片区域if (sx >= px && sy >= py && sx <= (px + wid) && sy <= (py + wid)) {obj.px += (nx - sx);obj.py += (ny - sy);}ti[current]=obj;}else{//缩放模式var obj = ti[current],wid=this.getCapWidth(obj.size),px=obj.px,py=obj.py;var ox=obj.ox,oy=obj.oy;//px+wid/2var now=Math.sqrt((nx-ox)*(nx-ox)+(ny-oy)*(ny-oy));//旧半径,要保持旋转中心不变var old_size=ti[current].size;ti[current].size=now*Math.SQRT2;ti[current].px = ox - ti[current].size/2;ti[current].py = oy - ti[current].size/2;var [y,x]=[(ny-oy),(nx-ox)],tan_a =  y* 1.0 / x, tan_b = 1,
//获取当前点与旋转原点的连线与y轴的夹角origin_degree = Math.atan(tan_a)*180/Math.PI,
//因为rotate_degree = origin_degree -45 ;//处理一些特殊情况if ((y >= 0 && x < 0) || (y < 0 && x < 0))rotate_degree=135+origin_degree;// console.log(origin_degree + ' ' + rotate_degree + ' ' + y + ' ' + x)ti[current].degree = rotate_degree;//  console.log(ox+' now:['+nx+','+ny+'] '+(ny-oy)+' '+(nx-ox)+' '+ti[current].degree)}this.data.targetIcon = ti;this.data.startX = nx;this.data.startY = ny;this.drawCap();
},

如果大家觉得有不足或不懂的地方,欢迎在评论区留言~~

微信小程序之画布绘制并管理多张图片相关推荐

  1. 微信小程序Canvas画布绘制以及保存

    <canvas canvas-id="firstCanvas" style="width: 320px;height: 500px;" bindlongt ...

  2. 微信小程序实现图案绘制

    微信小程序实现图案绘制 如图 直接贴代码 1,wxml <view class='page'><view class='hd'><text>{{lockType== ...

  3. 解决了:微信小程序使用canvas绘制倒计时圆圈和数字居中的实现

    微信小程序使用canvas绘制倒计时圆圈和数字居中的实现 1.显示结果 2.过程: (1)wxml + css <!-- 每道题 --><view style="backg ...

  4. 微信小程序使用canvas绘制二维码实现跳转小程序

    开始接到这个需求的时候,我查阅文档获取小程序码 | 微信开放文档 发现两种途径 需要后端在服务器上调用接口拿到二维码,因为调用的 https://api.weixin.qq.com这个域名是不允许上白 ...

  5. html5绘制图形幸运大转盘,微信小程序利用canvas 绘制幸运大转盘功能

    小程序对 canvas api 跟h5的不太一致 ,所以这个搞的比较久,不多说,先贴代码 Page({ /** * 页面的初始数据 */ data: { awardsConfig: {}, resta ...

  6. uniapp开发微信小程序使用painter绘制海报

    uniapp开发微信小程序使用painter绘制海报 参考文章: 1.简书大佬文章https://www.jianshu.com/p/e9cab600cf6c 2.CSDN大佬文章https://bl ...

  7. 基于微信小程序小区租拼车管理信息系统+后台ssm

    随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟.本文介绍了微信小程序小区租拼车管理信息系统的开发全过程.通过分析微信小程序小区租拼车管理信息系统管理的不足,创建了一个 ...

  8. 微信小程序,画布中,根据需要展示的图片比例,获取能截取原图中的最大图片尺寸,并且不变形展示

    在微信小程序中,想要做一个分享海报,就需要用到画布,在画布上绘制图片时就会遇到图片变形的情况,下面我会给出我的解决办法. 先画个图片意思意思下: 1. 先根据传入图片地址获取原图片的尺寸: // 获取 ...

  9. 微信小程序之画布的旋转,你搞懂了吗?

    最近在学习微信小程序的时候,学习到画布时,旋转功能把我有点搞糊涂了.因为我一直以为,旋转的是画布,但其实,旋转的是坐标系. 坐标系方向为:画布向右为x,向左为-x,向上为-y,向下为y 程序示例如下: ...

最新文章

  1. 记住密码以及Android 列表的操作
  2. 3月6日工作日志-88250
  3. 查看“Active Directory 架构”
  4. html转义符 xsl转义符
  5. Android开源项目分类汇总-转载
  6. VS2010解决方案位置不对和改变程序字体的方案
  7. 《Head First Python》第四章--持久存储
  8. 揭秘熊猫TV HEVC直播
  9. 图书推荐(持续更新)
  10. Spring AOP的简单示例
  11. ❤️六万字《Spring框架从入门到精通》(建议收藏)❤️
  12. ubuntu16.04 安装中文输入法
  13. sql字段合并mysql_sql合并字段
  14. Softmax 回归 + 损失函数 + 图片分类数据集 动手学深度学习v2 pytorch
  15. 中国图形图象学报和计算机科学,《中国图象图形学报》编辑部
  16. java cropper_cropper 使用总结
  17. 微信小程序防抖功能的实现
  18. 77. Combinations
  19. Android 各国语言包字符串缩写
  20. space-evenly

热门文章

  1. kubernetes报错笔记 (一) calico报错
  2. 闪讯利用openwrt路由器拨号教程(一)
  3. 扩大swap分区内存
  4. 【Pytorch】第 9 章 :Capstone 项目——用 DQN 玩 Flappy Bird
  5. Unity优化方面的一些小总结
  6. PostgreSQL 11 preview - bloom filter 误报率评估测试及如何降低误报 - 暨bloom filter应用于HEAP与INDEX的一致性检测...
  7. linux mint方便快捷安装android studio
  8. 小米自带电子邮件软件设置(网易邮箱)
  9. JQuery实现的后台框架(动易+Slashdot Menu)
  10. 计算机研究生就业方向之去银行券商信息技术部门