宝哥软件园

小程序-九宫格心形拼图效果

编辑:宝哥软件园 来源:互联网 时间:2021-12-08

这张图前几天在朋友圈看了好几遍。

小程序—九宫格心形拼图效果(图1)

这种画是由九幅画组成的心形画。

我觉得很有意思,就上网查了查怎么做。大部分俗语都是用美图秀秀的益智功能来做的。在微信小程序中,还有一个制作心形拼图的小程序。试了一遍之后,觉得可以简单一点,就自己做了一个小程序。

小程序—九宫格心形拼图效果(图2)

实现小程序的思路

1.有两个画布,一个小的展示最后会发生什么,一个大的最后截图,生成图片保存到相册。

通过CSS的定位,把大画布移到屏幕外,让用户看不到就足够了。

但是,如果用小画布保存图片,最终的图片会有点模糊。

2.画布可以看作是一个9 * 9的网格,

小程序—九宫格心形拼图效果(图3)

它由一个叫做心的数组表示。就这样。

小程序—九宫格心形拼图效果(图4)

用小方块拼出心形,根据数组的内容在画布上渲染。

小程序的功能

这个小程序具有选择单幅图片、选择多幅图片、补充图片、保存图片、复位、推荐、反馈等功能。

选择单张图片

当用户点击心形区域时,可以选择一张图片,调用wx.chooseImage从本地相册中选择一张图片,然后在画布上画出这张图片,用户点击即可。

将touchend事件绑定到小画布上。事件触发后,事件中有一个changedTouches属性,它是一个保存当前正在变化的触摸点信息的数组。该数组中的元素具有X和Y属性,即触摸点与画布左上角之间的距离。

//x轴上触摸点的值var x=e.changedTouches[0]。x;//y轴上触摸点的值var y=e.changedTouches[0]。y;用X轴和Y轴之间的距离复制代码后,找出它应该画在哪个网格上。

//网格表示网格的宽度//确定x=Math.floor(x/grid)中x轴是哪个网格;//确定Y轴在哪个网格Y=math . floor(Y/网格);复制代码后要知道画哪个网格,就要确定画图片的哪个部分,因为所有的网格都是正方形的,但是用户选择的图片不一定是正方形的。如果压缩成正方形,会很难看,所以我在画的时候,会选择右边中间的部分来画。

通过wx.getImageInfo获取图片信息,取短边作为正方形的宽度,然后从(长边-短边)/2开始绘制。

//获取图片的宽度和高度var width=res.width可变高度=res.height//如果图片不是正方形,只画中间部分。//sWidth表示正方形的宽度。var sWidth=宽度高度?高度:宽;//sx为源图像矩形选择框左上角的x坐标var sx=0;//sy为源图像矩形选择框左上角的Y坐标var sy=0;if(宽度高度){sx=(宽度-高度)/2;}if(宽度高度){sy=(高度-宽度)/2;}在复制代码知道要绘制什么和在哪里绘制后,调用canvasContext.drawImage进行绘制。

选择多张图片

多重选择

张图片,同样是调用wx.chooseImage 方法,成功选择多张图片后,返回的对象中有一个tempFilePaths 属性,这个属性保存了,图片的本地文件路径列表。

小程序—九宫格心形拼图效果(图5)

然后遍历 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、为了保存的图片,在用户的相册中也能保持心形。需要按下面这个顺序来保存图片

小程序—九宫格心形拼图效果(图6)

3、wx.canvasToTempFilePath中有两个选填的参数 destWidth 和 destHeight,这个两个参数决定 输出图片宽度和高度,如果不是准确的知道是多少,用默认值就可以。

destWidth和destHeight单位是物理像素(pixel),canvas 绘制的时候用的是逻辑像素(物理像素=逻辑像素 * density),所以这里如果只是使用 canvas 中的 width 和 height(逻辑像素)作为输出图片的长宽的话,生成的图片 width 和 height 实际上是缩放了到 canvas 的1 / density大小了,所以就显得比较模糊了。

而默认值是 width * 屏幕像素密度

小程序—九宫格心形拼图效果(图7)

文档中提到的屏幕像素密度,应该不是指每英寸屏幕所拥有的像素数,而是指设备像素比(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 open-type='share'>推荐给朋友</button> <button open-type='feedback'>意见反馈复制代码

这个两个功能就是用了,微信小程序的button 组件,这里需要注意的就是,在清除 button 的默认样式时,需要把button 的 after伪元素的边框也去掉。

button::after{  border: 0; }复制代码

可以优化的地方

有一些地方是小程序在替用户做选择,比如,如果所选择的图片不是正方形,就画中间的部分,但是中间的部分不一定是用户想要的,而如果每张图片都要用户自己来选择画哪部分,一共81张图片,显然是有些麻烦了,这里还可以继续优化下。

还有在补充图片的时候,补充的图片也不一定是用户喜欢的,所以这部分再考虑是不是可以加一些标签,用户选择不同的标签,来补充符合标签的图片,类似 QQ音乐的歌词海报这样。

小程序—九宫格心形拼图效果(图8)

总结

这次做的这个九宫格心形拼图的小程序,第一版已经上线了。

小程序—九宫格心形拼图效果(图2)

如果你喜欢这个小程序的话,可以star支持一下。

这个小程序不管在代码,还是功能上都还有许多地方可以继续优化,如果有需要的朋友可以直接拿去改。

更多资讯
游戏推荐
更多+