>  기사  >  웹 프론트엔드  >  캔버스를 사용하여 9각형 하트 모양 퍼즐을 구현하는 방법(코드 포함)

캔버스를 사용하여 9각형 하트 모양 퍼즐을 구현하는 방법(코드 포함)

不言
不言원래의
2018-08-01 13:59:574903검색

9각형 하트 모양 퍼즐을 캔버스(코드 포함)로 구현하는 방법을 소개한 글입니다. 도움이 필요한 친구들이 참고하시면 좋겠습니다. .

설명

며칠 전 친구들 사이에서 이런 사진을 여러 번 봤습니다.

캔버스를 사용하여 9각형 하트 모양 퍼즐을 구현하는 방법(코드 포함)

이런 그림은 9개의 그림으로 이루어진 하트 모양이에요.

굉장히 재미있다고 생각해서 어떻게 하는지 알아보려고 인터넷으로 찾아보니 대부분 메이투 슈슈의 퍼즐 기능을 활용한다고 하더라구요. 하트 모양 퍼즐을 전문적으로 만드는 위챗 미니 프로그램에서 다 시도해본 후, 더 간단할 수 있겠다는 생각이 들어서 직접 작은 프로그램을 만들었습니다.

캔버스를 사용하여 9각형 하트 모양 퍼즐을 구현하는 방법(코드 포함)

작은 프로그램 구현 아이디어

1 캔버스가 두 개 있습니다. 캔버스는 최종적으로 어떤 모습일지 보여줍니다. 큰 캔버스를 사용하여 최종적으로 스크린샷을 찍고, 사진을 생성하고, 앨범에 저장합니다.
CSS 위치 지정을 통해 사용자가 볼 수 없도록 큰 캔버스를 화면 밖으로 이동하면 됩니다.
그리고 작은 캔버스를 사용하여 사진을 저장하면 최종 사진이 약간 흐려질 수 있습니다.

2. 캔버스는 9*9 그리드로 볼 수 있습니다. heart라는 배열로 표현됩니다.

캔버스를 사용하여 9각형 하트 모양 퍼즐을 구현하는 방법(코드 포함)

작은 격자를 사용하여 하트 모양을 표현하고 내용에 따라 캔버스에 렌더링합니다. 배열.

미니 프로그램 기능캔버스를 사용하여 9각형 하트 모양 퍼즐을 구현하는 방법(코드 포함)이 미니 프로그램에는 사진 한 장 선택, 여러 장 선택, 사진 보완, 사진 저장, 재설정, 추천, 피드백 기능이 있습니다. 기능.

사진 한 장 선택

사용자가 하트 모양 영역을 클릭하면 사진 한 장을 선택할 수 있으며, wx.chooseImage를 호출하여 로컬 앨범에서 사진을 선택할 수 있습니다. 를 클릭한 다음 캔버스에 이 그림을 그립니다. 구체적인 그리기 위치는 사용자가 클릭한 위치입니다.

작은 캔버스에 터치엔드 이벤트를 바인딩합니다. 이벤트가 발생한 후 이벤트에 변경된 터치 속성이 있습니다. 이 배열에는 현재 변경된 터치 포인트 정보가 저장됩니다. x 및 y 속성은 터치 지점과 캔버스의 왼쪽 상단 사이의 거리입니다.

// 触摸点在 x 轴的值
var x = e.changedTouches[0].x;
// 触摸点在 y 轴的值
var y = e.changedTouches[0].y;
x축과 y축 사이의 거리를 구한 후 어느 그리드에 그려야 할지 파악합니다.

//grid 表示一个格子的宽度

// 确定 x 轴是在第几个格子
x = Math.floor(x / grid);

// 确定 y 轴是在第几个格子
y = Math.floor(y / grid);

어떤 격자를 그릴지 알고 나면 그림의 어느 부분을 그릴지 결정해야 합니다. 격자는 모두 정사각형이지만 사용자가 선택한 그림이 반드시 정사각형인 것은 아니기 때문입니다. 정사각형으로 압축하면 촌스러워서 그릴때 중간부분을 선택해서 그렸는데,

