Maison > Article > interface Web > Comment implémenter un puzzle de neuf carrés en forme de cœur à l'aide de Canvas (avec code)
Cet article vous présente la méthode de réalisation du puzzle en forme de cœur à neuf carrés en toile (avec code). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.
J'ai vu ce genre de photo plusieurs fois dans Moments il y a quelques jours.
Ce genre d'image est une forme de cœur composée de neuf images.
J'ai pensé que c'était très intéressant, alors j'ai vérifié en ligne comment le faire. La plupart d'entre eux ont dit que je pouvais utiliser la fonction puzzle de Meitu XiuXiu pour le faire. Il y a aussi un mini programme dans le mini WeChat. programme spécialisé dans la création de puzzles en forme de cœur. Après les avoir tous essayés, j'ai senti que cela pouvait être plus simple, alors j'ai créé moi-même un petit programme.
1 Il y a deux toiles. Une petite toile montre à quoi cela ressemblera. la fin. Une grande toile est utilisée pour enfin prendre des captures d'écran, générer des images et les enregistrer dans l'album.
Grâce au positionnement CSS, déplacez simplement le grand canevas en dehors de l'écran afin que les utilisateurs ne puissent pas le voir.
Et si vous utilisez une petite toile pour enregistrer l'image, l'image finale sera un peu floue.
2. La toile peut être considérée comme une grille 9*9,
est représentée par un tableau appelé coeur Comme ça.
Utilisez les petites grilles pour épeler une forme de cœur et affichez-la sur le canevas en fonction du contenu du tableau.
Ce mini programme a plusieurs fonctions : sélectionner une seule image, sélectionner plusieurs images, compléter des images, enregistrer des images, réinitialiser, recommander et donner des commentaires.
Lorsque l'utilisateur clique sur la zone en forme de cœur, il peut sélectionner une seule image, appeler wx.chooseImage pour sélectionner l'image dans l'album local, et puis sélectionnez l'image, dessinée sur la toile, la position de dessin spécifique est la position où l'utilisateur clique.
Liez l'événement touchend sur le petit canevas. Une fois l'événement déclenché, il y a un attribut changesTouches dans l'événement. Il s'agit d'un tableau qui enregistre les informations du point de contact actuellement modifiées. Les éléments de ce tableau incluent x. et l'attribut y, qui est la distance entre le point de contact et le coin supérieur gauche du canevas.
// 触摸点在 x 轴的值 var x = e.changedTouches[0].x; // 触摸点在 y 轴的值 var y = e.changedTouches[0].y;
Après avoir connu la distance entre l'axe des x et l'axe des y, déterminez sur quelle grille doit être dessinée.
//grid 表示一个格子的宽度 // 确定 x 轴是在第几个格子 x = Math.floor(x / grid); // 确定 y 轴是在第几个格子 y = Math.floor(y / grid);
Après avoir su quelle grille dessiner, vous devez déterminer quelle partie de l'image dessiner, car toutes les grilles sont carrées, mais l'image sélectionnée par l'utilisateur n'est pas nécessairement un carré si c'est le cas. compressé en carré, ce sera moche, alors quand je dessinais, j'ai choisi la partie centrale pour dessiner
Obtenez les informations sur l'image via wx.getImageInfo, utilisez le côté court comme largeur du carré. , puis dessinez à partir de l'endroit (长边 - 短边)/2
.
// 获取图片的宽和高 var width = res.width; var height = res.height; // 如果图片不是正方形,只画中间的部分 // sWidth 表示正方形的宽 var sWidth = width > height ? height : width; // sx 是源图像的矩形选择框的左上角 X 坐标 var sx = 0; // sy 是源图像的矩形选择框的左上角 y 坐标 var sy = 0; if (width > height) { sx = (width - height) / 2; } if (width <p>Une fois que vous savez quoi dessiner et où dessiner, appelez simplement canvasContext.drawImage pour dessiner. </p><h4>Sélectionner plusieurs images</h4><p>Pour sélectionner plusieurs images, la méthode wx.chooseImage est également appelée. Après avoir sélectionné avec succès plusieurs images, l'objet renvoyé a un attribut tempFilePaths, qui est enregistré dans la liste locale. chemins de fichiers pour les images. </p><p><span class="img-wrap"><img src="https://img.php.cn//upload/image/676/859/705/1533102912371640.png" title="1533102912371640.png" alt="Comment implémenter un puzzle de neuf carrés en forme de cœur à laide de Canvas (avec code)"></span></p><p>Parcourez ensuite le tableau cardiaque, qui est un tableau qui stocke des données en forme de cœur. Si la valeur d'un élément du tableau est 1, c'est-à-dire au cœur Dans la plage de forme, prenez une photo dans tempFilePaths dans l'ordre et dessinez-la. La même chose est vraie lors du dessin. Si ce n'est pas un carré, dessinez simplement la partie centrale. </p><h4>Images supplémentaires</h4><p>Dans le fichier image, plusieurs images sont enregistrées pour compléter la forme du cœur, et leurs chemins sont enregistrés dans un tableau. </p><pre class="brush:php;toolbar:false"> // 用来补充心形的图片 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', ]
Ensuite, il s'agit de parcourir le tableau du cœur. Si la valeur d'un élément du tableau est 1, sélectionnez au hasard une image de ce groupe d'images à dessiner.
Dessinez une image, dessinez plusieurs images et complétez des images. Ils dessinent tous des images sur la toile afin d'éviter que les positions des images qui ont été dessinées ne soient écrasées, les niveaux des images qu'ils dessinent sont. différent.
补充图片:1 画多张图片:2 画一张图片:3
Ceux qui ont des niveaux plus élevés peuvent couvrir ceux qui ont des niveaux inférieurs, et ceux qui ont des niveaux inférieurs ne peuvent pas couvrir ceux qui ont des niveaux plus élevés. Ceux du même niveau peuvent être couverts dans les deux cas sauf ceux qui dessinent plusieurs images.
简单意思就是:
补充图片,补充完了之后,再补充会把原来补充的覆盖掉,但是用户选择的图片不会被覆盖掉。
画多张图片,可以覆盖掉补充的图片,但用户选择的图片也不会覆盖掉。
画一张图片,不管这个位置有没有图片,都会再画一张。
保存图片的时候,就是按顺序对大的 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 像素。
用API wx.getSystemInfo 可以查看设备像素比
wx.getSystemInfo({ success: function(res) { console.log(res.pixelRatio) } })
这里如果我的理解有误,还请知道的小伙伴指出。
说了这么多,主要就是想说用默认的值其实就已经很清晰了。
4、因为要保存9张图片,所以需要一些时间,这个时候就需要一个进度条了,保存图片的时候,显示进度条,禁用保存按钮,毕竟点击一下按钮就是9张图片,所以这个时候还是禁用了好,每保存一张图片进度条的值就 +12 ,超过100的时候,就表示 9张图片都保存好了。
而微信小程序中也刚好有进度条(progress)这个组件。
这个功能就是遍历 heart 数组,用一种颜色,根据数组内容,把心形画出来。然后再在 x 轴 和 y 轴上画两条线,行成九宫格的样子。
<button>推荐给朋友</button> <button>意见反馈</button>
这个两个功能就是用了,微信小程序的 button 组件,这里需要注意的就是,在清除 button 的默认样式时,需要把 button 的 after
伪元素的边框也去掉。
button::after{ border: 0; }
有一些地方是小程序在替用户做选择,比如,如果所选择的图片不是正方形,就画中间的部分,但是中间的部分不一定是用户想要的,而如果每张图片都要用户自己来选择画哪部分,一共81张图片,显然是有些麻烦了,这里还可以继续优化下。
还有在补充图片的时候,补充的图片也不一定是用户喜欢的,所以这部分再考虑是不是可以加一些标签,用户选择不同的标签,来补充符合标签的图片,类似 QQ音乐的歌词海报这样。
这次做的这个九宫格心形拼图的小程序,第一版已经上线了。
开源地址:https://github.com/FEWY/jigsaw
相关文章推荐:
HTML5 Canvas实现交互式地铁线路图
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!