soiz commited on
Commit
987f315
·
verified ·
1 Parent(s): 0976882

Create snail-extension.js

Browse files
Files changed (1) hide show
  1. scaffolding/snail-extension.js +134 -0
scaffolding/snail-extension.js ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class Posenet2Scratch {
2
+ constructor(runtime) {
3
+ this.runtime = runtime;
4
+ this.poses = [];
5
+ this.keypoints = [];
6
+ this._locale = this.setLocale();
7
+
8
+ const video = document.createElement("video");
9
+ video.width = 480;
10
+ video.height = 360;
11
+ video.autoplay = true;
12
+ video.style.display = "none";
13
+
14
+ navigator.mediaDevices
15
+ .getUserMedia({ video: true, audio: false })
16
+ .then((stream) => {
17
+ video.srcObject = stream;
18
+ });
19
+
20
+ video.addEventListener("loadeddata", () => {
21
+ // Load posenet model and process poses
22
+ posenet.load().then((net) => {
23
+ const detectPose = () => {
24
+ net.estimateMultiplePoses(video, {
25
+ flipHorizontal: false,
26
+ }).then((poses) => {
27
+ this.poses = poses;
28
+ this.keypoints = poses[0]?.keypoints || [];
29
+ requestAnimationFrame(detectPose);
30
+ });
31
+ };
32
+ detectPose();
33
+ });
34
+ });
35
+
36
+ this.runtime.ioDevices.video.enableVideo();
37
+ }
38
+
39
+ setLocale() {
40
+ const supportedLocales = ["en", "ja", "ja-Hira"];
41
+ const locale = navigator.language || "en";
42
+ return supportedLocales.includes(locale) ? locale : "en";
43
+ }
44
+
45
+ getX(args) {
46
+ const personIndex = parseInt(args.PERSON_NUMBER, 10) - 1;
47
+ const partIndex = parseInt(args.PART, 10);
48
+ const pose = this.poses[personIndex];
49
+
50
+ if (pose && pose.pose.keypoints[partIndex]) {
51
+ const x = pose.pose.keypoints[partIndex].position.x;
52
+ return this.runtime.ioDevices.video.mirror ? 240 - x : x - 240;
53
+ }
54
+ return "";
55
+ }
56
+
57
+ getY(args) {
58
+ const personIndex = parseInt(args.PERSON_NUMBER, 10) - 1;
59
+ const partIndex = parseInt(args.PART, 10);
60
+ const pose = this.poses[personIndex];
61
+
62
+ if (pose && pose.pose.keypoints[partIndex]) {
63
+ const y = pose.pose.keypoints[partIndex].position.y;
64
+ return 180 - y;
65
+ }
66
+ return "";
67
+ }
68
+
69
+ getPeopleCount() {
70
+ return this.poses.length;
71
+ }
72
+
73
+ getInfo() {
74
+ return {
75
+ id: "posenet2scratch",
76
+ name: "Posenet2Scratch",
77
+ blocks: [
78
+ {
79
+ opcode: "getX",
80
+ blockType: "reporter",
81
+ text: "[PART] x of person no. [PERSON_NUMBER]",
82
+ arguments: {
83
+ PERSON_NUMBER: { type: "string", menu: "personNumbers", defaultValue: "1" },
84
+ PART: { type: "string", menu: "parts", defaultValue: "0" },
85
+ },
86
+ },
87
+ {
88
+ opcode: "getY",
89
+ blockType: "reporter",
90
+ text: "[PART] y of person no. [PERSON_NUMBER]",
91
+ arguments: {
92
+ PERSON_NUMBER: { type: "string", menu: "personNumbers", defaultValue: "1" },
93
+ PART: { type: "string", menu: "parts", defaultValue: "0" },
94
+ },
95
+ },
96
+ {
97
+ opcode: "getPeopleCount",
98
+ blockType: "reporter",
99
+ text: "people count",
100
+ },
101
+ ],
102
+ menus: {
103
+ personNumbers: {
104
+ acceptReporters: true,
105
+ items: Array.from({ length: 10 }, (_, i) => ({ text: `${i + 1}`, value: `${i + 1}` })),
106
+ },
107
+ parts: {
108
+ acceptReporters: true,
109
+ items: [
110
+ { text: "nose", value: "0" },
111
+ { text: "left eye", value: "1" },
112
+ { text: "right eye", value: "2" },
113
+ { text: "left ear", value: "3" },
114
+ { text: "right ear", value: "4" },
115
+ { text: "left shoulder", value: "5" },
116
+ { text: "right shoulder", value: "6" },
117
+ { text: "left elbow", value: "7" },
118
+ { text: "right elbow", value: "8" },
119
+ { text: "left wrist", value: "9" },
120
+ { text: "right wrist", value: "10" },
121
+ { text: "left hip", value: "11" },
122
+ { text: "right hip", value: "12" },
123
+ { text: "left knee", value: "13" },
124
+ { text: "right knee", value: "14" },
125
+ { text: "left ankle", value: "15" },
126
+ { text: "right ankle", value: "16" },
127
+ ],
128
+ },
129
+ },
130
+ };
131
+ }
132
+ }
133
+
134
+ Scratch.extensions.register(new Posenet2Scratch());