logo头像

不要跟我谈理想,我的理想是不工作

前端知识-小程序使用canvas画七巧板

每周的工作状态

image

黄·历 - almanac

综合运势:★ ★ ★ ★ ★
爱情运势:★ ★ ★ ★ ★
财富运势:★ ★ ★ ★ ★
事业学业:★ ★ ★ ★ ★

准备事项

开发工具:uni-app,一套代码编到10个平台;

开发环境:HBuilder,Vue,Node;

部署环境:微信小程序;

如下图所示:

image

画七巧板的点位值:

按照七巧板的图,把七巧板的每个色块按照{x,y}的对象方式存储在一个数组里。有七个色块,数组就有七个值:每个数组按照比例存储四块的每个点的位置信息;每个色块再加个颜色值,这个颜色随自己喜好添加。

1
2
3
4
5
6
7
8
9
tangram: [
{ p: [{ x: 0, y: 0 }, { x: 800, y: 0 }, { x: 400, y: 400 }], color: '#caff67' },
{ p: [{ x: 0, y: 0 }, { x: 400, y: 400 }, { x: 0, y: 800 }], color: '#67bccf' },
{ p: [{ x: 800, y: 0 }, { x: 800, y: 400 }, { x: 600, y: 600 }, { x: 600, y: 200 }], color: '#cf3d61' },
{ p: [{ x: 600, y: 200 }, { x: 600, y: 600 }, { x: 400, y: 400 }], color: '#f9f51a' },
{ p: [{ x: 400, y: 400 }, { x: 600, y: 600 }, { x: 400, y: 800 }, { x: 200, y: 600 }], color: '#a594c0' },
{ p: [{ x: 200, y: 600 }, { x: 400, y: 800 }, { x: 0, y: 800 }], color: '#fa8ccc' },
{ p: [{ x: 800, y: 400 }, { x: 800, y: 800 }, { x: 400, y: 800 }], color: '#f6ca29' }
]

画七巧板

正常浏览器页面写canvas:

1
2
var canvas=document.getElementById("canvas");
var context=canvas.getContext("2d");

基于uni-app实现小程序,这样是获取不到的。☺

html添加canvas元素:

HTML页面写canvas:

1
2
3
<template>
<view><canvas style="width: 100vw;height: 100vw;" type="2d" canvas-id="tangram" id="tangram"></canvas></view>
</template>

1.上述vue的html代码编译为h5:

1
2
3
4
<uni-canvas data-v-2fdafd79="" canvas-id="tangram" type="2d" id="tangram" style="width: 100vw; height: 100vw;">
<canvas width="393" height="393" style="height: 393px; width: 393px;"></canvas>
<div style="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; overflow: hidden;"></div>
</uni-canvas>

2.编译为小程序为:

1
<canvas canvas-id="tangram" id="tangram" style="width: 100vw;height: 100vw;" type="2d"></canvas>

获取canvas元素:

H5获取canvas元素:

1
2
this.canvas = document.querySelector('#tangram canvas');
this.ctx = this.canvas.getContext('2d');

小程序获取canvas元素:

1
2
3
4
5
6
7
8
const query = uni.createSelectorQuery();
query
.select('#tangram')
.fields({ node: true, size: true })
.exec(res => {
this.canvas = res[0].node;
this.ctx = this.canvas.getContext('2d');
}

由于不同手机的分辨率和宽度像素不确定,还有手机的像素密度值。我们还需要调整七巧板点位置的相对比例(这个下边会有相关代码):

此处我们按照整个屏幕来调整,首先先获取手机相关信息,除此之外手机还有一个像素密度值pixelRatio:

1
2
3
4
5
6
uni.getSystemInfo({
success: res => {
this.systemInfo = res;
console.log(res);
}
})

获取系统信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
errMsg: "getSystemInfo:ok"
language: "zh-CN"
model: "iPhone"
pixelRatio: 2
platform: "ios"
screenHeight: 667
screenWidth: 375
statusBarHeight: 0
system: "iOS 13.2.3"
windowBottom: 0
windowHeight: 623
windowTop: 44
windowWidth: 375

根据系统和屏幕信息给canvas设置width和height:

给canvas设置width和height:

h5设置为:

1
2
3
const dpr = uni.getSystemInfoSync().pixelRatio;
this.canvas.width = this.systemInfo.windowWidth * dpr;
this.canvas.height = this.systemInfo.windowWidth * dpr;

小程序设置为:

1
2
3
const dpr = uni.getSystemInfoSync().pixelRatio;
this.canvas.width = res[0].width * dpr;
this.canvas.height = res[0].width * dpr;

由于手机端有pixelRatio像素密度,真实的手机端需要canvas缩放,负责显示为半个canvas,所以在小程序端需要添加(h5端添加显示错乱):

1
this.ctx.scale(dpr, dpr);

用canvas画七巧板:

七巧板点位置的数字:

【0,200,400,600,800】

如果不调整,不是全屏展示整个七巧板,可以按照最小手机的分辨率相对按比例缩小;如果要全屏展示七巧板,我们需要获取屏幕的宽度,然后按照比例进行缩放上述点位置;

获取到canvas,然后接下来就是画七巧板。我们吧这个方法提出来直接写个方法,获取到canvas,执行this.draw();

画之前,先按照比例缩放七巧板点位置的比例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
this.tangram.map(plece => {
return plece.p.map(coordinate => {
if (coordinate.x === 200) {
coordinate.x = this.systemInfo.windowWidth / 4;
} else if (coordinate.x === 400) {
coordinate.x = this.systemInfo.windowWidth / 2;
} else if (coordinate.x === 600) {
coordinate.x = (this.systemInfo.windowWidth / 4) * 3;
} else if (coordinate.x === 800) {
coordinate.x = this.systemInfo.windowWidth;
}
if (coordinate.y === 200) {
coordinate.y = this.systemInfo.windowWidth / 4;
} else if (coordinate.y === 400) {
coordinate.y = this.systemInfo.windowWidth / 2;
} else if (coordinate.y === 600) {
coordinate.y = (this.systemInfo.windowWidth / 4) * 3;
} else if (coordinate.y === 800) {
coordinate.y = this.systemInfo.windowWidth;
}
});
});
for (var i = 0; i < this.tangram.length; i++) {
this.draw(this.tangram[i], ctx);
}

draw()方法:

1
2
3
4
5
6
7
8
9
10
draw(plece, cxt) {
cxt.beginPath();
cxt.moveTo(plece.p[0].x, plece.p[0].y);
for (var i = 1; i < plece.p.length; i++) {
cxt.lineTo(plece.p[i].x, plece.p[i].y);
}
cxt.closePath();
cxt.fillStyle = plece.color;
cxt.fill();
}

画七巧板

代码中使用this,需要data里边定义变量:

1
2
3
4
systemInfo: {},
canvas: null,
ctx: null,
tangram: []

完结,如果想体验直接扫码访问小程序,进入首页,点击体验或者授权都可以,

菜单canvas下,点击Tangram.js,就可以浏览七巧板效果;

体验地址

小程序码:

image

h5访问地址:

h5展示-浏览器打开手机浏览模式F12

公众号访问:

image

支付宝打赏 微信打赏

赞赏是不耍流氓的鼓励