Skip to content

Commit f9f608b

Browse files
Merge pull request #256 from Leoqh96/master
chore(examples): add clasGame
2 parents c2bfab3 + b8c38d5 commit f9f608b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+2524
-0
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# 「寻物大作战」微信小程序代码示例
2+
3+
## 1.介绍
4+
本目录为寻物大作战微信小程序代码,通过使用 [Paddle.js](https://github.com/PaddlePaddle/Paddle.js) 以及 [Paddle.js微信小程序插件](https://mp.weixin.qq.com/wxopen/plugindevdoc?appid=wx7138a7bb793608c3&token=956931339&lang=zh_CN) 完成在小程序上利用用户终端算力实现识物效果。
5+
6+
## 2. 项目启动
7+
8+
### 2.1 准备工作
9+
* [申请微信小程序账号](https://mp.weixin.qq.com/)
10+
* [微信小程序开发者工具](https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html)
11+
* 前端开发环境准备:node、npm
12+
13+
### 2.2 启动步骤
14+
#### **1. clone Paddle.js**
15+
```sh
16+
git clone https://github.com/PaddlePaddle/Paddle.js.git
17+
```
18+
19+
#### **2. 进入 xxx 目录,安装依赖**
20+
```sh
21+
cd Paddle.js/packages/paddlejs-examples/xxx && npm install
22+
```
23+
24+
#### **3. 微信小程序导入代码**
25+
打开微信开发者工具 --> 导入 --> 选定目录,输入相关信息
26+
27+
#### **4. 添加 Paddle.js微信小程序插件**
28+
小程序管理界面 --> 设置 --> 第三方设置 --> 插件管理 --> 添加插件 --> 搜索 `wx7138a7bb793608c3` 并添加
29+
[参考文档](https://developers.weixin.qq.com/miniprogram/dev/framework/plugin/using.html)
30+
31+
#### **5. 构建依赖**
32+
点击开发者工具中的菜单栏:工具 --> 构建 npm
33+
***原因**:node_modules 目录不会参与编译、上传和打包中,小程序想要使用 npm 包必须走一遍“构建 npm”的过程,构建完成会生成一个 miniprogram_npm 目录,里面会存放构建打包后的 npm 包,也就是小程序真正使用的 npm 包。*
34+
[参考文档](https://developers.weixin.qq.com/miniprogram/dev/devtools/npm.html)
35+
36+
### 2.3 效果展示
37+
<img src="./exampleImage/demo1.gif" style="zoom:50%;" />
38+
39+
## 3. 实现思路说明
40+
***主体实现思路可以归纳为,利用 Paddle.js 持续预测摄像头视频流中的图像信息,判断和题目物品是否相符。***
41+
42+
### **3.1 Paddle.js 实现推理预测**
43+
```typescript
44+
// 引入 paddlejs 和 paddlejs-plugin,注册小程序环境变量和合适的 backend
45+
import * as paddlejs from '@paddlejs/paddlejs-core';
46+
import '@paddlejs/paddlejs-backend-webgl';
47+
const plugin = requirePlugin('paddlejs-plugin');
48+
plugin.register(paddlejs, wx);
49+
50+
// 初始化推理引擎
51+
const runner = new paddlejs.Runner({modelPath, feedShape, mean, std});
52+
await runner.init();
53+
54+
// 推理预测
55+
const weightArr = await runner.predict(image);
56+
```
57+
58+
### **3.2 onCameraFrame获取视频流**
59+
小程序相机组件的 [onCameraFrame](https://developers.weixin.qq.com/miniprogram/dev/api/media/camera/CameraContext.onCameraFrame.html) 方法接收一个回调函数,会实时向回调函数中传入当前摄像头中的图像。针对传入的每帧图像使用 Paddle.js 进行预测,预测方法是 Paddle.js 的 `predict` API。该函数作为 Paddle.js 的推理 API,会根据不同的模型而产出具有不同意义的结果。本次使用的是物品分类模型,产出的结果是一个**置信度数组**,代表当前图像与各个物品匹配的置信度,置信度数组中最大一项所对应的物品就是最终的预测物品索引。
60+
```typescript
61+
// 注册回调数 处理视频流帧
62+
const listener = cameraContext.onCameraFrame(frame => {
63+
// 推理
64+
const weightArr = await runner.predict(frame);
65+
// 获取置信度数组最大项的索引
66+
const maxIdx = res.index0f(Math.max.apply(null, weightArr));
67+
// 从物品列表中找到索引对应的物品
68+
const result = mobilenetMap[`${maxIdx}`];
69+
// 结合业务场景选择结果使用方式
70+
// ...
71+
});
72+
73+
//开始捕获视频流
74+
listener.start();
75+
```
76+
77+
## 4. 更多
78+
* [详细文档](https://mp.weixin.qq.com/s/GP1lc3FZ6lQyD7FJfU67xw)
Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
@charset "UTF-8";/*!
2+
* animate.css - https://animate.style/
3+
* Version - 4.1.1
4+
* Licensed under the MIT license - http://opensource.org/licenses/MIT
5+
*
6+
* Copyright (c) 2020 Animate.css
7+
*/
8+
/* wxss 不支持根元素选择器 */
9+
10+
.animate__animated {
11+
animation-duration: 1000ms;
12+
/* animation-duration: var(--animate-duration); */
13+
animation-fill-mode: both;
14+
}
15+
.animate__animated.animate__infinite {
16+
-webkit-animation-iteration-count: infinite;
17+
animation-iteration-count: infinite;
18+
}
19+
20+
.animate__animated.animate__duration-200ms {
21+
animation-duration: 200ms;
22+
}
23+
.animate__animated.animate__duration-300ms {
24+
animation-duration: 300ms;
25+
}
26+
.animate__animated.animate__duration-500ms {
27+
animation-duration: 500ms;
28+
}
29+
.animate__animated.animate__duration-600ms {
30+
animation-duration: 600ms;
31+
}
32+
.animate__animated.animate__duration-700ms {
33+
animation-duration: 700ms;
34+
}
35+
36+
37+
.animate__animated.animate__duration-2000ms {
38+
animation-duration: 2000ms;
39+
}
40+
41+
@media print, (prefers-reduced-motion: reduce) {
42+
.animate__animated {
43+
-webkit-animation-duration: 1ms !important;
44+
animation-duration: 1ms !important;
45+
-webkit-transition-duration: 1ms !important;
46+
transition-duration: 1ms !important;
47+
-webkit-animation-iteration-count: 1 !important;
48+
animation-iteration-count: 1 !important;
49+
}
50+
51+
.animate__animated[class*='Out'] {
52+
opacity: 0;
53+
}
54+
}
55+
/* Attention seekers */
56+
@keyframes bounce {
57+
from,
58+
20%,
59+
53%,
60+
to {
61+
-webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
62+
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
63+
-webkit-transform: translate3d(0, 0, 0);
64+
transform: translate3d(0, 0, 0);
65+
}
66+
67+
40%,
68+
43% {
69+
-webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
70+
animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
71+
-webkit-transform: translate3d(0, -30px, 0) scaleY(1.1);
72+
transform: translate3d(0, -30px, 0) scaleY(1.1);
73+
}
74+
75+
70% {
76+
-webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
77+
animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
78+
-webkit-transform: translate3d(0, -15px, 0) scaleY(1.05);
79+
transform: translate3d(0, -15px, 0) scaleY(1.05);
80+
}
81+
82+
80% {
83+
-webkit-transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
84+
transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
85+
-webkit-transform: translate3d(0, 0, 0) scaleY(0.95);
86+
transform: translate3d(0, 0, 0) scaleY(0.95);
87+
}
88+
89+
90% {
90+
-webkit-transform: translate3d(0, -4px, 0) scaleY(1.02);
91+
transform: translate3d(0, -4px, 0) scaleY(1.02);
92+
}
93+
}
94+
.animate__bounce {
95+
-webkit-animation-name: bounce;
96+
animation-name: bounce;
97+
-webkit-transform-origin: center bottom;
98+
transform-origin: center bottom;
99+
}
100+
101+
/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */
102+
103+
@keyframes pulse {
104+
from {
105+
-webkit-transform: scale3d(1, 1, 1);
106+
transform: scale3d(1, 1, 1);
107+
}
108+
109+
50% {
110+
-webkit-transform: scale3d(1.05, 1.05, 1.05);
111+
transform: scale3d(1.05, 1.05, 1.05);
112+
}
113+
114+
to {
115+
-webkit-transform: scale3d(1, 1, 1);
116+
transform: scale3d(1, 1, 1);
117+
}
118+
}
119+
120+
@keyframes pulsePro {
121+
from {
122+
-webkit-transform: scale3d(1, 1, 1);
123+
transform: scale3d(1, 1, 1);
124+
}
125+
126+
50% {
127+
-webkit-transform: scale3d(1.8, 1.8, 1.8);
128+
transform: scale3d(1.8, 1.8, 1.8);
129+
}
130+
131+
to {
132+
-webkit-transform: scale3d(1, 1, 1);
133+
transform: scale3d(1, 1, 1);
134+
}
135+
}
136+
137+
.animate__pulsePro {
138+
animation-name: pulsePro;
139+
animation-timing-function: ease-in-out;
140+
}
141+
142+
.animate__pulse {
143+
-webkit-animation-name: pulse;
144+
animation-name: pulse;
145+
-webkit-animation-timing-function: ease-in-out;
146+
animation-timing-function: ease-in-out;
147+
}
148+
149+
@keyframes tada {
150+
from {
151+
-webkit-transform: scale3d(1, 1, 1);
152+
transform: scale3d(1, 1, 1);
153+
}
154+
155+
10%,
156+
20% {
157+
-webkit-transform: scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg);
158+
transform: scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg);
159+
}
160+
161+
30%,
162+
50%,
163+
70%,
164+
90% {
165+
-webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);
166+
transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);
167+
}
168+
169+
40%,
170+
60%,
171+
80% {
172+
-webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);
173+
transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);
174+
}
175+
176+
to {
177+
-webkit-transform: scale3d(1, 1, 1);
178+
transform: scale3d(1, 1, 1);
179+
}
180+
}
181+
.animate__tada {
182+
-webkit-animation-name: tada;
183+
animation-name: tada;
184+
}
185+
186+
/* Fading entrances */
187+
188+
@keyframes fadeIn {
189+
from {
190+
opacity: 0;
191+
}
192+
193+
to {
194+
opacity: 1;
195+
}
196+
}
197+
.animate__fadeIn {
198+
-webkit-animation-name: fadeIn;
199+
animation-name: fadeIn;
200+
}
201+
202+
@keyframes zoomIn {
203+
from {
204+
opacity: 0;
205+
-webkit-transform: scale3d(0.3, 0.3, 0.3);
206+
transform: scale3d(0.3, 0.3, 0.3);
207+
}
208+
209+
50% {
210+
opacity: 1;
211+
}
212+
}
213+
.animate__zoomIn {
214+
-webkit-animation-name: zoomIn;
215+
animation-name: zoomIn;
216+
}
217+
218+
@keyframes flipInY {
219+
from {
220+
-webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
221+
transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
222+
-webkit-animation-timing-function: ease-in;
223+
animation-timing-function: ease-in;
224+
opacity: 0;
225+
}
226+
227+
40% {
228+
-webkit-transform: perspective(400px) rotate3d(0, 1, 0, -20deg);
229+
transform: perspective(400px) rotate3d(0, 1, 0, -20deg);
230+
-webkit-animation-timing-function: ease-in;
231+
animation-timing-function: ease-in;
232+
}
233+
234+
60% {
235+
-webkit-transform: perspective(400px) rotate3d(0, 1, 0, 10deg);
236+
transform: perspective(400px) rotate3d(0, 1, 0, 10deg);
237+
opacity: 1;
238+
}
239+
240+
80% {
241+
-webkit-transform: perspective(400px) rotate3d(0, 1, 0, -5deg);
242+
transform: perspective(400px) rotate3d(0, 1, 0, -5deg);
243+
}
244+
245+
to {
246+
-webkit-transform: perspective(400px);
247+
transform: perspective(400px);
248+
}
249+
}
250+
.animate__flipInY {
251+
-webkit-backface-visibility: visible !important;
252+
backface-visibility: visible !important;
253+
-webkit-animation-name: flipInY;
254+
animation-name: flipInY;
255+
}
256+
257+
@keyframes fadeOut {
258+
from {
259+
opacity: 1;
260+
}
261+
262+
to {
263+
opacity: 0;
264+
}
265+
}
266+
.animate__fadeOut {
267+
-webkit-animation-name: fadeOut;
268+
animation-name: fadeOut;
269+
}
270+
271+
@keyframes fadeInDownBig {
272+
from {
273+
opacity: 0;
274+
-webkit-transform: translate3d(0, -2000px, 0);
275+
transform: translate3d(0, -2000px, 0);
276+
}
277+
278+
to {
279+
opacity: 1;
280+
-webkit-transform: translate3d(0, 0, 0);
281+
transform: translate3d(0, 0, 0);
282+
}
283+
}
284+
.animate__fadeInDownBig {
285+
-webkit-animation-name: fadeInDownBig;
286+
animation-name: fadeInDownBig;
287+
}
288+
289+
@keyframes zoomOut {
290+
from {
291+
opacity: 1;
292+
}
293+
294+
50% {
295+
opacity: 0;
296+
-webkit-transform: scale3d(0.3, 0.3, 0.3);
297+
transform: scale3d(0.3, 0.3, 0.3);
298+
}
299+
300+
to {
301+
opacity: 0;
302+
}
303+
}
304+
.animate__zoomOut {
305+
-webkit-animation-name: zoomOut;
306+
animation-name: zoomOut;
307+
}

0 commit comments

Comments
 (0)