小程序九宫格心形拼图效果怎么做(九宫格心形图片制作教程)
- 时间:
- 来源: 网络
最近朋友圈大家是不是被九宫格心形图所刷屏,这种图片是用九张图片拼成一个心形而成,那么如何用微信小程序实现这种九宫格心形图的效果?
实现小程序的思路
1、有两个canvas,一个小的canvas显示最后会是什么样子,一个大的canvas用来最后进行截图,生成图片,保存到相册。
通过CSS的定位,把大的canvas移到屏幕外面不让用户看到就可以了。
而如果用小的canvas保存图片的话,最后的图片有些模糊。
2、canvas可以看成一个9*9的网格,
用一个叫heart的数组来表示就是这样的。
用其中的小格子,来拼出心形,根据数组的内容在canvas上进行渲染。
小程序的功能
这个小程序有选择单张图片,选择多张图片,补充图片,保存图片,重置,推荐,意见反馈,这几个功能。
选择单张图片
当用户点击心形区域的时候,就可以选择单张图片,调用wx.chooseImage就可以从本地相册选择图片,然后就把这张图,画在canvas上,具体画的位置就是用户点击的位置。
在小的canvas上绑定touchend事件,触发事件后,事件中有一个changedTouches属性,这是一个保存了,当前变化的触摸点信息的数组,这个数组中的元素有x和y属性,也就是触摸点距离canvas左上角的距离。
//触摸点在x轴的值
varx=e.changedTouches[0].x;
//触摸点在y轴的值
vary=e.changedTouches[0].y;
复制代码
有x轴和y轴的距离后,算出具体应该画在哪个格子上。
//grid表示一个格子的宽度
//确定x轴是在第几个格子
x=Math.floor(x/grid);
//确定y轴是在第几个格子
y=Math.floor(y/grid);
复制代码
知道在哪个格子画之后,就要确定画图片的哪部分了,因为所有的格子都是正方形的,但是用户选择的图片不一定是正方形,如果压缩成正方形会很难看,所以我画的时候,选择了正中间的部分来画,
通过wx.getImageInfo来获取图片信息,以短边为正方形的宽,然后从(长边-短边)/2的地方来画。
//获取图片的宽和高
varwidth=res.width;
varheight=res.height;
//如果图片不是正方形,只画中间的部分
//sWidth表示正方形的宽
varsWidth=width>height?height:width;
//sx是源图像的矩形选择框的左上角X坐标
varsx=0;
//sy是源图像的矩形选择框的左上角y坐标
varsy=0;
if(width>height){
sx=(width-height)/2;
}
if(width sy=(height-width)/2; } 复制代码 知道画什么,在哪里画之后,调用canvasContext.drawImage来画就可以了。 选择多张图片 选择多张图片,同样是调用wx.chooseImage方法,成功选择多张图片后,返回的对象中有一个tempFilePaths属性,这个属性保存了,图片的本地文件路径列表。 然后遍历heart数组,也就是保存心形数据的数组,如果数组中某个元素的值是1,也就是说在心形范围内,就按顺序从tempFilePaths中取一张图片画上去,画的时候同样的,如果不是正方形就只画中间的部分。 补充图片 在image的文件中,有保存几张图片,用来补充心形,他们的路径保存在一个数组中。 //用来补充心形的图片 images:[ '/images/1.jpg', '/images/2.jpg', '/images/3.jpg', '/images/4.jpg', '/images/5.jpg', '/images/6.jpg', '/images/7.jpg', '/images/8.jpg', '/images/9.jpg', '/images/10.jpg', ] 复制代码 然后就是遍历heart数组,如果数组的某个元素的值是1,就随机从这组图片中选择一张画上去。 画一张图片,画多张图片,补充图片,他们都是在canvas上画图片,为了避免已经画了图片的位置被覆盖,他们所画的图片的等级是不同的。 补充图片:1 画多张图片:2 画一张图片:3 复制代码 等级高的可以覆盖等级低的,等级低的不能覆盖等级高的,同等级的,除了画多张图片的不能覆盖,其余的两种情况,都可以覆盖。 简单意思就是:补充图片,补充完了之后,再补充会把原来补充的覆盖掉,但是用户选择的图片不会被覆盖掉。 画多张图片,可以覆盖掉补充的图片,但用户选择的图片也不会覆盖掉。 画一张图片,不管这个位置有没有图片,都会再画一张。 保存图片 保存图片的时候,就是按顺序对大的canvas进行截取,然后保存成图片,主要靠wx.canvasToTempFilePath这个API来实现,这个API,可以把当前画布指定区域的内容导出生成指定大小的图片,并返回文件路径。 这里要注意几个细节 1、为了避免最后保存的图片有黑色背景,最好开始的时候就在canvas上画一个和canvas大小一样的矩形,矩形填充上颜色。 2、为了保存的图片,在用户的相册中也能保持心形。需要按下面这个顺序来保存图片 3、wx.canvasToTempFilePath中有两个选填的参数destWidth和destHeight,这个两个参数决定输出图片宽度和高度,如果不是准确的知道是多少,用默认值就可以。 destWidth和destHeight单位是物理像素(pixel),canvas绘制的时候用的是逻辑像素(物理像素=逻辑像素*density),所以这里如果只是使用canvas中的width和height(逻辑像素)作为输出图片的长宽的话,生成的图片width和height实际上是缩放了到canvas的1/density大小了,所以就显得比较模糊了。 而默认值是width*屏幕像素密度 文档中提到的屏幕像素密度,应该不是指每英寸屏幕所拥有的像素数,而是指设备像素比(pixelRatio),也就是用多少个物理像素去显示1px的CSS像素。用APIwx.getSystemInfo可以查看设备像素比 wx.getSystemInfo({ success:function(res){ console.log(res.pixelRatio) } }) 复制代码 这里如果我的理解有误,还请知道的小伙伴指出。 说了这么多,主要就是想说用默认的值其实就已经很清晰了。 4、因为要保存9张图片,所以需要一些时间,这个时候就需要一个进度条了,保存图片的时候,显示进度条,禁用保存按钮,毕竟点击一下按钮就是9张图片,所以这个时候还是禁用了好,每保存一张图片进度条的值就+12,超过100的时候,就表示9张图片都保存好了。 而微信小程序中也刚好有进度条(progress)这个组件。 重置 这个功能就是遍历heart数组,用一种颜色,根据数组内容,把心形画出来。然后再在x轴和y轴上画两条线,行成九宫格的样子。 推荐和意见反馈 复制代码 这个两个功能就是用了,微信小程序的button组件,这里需要注意的就是,在清除button的默认样式时,需要把button的after伪元素的边框也去掉。 button::after{ border:0; } 复制代码 可以优化的地方 有一些地方是小程序在替用户做选择,比如,如果所选择的图片不是正方形,就画中间的部分,但是中间的部分不一定是用户想要的,而如果每张图片都要用户自己来选择画哪部分,一共81张图片,显然是有些麻烦了,这里还可以继续优化下。 还有在补充图片的时候,补充的图片也不一定是用户喜欢的,所以这部分再考虑是不是可以加一些标签,用户选择不同的标签,来补充符合标签的图片,类似QQ音乐的歌词海报这样。 微商好助手小程序工具开发公司长沙海商,是一家有着十年技术前沿的公司,我们以先进技术提供并解决各行业小程序开发,操作简单,支持多种社群营销活动,提供一套综合性的营销系统。以及可视化模板操作,大大减少人力物力成本。 微商好助手小程序工具提供多类型商城/门店小程序制作,可视化编辑1秒生成5步上线。通过拖拽、拼接模块布局小程序商城页面,所看即所得,只需要美工就能做出精美商城。更多小程序商店请查看:小程序商店 价值1980元火爆的0基础小程序制作开发赚钱训练营免费看