apptify 0.8.0 → 0.8.1
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/package.json +1 -1
- package/templates/playground/README.md +1 -1
- package/templates/playground/package.json +1 -1
- package/templates/playground/source-snapshot.json +13 -4
- package/templates/playground/src/components/gateway-paper-scene.vue +336 -0
- package/templates/playground/src/components/gateway-paper-story.ts +197 -0
- package/templates/playground/src/views/502.vue +65 -0
- package/tooling/prepare-playground.mjs +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"createdAt": "2026-
|
|
3
|
-
"libraryVersion": "0.8.
|
|
2
|
+
"createdAt": "2026-11-03T15:42:31.858Z",
|
|
3
|
+
"libraryVersion": "0.8.1",
|
|
4
4
|
"files": {
|
|
5
5
|
"index.html": "75f6d93e3962ddca97a13b666a04d98ba9b263b6c288171383db764215034fea",
|
|
6
6
|
"public/images/SOURCES.md": "24ccb6625b1168e48550b7651e9fc20cb747324d87666d39199608c7db20541b",
|
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
"src/components/UserMenu.vue": "2822ea367cc8b5b8351fe2d1053ac24758e040df6a509e03f68ec8c3fc7e283d",
|
|
26
26
|
"src/components/forbidden-paper-scene.vue": "a3ad3f3ff92a223a53fd5b08a5bea1a4be98cd2b035cfa64e70d69a6c6477c21",
|
|
27
27
|
"src/components/forbidden-paper-story.ts": "b4c798ec04eda22ef4da235c9ffd57721777ceb043829dc76e4628112d8cfbf6",
|
|
28
|
+
"src/components/gateway-paper-scene.vue": "7738aca72d96b01992dd84d38d983e44c3e919aa520ebbb9816c92cdcc4ce416",
|
|
29
|
+
"src/components/gateway-paper-story.ts": "90deba7f3475bbe8b0ddab13a9f0671ba4f0f73176cbf584c4ae27d26f8de3c3",
|
|
28
30
|
"src/components/not-found-paper-scene.vue": "39f12c23f04d72131d9da51e9a960894b621f2581c25e5b18463f7b458127209",
|
|
29
31
|
"src/components/not-found-paper-story.ts": "b7c02528ce58080662f0e55bc4a6b11c170fc987b3b5e377ff7c0db8f77ddf10",
|
|
30
32
|
"src/editor/AppleInputExample.vue": "b563cdcb1ec6b033a3a19878f68e7fe4cf39da9d3e838887b591b2364e1aad90",
|
|
@@ -118,6 +120,7 @@
|
|
|
118
120
|
"src/router/index.ts": "006cfb4d8d6b5daa9676cbf71210b321b13bde254feccd9428b7771366f245c2",
|
|
119
121
|
"src/style.css": "661cfb4c903fad83260644fe0b238830712cbfeb0b372a16589da89359fe1c5d",
|
|
120
122
|
"src/views/403.vue": "c47a321cfe5000c4e92e9e4264c4930ef9990671b378a3f7e742ab919d7e0d00",
|
|
123
|
+
"src/views/502.vue": "af2c2428ada9c2345d97d96f87b493ed22f71190efafbddcb9fdad3cb70a3b89",
|
|
121
124
|
"src/views/[...all].vue": "98797a9c353d390c7bf96da245feb9387e5e0cbec1a9f180ade457ae65c7484e",
|
|
122
125
|
"src/views/component-docs/[component].vue": "967673807de7264c663a87b96a2abd70b370dde102a4a030d153f1c012312dc9",
|
|
123
126
|
"src/views/components.vue": "3fd082b7621b010e9499d5274c183cf99df10dda67483efe90b3db14bf575485",
|
|
@@ -150,6 +153,8 @@
|
|
|
150
153
|
"src/components/UserMenu.vue": "playground/components/UserMenu.vue",
|
|
151
154
|
"src/components/forbidden-paper-scene.vue": "playground/components/forbidden-paper-scene.vue",
|
|
152
155
|
"src/components/forbidden-paper-story.ts": "playground/components/forbidden-paper-story.ts",
|
|
156
|
+
"src/components/gateway-paper-scene.vue": "playground/components/gateway-paper-scene.vue",
|
|
157
|
+
"src/components/gateway-paper-story.ts": "playground/components/gateway-paper-story.ts",
|
|
153
158
|
"src/components/not-found-paper-scene.vue": "playground/components/not-found-paper-scene.vue",
|
|
154
159
|
"src/components/not-found-paper-story.ts": "playground/components/not-found-paper-story.ts",
|
|
155
160
|
"src/editor/AppleInputExample.vue": "playground/editor/AppleInputExample.vue",
|
|
@@ -243,6 +248,7 @@
|
|
|
243
248
|
"src/router/index.ts": "playground/router/index.ts",
|
|
244
249
|
"src/style.css": "playground/style.css",
|
|
245
250
|
"src/views/403.vue": "playground/views/403.vue",
|
|
251
|
+
"src/views/502.vue": "playground/views/502.vue",
|
|
246
252
|
"src/views/[...all].vue": "playground/views/[...all].vue",
|
|
247
253
|
"src/views/component-docs/[component].vue": "playground/views/component-docs/[component].vue",
|
|
248
254
|
"src/views/components.vue": "playground/views/components.vue",
|
|
@@ -300,6 +306,8 @@
|
|
|
300
306
|
"playground/components/UserMenu.vue": "2822ea367cc8b5b8351fe2d1053ac24758e040df6a509e03f68ec8c3fc7e283d",
|
|
301
307
|
"playground/components/forbidden-paper-scene.vue": "a3ad3f3ff92a223a53fd5b08a5bea1a4be98cd2b035cfa64e70d69a6c6477c21",
|
|
302
308
|
"playground/components/forbidden-paper-story.ts": "b4c798ec04eda22ef4da235c9ffd57721777ceb043829dc76e4628112d8cfbf6",
|
|
309
|
+
"playground/components/gateway-paper-scene.vue": "7738aca72d96b01992dd84d38d983e44c3e919aa520ebbb9816c92cdcc4ce416",
|
|
310
|
+
"playground/components/gateway-paper-story.ts": "90deba7f3475bbe8b0ddab13a9f0671ba4f0f73176cbf584c4ae27d26f8de3c3",
|
|
303
311
|
"playground/components/not-found-paper-scene.vue": "39f12c23f04d72131d9da51e9a960894b621f2581c25e5b18463f7b458127209",
|
|
304
312
|
"playground/components/not-found-paper-story.ts": "b7c02528ce58080662f0e55bc4a6b11c170fc987b3b5e377ff7c0db8f77ddf10",
|
|
305
313
|
"playground/editor/AppleInputExample.vue": "b563cdcb1ec6b033a3a19878f68e7fe4cf39da9d3e838887b591b2364e1aad90",
|
|
@@ -393,6 +401,7 @@
|
|
|
393
401
|
"playground/router/index.ts": "006cfb4d8d6b5daa9676cbf71210b321b13bde254feccd9428b7771366f245c2",
|
|
394
402
|
"playground/style.css": "661cfb4c903fad83260644fe0b238830712cbfeb0b372a16589da89359fe1c5d",
|
|
395
403
|
"playground/views/403.vue": "c47a321cfe5000c4e92e9e4264c4930ef9990671b378a3f7e742ab919d7e0d00",
|
|
404
|
+
"playground/views/502.vue": "af2c2428ada9c2345d97d96f87b493ed22f71190efafbddcb9fdad3cb70a3b89",
|
|
396
405
|
"playground/views/[...all].vue": "98797a9c353d390c7bf96da245feb9387e5e0cbec1a9f180ade457ae65c7484e",
|
|
397
406
|
"playground/views/component-docs/[component].vue": "967673807de7264c663a87b96a2abd70b370dde102a4a030d153f1c012312dc9",
|
|
398
407
|
"playground/views/components.vue": "3fd082b7621b010e9499d5274c183cf99df10dda67483efe90b3db14bf575485",
|
|
@@ -416,7 +425,7 @@
|
|
|
416
425
|
"docs/PLAYGROUND-TEMPLATE.md": "e476d6622e89d8cb04d9acdd54c090e5d559d666bb49f266bcf36d3f3bf8fe67",
|
|
417
426
|
"docs/VALIDATION.md": "3c1755f4699d6b7d8febb44b2b0b00eb416b86559c26d8b69e46a1c98271af5f",
|
|
418
427
|
"README.md": "25b70a5feb2de4642940d6e25ec7e21b30ffb6efc726fbbe9c4aead234e90688",
|
|
419
|
-
"package.json": "
|
|
428
|
+
"package.json": "6f20057f8864f587890ccc0644fc21beb0752b410fdbb248f15c961bae9ea9b7",
|
|
420
429
|
"index.html": "75f6d93e3962ddca97a13b666a04d98ba9b263b6c288171383db764215034fea",
|
|
421
430
|
"vite.config.ts": "988aa18f3adf428ee3e82a41422bf76771d91b7fc3738ed36d731a497022f049",
|
|
422
431
|
"vite.lib.config.ts": "d7bc7e47f18ea4257eb1dafd8ed895f47cad8f756157cfa9a6e98b30086b1c72",
|
|
@@ -424,7 +433,7 @@
|
|
|
424
433
|
"tsconfig.lib.json": "c885806b003cee01192cddcaf32df3e7c6d369e645360398aa088c14b1c4792f",
|
|
425
434
|
"tooling/create-playground.mjs": "404227bb53b852f4c1ad8d8f406dab3cf3a89c53b5543bcd8c28234a2376ad44",
|
|
426
435
|
"tooling/npm-command.mjs": "51c08c53cd395e32ec9b71b258dafadcdad3e6b227090d5b7bfbe55b9d0a97ba",
|
|
427
|
-
"tooling/prepare-playground.mjs": "
|
|
436
|
+
"tooling/prepare-playground.mjs": "f49d7ca5ffecc4db79c0721974fd0f1877e515ccea377437a249bd7723fcd993",
|
|
428
437
|
"tooling/prepare-package.mjs": "a663ad0343bee2e711cdbc1c497daa89edc20752c67f17fc45d5173c6807b66b"
|
|
429
438
|
}
|
|
430
439
|
}
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<figure class="gateway-scene" :class="{ 'gateway-scene--dark': dark }">
|
|
3
|
+
<div class="gateway-scene__window">
|
|
4
|
+
<svg class="gateway-scene__art" ref="art" data-gateway-scene viewBox="0 0 1200 720" xmlns="http://www.w3.org/2000/svg" role="img" :aria-labelledby="`${uid}-title ${uid}-desc`">
|
|
5
|
+
<title :id="`${uid}-title`">青蛙与送往城镇的包裹</title>
|
|
6
|
+
<desc :id="`${uid}-desc`">飞虫带着包裹飞向城镇,守在城门里的青蛙伸出舌头,将飞虫和包裹一起吞下。</desc>
|
|
7
|
+
<defs>
|
|
8
|
+
<linearGradient :id="`${uid}-sky`" x1="0" y1="0" x2=".25" y2="1"><stop stop-color="var(--gateway-sky-top)"/><stop offset="1" stop-color="var(--gateway-sky)"/></linearGradient>
|
|
9
|
+
<linearGradient :id="`${uid}-stone`" x1="0" y1="0" x2=".8" y2="1"><stop stop-color="var(--gateway-stone)"/><stop offset="1" stop-color="var(--gateway-stone-shadow)"/></linearGradient>
|
|
10
|
+
<linearGradient :id="`${uid}-wood`" x1="0" y1="0" x2="1" y2=".3"><stop stop-color="#cc9969"/><stop offset="1" stop-color="#a77750"/></linearGradient>
|
|
11
|
+
<filter :id="`${uid}-shadow`" x="-25%" y="-25%" width="160%" height="165%"><feDropShadow dx="1.3" dy="5" stdDeviation="2.7" flood-color="#4b4031" flood-opacity=".16"/></filter>
|
|
12
|
+
<filter :id="`${uid}-soft`" x="-25%" y="-30%" width="160%" height="175%"><feDropShadow dx=".6" dy="2.2" stdDeviation="1.35" flood-color="#4b4031" flood-opacity=".15"/></filter>
|
|
13
|
+
<pattern :id="`${uid}-grain`" width="53" height="47" patternUnits="userSpaceOnUse"><path d="m5 8 .6-.2m27 13 .7-.4m13 15 .5-.2M16 40l.7-.2" stroke="#665236" stroke-width=".65" stroke-opacity=".1"/><path d="m12 15 1.3-.5m29-9 1-.4m-19 27 1.1-.4" stroke="#fff9e5" stroke-width=".8" stroke-opacity=".34"/></pattern>
|
|
14
|
+
<clipPath :id="`${uid}-frame`"><path d="M38 80Q38 40 80 36L1111 22Q1155 22 1162 71L1183 631Q1185 670 1139 682L87 704Q35 702 34 657Z"/></clipPath>
|
|
15
|
+
<g :id="`${uid}-pine`"><path d="M0-112-32-53-18-56-48-11-28-16-58 31H52L27-17 43-10 17-57 31-52Z" fill="currentColor"/><path d="M0-112V31H52L27-17 43-10 17-57 31-52Z" fill="#f6edcc" fill-opacity=".1"/><path d="M-2 18V49" stroke="currentColor" stroke-width="7"/></g>
|
|
16
|
+
<g :id="`${uid}-bush`"><path d="M-49 0-46-23-28-30-19-47 6-48 21-34 41-36 55-16 52 0Z" fill="currentColor"/><path d="m-19-47 7 24 33-11-15-14Z" fill="#e9dbb0" fill-opacity=".12"/></g>
|
|
17
|
+
</defs>
|
|
18
|
+
<path d="M47 92Q46 49 88 47L1120 33Q1167 35 1175 84L1194 642Q1196 686 1146 694L94 715Q44 713 44 665Z" fill="var(--gateway-frame-shadow)"/>
|
|
19
|
+
<g :clip-path="`url(#${uid}-frame)`">
|
|
20
|
+
<path d="M0 0H1200V720H0Z" :fill="`url(#${uid}-sky)`"/>
|
|
21
|
+
<g data-part="camera">
|
|
22
|
+
<circle cx="895" cy="143" r="48" fill="var(--gateway-sun)"/>
|
|
23
|
+
<path d="M-1200 348 14 293 178 217 330 298 461 203 635 312 802 265 981 308 1173 232 2400 348V1000H-1200Z" fill="var(--gateway-mountain-far)"/>
|
|
24
|
+
<path d="m178 217 152 81 131-95-92 116-128 12-91-52-145 63Z" fill="var(--gateway-mountain-fold)"/>
|
|
25
|
+
<path d="M-1500 416 56 357 203 330 360 382 499 324 639 373 810 338 1011 364 1230 306 2500 410V1100H-1500Z" fill="var(--gateway-mountain-near)"/>
|
|
26
|
+
<g color="var(--gateway-pine)"><use :href="`#${uid}-pine`" transform="translate(307 415) scale(.64)"/><use :href="`#${uid}-pine`" transform="translate(352 423) scale(.36)"/><use :href="`#${uid}-pine`" transform="translate(414 430) scale(.47)"/></g>
|
|
27
|
+
<path d="M-1600 467Q-100 388 183 425T680 430Q983 386 2800 436V1800H-1600Z" fill="var(--gateway-ground-back)"/>
|
|
28
|
+
<path d="M-1600 501Q18 441 267 459T738 465Q1000 441 2800 492V1800H-1600Z" fill="var(--gateway-ground)"/>
|
|
29
|
+
|
|
30
|
+
<g data-part="town-far">
|
|
31
|
+
<path d="M926 346V188l26-7v-19h24v18l29-3v-22h25v23l28 2v-20h23v24l19 3v165Z" fill="#b9b8a0"/>
|
|
32
|
+
<path d="m926 188 25 9 149 4v-14l-19-3v-24h-23v20l-28-2v-23h-25v22l-29 3v-18h-24v19Z" fill="#d1ccb2"/>
|
|
33
|
+
<path d="M926 188 950 198V349l-24-3Z" fill="#a5ac96"/>
|
|
34
|
+
<path d="M950 212h150m-150 39h150m-150 40h150m-120-78v38m67-38v38m-35 1v40m63-40v40" stroke="#929a85" stroke-width="1.5" stroke-opacity=".25" fill="none"/>
|
|
35
|
+
<g fill="#7b8977"><path d="M975 226q0-11 8-11t8 11v17h-16Z"/><path d="M1036 225q0-11 8-11t8 11v17h-16Z"/><path d="M1005 280q0-11 8-11t8 11v19h-16Z"/></g>
|
|
36
|
+
<path d="M1083 341V249l25-5 27 8v97Z" fill="#b3b5a0"/>
|
|
37
|
+
<path d="m1075 251 33-58 35 61-34-6Z" fill="#8e9180"/>
|
|
38
|
+
<path d="m1108 193 35 61-34-6Z" fill="#a6a48d"/>
|
|
39
|
+
<path d="M899 372V276l18-6 21 7v103Z" fill="#c6c3a8"/>
|
|
40
|
+
<path d="m891 277 26-47 30 50-30-7Z" fill="#a39b85"/>
|
|
41
|
+
<path d="M1013 157v-31" stroke="#8a826c" stroke-width="2.3"/>
|
|
42
|
+
<g data-part="flag-keep"><path d="M1014 127q16-8 34 0l-7 8 7 8q-17-8-34 0Z" fill="#b8916d"/><path d="M1015 128q14-6 28-1" stroke="#d5b58a" stroke-width="1" fill="none"/></g>
|
|
43
|
+
</g>
|
|
44
|
+
|
|
45
|
+
<path d="M-1200 566Q25 492 351 506L674 512Q773 514 855 477L1035 420 1195 421 1230 464 1050 469Q902 517 816 549L675 570Q370 577 130 566L-1200 645Z" fill="var(--gateway-road)"/>
|
|
46
|
+
<path d="M-1200 578Q25 505 351 518L674 524Q790 524 862 489L1042 435 1198 434" fill="none" stroke="var(--gateway-road-light)" stroke-width="3"/>
|
|
47
|
+
<path d="M-1200 645 130 566Q370 577 675 570L816 549Q902 517 1050 469l180-5" fill="none" stroke="var(--gateway-road-edge)" stroke-width="2"/>
|
|
48
|
+
<g fill="#c1b293"><path d="m794 529 38-10 27 3-43 11Z"/><path d="m863 506 30-10 28 1-33 12Z"/><path d="m936 479 28-10 26 0-33 12Z"/><path d="m1017 450 26-8 30 1-29 9Z"/></g>
|
|
49
|
+
|
|
50
|
+
<g data-part="town" :filter="`url(#${uid}-soft)`">
|
|
51
|
+
<path d="M799 427 793 337 839 300 885 336 888 432Z" fill="#dcccad"/>
|
|
52
|
+
<path d="M839 300 885 336 888 432 850 430 846 340Z" fill="#c3b294"/>
|
|
53
|
+
<path d="m780 340 58-51 67 51-24 6-43-37-46 39Z" fill="#ab795e"/>
|
|
54
|
+
<path d="m838 289 67 51-24 6-43-37Z" fill="#8b6351"/>
|
|
55
|
+
<path d="M803 337v88m33-111 3 114m-39-51 49 3m-47 18 45-1" stroke="#9d8768" stroke-width="4" fill="none"/>
|
|
56
|
+
<path d="M810 351h17v18h-17Z" fill="#7d8170"/><path d="M811 352h7v15h-7Z" fill="#e0cb94"/>
|
|
57
|
+
<path d="M815 427v-22q0-11 10-11t10 11v23Z" fill="#8c795f"/>
|
|
58
|
+
|
|
59
|
+
<path d="M916 401V315l39-21 47 23v86Z" fill="#d8c5a2"/>
|
|
60
|
+
<path d="M955 294 1002 317V403l-38-3Z" fill="#b7a388"/>
|
|
61
|
+
<path d="m902 320 51-67 60 67-57-12Z" fill="#a47159"/>
|
|
62
|
+
<path d="m953 253 60 67-57-12Z" fill="#bf9068"/>
|
|
63
|
+
<path d="M928 349q0-9 8-9t8 9v21h-16Z" fill="#847c65"/>
|
|
64
|
+
<path d="M931 348h5v19h-5Z" fill="#dfc994"/>
|
|
65
|
+
<path d="M976 344h13v24h-13Z" fill="#756e5d"/>
|
|
66
|
+
<path d="M954 257v-32" stroke="#88755b" stroke-width="2.5"/>
|
|
67
|
+
<g data-part="flag-town"><path d="M955 225q16-6 28 0l-6 6 6 7q-13-5-28 0Z" fill="#a36f56"/></g>
|
|
68
|
+
|
|
69
|
+
<path d="M1015 435 1012 351 1052 317 1109 350 1112 433Z" fill="#ddceb2"/>
|
|
70
|
+
<path d="M1052 317 1109 350 1112 433 1070 433l-6-80Z" fill="#c3b296"/>
|
|
71
|
+
<path d="m998 356 52-53 74 49-17 10-57-39-41 37Z" fill="#859183"/>
|
|
72
|
+
<path d="m1050 303 74 49-17 10-57-39Z" fill="#687b73"/>
|
|
73
|
+
<path d="M1022 359v71m33-104 5 107m-42-39 90-3m-87-24 29 14m28-15 24 21" stroke="#9d8c70" stroke-width="3.5" fill="none"/>
|
|
74
|
+
<path d="M1030 366h15v20h-15Zm47 0h14v20h-14Z" fill="#8f927a"/>
|
|
75
|
+
<path d="M1033 368h5v16h-5Z" fill="#ebd5a6"/>
|
|
76
|
+
<path d="M1032 433v-24q0-11 10-11t10 11v24Z" fill="#9f8967"/>
|
|
77
|
+
<path d="m1023 397 39-2 3 8-42 2Z" fill="#b49167"/>
|
|
78
|
+
<path d="m1039 313-1-21 12-1 1 14Z" fill="#b1a48c"/>
|
|
79
|
+
|
|
80
|
+
<path d="M878 455 876 378 919 349 960 379 964 452Z" fill="#ead9b6"/>
|
|
81
|
+
<path d="M919 349 960 379 964 452 926 454 925 381Z" fill="#c6b394"/>
|
|
82
|
+
<path d="m862 382 56-45 58 43-17 8-41-32-42 33Z" fill="#bc8c67"/>
|
|
83
|
+
<path d="m918 337 58 43-17 8-41-32Z" fill="#966d54"/>
|
|
84
|
+
<path d="M882 383h29v24h-29Z" fill="#878a71"/>
|
|
85
|
+
<path d="m896 384 1 22m-13-11h25" stroke="#d7c495" stroke-width="2"/>
|
|
86
|
+
<path d="M897 455v-28q0-11 10-11t10 11v27Z" fill="#9f8969"/>
|
|
87
|
+
<path d="M886 454v-22h5v22" fill="#c4b08b"/>
|
|
88
|
+
<path d="m881 419 40-3 5 9-45 2Z" fill="#8b987a"/>
|
|
89
|
+
</g>
|
|
90
|
+
<g color="#8b9b76"><use :href="`#${uid}-bush`" transform="translate(841 458) scale(.4)"/><use :href="`#${uid}-bush`" transform="translate(989 432) scale(.28)"/></g>
|
|
91
|
+
<g data-part="courtyard-tree" transform="translate(-24 0)" :filter="`url(#${uid}-soft)`">
|
|
92
|
+
<path d="m1124 461 4-75-19-24 5-9 20 23 6-39 10-1-4 45 19-14 8 4-24 25 2 63Z" fill="#a17a55"/>
|
|
93
|
+
<path d="m1093 369-5-28 20-27 27-9 31 10 20 25-5 32-24 19-33 2Z" fill="#8fa07b"/>
|
|
94
|
+
<path d="m1108 314 27-9 31 10 20 25-44 3-37 13-17-15Z" fill="#b4bb88"/>
|
|
95
|
+
<path d="m1142 343 44-3-5 32-24 19-15-22Z" fill="#a1ae7d"/>
|
|
96
|
+
</g>
|
|
97
|
+
|
|
98
|
+
<g data-part="tree" :filter="`url(#${uid}-shadow)`">
|
|
99
|
+
<path d="M139 500 150 405 149 332 114 300 82 290 65 263 80 254 113 278 145 291 139 212 177 205 185 314 216 276 235 242 251 245 241 285 193 350 200 423 211 498 178 510Z" :fill="`url(#${uid}-wood)`"/>
|
|
100
|
+
<path d="m174 206 11 108 31-38 19-34 16 3-10 40-48 65 7 73 11 75-25 5-10-90-7-109-8-93Z" fill="#966947"/>
|
|
101
|
+
<path d="m147 226 12 89 4 78-10 86m19-139 4 28m22-49 28-42m-80 42-26-29-34-16" stroke="#7c563d" stroke-width="2" fill="none" stroke-opacity=".46"/>
|
|
102
|
+
<path d="m151 415-5 73m13-260 8 54" stroke="#e6bd86" stroke-width="2" fill="none" stroke-opacity=".55"/>
|
|
103
|
+
<g data-part="canopy">
|
|
104
|
+
<path d="M77 304 42 269 45 212 75 170 119 160 142 121 193 110 236 139 254 178 290 199 302 242 282 285 239 301 213 329 162 333 124 312Z" fill="var(--gateway-canopy-dark)"/>
|
|
105
|
+
<path d="M45 212 75 170 119 160 155 189 140 235 100 256 42 269Z" fill="var(--gateway-canopy-edge)"/>
|
|
106
|
+
<path d="m119 160 23-39 51-11 43 29 18 39-47 23-52-12Z" fill="var(--gateway-canopy-light)"/>
|
|
107
|
+
<path d="m193 110 43 29 18 39-47 23-25-46Z" fill="var(--gateway-canopy-fold)"/>
|
|
108
|
+
<path d="m254 178 36 21 12 43-20 43-43 16-30-49-2-51Z" fill="var(--gateway-canopy-side)"/>
|
|
109
|
+
<path d="m140 235 15-46 52 12 2 51 30 49-26 28-51 4-38-21-47-8-35-35 58-13Z" fill="var(--gateway-canopy-mid)"/>
|
|
110
|
+
<path d="m140 235 69 17 30 49-26 28-51 4-38-21 22-31Z" fill="var(--gateway-canopy-front)"/>
|
|
111
|
+
<path d="m42 269 58-13 46 25-22 31-47-8Z" fill="var(--gateway-canopy-shadow)"/>
|
|
112
|
+
<path d="m75 170 61 24m6-73 40 34m57 146-30-49" stroke="#e9ddb4" stroke-width="1.5" stroke-opacity=".36" fill="none"/>
|
|
113
|
+
</g>
|
|
114
|
+
</g>
|
|
115
|
+
<g color="#8c9d71"><use :href="`#${uid}-bush`" transform="translate(110 506) scale(.54)"/><use :href="`#${uid}-bush`" transform="translate(247 495) scale(.35)"/></g>
|
|
116
|
+
<g color="#71896b"><use :href="`#${uid}-bush`" transform="translate(66 513) scale(.5)"/></g>
|
|
117
|
+
|
|
118
|
+
<path d="m479 546 280-8 51 21-301 11Z" fill="#8c866a" fill-opacity=".22"/>
|
|
119
|
+
<g data-part="gateway" :filter="`url(#${uid}-shadow)`">
|
|
120
|
+
<path d="M498 539 503 300 734 292 761 304 764 538Z" fill="#b2a78a"/>
|
|
121
|
+
<path d="M521 540 523 411Q525 345 587 331 653 317 702 352 733 375 733 415V539Z" fill="#7c8370"/>
|
|
122
|
+
<path d="M539 540V414Q540 359 591 345 647 333 693 365 714 383 715 416V541Z" fill="#8f977b"/>
|
|
123
|
+
<path d="M550 541V418Q550 371 596 356 650 345 690 378 706 395 706 420V543Z" fill="#9ca487"/>
|
|
124
|
+
<path d="m563 409 53-38 41 13 23 42v116H559Z" fill="#a5ad8c"/>
|
|
125
|
+
<path d="M531 503 722 496l12 45-211 0Z" fill="#b4b18f"/>
|
|
126
|
+
<path d="m552 501 47-3m72-2 35-1" stroke="#d2c9a4" stroke-width="1.4" fill="none"/>
|
|
127
|
+
<path d="M498 539 504 311 531 310 527 541Z" fill="#cbbb9b"/>
|
|
128
|
+
<path d="M734 302 761 304 764 538l-26 7Z" fill="#aa9b81"/>
|
|
129
|
+
<path d="M497 537 524 541l7-130q1-68 64-86 61-15 106 21 28 24 33 66l4 131 27-5-4-126q-3-81-65-110-63-31-121 0-71 32-74 107Z" :fill="`url(#${uid}-stone)`"/>
|
|
130
|
+
<path d="M525 539 529 412Q529 346 590 326 647 309 697 347 728 370 734 413l4 129" fill="none" stroke="#e3d2af" stroke-width="5"/>
|
|
131
|
+
<g fill="none" stroke="#a19176" stroke-width="1.6" stroke-opacity=".65"><path d="m499 459 28 1m-25-65 28 8m-17-54 28 12m6-52 24 25m22-38 12 29m43-31-4 28m47-15-12 26m43 4-21 18m38 21-27 12m33 64-28 2"/></g>
|
|
132
|
+
<path d="m485 302 26-19 250-6 29 18-3 36-298 7Z" fill="#a6977b"/>
|
|
133
|
+
<path d="M486 300v-33l29-2v-24l29-1v24l29-1v-25l31-1v24l31-1v-24l31-1v25l31-1v-23l30-1v23l30-1v-23l29-1v61l-4 26-296 7Z" fill="var(--gateway-stone-light)"/>
|
|
134
|
+
<path d="m486 300 296-7-4 19-292 9Z" fill="#beab8b"/>
|
|
135
|
+
<path d="m486 300 296-7" stroke="#ecddbc" stroke-width="2"/>
|
|
136
|
+
<path d="m515 241 11 8v16l-11 0m58-26 11 9v15l-11 0m62-26 11 9v15l-11 0m61-23 10 8v15l-10 0m60-22 11 9v49l-11-3" fill="#b6a286"/>
|
|
137
|
+
<path d="m573 285 111-3 10 29-124 3Z" fill="#ad8d64"/>
|
|
138
|
+
<path d="m574 282 108-3 10 29-124 3Z" fill="#e0c396"/>
|
|
139
|
+
<path d="m575 283 104-3m-107 28 115-3" stroke="#f6dfb5" stroke-width="1.2" fill="none"/>
|
|
140
|
+
<circle cx="578" cy="293" r="1.7" fill="#a48961"/><circle cx="679" cy="291" r="1.7" fill="#a48961"/>
|
|
141
|
+
<text x="628" y="302" font-family="Georgia, 'Times New Roman', serif" font-size="18" font-weight="600" text-anchor="middle" fill="#725a3d" letter-spacing=".5">gateway</text>
|
|
142
|
+
</g>
|
|
143
|
+
<g fill="#a6ad83"><path d="m477 548 22-2 13 6-37 6Z"/><path d="m756 538 24 0 18 12-41 5Z"/></g>
|
|
144
|
+
<g fill="#83976d"><path d="m483 545-6-19 11 12 2-24 7 24 11-11-7 19Z"/><path d="m771 542-5-19 10 14 7-25 3 27 12-14-8 23Z"/></g>
|
|
145
|
+
|
|
146
|
+
<g data-part="frog-root" transform="translate(636 539)">
|
|
147
|
+
<ellipse cx="0" cy="2" rx="91" ry="11" fill="#515b43" fill-opacity=".2"/>
|
|
148
|
+
<g data-part="frog-legs" :filter="`url(#${uid}-soft)`">
|
|
149
|
+
<path d="M-40-56C-60-74-89-57-89-36-89-14-66 1-38-5L-19-26Z" fill="#829c65"/>
|
|
150
|
+
<path d="M40-56C60-74 89-57 89-36 89-14 66 1 38-5L19-26Z" fill="#78935e"/>
|
|
151
|
+
<path d="M-44-54C-62-68-80-51-80-36L-71-19-52-15Z" fill="#9fb37a"/>
|
|
152
|
+
<path d="M45-54C63-67 80-50 80-36L72-23 52-16Z" fill="#92aa6e"/>
|
|
153
|
+
<path d="M-66-14C-83-15-96-6-89-1L-78 0C-76 7-67 8-64 2-60 9-51 8-48 1L-38-5-42-17Z" fill="#91a971"/>
|
|
154
|
+
<path d="M66-14C83-15 96-6 89-1L78 0C76 7 67 8 64 2 60 9 51 8 48 1L38-5 42-17Z" fill="#849e66"/>
|
|
155
|
+
</g>
|
|
156
|
+
<g data-part="frog-torso">
|
|
157
|
+
<path d="M-43-87C-69-64-67-22-47-9-27 7 25 7 47-9 69-26 64-70 40-88Z" fill="#91a96f"/>
|
|
158
|
+
<path d="M-39-80C-54-63-58-35-43-18-27-4 0 0 20-6-12 2-42-11-47-37-51-52-43-67-33-81Z" fill="#adc18a"/>
|
|
159
|
+
<path d="M-32-67C-48-49-46-23-27-12-11-2 16-3 32-14 49-28 44-51 30-68Z" fill="#e5d7ab"/>
|
|
160
|
+
<path d="M20-67C37-50 43-28 26-12L10-5Q23-5 32-14C49-28 44-51 30-68Z" fill="#d4c699"/>
|
|
161
|
+
<g data-part="frog-throat"><path d="M-28-68Q0-84 29-67L22-47Q0-37-23-48Z" fill="#eddfb7"/></g>
|
|
162
|
+
</g>
|
|
163
|
+
<g data-part="frog-head" :filter="`url(#${uid}-soft)`">
|
|
164
|
+
<path d="M-73-84C-90-96-88-119-70-129-75-150-59-168-42-165-25-165-16-151-15-143Q0-148 16-143C21-160 35-168 51-164 70-160 77-146 71-129 90-119 91-98 75-85 44-64-41-64-73-84Z" fill="#9eb77c"/>
|
|
165
|
+
<path d="M-70-129C-75-150-59-168-42-165-25-165-16-151-15-143Q0-148 16-143C21-160 35-168 51-164 66-160 73-151 73-140 64-154 53-158 42-156 31-154 24-143 22-135 4-140-13-140-23-133-24-149-33-157-45-156-59-154-65-145-65-131Z" fill="#bbcb92"/>
|
|
166
|
+
<path d="M-79-119C-86-102-73-91-51-85Q1-69 51-84 73-90 83-106C84-98 81-91 75-85 44-64-41-64-73-84-85-94-88-107-79-119Z" fill="#8ba46a"/>
|
|
167
|
+
<path d="M-58-102Q-49-107-42-102Q-49-94-58-98Z" fill="#c4b58a" fill-opacity=".6"/>
|
|
168
|
+
<path d="M44-102Q53-107 62-102Q54-95 46-98Z" fill="#c4b58a" fill-opacity=".6"/>
|
|
169
|
+
<g data-part="eye-left" transform="translate(-44 -140)">
|
|
170
|
+
<ellipse rx="17" ry="19" fill="#ecdfb9"/>
|
|
171
|
+
<g data-part="pupil-left"><ellipse rx="10.7" ry="13.2" fill="#3e4635"/><ellipse cx="-2.5" cy="-4.5" rx="3" ry="3.4" fill="#faf0d6"/><circle cx="3.4" cy="3.8" r="1.15" fill="#b2bd91"/></g>
|
|
172
|
+
</g>
|
|
173
|
+
<g data-part="eye-right" transform="translate(44 -140)">
|
|
174
|
+
<ellipse rx="17" ry="19" fill="#ecdfb9"/>
|
|
175
|
+
<g data-part="pupil-right"><ellipse rx="10.7" ry="13.2" fill="#3e4635"/><ellipse cx="-2.5" cy="-4.5" rx="3" ry="3.4" fill="#faf0d6"/><circle cx="3.4" cy="3.8" r="1.15" fill="#b2bd91"/></g>
|
|
176
|
+
</g>
|
|
177
|
+
<g fill="#71885a"><ellipse cx="-7" cy="-113" rx="1.8" ry="1.4"/><ellipse cx="7" cy="-113" rx="1.8" ry="1.4"/></g>
|
|
178
|
+
<path d="M-23-94Q0-84 24-94" data-part="mouth-closed" fill="none" stroke="#566f46" stroke-width="2.3" stroke-linecap="round"/>
|
|
179
|
+
<g data-part="mouth-open" display="none"><path data-part="mouth-cavity" d="M-20-96Q0-101 20-96Q22-77 0-77Q-22-77-20-96Z" fill="#52483b"/><path data-part="mouth-inner" d="M-13-82Q0-88 13-82L10-77H-10Z" fill="#b7796b"/></g>
|
|
180
|
+
</g>
|
|
181
|
+
<g data-part="frog-hands">
|
|
182
|
+
<path d="M-44-59Q-37-66-31-57L-24-18Q-11-11-15-4-19 0-25-4-27 7-34 4L-39-2Q-48 5-52-2L-49-12-53-43Z" fill="#a7bc80"/>
|
|
183
|
+
<path d="M44-59Q37-66 31-57L24-18Q11-11 15-4 19 0 25-4 27 7 34 4L39-2Q48 5 52-2L49-12 53-43Z" fill="#99b175"/>
|
|
184
|
+
<path d="M-46-48-40-17m86-31-6 31" stroke="#768f58" stroke-width="1.6" stroke-linecap="round" fill="none"/>
|
|
185
|
+
</g>
|
|
186
|
+
</g>
|
|
187
|
+
<g data-part="tongue" display="none">
|
|
188
|
+
<path data-part="tongue-edge" d="M636 449L636 449" fill="none" stroke="#a9685f" stroke-width="12" stroke-linecap="round"/>
|
|
189
|
+
<path data-part="tongue-fill" d="M636 448L636 448" fill="none" stroke="#d99686" stroke-width="8.2" stroke-linecap="round"/>
|
|
190
|
+
<path data-part="tongue-shine" d="M636 447L636 447" fill="none" stroke="#efbc9f" stroke-width="1.3" stroke-linecap="round"/>
|
|
191
|
+
<g data-part="tongue-tip"><ellipse rx="10.5" ry="7.5" fill="#d99686"/><path d="M-5-1Q0-5 5-1" stroke="#efbc9f" stroke-width="1.2" fill="none"/></g>
|
|
192
|
+
</g>
|
|
193
|
+
<ellipse data-part="bug-shadow" cx="0" cy="539" rx="20" ry="3" fill="#81785a" fill-opacity=".14"/>
|
|
194
|
+
<g data-part="bug" transform="translate(-180 400)">
|
|
195
|
+
<g data-part="bug-pitch">
|
|
196
|
+
<g data-part="wing-back" transform="rotate(12 -5 -8)"><path d="M-5-9C-23-28-16-48-4-49 10-49 13-30 2-9Z" fill="#c3d2ba"/><path d="M-5-14-3-41" stroke="#f8eed3" stroke-width="1.1" fill="none"/></g>
|
|
197
|
+
<path d="M-19 8-28 19m18-9-2 13m20-12 8 10" data-part="bug-legs" fill="none" stroke="#796b4d" stroke-width="2.5" stroke-linecap="round"/>
|
|
198
|
+
<path d="M-24-8C-21-21 3-25 14-12 25 2 15 16-2 16-21 15-28 5-24-8Z" fill="#c99e5f"/>
|
|
199
|
+
<path d="M-24-8C-21-21 3-25 14-12L8-6Q-5-18-24-8Z" fill="#e4c17e"/>
|
|
200
|
+
<path d="M-12-18Q-3-1-10 14m14-32Q14-3 5 16" stroke="#8d7753" stroke-width="5" fill="none"/>
|
|
201
|
+
<g data-part="bug-bag" transform="rotate(0 -22 -2)" :filter="`url(#${uid}-soft)`">
|
|
202
|
+
<path d="M-26-6Q-27-18-39-17-48-16-48-9" fill="none" stroke="#a07a50" stroke-width="3"/>
|
|
203
|
+
<path d="M-57-5Q-57-12-48-12L-28-10Q-21-9-22-1L-24 27Q-42 31-59 22Z" fill="#d5ac73"/>
|
|
204
|
+
<path d="M-57-5-58 22-49 26-47-9Z" fill="#bb8f5d"/>
|
|
205
|
+
<path d="M-57-7-29-8-24-2-27 5-55 3Z" fill="#e4c38c"/>
|
|
206
|
+
<path d="M-56 3-27 5" stroke="#b48b58" stroke-width="1"/>
|
|
207
|
+
<path d="m-50 24 20 2" stroke="#e9cc97" stroke-width="1"/>
|
|
208
|
+
<text x="-40" y="18" text-anchor="middle" font-family="Georgia, 'Times New Roman', serif" font-size="8.4" font-weight="600" fill="#725437">packet</text>
|
|
209
|
+
</g>
|
|
210
|
+
<g data-part="wing-front" transform="rotate(-20 -5 -9)"><path d="M-5-9C-29-18-41-43-28-50-12-59 4-32 0-11Z" fill="#e1e4ce"/><path d="M-7-15-25-44m17 20-15-3" stroke="#a4b9a5" stroke-width="1" fill="none"/></g>
|
|
211
|
+
<path d="M6-12C12-24 33-19 36-6 40 8 30 18 17 14 3 11-1-1 6-12Z" fill="#a4b17b"/>
|
|
212
|
+
<path d="M8-13Q20-24 31-13" stroke="#cad29b" stroke-width="2.3" fill="none" stroke-linecap="round"/>
|
|
213
|
+
<ellipse cx="26" cy="-4" rx="3" ry="3.9" fill="#3e4432"/><circle cx="26.8" cy="-5.2" r="1.1" fill="#faf0d5"/>
|
|
214
|
+
<path d="M30 6q3 1 4-1" fill="none" stroke="#6e7950" stroke-width="1.2" stroke-linecap="round"/>
|
|
215
|
+
<path d="M13-18q-6-13-13-12m24 13q2-14 10-17" fill="none" stroke="#74805b" stroke-width="2" stroke-linecap="round"/>
|
|
216
|
+
<circle cx="0" cy="-30" r="2.2" fill="#7c8860"/><circle cx="34" cy="-34" r="2.2" fill="#7c8860"/>
|
|
217
|
+
</g>
|
|
218
|
+
</g>
|
|
219
|
+
<g data-part="lip-root" transform="translate(636 539)"><g data-part="lip-head">
|
|
220
|
+
<path data-part="lip-front" d="M-23-94Q0-84 24-94" fill="none" stroke="#8ba46a" stroke-width="3" stroke-linecap="round"/>
|
|
221
|
+
</g></g>
|
|
222
|
+
|
|
223
|
+
<g fill="#aeaa83"><path d="m328 551 15-3 15 3-20 4Z"/><path d="m407 529 11-2 10 3-13 2Z"/><path d="m264 544 7-2 9 3-10 2Z"/></g>
|
|
224
|
+
<g fill="none" stroke="#d9cda8" stroke-width="1.7"><path d="m236 568 90 0m40-18 42 1m334 13 31-4"/></g>
|
|
225
|
+
<path d="M-1600 655Q10 570 192 599L355 659Q647 627 841 636L1196 584 2800 674V1800H-1600Z" fill="var(--gateway-foreground)"/>
|
|
226
|
+
<path d="M-1600 688Q24 621 167 634L291 689 922 682 1227 640 2800 740V1800H-1600Z" fill="var(--gateway-foreground-near)"/>
|
|
227
|
+
<g fill="#839767"><path d="m272 604-8-26 15 19 4-33 7 33 17-16-10 27Z"/><path d="m764 625-5-21 11 16 5-29 6 28 13-14-7 23Z"/><path d="m1077 590-8-26 14 19 5-35 7 35 16-20-9 29Z"/></g>
|
|
228
|
+
<g fill="#c9c694"><path d="m99 643-8-23 13 13 4-29 6 30 15-14-9 25Z"/></g>
|
|
229
|
+
<g color="#728a6a"><use :href="`#${uid}-bush`" transform="translate(1121 646) scale(.8)"/></g>
|
|
230
|
+
<path d="M-1600-1000H2800V1800H-1600Z" :fill="`url(#${uid}-grain)`" pointer-events="none"/>
|
|
231
|
+
</g>
|
|
232
|
+
</g>
|
|
233
|
+
<path d="M42 83 40 645Q40 682 85 681" fill="none" stroke="#fff8e0" stroke-width="2" stroke-opacity=".48"/>
|
|
234
|
+
</svg>
|
|
235
|
+
</div>
|
|
236
|
+
<button v-if="canAnimate" class="gateway-scene__pause" type="button" :aria-label="userPaused ? '继续动画' : '暂停动画'" @click="togglePause">
|
|
237
|
+
<Play v-if="userPaused" :size="12" aria-hidden="true" /><Pause v-else :size="12" aria-hidden="true" />
|
|
238
|
+
</button>
|
|
239
|
+
</figure>
|
|
240
|
+
</template>
|
|
241
|
+
|
|
242
|
+
<script setup lang="ts">
|
|
243
|
+
import { computed, nextTick, onBeforeUnmount, onMounted, ref, useId, watch } from 'vue'
|
|
244
|
+
import { Pause, Play } from 'lucide-vue-next'
|
|
245
|
+
import { useApple } from 'apptify'
|
|
246
|
+
import { resolveMotion } from 'apptify'
|
|
247
|
+
import { createGatewayStory, type GatewayStory } from './gateway-paper-story'
|
|
248
|
+
|
|
249
|
+
const uid = `gateway-${useId().replace(/:/g, '')}`
|
|
250
|
+
const apple = useApple()
|
|
251
|
+
const art = ref<SVGSVGElement>()
|
|
252
|
+
const dark = computed(() => apple.theme.value.current.scheme === 'dark')
|
|
253
|
+
const canAnimate = computed(() => resolveMotion('inherit', apple.motion.value.mode, apple.motion.value.reduced) === 'full')
|
|
254
|
+
const userPaused = ref(false)
|
|
255
|
+
let player: GatewayStory | undefined
|
|
256
|
+
let mounted = false
|
|
257
|
+
|
|
258
|
+
function togglePause() {
|
|
259
|
+
userPaused.value = !userPaused.value
|
|
260
|
+
if (userPaused.value) player?.pause()
|
|
261
|
+
else player?.play()
|
|
262
|
+
}
|
|
263
|
+
watch(canAnimate, enabled => { player?.setReducedMotion(!enabled) }, { flush: 'post' })
|
|
264
|
+
onMounted(async () => {
|
|
265
|
+
mounted = true
|
|
266
|
+
await nextTick()
|
|
267
|
+
if (mounted && art.value) player = createGatewayStory(art.value, !canAnimate.value)
|
|
268
|
+
})
|
|
269
|
+
onBeforeUnmount(() => { mounted = false; player?.dispose() })
|
|
270
|
+
</script>
|
|
271
|
+
|
|
272
|
+
<style scoped>
|
|
273
|
+
.gateway-scene {
|
|
274
|
+
--gateway-sky-top: #f4ead8;
|
|
275
|
+
--gateway-sky: #e5e2c9;
|
|
276
|
+
--gateway-frame-shadow: #d5ccba;
|
|
277
|
+
--gateway-sun: #fbf1cf;
|
|
278
|
+
--gateway-mountain-far: #d8d9bf;
|
|
279
|
+
--gateway-mountain-fold: #e5e0c5;
|
|
280
|
+
--gateway-mountain-near: #b9c3a5;
|
|
281
|
+
--gateway-pine: #92a184;
|
|
282
|
+
--gateway-ground-back: #aebb95;
|
|
283
|
+
--gateway-ground: #c4c79f;
|
|
284
|
+
--gateway-road: #d5c59e;
|
|
285
|
+
--gateway-road-light: #eadabd;
|
|
286
|
+
--gateway-road-edge: #b4ad87;
|
|
287
|
+
--gateway-foreground: #a7b28b;
|
|
288
|
+
--gateway-foreground-near: #819877;
|
|
289
|
+
--gateway-canopy-dark: #82936e;
|
|
290
|
+
--gateway-canopy-mid: #aab681;
|
|
291
|
+
--gateway-canopy-light: #bcc18a;
|
|
292
|
+
--gateway-canopy-fold: #a7b47c;
|
|
293
|
+
--gateway-canopy-edge: #a8b17a;
|
|
294
|
+
--gateway-canopy-side: #91a173;
|
|
295
|
+
--gateway-canopy-front: #bbc18b;
|
|
296
|
+
--gateway-canopy-shadow: #8a9b70;
|
|
297
|
+
--gateway-stone: #d4c4a4;
|
|
298
|
+
--gateway-stone-shadow: #b9aa8d;
|
|
299
|
+
--gateway-stone-light: #d6c5a2;
|
|
300
|
+
position: relative; min-width: 0; margin: 0;
|
|
301
|
+
}
|
|
302
|
+
.gateway-scene--dark {
|
|
303
|
+
--gateway-sky-top: #253536;
|
|
304
|
+
--gateway-sky: #354a47;
|
|
305
|
+
--gateway-frame-shadow: #121d1f;
|
|
306
|
+
--gateway-sun: #ddcd9d;
|
|
307
|
+
--gateway-mountain-far: #3a5149;
|
|
308
|
+
--gateway-mountain-fold: #3f5850;
|
|
309
|
+
--gateway-mountain-near: #466357;
|
|
310
|
+
--gateway-pine: #78917b;
|
|
311
|
+
--gateway-ground-back: #60795c;
|
|
312
|
+
--gateway-ground: #788462;
|
|
313
|
+
--gateway-road: #9c9d72;
|
|
314
|
+
--gateway-road-light: #c0b58a;
|
|
315
|
+
--gateway-road-edge: #727a57;
|
|
316
|
+
--gateway-foreground: #526c4b;
|
|
317
|
+
--gateway-foreground-near: #334e42;
|
|
318
|
+
--gateway-canopy-dark: #496549;
|
|
319
|
+
--gateway-canopy-mid: #738958;
|
|
320
|
+
--gateway-canopy-light: #94a66b;
|
|
321
|
+
--gateway-canopy-fold: #7d9662;
|
|
322
|
+
--gateway-canopy-edge: #81935a;
|
|
323
|
+
--gateway-canopy-side: #59764d;
|
|
324
|
+
--gateway-canopy-front: #8c9e65;
|
|
325
|
+
--gateway-canopy-shadow: #546f48;
|
|
326
|
+
--gateway-stone: #a49e7d;
|
|
327
|
+
--gateway-stone-shadow: #817f64;
|
|
328
|
+
--gateway-stone-light: #b0aa86;
|
|
329
|
+
}
|
|
330
|
+
.gateway-scene__window { overflow: hidden; padding: 4px; }
|
|
331
|
+
.gateway-scene__art { display: block; width: 100%; height: auto; overflow: visible; isolation: isolate; }
|
|
332
|
+
.gateway-scene__pause { position: absolute; right: 1.5%; bottom: -5px; width: 32px; height: 32px; padding: 0; display: grid; place-items: center; border: 0; border-radius: 50%; background: transparent; color: var(--apple-secondary); cursor: pointer; }
|
|
333
|
+
.gateway-scene__pause:hover { background: var(--apple-hover); }
|
|
334
|
+
.gateway-scene__pause:focus-visible { outline: 2px solid var(--apple-accent); outline-offset: 2px; }
|
|
335
|
+
@media (max-width: 880px) { .gateway-scene__window { margin-inline: -12px; } .gateway-scene__pause { right: -1%; } }
|
|
336
|
+
</style>
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
interface Point { x: number; y: number }
|
|
2
|
+
export interface GatewaySnapshot {
|
|
3
|
+
seconds: number
|
|
4
|
+
phase: number
|
|
5
|
+
intro: boolean
|
|
6
|
+
zoom: number
|
|
7
|
+
bug: Point & { angle: number; scale: number; visible: boolean; captured: boolean }
|
|
8
|
+
mouth: Point
|
|
9
|
+
tip: Point
|
|
10
|
+
tongueVisible: boolean
|
|
11
|
+
contact: number
|
|
12
|
+
shoot: number
|
|
13
|
+
retractEnd: number
|
|
14
|
+
period: number
|
|
15
|
+
introEnd: number
|
|
16
|
+
}
|
|
17
|
+
export interface GatewayStory {
|
|
18
|
+
seek(seconds: number): GatewaySnapshot
|
|
19
|
+
play(): void
|
|
20
|
+
pause(): void
|
|
21
|
+
getState(): GatewaySnapshot
|
|
22
|
+
setReducedMotion(value: boolean): void
|
|
23
|
+
dispose(): void
|
|
24
|
+
timing: Readonly<{ contact: number; shoot: number; retractEnd: number; period: number; introEnd: number; initialPhase: number; zoomStart: number }>
|
|
25
|
+
}
|
|
26
|
+
type GatewayArt = SVGSVGElement & { gatewayStory?: GatewayStory }
|
|
27
|
+
|
|
28
|
+
export function createGatewayStory(svg: GatewayArt, reducedMotion = false): GatewayStory {
|
|
29
|
+
const get = (name: string) => {
|
|
30
|
+
const el = svg.querySelector<SVGElement>(`[data-part="${name}"]`);
|
|
31
|
+
if (!el) throw new Error(`Missing gateway part: ${name}`);
|
|
32
|
+
return el;
|
|
33
|
+
};
|
|
34
|
+
const parts = Object.fromEntries([
|
|
35
|
+
'camera','bug','bug-pitch','bug-bag','bug-legs','wing-front','wing-back','bug-shadow',
|
|
36
|
+
'frog-torso','frog-head','frog-throat','eye-left','eye-right','pupil-left','pupil-right',
|
|
37
|
+
'mouth-closed','mouth-open','mouth-cavity','mouth-inner','lip-head','lip-front',
|
|
38
|
+
'tongue','tongue-edge','tongue-fill','tongue-shine','tongue-tip','flag-keep','flag-town'
|
|
39
|
+
].map(name => [name, get(name)]));
|
|
40
|
+
const clamp = (x: number, a=0, b=1) => Math.max(a, Math.min(b, x));
|
|
41
|
+
const mix = (a: number,b: number,t: number) => a+(b-a)*t;
|
|
42
|
+
const smooth = (x: number) => { x=clamp(x); return x*x*(3-2*x); };
|
|
43
|
+
const segment = (t: number,a: number,b: number) => smooth((t-a)/(b-a));
|
|
44
|
+
const pulse = (t: number,a: number,b: number) => t>a && t<b ? Math.sin(Math.PI*(t-a)/(b-a)) ** 2 : 0;
|
|
45
|
+
const attr = (name: string,key: string,value: string | number) => parts[name].setAttribute(key,String(value));
|
|
46
|
+
const show = (name: string, yes: boolean) => attr(name,'display',yes?'inline':'none');
|
|
47
|
+
const n = (x: number) => Number(x.toFixed(4));
|
|
48
|
+
const root = {x:636, y:539};
|
|
49
|
+
const speed=174, startX=-130, catchX=500;
|
|
50
|
+
const contact=(catchX-startX)/speed;
|
|
51
|
+
const shoot=contact-.155;
|
|
52
|
+
const retractEnd=contact+.37;
|
|
53
|
+
const period=4.85;
|
|
54
|
+
const initialPhase=1.25;
|
|
55
|
+
const zoomStart=retractEnd-initialPhase+.18;
|
|
56
|
+
const introEnd=zoomStart+1.55;
|
|
57
|
+
const flight = (t: number) => {
|
|
58
|
+
const x=startX+speed*t;
|
|
59
|
+
const y=408+11*Math.sin(x*.010+.6)+4*Math.sin(x*.032+.4)-.018*(x-400);
|
|
60
|
+
const dy=11*.010*Math.cos(x*.010+.6)+4*.032*Math.cos(x*.032+.4)-.018;
|
|
61
|
+
return {x,y,angle:Math.atan2(dy,1)*180/Math.PI*.48};
|
|
62
|
+
};
|
|
63
|
+
const hit=flight(contact);
|
|
64
|
+
const bezier = (a: number,b: number,c: number,d: number,t: number) => (1-t)**3*a+3*(1-t)**2*t*b+3*(1-t)*t*t*c+t**3*d;
|
|
65
|
+
let disposed=false, raf=0, clock=0, lastNow=0, userPaused=false;
|
|
66
|
+
let inView=true;
|
|
67
|
+
const reduce=window.matchMedia('(prefers-reduced-motion: reduce)');
|
|
68
|
+
let observer: IntersectionObserver | undefined;
|
|
69
|
+
let snapshot: GatewaySnapshot | undefined;
|
|
70
|
+
|
|
71
|
+
function render(seconds: number): GatewaySnapshot {
|
|
72
|
+
const intro=seconds<introEnd;
|
|
73
|
+
const t=intro ? Math.min(initialPhase+seconds,period-.01) : (seconds-introEnd)%period;
|
|
74
|
+
const anticipating=segment(t,shoot-.25,shoot)*(1-segment(t,shoot,shoot+.12));
|
|
75
|
+
const action=pulse(t,shoot,retractEnd+.10);
|
|
76
|
+
const gulp=pulse(t,retractEnd+.08,retractEnd+.42);
|
|
77
|
+
|
|
78
|
+
const hx=-3.5*action, hy=1.5*anticipating-1.5*action+.7*gulp;
|
|
79
|
+
const headAngle=-1.0*action;
|
|
80
|
+
const headTransform=`translate(${n(hx)} ${n(hy)}) rotate(${n(headAngle)} 0 -100)`;
|
|
81
|
+
attr('frog-head','transform',headTransform);
|
|
82
|
+
attr('lip-head','transform',headTransform);
|
|
83
|
+
attr('frog-torso','transform',`scale(${n(1+.008*anticipating)} ${n(1-.016*anticipating+.004*Math.sin(seconds*1.8))})`);
|
|
84
|
+
attr('frog-throat','transform',`translate(0 -57) scale(${n(1+.035*gulp)} ${n(1+.055*gulp)}) translate(0 57)`);
|
|
85
|
+
|
|
86
|
+
const rad=headAngle*Math.PI/180;
|
|
87
|
+
const localMouth={x:-2, y:-90};
|
|
88
|
+
const mouth={x:root.x+hx+localMouth.x*Math.cos(rad)-(localMouth.y+100)*Math.sin(rad),
|
|
89
|
+
y:root.y+hy-100+localMouth.x*Math.sin(rad)+(localMouth.y+100)*Math.cos(rad)};
|
|
90
|
+
let bug=flight(Math.min(t,contact)), scale=1, pitch=bug.angle, captured=false;
|
|
91
|
+
let tip={...mouth}, tongueVisible=false, retract=0;
|
|
92
|
+
if(t>=shoot && t<contact) {
|
|
93
|
+
const u=clamp((t-shoot)/(contact-shoot));
|
|
94
|
+
const extension=1-(1-u)**2;
|
|
95
|
+
tip={x:mix(mouth.x,hit.x,extension), y:mix(mouth.y,hit.y,extension)};
|
|
96
|
+
tongueVisible=true;
|
|
97
|
+
} else if(t>=contact && t<retractEnd) {
|
|
98
|
+
retract=clamp((t-contact)/(retractEnd-contact));
|
|
99
|
+
const u=retract;
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
bug={x:bezier(hit.x,hit.x+23,mouth.x-22,mouth.x,u),
|
|
103
|
+
y:bezier(hit.y,hit.y+2,mouth.y-12,mouth.y,u), angle:0};
|
|
104
|
+
scale=1-smooth((u-.79)/.21);
|
|
105
|
+
pitch=mix(hit.angle,20,smooth(u));
|
|
106
|
+
tip={x:bug.x,y:bug.y};
|
|
107
|
+
tongueVisible=true;
|
|
108
|
+
captured=true;
|
|
109
|
+
}
|
|
110
|
+
const visible=t<retractEnd && scale>.0001;
|
|
111
|
+
show('bug',visible);
|
|
112
|
+
|
|
113
|
+
if(visible) {
|
|
114
|
+
attr('bug','transform',`translate(${n(bug.x)} ${n(bug.y)}) scale(${n(scale)})`);
|
|
115
|
+
attr('bug-pitch','transform',`rotate(${n(pitch)})`);
|
|
116
|
+
}
|
|
117
|
+
const wing=2*Math.PI*11.3*seconds;
|
|
118
|
+
const flutter=captured?1.2:1;
|
|
119
|
+
attr('wing-front','transform',`translate(-5 -9) rotate(${n(-18+35*Math.sin(wing)*flutter)}) scale(1 ${n(.45+.55*Math.abs(Math.cos(wing)))}) translate(5 9)`);
|
|
120
|
+
attr('wing-back','transform',`translate(-5 -8) rotate(${n(18-33*Math.sin(wing+.9)*flutter)}) scale(1 ${n(.55+.45*Math.abs(Math.cos(wing+.9)))}) translate(5 8)`);
|
|
121
|
+
attr('bug-bag','transform',`rotate(${n(captured?-16*smooth(retract):5.5*Math.sin(seconds*5.1-.9)-3)} -22 -2)`);
|
|
122
|
+
attr('bug-legs','d',captured?'M-19 8-26 10m16 0-5 8m23-7 7 5':`M-19 8-28 ${n(18+2*Math.sin(seconds*8))}m18-8-2 13m20-12 8 10`);
|
|
123
|
+
show('bug-shadow',visible && !captured);
|
|
124
|
+
attr('bug-shadow','cx',n(bug.x));
|
|
125
|
+
attr('bug-shadow','rx',n(18+(bug.y-400)*.06));
|
|
126
|
+
|
|
127
|
+
const look=t<contact?clamp((bug.x-root.x)/120,-1,1):(1-segment(t,retractEnd,retractEnd+.55))*-.45;
|
|
128
|
+
const lookY=t<contact?clamp((bug.y-(root.y-140))/80,-1,1):.15;
|
|
129
|
+
for(const name of ['pupil-left','pupil-right']) attr(name,'transform',`translate(${n(look*3.8)} ${n(lookY*2)})`);
|
|
130
|
+
const blink=1-.94*Math.max(pulse(t,retractEnd+.12,retractEnd+.36),pulse(t,.53,.70));
|
|
131
|
+
attr('eye-left','transform',`translate(-44 -140) scale(1 ${n(blink)})`);
|
|
132
|
+
attr('eye-right','transform',`translate(44 -140) scale(1 ${n(blink)})`);
|
|
133
|
+
const opening=segment(t,shoot-.09,shoot+.035)*(1-segment(t,retractEnd-.015,retractEnd+.13));
|
|
134
|
+
const w=10+10*opening, bottom=-94+18*opening;
|
|
135
|
+
show('mouth-closed',opening<.03);
|
|
136
|
+
show('mouth-open',opening>=.03);
|
|
137
|
+
attr('mouth-cavity','d',`M${-w} -96Q0 ${n(-98-2*opening)} ${w} -96Q${n(w+1)} ${n(bottom)} 0 ${n(bottom)}Q${n(-w-1)} ${n(bottom)} ${-w} -96Z`);
|
|
138
|
+
attr('mouth-inner','d',`M${n(-12*opening)} ${n(bottom-2*opening)}Q0 ${n(bottom-7*opening)} ${n(12*opening)} ${n(bottom-2*opening)}Q0 ${n(bottom)} ${n(-12*opening)} ${n(bottom-2*opening)}Z`);
|
|
139
|
+
attr('lip-front','d',opening<.03?'M-24-92Q0-82 25-92':`M${n(-w-1)} ${n(bottom-5)}Q0 ${n(bottom+6)} ${n(w+1)} ${n(bottom-5)}`);
|
|
140
|
+
attr('lip-front','stroke-width',opening<.03?1.5:4.5);
|
|
141
|
+
show('tongue',tongueVisible);
|
|
142
|
+
if(tongueVisible) {
|
|
143
|
+
|
|
144
|
+
const length=Math.hypot(tip.x-mouth.x,tip.y-mouth.y);
|
|
145
|
+
const bend=Math.min(7,length*.035)*(captured?Math.sin(retract*Math.PI):.45);
|
|
146
|
+
const path=(offset: number)=>`M${n(mouth.x)} ${n(mouth.y+offset)} Q${n((mouth.x+tip.x)/2)} ${n((mouth.y+tip.y)/2+bend+offset)} ${n(tip.x)} ${n(tip.y+offset)}`;
|
|
147
|
+
const thickness=clamp(length/14);
|
|
148
|
+
attr('tongue-edge','stroke-width',n(12*thickness)); attr('tongue-fill','stroke-width',n(8.2*thickness)); attr('tongue-shine','stroke-width',n(1.3*thickness));
|
|
149
|
+
attr('tongue-edge','d',path(thickness)); attr('tongue-fill','d',path(0)); attr('tongue-shine','d',path(-2.5*thickness));
|
|
150
|
+
attr('tongue-tip','transform',`translate(${n(tip.x)} ${n(tip.y)}) rotate(${n(Math.atan2(tip.y-mouth.y,tip.x-mouth.x)*180/Math.PI)}) scale(${n(Math.min(1,length/10))})`);
|
|
151
|
+
}
|
|
152
|
+
attr('flag-keep','transform',`translate(1014 127) skewY(${n(Math.sin(seconds*2)*2)}) translate(-1014 -127)`);
|
|
153
|
+
attr('flag-town','transform',`translate(955 225) skewY(${n(Math.sin(seconds*2+.8)*2)}) translate(-955 -225)`);
|
|
154
|
+
let zoom=1, focus={x:600,y:360};
|
|
155
|
+
if(intro) {
|
|
156
|
+
const out=segment(seconds,zoomStart,introEnd);
|
|
157
|
+
const focusBug=t<retractEnd?bug:mouth;
|
|
158
|
+
zoom=mix(3.05,1,out);
|
|
159
|
+
focus={x:mix(focusBug.x-8,600,out),y:mix(focusBug.y-13,360,out)};
|
|
160
|
+
}
|
|
161
|
+
attr('camera','transform',`translate(600 360) scale(${n(zoom)}) translate(${n(-focus.x)} ${n(-focus.y)})`);
|
|
162
|
+
svg.dataset.story=reduce.matches || reducedMotion ? "static" : intro ? "intro" : "loop";
|
|
163
|
+
snapshot={seconds,phase:t,intro,zoom,bug:{...bug,scale,visible,captured},mouth,tip,tongueVisible,contact,shoot,retractEnd,period,introEnd};
|
|
164
|
+
return snapshot;
|
|
165
|
+
}
|
|
166
|
+
const allowed=()=>!disposed&&!userPaused&&!document.hidden&&inView&&!reduce.matches&&!reducedMotion;
|
|
167
|
+
function stopRAF() { if(raf) cancelAnimationFrame(raf); raf=0; lastNow=0; }
|
|
168
|
+
function tick(now: number) {
|
|
169
|
+
raf=0; if(!allowed()) {lastNow=0;return;}
|
|
170
|
+
if(lastNow) clock+=Math.min((now-lastNow)/1000,.08);
|
|
171
|
+
lastNow=now; render(clock); raf=requestAnimationFrame(tick);
|
|
172
|
+
}
|
|
173
|
+
function sync() { svg.dataset.playing=String(allowed()); if(allowed()) {if(!raf) {lastNow=0;raf=requestAnimationFrame(tick);}} else stopRAF(); }
|
|
174
|
+
function motionChanged() {
|
|
175
|
+
if(reduce.matches || reducedMotion) {stopRAF();render(introEnd+2.7);sync();}
|
|
176
|
+
else {clock=Math.max(clock,introEnd);render(clock);sync();}
|
|
177
|
+
}
|
|
178
|
+
document.addEventListener('visibilitychange',sync);
|
|
179
|
+
reduce.addEventListener('change',motionChanged);
|
|
180
|
+
if('IntersectionObserver' in window) {
|
|
181
|
+
observer=new IntersectionObserver(entries=>{inView=entries[0]?.isIntersecting??true;sync();},{threshold:0});
|
|
182
|
+
observer.observe(svg);
|
|
183
|
+
}
|
|
184
|
+
if(reduce.matches || reducedMotion) render(introEnd+2.7); else render(0);
|
|
185
|
+
const controller={
|
|
186
|
+
seek(seconds: number){if(!Number.isFinite(seconds)||seconds<0) throw new RangeError('seconds must be finite and non-negative');userPaused=true;sync();clock=seconds;return render(clock);},
|
|
187
|
+
play(){userPaused=false;sync();},
|
|
188
|
+
pause(){userPaused=true;sync();},
|
|
189
|
+
getState(){return snapshot!;},
|
|
190
|
+
setReducedMotion(value: boolean){reducedMotion=value;motionChanged();},
|
|
191
|
+
dispose(){if(disposed)return;disposed=true;stopRAF();svg.dataset.playing="false";observer?.disconnect();document.removeEventListener('visibilitychange',sync);reduce.removeEventListener('change',motionChanged);delete svg.gatewayStory;},
|
|
192
|
+
timing:Object.freeze({contact,shoot,retractEnd,period,introEnd,initialPhase,zoomStart})
|
|
193
|
+
};
|
|
194
|
+
svg.gatewayStory=controller;
|
|
195
|
+
sync();
|
|
196
|
+
return controller;
|
|
197
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<main class="main-content paper-502-page">
|
|
3
|
+
<apple-card class="paper-502-card" shadow="none" zoom="none">
|
|
4
|
+
<template #title>
|
|
5
|
+
<div class="paper-502-heading">
|
|
6
|
+
<p class="paper-502-number" aria-hidden="true">502</p>
|
|
7
|
+
<h1>网关错误</h1>
|
|
8
|
+
</div>
|
|
9
|
+
</template>
|
|
10
|
+
<p class="paper-502-copy">包裹在城门口被拦住了。<br />服务暂时无法响应,请稍后再试。</p>
|
|
11
|
+
<div class="paper-502-actions">
|
|
12
|
+
<router-link v-slot="{ href, navigate }" :to="homePath" custom>
|
|
13
|
+
<apple-button :href="href" @click="navigate">返回首页</apple-button>
|
|
14
|
+
</router-link>
|
|
15
|
+
<apple-link as="button" @click="goBack"><ArrowLeft :size="16" aria-hidden="true" /> 返回上一页</apple-link>
|
|
16
|
+
</div>
|
|
17
|
+
</apple-card>
|
|
18
|
+
<GatewayPaperScene class="paper-502-illustration" />
|
|
19
|
+
</main>
|
|
20
|
+
</template>
|
|
21
|
+
|
|
22
|
+
<route lang="json">
|
|
23
|
+
{ "alias": "/error/502", "meta": { "title": "网关错误" } }
|
|
24
|
+
</route>
|
|
25
|
+
|
|
26
|
+
<script setup lang="ts">
|
|
27
|
+
import { ArrowLeft } from 'lucide-vue-next'
|
|
28
|
+
import { useRouter } from 'vue-router'
|
|
29
|
+
import GatewayPaperScene from '../components/gateway-paper-scene.vue'
|
|
30
|
+
|
|
31
|
+
const router = useRouter()
|
|
32
|
+
const homePath = router.getRoutes().some(page => page.path === '/') ? '/' : '/settings'
|
|
33
|
+
function goBack() {
|
|
34
|
+
if (typeof router.options.history.state.back === 'string') router.back()
|
|
35
|
+
else void router.push(homePath)
|
|
36
|
+
}
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<style scoped>
|
|
40
|
+
.paper-502-page { max-width: 1360px; display: grid; grid-template-columns: minmax(260px, .78fr) minmax(0, 1.65fr); align-content: center; align-items: center; column-gap: 16px; padding-top: 38px; padding-bottom: calc(38px + 64px); }
|
|
41
|
+
.paper-502-card { background: transparent; border: 0; overflow: visible; }
|
|
42
|
+
.paper-502-card :deep(.apple-card__body) { padding: 0 0 0 8px; }
|
|
43
|
+
.paper-502-card :deep(.apple-card__heading) { margin: 0; }
|
|
44
|
+
.paper-502-heading { width: 100%; }
|
|
45
|
+
.paper-502-number { color: var(--apple-text); font-family: Georgia, 'Times New Roman', serif; font-size: clamp(78px, 8.2vw, 118px); line-height: .9; letter-spacing: -.075em; margin: 0 0 28px; font-weight: 400; }
|
|
46
|
+
.paper-502-heading h1 { font-size: clamp(26px, 2.7vw, 35px); line-height: 1.35; letter-spacing: -.035em; font-weight: 600; margin: 0 0 17px; }
|
|
47
|
+
.paper-502-copy { font-size: 13px; line-height: 1.95; color: var(--apple-secondary); margin: 0; text-wrap: pretty; }
|
|
48
|
+
.paper-502-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 27px; }
|
|
49
|
+
.paper-502-actions .apple-link { font-size: 12px; padding-inline: 8px; color: var(--apple-secondary); }
|
|
50
|
+
.paper-502-illustration { min-width: 0; }
|
|
51
|
+
@media (max-width: 880px) {
|
|
52
|
+
.paper-502-page { grid-template-columns: minmax(0, 1fr); max-width: 680px; padding-top: 18px; }
|
|
53
|
+
.paper-502-illustration { grid-row: 1; }
|
|
54
|
+
.paper-502-card { margin-top: 26px; }
|
|
55
|
+
.paper-502-card :deep(.apple-card__body) { padding: 0; text-align: center; }
|
|
56
|
+
.paper-502-number { font-size: 70px; margin-bottom: 18px; }
|
|
57
|
+
.paper-502-heading h1 { font-size: 26px; margin-bottom: 12px; }
|
|
58
|
+
.paper-502-actions { justify-content: center; margin-top: 18px; }
|
|
59
|
+
}
|
|
60
|
+
@media (max-width: 420px) {
|
|
61
|
+
.paper-502-page { padding-inline: 18px; padding-top: 12px; }
|
|
62
|
+
.paper-502-copy { font-size: 12px; }
|
|
63
|
+
.paper-502-card { margin-top: 22px; }
|
|
64
|
+
}
|
|
65
|
+
</style>
|
|
@@ -50,7 +50,7 @@ async function adapt(directory) {
|
|
|
50
50
|
source = source.replace('to="/" aria-label="Apptify 首页"', ':to="homePath" aria-label="Apptify 首页"')
|
|
51
51
|
source = source.replace(navigationEnd, "].filter(item => router.getRoutes().some(page => page.path === item.href))\nconst homePath = navigation[0]?.href ?? '/'\n\nfunction navigate")
|
|
52
52
|
}
|
|
53
|
-
if (['[...all].vue', '403.vue'].some(view => path === join(output, 'src/views', view))) {
|
|
53
|
+
if (['[...all].vue', '403.vue', '502.vue'].some(view => path === join(output, 'src/views', view))) {
|
|
54
54
|
source = source.replace('to="/" custom', ':to="homePath" custom')
|
|
55
55
|
source = source.replace('const router = useRouter()', "const router = useRouter()\nconst homePath = router.getRoutes().some(page => page.path === '/') ? '/' : '/settings'")
|
|
56
56
|
source = source.replace("else void router.push('/')", 'else void router.push(homePath)')
|
|
@@ -92,7 +92,7 @@ await writeFile(join(output, 'gitignore'), 'node_modules/\ndist/\n.env.local\n')
|
|
|
92
92
|
await writeFile(join(output, 'README.md'), [
|
|
93
93
|
"# Apptify 应用模板",
|
|
94
94
|
"",
|
|
95
|
-
"可编辑的 Vue 应用,包含导航、账号表单、外观设置、403、404 与组件示例。建议 Node.js 22 或 24 LTS。",
|
|
95
|
+
"可编辑的 Vue 应用,包含导航、账号表单、外观设置、403、404、502 与组件示例。建议 Node.js 22 或 24 LTS。",
|
|
96
96
|
"",
|
|
97
97
|
"```sh",
|
|
98
98
|
"npm install",
|