wx.getImageInfo를 통해 이미지 정보를 얻고, 짧은 쪽을 너비로 잡아요 정사각형을 그린 다음

위치에서 그림을 그립니다.

// 获取图片的宽和高
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>무엇을 그릴지, 어디에 그릴지 결정한 후에는 canvasContext.drawImage를 호출하여 그릴 수 있습니다. </p><p>여러 사진 선택</p><p>여러 사진을 선택하려면 wx.chooseImage 메서드도 호출됩니다. 반환된 객체에는 tempFilePaths 속성이 있습니다. 이미지의 로컬 파일 경로 목록을 저장합니다. <code>(长边 - 短边)/2 </code></p><p></p><h4></h4><p>그런 다음 하트 모양의 데이터를 저장하는 배열인 하트 배열을 순회합니다. 배열의 요소는 1 즉, 하트 모양 범위 내에서 tempFilePaths 에서 순서대로 찍어서 그려주시면 됩니다. 정사각형이 아닐 경우에는 가운데 부분만 그려주시면 됩니다. . </p><p>보충사진<span class="img-wrap"><img src="https://img.php.cn//upload/image/676/859/705/1533102912371640.png" title="1533102912371640.png" alt="캔버스를 사용하여 9각형 하트 모양 퍼즐을 구현하는 방법(코드 포함)">이미지 파일에는 하트 모양을 보완하기 위해 여러 장의 사진이 저장되어 있고, 그 경로가 배열로 저장되어 있습니다. </span></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',
 ]
그 다음은 하트 배열을 순회하는 것입니다. 배열 요소의 값이 1이면 이 그림 그룹에서 그림 중 하나를 무작위로 선택하여 그립니다.

그림 한 장 그리기, 여러 장 그리기, 보충 그림 모두 캔버스에 그림을 그린 위치를 덮어쓰지 않기 위해 그리는 그림의 수준은 다음과 같습니다. 다르다.

补充图片:1
画多张图片:2
画一张图片:3

등급이 높은 사람은 낮은 등급을 보장할 수 있고, 등급이 낮은 사람은 높은 등급을 보장할 수 없습니다. 여러 그림을 그립니다.

简单意思就是:
补充图片,补充完了之后,再补充会把原来补充的覆盖掉,但是用户选择的图片不会被覆盖掉。            
画多张图片,可以覆盖掉补充的图片,但用户选择的图片也不会覆盖掉。        
画一张图片,不管这个位置有没有图片,都会再画一张。

保存图片

保存图片的时候,就是按顺序对大的 canvas 进行截取,然后保存成图片,主要靠 wx.canvasToTempFilePath  这个API来实现,这个 API ,可以把当前画布指定区域的内容导出生成指定大小的图片,并返回文件路径。

这里要注意几个细节

1、为了避免最后保存的图片有黑色背景,最好开始的时候就在 canvas 上画一个 和 canvas 大小一样的矩形,矩形填充上颜色。

2、为了保存的图片,在用户的相册中也能保持心形。需要按下面这个顺序来保存图片

캔버스를 사용하여 9각형 하트 모양 퍼즐을 구현하는 방법(코드 포함)

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

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

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

캔버스를 사용하여 9각형 하트 모양 퍼즐을 구현하는 방법(코드 포함)

文档中提到的屏幕像素密度,应该不是指每英寸屏幕所拥有的像素数,而是指设备像素比(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音乐的歌词海报这样。

캔버스를 사용하여 9각형 하트 모양 퍼즐을 구현하는 방법(코드 포함)

总结

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

开源地址:https://github.com/FEWY/jigsaw  

相关文章推荐:
HTML5 Canvas实现交互式地铁线路图

使用h5 canvas实现时钟的动态效果

위 내용은 캔버스를 사용하여 9각형 하트 모양 퍼즐을 구현하는 방법(코드 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.