@playcraft/build 0.0.9 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +122 -6
- package/dist/analyzers/__tests__/optimization-analyzer.test.d.ts +1 -0
- package/dist/analyzers/__tests__/optimization-analyzer.test.js +169 -0
- package/dist/analyzers/build-analyzer.d.ts +98 -0
- package/dist/analyzers/build-analyzer.js +1160 -0
- package/dist/analyzers/enhanced-report-template.d.ts +13 -0
- package/dist/analyzers/enhanced-report-template.js +957 -0
- package/dist/analyzers/index.d.ts +6 -0
- package/dist/analyzers/index.js +9 -0
- package/dist/analyzers/optimization-analyzer.d.ts +88 -0
- package/dist/analyzers/optimization-analyzer.js +278 -0
- package/dist/analyzers/playable-analyzer.d.ts +91 -0
- package/dist/analyzers/playable-analyzer.js +977 -0
- package/dist/analyzers/report-template.d.ts +50 -0
- package/dist/analyzers/report-template.js +591 -0
- package/dist/analyzers/scene-asset-collector.js +8 -0
- package/dist/base-builder.d.ts +9 -0
- package/dist/base-builder.js +156 -2
- package/dist/build-state-manager.d.ts +110 -0
- package/dist/build-state-manager.js +169 -0
- package/dist/generators/config-generator.d.ts +2 -0
- package/dist/generators/config-generator.js +179 -10
- package/dist/index.d.ts +8 -0
- package/dist/index.js +6 -0
- package/dist/loaders/playcanvas-loader.d.ts +7 -0
- package/dist/loaders/playcanvas-loader.js +17 -0
- package/dist/platforms/adikteev.js +4 -2
- package/dist/platforms/applovin.js +9 -3
- package/dist/platforms/inmobi.js +4 -2
- package/dist/platforms/ironsource.js +4 -1
- package/dist/platforms/liftoff.js +8 -3
- package/dist/platforms/snapchat.js +8 -2
- package/dist/platforms/unity.js +8 -2
- package/dist/playable-builder.js +3 -1
- package/dist/state/build-state-manager.d.ts +174 -0
- package/dist/state/build-state-manager.js +235 -0
- package/dist/state/index.d.ts +4 -0
- package/dist/state/index.js +2 -0
- package/dist/state/state-to-report-converter.d.ts +141 -0
- package/dist/state/state-to-report-converter.js +177 -0
- package/dist/types.d.ts +1 -0
- package/dist/utils.d.ts +4 -0
- package/dist/utils.js +11 -0
- package/dist/vite/config-builder.js +11 -1
- package/dist/vite/platform-configs.d.ts +1 -0
- package/dist/vite/platform-configs.js +1 -0
- package/dist/vite/plugin-build-state.d.ts +13 -0
- package/dist/vite/plugin-build-state.js +147 -0
- package/dist/vite/plugin-esm-html-generator.js +11 -2
- package/dist/vite/plugin-platform.js +3 -1
- package/dist/vite/plugin-playcanvas.d.ts +1 -0
- package/dist/vite/plugin-playcanvas.js +160 -20
- package/dist/vite/plugin-source-builder.js +1 -0
- package/dist/vite/plugin-template-minifier.d.ts +20 -0
- package/dist/vite/plugin-template-minifier.js +392 -0
- package/package.json +12 -12
- package/templates/patches/one-page-mraid-resize-canvas.js +18 -4
- package/dist/templates/__loading__.js +0 -100
- package/dist/templates/__modules__.js +0 -47
- package/dist/templates/__settings__.template.js +0 -20
- package/dist/templates/__start__.js +0 -332
- package/dist/templates/index.html +0 -18
- package/dist/templates/logo.png +0 -0
- package/dist/templates/manifest.json +0 -1
- package/dist/templates/patches/cannon.min.js +0 -28
- package/dist/templates/patches/lz4.js +0 -10
- package/dist/templates/patches/one-page-http-get.js +0 -20
- package/dist/templates/patches/one-page-inline-game-scripts.js +0 -52
- package/dist/templates/patches/one-page-mraid-resize-canvas.js +0 -46
- package/dist/templates/patches/p2.min.js +0 -27
- package/dist/templates/patches/playcraft-no-xhr.js +0 -76
- package/dist/templates/playcanvas-stable.min.js +0 -16363
- package/dist/templates/styles.css +0 -43
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vite 插件:模板字符串压缩
|
|
3
|
+
*
|
|
4
|
+
* 在构建完成后(closeBundle 阶段)对输出的 HTML 文件进行后处理,
|
|
5
|
+
* 压缩 JS 代码中的多行模板字符串,减小包体积。
|
|
6
|
+
*
|
|
7
|
+
* 这个插件必须在 vite-plugin-singlefile 之后运行,
|
|
8
|
+
* 因为它直接处理最终输出的文件,而不是通过 Vite 的 HTML 处理管道。
|
|
9
|
+
*/
|
|
10
|
+
import fs from 'fs/promises';
|
|
11
|
+
import path from 'path';
|
|
12
|
+
/**
|
|
13
|
+
* 压缩 JS 代码中的模板字符串
|
|
14
|
+
*
|
|
15
|
+
* 处理策略:
|
|
16
|
+
* 1. 找到所有多行模板字符串(包含 \n 的反引号字符串)
|
|
17
|
+
* 2. 对于不包含 ${...} 的简单模板字符串,将换行和多余空白压缩
|
|
18
|
+
* 3. 对于包含 ${...} 的复杂模板字符串,保守处理
|
|
19
|
+
*/
|
|
20
|
+
function minifyTemplateStrings(code) {
|
|
21
|
+
const result = [];
|
|
22
|
+
let i = 0;
|
|
23
|
+
let minifiedCount = 0;
|
|
24
|
+
let totalSaved = 0;
|
|
25
|
+
while (i < code.length) {
|
|
26
|
+
// 跳过字符串字面量(避免误处理)
|
|
27
|
+
if (code[i] === '"' || code[i] === "'") {
|
|
28
|
+
const quote = code[i];
|
|
29
|
+
result.push(code[i]);
|
|
30
|
+
i++;
|
|
31
|
+
while (i < code.length && code[i] !== quote) {
|
|
32
|
+
if (code[i] === '\\' && i + 1 < code.length) {
|
|
33
|
+
result.push(code[i], code[i + 1]);
|
|
34
|
+
i += 2;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
result.push(code[i]);
|
|
38
|
+
i++;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (i < code.length) {
|
|
42
|
+
result.push(code[i]);
|
|
43
|
+
i++;
|
|
44
|
+
}
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
// 处理模板字符串
|
|
48
|
+
if (code[i] === '`') {
|
|
49
|
+
const startPos = i;
|
|
50
|
+
i++; // 跳过开始的反引号
|
|
51
|
+
// 收集模板字符串内容
|
|
52
|
+
let content = '';
|
|
53
|
+
let nestingLevel = 0; // 跟踪 ${...} 嵌套
|
|
54
|
+
while (i < code.length) {
|
|
55
|
+
if (code[i] === '\\' && i + 1 < code.length) {
|
|
56
|
+
// 转义字符
|
|
57
|
+
content += code[i] + code[i + 1];
|
|
58
|
+
i += 2;
|
|
59
|
+
}
|
|
60
|
+
else if (code[i] === '$' && code[i + 1] === '{') {
|
|
61
|
+
// 模板表达式开始
|
|
62
|
+
content += '${';
|
|
63
|
+
i += 2;
|
|
64
|
+
nestingLevel++;
|
|
65
|
+
// 找到匹配的 }
|
|
66
|
+
let braceCount = 1;
|
|
67
|
+
while (i < code.length && braceCount > 0) {
|
|
68
|
+
if (code[i] === '{') {
|
|
69
|
+
braceCount++;
|
|
70
|
+
content += code[i];
|
|
71
|
+
}
|
|
72
|
+
else if (code[i] === '}') {
|
|
73
|
+
braceCount--;
|
|
74
|
+
content += code[i];
|
|
75
|
+
}
|
|
76
|
+
else if (code[i] === '`') {
|
|
77
|
+
// 嵌套的模板字符串,递归处理
|
|
78
|
+
content += code[i];
|
|
79
|
+
i++;
|
|
80
|
+
while (i < code.length && code[i] !== '`') {
|
|
81
|
+
if (code[i] === '\\' && i + 1 < code.length) {
|
|
82
|
+
content += code[i] + code[i + 1];
|
|
83
|
+
i += 2;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
content += code[i];
|
|
87
|
+
i++;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (i < code.length) {
|
|
91
|
+
content += code[i];
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else if (code[i] === '"' || code[i] === "'") {
|
|
95
|
+
// 嵌套的字符串
|
|
96
|
+
const quote = code[i];
|
|
97
|
+
content += code[i];
|
|
98
|
+
i++;
|
|
99
|
+
while (i < code.length && code[i] !== quote) {
|
|
100
|
+
if (code[i] === '\\' && i + 1 < code.length) {
|
|
101
|
+
content += code[i] + code[i + 1];
|
|
102
|
+
i += 2;
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
content += code[i];
|
|
106
|
+
i++;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (i < code.length) {
|
|
110
|
+
content += code[i];
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
content += code[i];
|
|
115
|
+
}
|
|
116
|
+
i++;
|
|
117
|
+
}
|
|
118
|
+
nestingLevel--;
|
|
119
|
+
}
|
|
120
|
+
else if (code[i] === '`') {
|
|
121
|
+
// 找到结束的反引号
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
content += code[i];
|
|
126
|
+
i++;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const originalLength = content.length;
|
|
130
|
+
// 决定是否压缩这个模板字符串
|
|
131
|
+
if (shouldMinifyTemplate(content)) {
|
|
132
|
+
const minified = minifyTemplateContent(content);
|
|
133
|
+
result.push('`' + minified + '`');
|
|
134
|
+
const saved = originalLength - minified.length;
|
|
135
|
+
if (saved > 0) {
|
|
136
|
+
minifiedCount++;
|
|
137
|
+
totalSaved += saved;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
result.push('`' + content + '`');
|
|
142
|
+
}
|
|
143
|
+
i++; // 跳过结束的反引号
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
result.push(code[i]);
|
|
147
|
+
i++;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (minifiedCount > 0) {
|
|
151
|
+
console.log(`[TemplateMinifier] 压缩了 ${minifiedCount} 个模板字符串,节省约 ${(totalSaved / 1024).toFixed(2)} KB`);
|
|
152
|
+
}
|
|
153
|
+
return result.join('');
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* 判断是否应该压缩这个模板字符串
|
|
157
|
+
*/
|
|
158
|
+
function shouldMinifyTemplate(content) {
|
|
159
|
+
// 必须包含换行才需要压缩
|
|
160
|
+
if (!content.includes('\n')) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
// 长度太短不值得压缩
|
|
164
|
+
if (content.length < 50) {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
// 着色器代码也需要压缩!不要跳过
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* 判断是否是着色器代码(GLSL 或 WGSL)
|
|
172
|
+
*/
|
|
173
|
+
function isShaderCode(content) {
|
|
174
|
+
// GLSL 关键特征
|
|
175
|
+
const glslKeywords = [
|
|
176
|
+
/\buniform\s+\w+/,
|
|
177
|
+
/\bvarying\s+\w+/,
|
|
178
|
+
/\battribute\s+\w+/,
|
|
179
|
+
/\bvoid\s+main\s*\(/,
|
|
180
|
+
/\bgl_Position\b/,
|
|
181
|
+
/\bgl_FragColor\b/,
|
|
182
|
+
/\bgl_FragCoord\b/,
|
|
183
|
+
/\bprecision\s+(highp|mediump|lowp)/,
|
|
184
|
+
/\b(vec2|vec3|vec4|mat3|mat4|sampler2D)\b/,
|
|
185
|
+
/\btexture2D\s*\(/,
|
|
186
|
+
/\btexelFetch\s*\(/,
|
|
187
|
+
];
|
|
188
|
+
// WGSL 关键特征
|
|
189
|
+
const wgslKeywords = [
|
|
190
|
+
/@(vertex|fragment|compute)\b/,
|
|
191
|
+
/@(group|binding)\s*\(/,
|
|
192
|
+
/@builtin\s*\(/,
|
|
193
|
+
/@workgroup_size\s*\(/,
|
|
194
|
+
/\bfn\s+\w+\s*\(/,
|
|
195
|
+
/\bvar<\w+>/,
|
|
196
|
+
/\b(vec2f|vec3f|vec4f|vec2i|vec3i|vec4i|vec2u|vec3u|vec4u)\b/,
|
|
197
|
+
/\bstruct\s+\w+\s*\{/,
|
|
198
|
+
/\btextureLoad\s*\(/,
|
|
199
|
+
/\btextureSample\s*\(/,
|
|
200
|
+
/\bworkgroupBarrier\s*\(/,
|
|
201
|
+
/\barray<\w+/,
|
|
202
|
+
];
|
|
203
|
+
const allKeywords = [...glslKeywords, ...wgslKeywords];
|
|
204
|
+
let matchCount = 0;
|
|
205
|
+
for (const keyword of allKeywords) {
|
|
206
|
+
if (keyword.test(content)) {
|
|
207
|
+
matchCount++;
|
|
208
|
+
if (matchCount >= 2) {
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* 压缩模板字符串内容
|
|
217
|
+
*/
|
|
218
|
+
function minifyTemplateContent(content) {
|
|
219
|
+
// 检查是否是着色器代码
|
|
220
|
+
if (isShaderCode(content)) {
|
|
221
|
+
return minifyShaderContent(content);
|
|
222
|
+
}
|
|
223
|
+
// 检查是否包含 ${...} 模板表达式
|
|
224
|
+
const hasTemplateExpr = /\$\{/.test(content);
|
|
225
|
+
if (hasTemplateExpr) {
|
|
226
|
+
// 包含模板表达式,保守处理
|
|
227
|
+
// 只压缩纯空白行和行首缩进,保留换行结构
|
|
228
|
+
return content
|
|
229
|
+
// 移除行首缩进(保留换行)
|
|
230
|
+
.replace(/\n[ \t]+/g, '\n')
|
|
231
|
+
// 移除多个连续空行
|
|
232
|
+
.replace(/\n{3,}/g, '\n\n')
|
|
233
|
+
// 移除开头的空白
|
|
234
|
+
.replace(/^[ \t\n]+/, '')
|
|
235
|
+
// 移除结尾的空白
|
|
236
|
+
.replace(/[ \t\n]+$/, '');
|
|
237
|
+
}
|
|
238
|
+
// 不包含模板表达式,可以更激进地压缩
|
|
239
|
+
// 但要注意保留字符串内容的语义
|
|
240
|
+
// 检查是否像是 JSON 或配置数据
|
|
241
|
+
const trimmed = content.trim();
|
|
242
|
+
if ((trimmed.startsWith('{') && trimmed.endsWith('}')) ||
|
|
243
|
+
(trimmed.startsWith('[') && trimmed.endsWith(']'))) {
|
|
244
|
+
// 可能是 JSON,尝试压缩
|
|
245
|
+
try {
|
|
246
|
+
// 尝试解析为 JSON,然后重新序列化为紧凑格式
|
|
247
|
+
const parsed = JSON.parse(trimmed);
|
|
248
|
+
return JSON.stringify(parsed);
|
|
249
|
+
}
|
|
250
|
+
catch {
|
|
251
|
+
// 不是有效 JSON,按普通文本处理
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
// 普通多行文本,压缩空白但保留必要的空格
|
|
255
|
+
return content
|
|
256
|
+
// 将换行和周围空白替换为单个空格
|
|
257
|
+
.replace(/\s*\n\s*/g, ' ')
|
|
258
|
+
// 合并多个空格
|
|
259
|
+
.replace(/ +/g, ' ')
|
|
260
|
+
.trim();
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* 压缩着色器代码(GLSL/WGSL)
|
|
264
|
+
*
|
|
265
|
+
* 着色器代码需要特殊处理:
|
|
266
|
+
* 1. 预处理器指令(#define, #ifdef 等)需要独占一行
|
|
267
|
+
* 2. 可以移除多余的空白和缩进
|
|
268
|
+
* 3. 保留关键字之间的空格
|
|
269
|
+
*/
|
|
270
|
+
function minifyShaderContent(code) {
|
|
271
|
+
const lines = code.split('\n');
|
|
272
|
+
const processedLines = [];
|
|
273
|
+
for (let line of lines) {
|
|
274
|
+
// 移除行首尾空白
|
|
275
|
+
line = line.trim();
|
|
276
|
+
// 跳过空行
|
|
277
|
+
if (!line)
|
|
278
|
+
continue;
|
|
279
|
+
// 跳过单行注释
|
|
280
|
+
if (line.startsWith('//'))
|
|
281
|
+
continue;
|
|
282
|
+
// 预处理器指令需要独占一行(#define, #ifdef, #endif, #include 等)
|
|
283
|
+
if (line.startsWith('#')) {
|
|
284
|
+
processedLines.push('\n' + line);
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
// 压缩行内多余空白,但保守处理
|
|
288
|
+
line = line
|
|
289
|
+
// 将多个空白替换为单个空格
|
|
290
|
+
.replace(/\s+/g, ' ')
|
|
291
|
+
// 移除分号后的空格(但不移除分号)
|
|
292
|
+
.replace(/;\s+/g, ';')
|
|
293
|
+
// 移除逗号后多余空格(保留一个)
|
|
294
|
+
.replace(/,\s+/g, ', ')
|
|
295
|
+
// 移除括号内侧的空格
|
|
296
|
+
.replace(/\(\s+/g, '(')
|
|
297
|
+
.replace(/\s+\)/g, ')')
|
|
298
|
+
// 移除花括号内侧的空格
|
|
299
|
+
.replace(/\{\s+/g, '{')
|
|
300
|
+
.replace(/\s+\}/g, '}')
|
|
301
|
+
// 移除方括号内侧的空格
|
|
302
|
+
.replace(/\[\s+/g, '[')
|
|
303
|
+
.replace(/\s+\]/g, ']')
|
|
304
|
+
// 移除冒号周围的空格(WGSL 类型声明)
|
|
305
|
+
.replace(/\s*:\s*/g, ':')
|
|
306
|
+
// 移除箭头周围的空格(WGSL 返回类型)
|
|
307
|
+
.replace(/\s*->\s*/g, '->')
|
|
308
|
+
.trim();
|
|
309
|
+
if (line) {
|
|
310
|
+
processedLines.push(line);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
// 合并非预处理器行,预处理器指令保留换行
|
|
315
|
+
let result = '';
|
|
316
|
+
for (const line of processedLines) {
|
|
317
|
+
if (line.startsWith('\n')) {
|
|
318
|
+
// 预处理器指令,保留换行
|
|
319
|
+
result += line;
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
// 普通代码,用换行连接(保守做法,避免语法错误)
|
|
323
|
+
if (result && !result.endsWith('\n')) {
|
|
324
|
+
result += '\n';
|
|
325
|
+
}
|
|
326
|
+
result += line;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return result.trim();
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* 创建模板字符串压缩插件
|
|
333
|
+
*/
|
|
334
|
+
export function viteTemplateMinifierPlugin(options) {
|
|
335
|
+
const { outputDir, enabled = true } = options;
|
|
336
|
+
return {
|
|
337
|
+
name: 'vite-plugin-template-minifier',
|
|
338
|
+
enforce: 'post', // 在其他插件之后执行
|
|
339
|
+
async closeBundle() {
|
|
340
|
+
if (!enabled) {
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
// 查找输出目录中的 HTML 文件
|
|
344
|
+
const htmlPath = path.join(outputDir, 'index.html');
|
|
345
|
+
try {
|
|
346
|
+
await fs.access(htmlPath);
|
|
347
|
+
}
|
|
348
|
+
catch {
|
|
349
|
+
// HTML 文件不存在,跳过
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
console.log('[TemplateMinifier] 开始压缩模板字符串...');
|
|
353
|
+
try {
|
|
354
|
+
let html = await fs.readFile(htmlPath, 'utf-8');
|
|
355
|
+
const originalSize = html.length;
|
|
356
|
+
// 压缩 HTML 中的 JS 代码里的模板字符串
|
|
357
|
+
// 找到所有 <script> 标签并处理其内容
|
|
358
|
+
html = html.replace(/<script([^>]*)>([\s\S]*?)<\/script>/gi, (match, attrs, content) => {
|
|
359
|
+
// 跳过外部脚本
|
|
360
|
+
if (/\bsrc\s*=/.test(attrs)) {
|
|
361
|
+
return match;
|
|
362
|
+
}
|
|
363
|
+
// 跳过非 JS 脚本(如 JSON、importmap)
|
|
364
|
+
const typeMatch = attrs.match(/\btype\s*=\s*["']([^"']+)["']/i);
|
|
365
|
+
if (typeMatch) {
|
|
366
|
+
const type = typeMatch[1].toLowerCase();
|
|
367
|
+
if (type === 'application/json' ||
|
|
368
|
+
type === 'importmap' ||
|
|
369
|
+
type === 'application/ld+json') {
|
|
370
|
+
return match;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
// 压缩 JS 中的模板字符串
|
|
374
|
+
const minified = minifyTemplateStrings(content);
|
|
375
|
+
return `<script${attrs}>${minified}</script>`;
|
|
376
|
+
});
|
|
377
|
+
const newSize = html.length;
|
|
378
|
+
const saved = originalSize - newSize;
|
|
379
|
+
if (saved > 0) {
|
|
380
|
+
await fs.writeFile(htmlPath, html, 'utf-8');
|
|
381
|
+
console.log(`[TemplateMinifier] 完成!节省 ${(saved / 1024).toFixed(2)} KB (${((saved / originalSize) * 100).toFixed(2)}%)`);
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
console.log('[TemplateMinifier] 没有可压缩的内容');
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
catch (error) {
|
|
388
|
+
console.error('[TemplateMinifier] 压缩失败:', error);
|
|
389
|
+
}
|
|
390
|
+
},
|
|
391
|
+
};
|
|
392
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@playcraft/build",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.10",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -27,27 +27,27 @@
|
|
|
27
27
|
"release": "node scripts/release.js"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@gltf-transform/core": "^4.
|
|
31
|
-
"@gltf-transform/extensions": "^4.
|
|
32
|
-
"@gltf-transform/functions": "^4.
|
|
33
|
-
"@vheemstra/vite-plugin-imagemin": "^2.
|
|
30
|
+
"@gltf-transform/core": "^4.3.0",
|
|
31
|
+
"@gltf-transform/extensions": "^4.3.0",
|
|
32
|
+
"@gltf-transform/functions": "^4.3.0",
|
|
33
|
+
"@vheemstra/vite-plugin-imagemin": "^2.2.1",
|
|
34
34
|
"archiver": "^7.0.1",
|
|
35
35
|
"draco3dgltf": "^1.5.7",
|
|
36
36
|
"imagemin-mozjpeg": "^10.0.0",
|
|
37
37
|
"imagemin-pngquant": "^10.0.0",
|
|
38
38
|
"imagemin-webp": "^8.0.0",
|
|
39
|
-
"lightningcss": "^1.
|
|
39
|
+
"lightningcss": "^1.31.1",
|
|
40
40
|
"mime-types": "^2.1.35",
|
|
41
41
|
"rollup-plugin-visualizer": "^6.0.5",
|
|
42
|
-
"sharp": "^0.33.
|
|
43
|
-
"terser": "^5.
|
|
44
|
-
"vite": "^6.
|
|
45
|
-
"vite-plugin-singlefile": "^2.
|
|
42
|
+
"sharp": "^0.33.5",
|
|
43
|
+
"terser": "^5.46.0",
|
|
44
|
+
"vite": "^6.4.1",
|
|
45
|
+
"vite-plugin-singlefile": "^2.3.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@types/archiver": "^6.0.4",
|
|
49
49
|
"@types/mime-types": "^2.1.4",
|
|
50
|
-
"@types/node": "^22.
|
|
51
|
-
"typescript": "^5.
|
|
50
|
+
"@types/node": "^22.19.8",
|
|
51
|
+
"typescript": "^5.9.3"
|
|
52
52
|
}
|
|
53
53
|
}
|
|
@@ -9,10 +9,13 @@
|
|
|
9
9
|
var windowWidth = window.innerWidth;
|
|
10
10
|
var windowHeight = window.innerHeight;
|
|
11
11
|
|
|
12
|
-
if
|
|
12
|
+
// Get MRAID max size if available
|
|
13
|
+
if (window.mraid && typeof mraid.getMaxSize === 'function') {
|
|
13
14
|
var mraidSize = mraid.getMaxSize();
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
if (mraidSize && mraidSize.width && mraidSize.height) {
|
|
16
|
+
windowWidth = mraidSize.width;
|
|
17
|
+
windowHeight = mraidSize.height;
|
|
18
|
+
}
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
if (this._fillMode === pc.FILLMODE_KEEP_ASPECT) {
|
|
@@ -29,8 +32,19 @@
|
|
|
29
32
|
} else if (this._fillMode === pc.FILLMODE_FILL_WINDOW) {
|
|
30
33
|
width = windowWidth;
|
|
31
34
|
height = windowHeight;
|
|
35
|
+
} else {
|
|
36
|
+
// FILLMODE_NONE: For MRAID, use KEEP_ASPECT behavior to ensure correct sizing
|
|
37
|
+
var r = this.graphicsDevice.canvas.width / this.graphicsDevice.canvas.height;
|
|
38
|
+
var winR = windowWidth / windowHeight;
|
|
39
|
+
|
|
40
|
+
if (r > winR) {
|
|
41
|
+
width = windowWidth;
|
|
42
|
+
height = width / r;
|
|
43
|
+
} else {
|
|
44
|
+
height = windowHeight;
|
|
45
|
+
width = height * r;
|
|
46
|
+
}
|
|
32
47
|
}
|
|
33
|
-
// OTHERWISE: FILLMODE_NONE use width and height that are provided
|
|
34
48
|
|
|
35
49
|
this.graphicsDevice.canvas.style.width = width + 'px';
|
|
36
50
|
this.graphicsDevice.canvas.style.height = height + 'px';
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
pc.script.createLoadingScreen((app) => {
|
|
2
|
-
const createCss = () => {
|
|
3
|
-
const css = `
|
|
4
|
-
body {
|
|
5
|
-
background-color: #283538;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
#application-splash-wrapper {
|
|
9
|
-
position: absolute;
|
|
10
|
-
top: 0;
|
|
11
|
-
left: 0;
|
|
12
|
-
height: 100%;
|
|
13
|
-
width: 100%;
|
|
14
|
-
background-color: #283538;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
#application-splash {
|
|
18
|
-
position: absolute;
|
|
19
|
-
top: calc(50% - 28px);
|
|
20
|
-
width: 264px;
|
|
21
|
-
left: calc(50% - 132px);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
#application-splash img {
|
|
25
|
-
width: 100%;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
#progress-bar-container {
|
|
29
|
-
margin: 20px auto 0 auto;
|
|
30
|
-
height: 2px;
|
|
31
|
-
width: 100%;
|
|
32
|
-
background-color: #1d292c;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
#progress-bar {
|
|
36
|
-
width: 0%;
|
|
37
|
-
height: 100%;
|
|
38
|
-
background-color: #f60;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
@media (max-width: 480px) {
|
|
42
|
-
#application-splash {
|
|
43
|
-
width: 170px;
|
|
44
|
-
left: calc(50% - 85px);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
`;
|
|
48
|
-
|
|
49
|
-
const style = document.createElement('style');
|
|
50
|
-
style.textContent = css;
|
|
51
|
-
document.head.appendChild(style);
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
const showSplash = () => {
|
|
55
|
-
const wrapper = document.createElement('div');
|
|
56
|
-
wrapper.id = 'application-splash-wrapper';
|
|
57
|
-
document.body.appendChild(wrapper);
|
|
58
|
-
|
|
59
|
-
const splash = document.createElement('div');
|
|
60
|
-
splash.id = 'application-splash';
|
|
61
|
-
wrapper.appendChild(splash);
|
|
62
|
-
splash.style.display = 'none';
|
|
63
|
-
|
|
64
|
-
const logo = document.createElement('img');
|
|
65
|
-
logo.src = `${ASSET_PREFIX}logo.png`;
|
|
66
|
-
splash.appendChild(logo);
|
|
67
|
-
logo.onload = () => {
|
|
68
|
-
splash.style.display = 'block';
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
const container = document.createElement('div');
|
|
72
|
-
container.id = 'progress-bar-container';
|
|
73
|
-
splash.appendChild(container);
|
|
74
|
-
|
|
75
|
-
const bar = document.createElement('div');
|
|
76
|
-
bar.id = 'progress-bar';
|
|
77
|
-
container.appendChild(bar);
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
const setProgress = (value) => {
|
|
81
|
-
const bar = document.getElementById('progress-bar');
|
|
82
|
-
if (bar) {
|
|
83
|
-
value = Math.min(1, Math.max(0, value));
|
|
84
|
-
bar.style.width = `${value * 100}%`;
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
const hideSplash = () => {
|
|
89
|
-
document.getElementById('application-splash-wrapper').remove();
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
createCss();
|
|
93
|
-
showSplash();
|
|
94
|
-
|
|
95
|
-
app.on('preload:end', () => {
|
|
96
|
-
app.off('preload:progress');
|
|
97
|
-
});
|
|
98
|
-
app.on('preload:progress', setProgress);
|
|
99
|
-
app.on('start', hideSplash);
|
|
100
|
-
});
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
var loadModules = function (modules, urlPrefix, doneCallback) { // eslint-disable-line no-unused-vars
|
|
2
|
-
|
|
3
|
-
if (typeof modules === "undefined" || modules.length === 0) {
|
|
4
|
-
// caller may depend on callback behaviour being async
|
|
5
|
-
setTimeout(doneCallback);
|
|
6
|
-
} else {
|
|
7
|
-
let remaining = modules.length;
|
|
8
|
-
const moduleLoaded = () => {
|
|
9
|
-
if (--remaining === 0) {
|
|
10
|
-
doneCallback();
|
|
11
|
-
}
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
modules.forEach(function (m) {
|
|
15
|
-
pc.WasmModule.setConfig(m.moduleName, {
|
|
16
|
-
glueUrl: urlPrefix + m.glueUrl,
|
|
17
|
-
wasmUrl: urlPrefix + m.wasmUrl,
|
|
18
|
-
fallbackUrl: urlPrefix + m.fallbackUrl
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
if (!m.hasOwnProperty('preload') || m.preload) {
|
|
22
|
-
if (m.moduleName === 'BASIS') {
|
|
23
|
-
// preload basis transcoder
|
|
24
|
-
pc.basisInitialize();
|
|
25
|
-
moduleLoaded();
|
|
26
|
-
} else if (m.moduleName === 'DracoDecoderModule') {
|
|
27
|
-
// preload draco decoder
|
|
28
|
-
if (pc.dracoInitialize) {
|
|
29
|
-
// 1.63 onwards
|
|
30
|
-
pc.dracoInitialize();
|
|
31
|
-
moduleLoaded();
|
|
32
|
-
} else {
|
|
33
|
-
// 1.62 and earlier
|
|
34
|
-
pc.WasmModule.getInstance(m.moduleName, () => { moduleLoaded(); });
|
|
35
|
-
}
|
|
36
|
-
} else {
|
|
37
|
-
// load remaining modules in global scope
|
|
38
|
-
pc.WasmModule.getInstance(m.moduleName, () => { moduleLoaded(); });
|
|
39
|
-
}
|
|
40
|
-
} else {
|
|
41
|
-
moduleLoaded();
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
window.loadModules = loadModules;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
window.ASSET_PREFIX = "";
|
|
2
|
-
window.SCRIPT_PREFIX = "";
|
|
3
|
-
window.SCENE_PATH = "{{SCENE_PATH}}";
|
|
4
|
-
window.CONTEXT_OPTIONS = {
|
|
5
|
-
'antialias': {{ANTIALIAS}},
|
|
6
|
-
'alpha': false,
|
|
7
|
-
'preserveDrawingBuffer': {{PRESERVE_DRAWING_BUFFER}},
|
|
8
|
-
'deviceTypes': [`webgl2`, `webgl1`],
|
|
9
|
-
'powerPreference': "{{POWER_PREFERENCE}}"
|
|
10
|
-
};
|
|
11
|
-
window.SCRIPTS = {{SCRIPTS}};
|
|
12
|
-
window.CONFIG_FILENAME = "config.json";
|
|
13
|
-
window.INPUT_SETTINGS = {
|
|
14
|
-
useKeyboard: {{USE_KEYBOARD}},
|
|
15
|
-
useMouse: {{USE_MOUSE}},
|
|
16
|
-
useGamepads: {{USE_GAMEPAD}},
|
|
17
|
-
useTouch: {{USE_TOUCH}}
|
|
18
|
-
};
|
|
19
|
-
pc.script.legacy = {{USE_LEGACY_SCRIPTS}};
|
|
20
|
-
window.PRELOAD_MODULES = {{PRELOAD_MODULES}};
|