pixel-daylight-switch-gsvegetable 2.0.0 → 2.2.0
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.ja.md +232 -0
- package/README.md +137 -648
- package/README.zh-CN.md +232 -0
- package/app.js +69 -8
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,505 +1,158 @@
|
|
|
1
1
|
# Pixel Daylight Switch
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
[](https://github.com/GSvegetable/pixel-daylight-switch/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/pixel-daylight-switch-gsvegetable)
|
|
5
|
+
[](LICENSE)
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
<a href="https://gsvegetable.github.io/pixel-daylight-switch/">Live Demo</a> ·
|
|
9
|
-
<a href="https://gsvegetable.github.io/pixel-daylight-switch/playground.html">Interactive Playground</a> ·
|
|
10
|
-
<a href="https://github.com/GSvegetable/pixel-daylight-switch/releases">Releases</a> ·
|
|
11
|
-
<a href="https://www.npmjs.com/package/pixel-daylight-switch-gsvegetable">NPM</a>
|
|
12
|
-
</p>
|
|
7
|
+
**Languages:** [English](README.md) · [简体中文](README.zh-CN.md) · [日本語](README.ja.md)
|
|
13
8
|
|
|
14
|
-
|
|
15
|
-
<img src="https://github.com/user-attachments/assets/f7f248a5-c39c-432c-92f6-73237abdfe6b" width="49%" alt="Pixel Daylight Switch in daytime" />
|
|
16
|
-
<img src="https://github.com/user-attachments/assets/b2e24e65-a378-4ac6-be7b-efd3070e4da8" width="49%" alt="Pixel Daylight Switch at night" />
|
|
17
|
-
</p>
|
|
9
|
+

|
|
18
10
|
|
|
19
|
-
|
|
20
|
-
<em>Drag the glass control. Watch a small world move from day to dusk to night.</em>
|
|
21
|
-
</p>
|
|
11
|
+
*A tiny animated world, held inside a refractive glass switch.*
|
|
22
12
|
|
|
23
|
-
|
|
13
|
+
Pixel Daylight Switch is a draggable day/night UI component. Move its glass control to travel between day, dusk and night while a miniature pixel-art world changes inside the lens. It uses vanilla JavaScript, WebGL2 and a Canvas 2D fallback, with no third-party runtime dependency.
|
|
24
14
|
|
|
25
|
-
|
|
15
|
+
**[Open the live demo](https://gsvegetable.github.io/pixel-daylight-switch/)** · **[Launch the parameter lab](https://gsvegetable.github.io/pixel-daylight-switch/playground.html)** · **[Install from npm](https://www.npmjs.com/package/pixel-daylight-switch-gsvegetable)**
|
|
26
16
|
|
|
27
|
-
##
|
|
17
|
+
## Start here
|
|
28
18
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
- **多实例**:同一页面可以放置多个独立开关。
|
|
57
|
-
- **轻量接入**:原生脚本无需构建工具或运行时依赖。
|
|
58
|
-
- **无障碍支持**:提供 switch 语义、键盘操作,并尊重减少动态效果偏好。
|
|
59
|
-
|
|
60
|
-
### 五种场景一览
|
|
61
|
-
|
|
62
|
-
<p align="center">
|
|
63
|
-
<img src="./assets/scene-gallery.png" alt="Pixel Daylight Switch — five pixel-art scenes: countryside, Japanese street, apartment, seaside, and mountain cabin" width="100%" />
|
|
64
|
-
</p>
|
|
65
|
-
|
|
66
|
-
## 快速开始
|
|
67
|
-
|
|
68
|
-
不使用 NPM,也不需要安装依赖。把容器和脚本放进 HTML:
|
|
19
|
+
| Goal | Direct link |
|
|
20
|
+
| --- | --- |
|
|
21
|
+
| Experience the switch | [Live demo](https://gsvegetable.github.io/pixel-daylight-switch/) |
|
|
22
|
+
| Customize scenes and visual behavior | [Interactive parameter lab](https://gsvegetable.github.io/pixel-daylight-switch/playground.html) |
|
|
23
|
+
| Inspect the component | [Preview page](https://gsvegetable.github.io/pixel-daylight-switch/preview.html) |
|
|
24
|
+
| Add it to a website with one script | [Embed loader source](embed.js) |
|
|
25
|
+
| Use it in a JavaScript project | [npm package](https://www.npmjs.com/package/pixel-daylight-switch-gsvegetable) |
|
|
26
|
+
| Read implementation details | [Runtime](app.js) · [Styles](style.css) |
|
|
27
|
+
| Download mobile builds | [Build notes and limitations](builds/README.md) · [GitHub Actions artifacts](https://github.com/GSvegetable/pixel-daylight-switch/actions/workflows/mobile-build.yml) |
|
|
28
|
+
| Check tests | [CI workflow](https://github.com/GSvegetable/pixel-daylight-switch/actions/workflows/ci.yml) |
|
|
29
|
+
| Review changes | [Changelog](CHANGELOG.md) |
|
|
30
|
+
| Report a bug | [Issue tracker](https://github.com/GSvegetable/pixel-daylight-switch/issues) |
|
|
31
|
+
|
|
32
|
+
## Features
|
|
33
|
+
|
|
34
|
+
- Five scenes: countryside, Japanese street, modern apartment, seaside lighthouse and mountain cabin.
|
|
35
|
+
- Refractive glass rendering with WebGL2 and a Canvas 2D fallback.
|
|
36
|
+
- Continuous drag interaction, tap/click switching and keyboard operation.
|
|
37
|
+
- Configurable motion, inertia, bounce, refraction, glass details, world speed, weather and scene.
|
|
38
|
+
- Multiple independent instances on one page.
|
|
39
|
+
- Switch semantics, live status announcements and `prefers-reduced-motion` support.
|
|
40
|
+
- `mount()` and `unmount()` lifecycle methods for dynamic applications.
|
|
41
|
+
- Rendering pauses when the document is hidden or the component is outside the viewport.
|
|
42
|
+
|
|
43
|
+
## Quick start — browser, no build step
|
|
44
|
+
|
|
45
|
+
Place a mount point on your page and load the runtime:
|
|
69
46
|
|
|
70
47
|
```html
|
|
71
|
-
<div data-ld-part="toggle-daylight"
|
|
72
|
-
|
|
73
|
-
<script
|
|
74
|
-
defer
|
|
75
|
-
src="https://gsvegetable.github.io/pixel-daylight-switch/app.js"
|
|
76
|
-
></script>
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
脚本会自动为每个匹配的容器创建 Canvas、交互按钮和状态播报元素。容器宽度会自适应父级,组件保持约 **1.6439:1** 的宽高比。
|
|
80
|
-
|
|
81
|
-
如果需要自行托管,可以下载仓库中的 `app.js`,将脚本地址替换为自己的静态资源地址。
|
|
82
|
-
|
|
83
|
-
## Android 与 iOS 应用
|
|
84
|
-
|
|
85
|
-
从 **v2.0.0** 开始,项目提供 Capacitor 原生应用构建路径。Web 版本继续独立运行;Android 与 iOS 使用同一份核心渲染器,不复制或重写场景、WebGL shader 和交互物理逻辑。
|
|
48
|
+
<div data-ld-part="toggle-daylight" style="width: min(100%, 800px);">
|
|
49
|
+
</div>
|
|
86
50
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
- **共享核心**:根目录的 `app.js` 与 `style.css` 是唯一渲染实现。
|
|
90
|
-
- **原生容器**:Capacitor 8 将同一套 Web 资源装入 Android WebView 和 iOS WKWebView。
|
|
91
|
-
- **移动外壳**:`mobile/` 只负责全屏布局、安全区域和移动端 viewport,不包含第二套场景引擎。
|
|
92
|
-
- **构建产物**:`mobile/www/` 由脚本生成并被 Git 忽略,避免提交重复的渲染资源。
|
|
93
|
-
|
|
94
|
-
### 环境要求
|
|
95
|
-
|
|
96
|
-
- Node.js 22+
|
|
97
|
-
- Android:Android Studio、Android SDK、JDK 21
|
|
98
|
-
- iOS:macOS、Xcode 26+;需要在 Mac 上构建和签名发布包
|
|
99
|
-
|
|
100
|
-
Capacitor 8 的平台最低版本为 Android 7.0(API 24)和 iOS 15。具体要求以 [Capacitor 环境文档](https://capacitorjs.com/docs/getting-started/environment-setup) 为准。
|
|
101
|
-
|
|
102
|
-
### 初始化原生工程
|
|
103
|
-
|
|
104
|
-
先安装依赖并生成 Web 资源:
|
|
105
|
-
|
|
106
|
-
```bash
|
|
107
|
-
npm install
|
|
108
|
-
npm run mobile:prepare
|
|
51
|
+
<script defer src="https://gsvegetable.github.io/pixel-daylight-switch/app.js"></script>
|
|
109
52
|
```
|
|
110
53
|
|
|
111
|
-
|
|
54
|
+
The browser runtime finds the mount point and creates the component UI. The host element needs a usable width.
|
|
112
55
|
|
|
113
|
-
|
|
114
|
-
npm run mobile:android:init
|
|
115
|
-
npm run mobile:ios:init
|
|
116
|
-
```
|
|
56
|
+
### Embed with one script
|
|
117
57
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
```bash
|
|
121
|
-
npm run mobile:android
|
|
122
|
-
npm run mobile:ios
|
|
123
|
-
```
|
|
58
|
+
For a self-inserting embed, add this script where you want the component to appear:
|
|
124
59
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
```bash
|
|
128
|
-
npm run mobile:open:android
|
|
129
|
-
npm run mobile:open:ios
|
|
60
|
+
```html
|
|
61
|
+
<script src="https://gsvegetable.github.io/pixel-daylight-switch/embed.js"></script>
|
|
130
62
|
```
|
|
131
63
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
### 自动构建
|
|
64
|
+
The loader inserts its own container, stylesheet and runtime. It currently creates one default instance with a fixed maximum display size; use the mount-point approach above when you need precise layout or custom attributes.
|
|
135
65
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
**发布边界:** App Store / Google Play 上架仍需要开发者账号、应用图标与商店素材、签名证书及隐私合规信息。此仓库的 CI 不会伪造签名或自动代表开发者提交商店。
|
|
139
|
-
|
|
140
|
-
## NPM 安装
|
|
66
|
+
## Install from npm
|
|
141
67
|
|
|
142
68
|
```bash
|
|
143
69
|
npm install pixel-daylight-switch-gsvegetable
|
|
144
70
|
```
|
|
145
71
|
|
|
146
|
-
|
|
72
|
+
**ES modules**
|
|
147
73
|
|
|
148
74
|
```js
|
|
149
75
|
import PixelDaylightSwitch from 'pixel-daylight-switch-gsvegetable';
|
|
150
76
|
|
|
151
|
-
const root = document.querySelector(
|
|
152
|
-
|
|
153
|
-
);
|
|
154
|
-
|
|
155
|
-
// 页面加载后动态创建的元素需要手动挂载
|
|
156
|
-
const destroy = PixelDaylightSwitch.mount(root);
|
|
77
|
+
const root = document.querySelector('[data-ld-part="toggle-daylight"]');
|
|
78
|
+
PixelDaylightSwitch.mount(root);
|
|
157
79
|
|
|
158
|
-
//
|
|
80
|
+
// Call before removing the root from the DOM.
|
|
159
81
|
PixelDaylightSwitch.unmount(root);
|
|
160
82
|
```
|
|
161
83
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
```js
|
|
165
|
-
import { mount, unmount } from 'pixel-daylight-switch-gsvegetable';
|
|
166
|
-
|
|
167
|
-
mount(root);
|
|
168
|
-
unmount(root);
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
### CommonJS
|
|
84
|
+
**CommonJS**
|
|
172
85
|
|
|
173
86
|
```js
|
|
174
87
|
const PixelDaylightSwitch = require('pixel-daylight-switch-gsvegetable');
|
|
175
|
-
|
|
176
|
-
PixelDaylightSwitch.mount(root);
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
包同时提供 ESM 和 CommonJS 入口。模块可以在 SSR 环境中导入;DOM 挂载只会在浏览器中执行。对于服务端渲染项目,请在客户端生命周期中调用 `mount()`。
|
|
180
|
-
|
|
181
|
-
## 框架集成
|
|
182
|
-
|
|
183
|
-
### React
|
|
184
|
-
|
|
185
|
-
```jsx
|
|
186
|
-
import { useEffect, useRef } from 'react';
|
|
187
|
-
import PixelDaylightSwitch from 'pixel-daylight-switch-gsvegetable';
|
|
188
|
-
|
|
189
|
-
export function DaylightSwitch() {
|
|
190
|
-
const rootRef = useRef(null);
|
|
191
|
-
|
|
192
|
-
useEffect(() => {
|
|
193
|
-
const root = rootRef.current;
|
|
194
|
-
if (!root) return;
|
|
195
|
-
|
|
196
|
-
PixelDaylightSwitch.mount(root);
|
|
197
|
-
return () => PixelDaylightSwitch.unmount(root);
|
|
198
|
-
}, []);
|
|
199
|
-
|
|
200
|
-
return <div ref={rootRef} data-ld-part="toggle-daylight" />;
|
|
201
|
-
}
|
|
202
88
|
```
|
|
203
89
|
|
|
204
|
-
|
|
90
|
+
The package exposes ESM and CommonJS entry points. Importing is safe in an SSR environment; call `mount()` only in a browser after the target element exists. The package's published file list is defined in [package.json](package.json).
|
|
205
91
|
|
|
206
|
-
|
|
207
|
-
<script setup>
|
|
208
|
-
import { ref, onMounted, onBeforeUnmount } from 'vue';
|
|
209
|
-
import PixelDaylightSwitch from 'pixel-daylight-switch-gsvegetable';
|
|
210
|
-
|
|
211
|
-
const root = ref(null);
|
|
92
|
+
## Configuration
|
|
212
93
|
|
|
213
|
-
|
|
214
|
-
PixelDaylightSwitch.mount(root.value);
|
|
215
|
-
});
|
|
94
|
+
Set optional attributes on the mount element. Defaults apply when an attribute is omitted or invalid.
|
|
216
95
|
|
|
217
|
-
|
|
218
|
-
PixelDaylightSwitch.unmount(root.value);
|
|
219
|
-
});
|
|
220
|
-
</script>
|
|
221
|
-
|
|
222
|
-
<template>
|
|
223
|
-
<div ref="root" data-ld-part="toggle-daylight"></div>
|
|
224
|
-
</template>
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
### Svelte
|
|
228
|
-
|
|
229
|
-
```svelte
|
|
230
|
-
<script>
|
|
231
|
-
import { onMount } from 'svelte';
|
|
232
|
-
import PixelDaylightSwitch from 'pixel-daylight-switch-gsvegetable';
|
|
233
|
-
|
|
234
|
-
let root;
|
|
235
|
-
|
|
236
|
-
onMount(() => {
|
|
237
|
-
PixelDaylightSwitch.mount(root);
|
|
238
|
-
return () => PixelDaylightSwitch.unmount(root);
|
|
239
|
-
});
|
|
240
|
-
</script>
|
|
241
|
-
|
|
242
|
-
<div bind:this={root} data-ld-part="toggle-daylight"></div>
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
> **生命周期原则:** 对于框架或路由动态创建的容器,在元素进入 DOM 后调用 `mount(element)`;在元素被移除前调用 `unmount(element)`。不要在同一个容器上重复创建自己的实例。
|
|
246
|
-
|
|
247
|
-
## 参数实验室 Playground
|
|
248
|
-
|
|
249
|
-
打开 [Pixel Daylight Playground](https://gsvegetable.github.io/pixel-daylight-switch/playground.html),可以在浏览器中试验组件配置。
|
|
250
|
-
|
|
251
|
-
- 拖动预览区中的开关,直接体验交互。
|
|
252
|
-
- 按运动反馈、玻璃光学、世界节奏和场景环境调整参数。
|
|
253
|
-
- 在五种像素场景之间切换。
|
|
254
|
-
- 选择天气、初始昼夜状态与世界时间倍率。
|
|
255
|
-
- 先调整参数,再点击「应用参数」更新预览。
|
|
256
|
-
- 复制生成的 HTML 配置,放入自己的项目。
|
|
257
|
-
|
|
258
|
-
Playground 是独立页面。它用于探索配置,不是组件运行时的依赖。
|
|
259
|
-
|
|
260
|
-
## 配置参数
|
|
261
|
-
|
|
262
|
-
所有配置都写在组件根元素的 HTML `data-*` 属性上。每个实例可以使用不同参数;未填写的参数使用默认值。
|
|
263
|
-
|
|
264
|
-
### 完整参数表
|
|
265
|
-
|
|
266
|
-
| HTML 属性 | 默认值 | 说明 |
|
|
96
|
+
| Attribute | Default | Description |
|
|
267
97
|
| --- | ---: | --- |
|
|
268
|
-
| `data-speed` | `9.5` |
|
|
269
|
-
| `data-refraction` | `1.24` |
|
|
270
|
-
| `data-bezel` | `0.046` |
|
|
271
|
-
| `data-start-night` | `false` |
|
|
272
|
-
| `data-friction` | `0.6` |
|
|
273
|
-
| `data-bounce` | `3.2` |
|
|
274
|
-
| `data-dispersion` | `0.05` |
|
|
275
|
-
| `data-shine` | `0.44` |
|
|
276
|
-
| `data-time-speed` | `1` |
|
|
277
|
-
| `data-weather` | `default` |
|
|
278
|
-
| `data-scene` | `countryside` |
|
|
279
|
-
|
|
280
|
-
### 场景选项
|
|
281
|
-
|
|
282
|
-
| 值 | 场景 |
|
|
283
|
-
| --- | --- |
|
|
284
|
-
| `countryside` | 乡村小屋(默认) |
|
|
285
|
-
| `japanese-street` | 日本街道 |
|
|
286
|
-
| `apartment` | 现代公寓 |
|
|
287
|
-
| `seaside` | 海边灯塔 |
|
|
288
|
-
| `mountain-cabin` | 山间木屋 |
|
|
98
|
+
| `data-speed` | `9.5` | Base response speed; greater than zero. |
|
|
99
|
+
| `data-refraction` | `1.24` | Glass lens refraction strength; greater than zero. |
|
|
100
|
+
| `data-bezel` | `0.046` | Relative glass-edge thickness; greater than zero. |
|
|
101
|
+
| `data-start-night` | `false` | Exact string `"true"` starts in night mode. |
|
|
102
|
+
| `data-friction` | `0.6` | Release inertia damping; clamped to `0.1–0.9`. |
|
|
103
|
+
| `data-bounce` | `3.2` | Edge rebound strength; clamped to `0–12`. |
|
|
104
|
+
| `data-dispersion` | `0.05` | RGB dispersion at the glass edge; clamped to `0–0.25`. |
|
|
105
|
+
| `data-shine` | `0.44` | Daylight glass highlight; clamped to `0–1.5`. |
|
|
106
|
+
| `data-time-speed` | `1` | World simulation speed; clamped to `0–8`. Set to `0` to freeze world motion. |
|
|
107
|
+
| `data-weather` | `default` | `default` or `snow`. Unknown values fall back to `default`. |
|
|
108
|
+
| `data-scene` | `countryside` | `countryside`, `japanese-street`, `apartment`, `seaside` or `mountain-cabin`. |
|
|
289
109
|
|
|
290
|
-
|
|
110
|
+
Example:
|
|
291
111
|
|
|
292
112
|
```html
|
|
293
113
|
<div
|
|
294
114
|
data-ld-part="toggle-daylight"
|
|
295
|
-
data-label="昼夜环境切换"
|
|
296
|
-
data-speed="12"
|
|
297
|
-
data-refraction="1.5"
|
|
298
|
-
data-bezel="0.05"
|
|
299
115
|
data-start-night="true"
|
|
300
|
-
data-
|
|
301
|
-
data-bounce="4.2"
|
|
302
|
-
data-dispersion="0.12"
|
|
303
|
-
data-shine="0.6"
|
|
304
|
-
data-time-speed="1.5"
|
|
116
|
+
data-scene="seaside"
|
|
305
117
|
data-weather="snow"
|
|
306
|
-
data-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
<script
|
|
310
|
-
defer
|
|
311
|
-
src="https://gsvegetable.github.io/pixel-daylight-switch/app.js"
|
|
312
|
-
></script>
|
|
118
|
+
data-time-speed="1.4"
|
|
119
|
+
data-refraction="1.3">
|
|
120
|
+
</div>
|
|
313
121
|
```
|
|
314
122
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
- 数值参数为空、不是有限数字或不符合正数要求时,会回退到默认值。
|
|
318
|
-
- `friction`、`bounce`、`dispersion`、`shine` 和 `time-speed` 会限制在表格所示范围内。
|
|
319
|
-
- 未知的 `weather` 值回退为 `default`。
|
|
320
|
-
- 未知的 `scene` 值回退为 `countryside`。
|
|
321
|
-
- `data-start-night` 只有值为字符串 `true` 时才启用。
|
|
322
|
-
|
|
323
|
-
## 交互与事件
|
|
324
|
-
|
|
325
|
-
### 用户交互
|
|
326
|
-
|
|
327
|
-
- **拖动**:连续控制昼夜进度。
|
|
328
|
-
- **点击**:在白天和夜晚之间切换。
|
|
329
|
-
- **键盘**:聚焦开关后可使用方向键操作。
|
|
330
|
-
- **无障碍**:交互按钮使用 `role="switch"` 与 `aria-checked`;状态变化通过 live region 播报。
|
|
331
|
-
- **减少动态效果**:尊重系统的 `prefers-reduced-motion` 设置。
|
|
332
|
-
|
|
333
|
-
### 读取昼夜进度
|
|
334
|
-
|
|
335
|
-
组件会在根元素上更新 CSS 自定义属性 `--night`:
|
|
336
|
-
|
|
337
|
-
- `0`:白天。
|
|
338
|
-
- `1`:夜晚。
|
|
339
|
-
- `0` 到 `1` 之间:昼夜过渡。
|
|
123
|
+
## Events and state
|
|
340
124
|
|
|
341
|
-
|
|
125
|
+
The root element exposes transition progress through the CSS custom property `--night`: `0` is day, `1` is night, and values between them represent the transition.
|
|
342
126
|
|
|
343
|
-
|
|
344
|
-
body {
|
|
345
|
-
background: color-mix(
|
|
346
|
-
in srgb,
|
|
347
|
-
#f5ecd9,
|
|
348
|
-
#1b2146 calc(var(--night, 0) * 100%)
|
|
349
|
-
);
|
|
350
|
-
}
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
### 监听状态事件
|
|
354
|
-
|
|
355
|
-
组件在昼夜状态发生变化时,会在组件根元素上派发可冒泡的 `daylight:change` 事件。事件的 `detail.night` 是布尔值。
|
|
127
|
+
When the committed day/night state changes, the root dispatches a bubbling, composed `daylight:change` event. `event.detail.night` is a boolean. It is not emitted on every animation frame.
|
|
356
128
|
|
|
357
129
|
```js
|
|
358
|
-
document.
|
|
359
|
-
document.documentElement.classList.toggle(
|
|
360
|
-
'dark',
|
|
361
|
-
event.detail.night
|
|
362
|
-
);
|
|
363
|
-
});
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
如果页面有多个实例,建议在单个根元素上监听,以区分具体是哪一个开关触发了事件:
|
|
130
|
+
const root = document.querySelector('[data-ld-part="toggle-daylight"]');
|
|
367
131
|
|
|
368
|
-
```js
|
|
369
132
|
root.addEventListener('daylight:change', (event) => {
|
|
370
|
-
console.log(
|
|
133
|
+
console.log(event.detail.night ? 'Night' : 'Day');
|
|
371
134
|
});
|
|
372
135
|
```
|
|
373
136
|
|
|
374
|
-
##
|
|
137
|
+
## Rendering, accessibility and performance
|
|
375
138
|
|
|
376
|
-
|
|
139
|
+
- WebGL2 renders the refractive lens; Canvas 2D is used if WebGL2 is unavailable or fails to initialize.
|
|
140
|
+
- The component scales its drawing surface to its container.
|
|
141
|
+
- Rendering pauses while the document is hidden or the component is outside the viewport.
|
|
142
|
+
- Keyboard and switch semantics are provided, with a live status announcement.
|
|
143
|
+
- The runtime respects the operating system's `prefers-reduced-motion` preference.
|
|
377
144
|
|
|
378
|
-
|
|
379
|
-
[data-ld-part="toggle-daylight"] {
|
|
380
|
-
--ld-bg: #f5ecd9;
|
|
381
|
-
--ld-surface: #8c9a62;
|
|
382
|
-
--ld-fg: #1b2146;
|
|
383
|
-
--ld-muted: #7f97b3;
|
|
384
|
-
--ld-accent: #efa02c;
|
|
385
|
-
--ld-radius: 9999px;
|
|
386
|
-
--ld-font: system-ui, sans-serif;
|
|
387
|
-
}
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
| CSS 变量 | 默认值 | 用途 |
|
|
391
|
-
| --- | --- | --- |
|
|
392
|
-
| `--ld-bg` | `#f5ecd9` | 背景调色输入 |
|
|
393
|
-
| `--ld-surface` | `#8c9a62` | 表面与场景调色输入 |
|
|
394
|
-
| `--ld-fg` | `#1b2146` | 前景颜色 |
|
|
395
|
-
| `--ld-muted` | `#7f97b3` | 次要颜色 |
|
|
396
|
-
| `--ld-accent` | `#efa02c` | 强调色与焦点颜色 |
|
|
397
|
-
| `--ld-radius` | `9999px` | 交互区域圆角 |
|
|
398
|
-
| `--ld-font` | `system-ui, sans-serif` | 组件字体 |
|
|
399
|
-
| `--ld-space` | `8px` | 焦点轮廓偏移相关尺寸 |
|
|
400
|
-
| `--ld-shadow` | `0 8px 24px rgb(27 33 70 / .2)` | 主题预留变量 |
|
|
401
|
-
| `--ld-motion` | `200ms` | 焦点轮廓过渡时长 |
|
|
145
|
+
Performance varies with browser, graphics hardware, device pixel ratio and the number of visible instances.
|
|
402
146
|
|
|
403
|
-
##
|
|
404
|
-
|
|
405
|
-
页面加载时,脚本会自动查找已有的 `[data-ld-part="toggle-daylight"]` 元素并挂载。对于之后动态创建的元素,调用公开 API:
|
|
406
|
-
|
|
407
|
-
```js
|
|
408
|
-
const root = document.createElement('div');
|
|
409
|
-
root.dataset.ldPart = 'toggle-daylight';
|
|
410
|
-
document.querySelector('#app').appendChild(root);
|
|
411
|
-
|
|
412
|
-
const destroy = PixelDaylightSwitch.mount(root);
|
|
413
|
-
|
|
414
|
-
// 需要移除时:
|
|
415
|
-
PixelDaylightSwitch.unmount(root);
|
|
416
|
-
root.remove();
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
`mount(element)` 对同一元素是幂等的:重复调用不会创建重复实例。成功挂载时会返回清理函数;如果挂载失败则返回 `null`。通常使用 `unmount(element)` 即可完成清理。
|
|
420
|
-
|
|
421
|
-
卸载会停止绘制并释放组件持有的事件监听器和观察器。它不会移除根元素本身。
|
|
422
|
-
|
|
423
|
-
## 渲染与兼容性
|
|
424
|
-
|
|
425
|
-
- **WebGL2**:用于绘制玻璃折射效果。
|
|
426
|
-
- **Canvas 2D**:WebGL2 不可用时作为渲染回退。
|
|
427
|
-
- **响应式布局**:组件保持固定宽高比,并随容器宽度缩放。
|
|
428
|
-
- **页面可见性**:页面隐藏或组件离开视口时,会暂停不必要的绘制。
|
|
429
|
-
- **减少动态效果**:支持系统减少动态效果偏好。
|
|
430
|
-
- **运行时依赖**:原生脚本不需要第三方运行时依赖。
|
|
431
|
-
|
|
432
|
-
组件需要现代浏览器提供 Canvas 2D;WebGL2 用于增强玻璃渲染体验。
|
|
433
|
-
|
|
434
|
-
## 项目目录结构
|
|
435
|
-
|
|
436
|
-
仓库采用轻量的原生 JavaScript 结构,无需前端打包工具。核心组件、演示页面、NPM 入口和自动化测试分别独立维护。
|
|
437
|
-
|
|
438
|
-
```text
|
|
439
|
-
pixel-daylight-switch/
|
|
440
|
-
├── assets/
|
|
441
|
-
│ └── scene-gallery.png # 五种像素场景总览图
|
|
442
|
-
├── mobile/
|
|
443
|
-
│ ├── index.html # Capacitor 原生应用入口
|
|
444
|
-
│ └── mobile.css # 移动端安全区域与全屏布局
|
|
445
|
-
├── scripts/
|
|
446
|
-
│ └── prepare-mobile.cjs # 生成 Capacitor Web 资源
|
|
447
|
-
├── .github/
|
|
448
|
-
│ └── workflows/
|
|
449
|
-
│ ├── ci.yml # Node.js 与 Chromium 持续集成
|
|
450
|
-
│ └── mobile-build.yml # Android / iOS 构建验证
|
|
451
|
-
│ └── npm-publish.yml # 通过 v* 标签触发 NPM 发布
|
|
452
|
-
├── capacitor.config.json # Capacitor 原生应用配置
|
|
453
|
-
├── tests/
|
|
454
|
-
│ ├── browser/
|
|
455
|
-
│ │ └── component.spec.cjs # Playwright 浏览器回归测试
|
|
456
|
-
│ ├── fixture.html # 浏览器测试页面
|
|
457
|
-
│ ├── package-smoke.cjs # 包入口与 SSR 冒烟测试
|
|
458
|
-
│ └── server.cjs # 本地测试静态服务器
|
|
459
|
-
├── app.js # 核心组件:渲染、交互与生命周期
|
|
460
|
-
├── embed.js # 独立嵌入入口
|
|
461
|
-
├── index.cjs # CommonJS 包入口
|
|
462
|
-
├── index.mjs # ESM 包入口
|
|
463
|
-
├── index.html # 主演示页面
|
|
464
|
-
├── preview.html # 预览页面
|
|
465
|
-
├── playground.html # 交互式参数实验室
|
|
466
|
-
├── style.css # 演示页面样式
|
|
467
|
-
├── package.json # NPM 元数据与脚本
|
|
468
|
-
├── playwright.config.cjs # Playwright 配置
|
|
469
|
-
├── CHANGELOG.md # 版本变更记录
|
|
470
|
-
├── LICENSE # Unlicense 许可证
|
|
471
|
-
├── llms.txt # 面向 AI 工具的项目说明
|
|
472
|
-
└── README.md # 项目文档
|
|
473
|
-
```
|
|
474
|
-
|
|
475
|
-
### 关键目录说明
|
|
476
|
-
|
|
477
|
-
- **`app.js`**:组件主体,包含昼夜状态、Canvas/WebGL 渲染、输入交互和实例生命周期管理。
|
|
478
|
-
- **`playground.html`**:可视化调整参数、切换场景并生成 HTML 配置。
|
|
479
|
-
- **`embed.js`**:面向嵌入式使用场景的入口脚本。
|
|
480
|
-
- **`tests/`**:包加载、SSR、挂载卸载、多实例、指针/触控和移动端回归测试。
|
|
481
|
-
- **`.github/workflows/`**:自动执行持续集成,并在版本标签触发时执行发布流程。
|
|
482
|
-
|
|
483
|
-
## 本地开发与测试
|
|
484
|
-
|
|
485
|
-
克隆项目:
|
|
147
|
+
## Development and tests
|
|
486
148
|
|
|
487
149
|
```bash
|
|
488
150
|
git clone https://github.com/GSvegetable/pixel-daylight-switch.git
|
|
489
151
|
cd pixel-daylight-switch
|
|
490
|
-
```
|
|
491
|
-
|
|
492
|
-
直接用浏览器打开 `index.html` 即可查看基础演示。项目无需打包构建。
|
|
493
|
-
|
|
494
|
-
### 自动化测试
|
|
495
|
-
|
|
496
|
-
运行包入口、CommonJS / ESM 和 SSR 安全检查:
|
|
497
|
-
|
|
498
|
-
```bash
|
|
499
152
|
npm test
|
|
500
153
|
```
|
|
501
154
|
|
|
502
|
-
|
|
155
|
+
Run the Chromium browser regression suite:
|
|
503
156
|
|
|
504
157
|
```bash
|
|
505
158
|
npm install --no-save @playwright/test@1.56.1
|
|
@@ -507,237 +160,73 @@ npx playwright install chromium
|
|
|
507
160
|
npm run test:browser
|
|
508
161
|
```
|
|
509
162
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
## 版本记录
|
|
513
|
-
|
|
514
|
-
### v1.3.1
|
|
515
|
-
|
|
516
|
-
- 修复组件卸载时主动销毁 WebGL context,导致同一 canvas/root 后续重新挂载可能异常的问题。
|
|
517
|
-
- 保留组件资源、事件监听器与观察器的清理,同时允许 canvas 在卸载后重新挂载。
|
|
518
|
-
- 增加 CommonJS、ESM、SSR、Node.js 18/20/22 和 Chromium 浏览器自动化检查。
|
|
519
|
-
- 增加重复挂载、多实例、指针交互、触控、移动端布局与监听器清理测试。
|
|
520
|
-
- 将浏览器回归纳入 NPM 发布前置检查。
|
|
521
|
-
|
|
522
|
-
### v1.3.0
|
|
523
|
-
|
|
524
|
-
- 新增日本街道、现代公寓、海边灯塔和山间木屋四种像素环境。
|
|
525
|
-
- 保留乡村小屋作为默认场景。
|
|
526
|
-
- Playground 支持切换场景并组合调整天气、昼夜和玻璃参数。
|
|
527
|
-
|
|
528
|
-
### v1.2.0
|
|
529
|
-
|
|
530
|
-
- 新增惯性阻尼、边缘回弹、玻璃色散和表面高光参数。
|
|
531
|
-
- 新增世界时间倍率与飘雪天气。
|
|
532
|
-
- 新增独立 Playground,支持参数分组、场景预设和 HTML 代码复制。
|
|
533
|
-
|
|
534
|
-
### v1.1.0
|
|
535
|
-
|
|
536
|
-
- 新增运动速度、镜片折射、外框厚度和初始夜晚状态配置。
|
|
537
|
-
|
|
538
|
-
### v1.0.0
|
|
539
|
-
|
|
540
|
-
- 首个公开版本。
|
|
541
|
-
|
|
542
|
-
详细记录见 [CHANGELOG.md](./CHANGELOG.md)。
|
|
543
|
-
|
|
544
|
-
## 许可证
|
|
545
|
-
|
|
546
|
-
本项目使用 [Unlicense](https://unlicense.org/) 公有领域协议。允许个人和商业用途,无需署名。
|
|
547
|
-
|
|
548
|
-
---
|
|
549
|
-
|
|
550
|
-
<a id="english"></a>
|
|
551
|
-
|
|
552
|
-
## English
|
|
553
|
-
|
|
554
|
-
**Pixel Daylight Switch** is a draggable day/night UI component with a tiny animated pixel world inside a refractive glass lens. Drag the control to move through daylight, dusk, and night.
|
|
555
|
-
|
|
556
|
-
### Features
|
|
557
|
-
|
|
558
|
-
- An animated pixel environment inside a glass switch.
|
|
559
|
-
- WebGL2 refraction rendering with a Canvas 2D fallback.
|
|
560
|
-
- Five scenes: countryside, Japanese street, modern apartment, seaside lighthouse, and mountain cabin.
|
|
561
|
-
- Continuous day/night transitions, pointer dragging, click, and keyboard interaction.
|
|
562
|
-
- Per-instance HTML data attributes for motion, optics, weather, and scene settings.
|
|
563
|
-
- Multiple independent instances on the same page.
|
|
564
|
-
- No runtime dependencies for the standalone script.
|
|
565
|
-
- Accessible switch semantics and reduced-motion support.
|
|
566
|
-
|
|
567
|
-
### Quick start
|
|
568
|
-
|
|
569
|
-
No package manager or build step is required:
|
|
570
|
-
|
|
571
|
-
```html
|
|
572
|
-
<div data-ld-part="toggle-daylight"></div>
|
|
573
|
-
|
|
574
|
-
<script
|
|
575
|
-
defer
|
|
576
|
-
src="https://gsvegetable.github.io/pixel-daylight-switch/app.js"
|
|
577
|
-
></script>
|
|
578
|
-
```
|
|
579
|
-
|
|
580
|
-
The script automatically mounts matching elements. It creates the internal canvas, interaction button, and live status region. The component scales with its container and keeps an aspect ratio of approximately **1.6439:1**.
|
|
581
|
-
|
|
582
|
-
### NPM
|
|
583
|
-
|
|
584
|
-
```bash
|
|
585
|
-
npm install pixel-daylight-switch-gsvegetable
|
|
586
|
-
```
|
|
587
|
-
|
|
588
|
-
ESM:
|
|
589
|
-
|
|
590
|
-
```js
|
|
591
|
-
import PixelDaylightSwitch from 'pixel-daylight-switch-gsvegetable';
|
|
592
|
-
|
|
593
|
-
const root = document.querySelector('[data-ld-part="toggle-daylight"]');
|
|
594
|
-
PixelDaylightSwitch.mount(root);
|
|
595
|
-
|
|
596
|
-
// Before removing the element:
|
|
597
|
-
PixelDaylightSwitch.unmount(root);
|
|
598
|
-
```
|
|
599
|
-
|
|
600
|
-
CommonJS:
|
|
601
|
-
|
|
602
|
-
```js
|
|
603
|
-
const PixelDaylightSwitch = require('pixel-daylight-switch-gsvegetable');
|
|
604
|
-
```
|
|
605
|
-
|
|
606
|
-
The package provides ESM and CommonJS entry points and is safe to import in SSR environments. Call `mount()` only after the element exists in the browser.
|
|
607
|
-
|
|
608
|
-
### Framework integration
|
|
163
|
+
GitHub Actions runs package and SSR checks on Node.js 18, 20 and 22, plus Chromium interaction and mobile regression tests. See [current workflow runs](https://github.com/GSvegetable/pixel-daylight-switch/actions/workflows/ci.yml).
|
|
609
164
|
|
|
610
|
-
|
|
165
|
+
## Android and iOS
|
|
611
166
|
|
|
612
|
-
|
|
167
|
+
The Capacitor app includes a native-friendly control surface for all five worlds (countryside, Japanese street, apartment, seaside and mountain cabin), plus an optional snowfall effect. Scene and weather changes reuse the shared renderer; the glass shader and day/night interaction remain the same. The app shell detects English, Simplified Chinese and Japanese from the device language. Its layout adapts to portrait and landscape: portrait keeps the switch and controls in a vertical flow, while wider landscape screens place the switch beside the scene and weather controls; compact landscape phones use a denser single-column layout. GitHub Actions produces an Android debug APK and an unsigned iOS Simulator archive. These are development artifacts, not store-ready releases: the Android APK is not a Play Store release, and the iOS Simulator build cannot be installed on a physical iPhone or iPad. See [mobile build notes](builds/README.md) and the [mobile workflow](https://github.com/GSvegetable/pixel-daylight-switch/actions/workflows/mobile-build.yml).
|
|
613
168
|
|
|
614
|
-
Use the [Interactive Playground](https://gsvegetable.github.io/pixel-daylight-switch/playground.html) to adjust motion, glass optics, world speed, weather, and scenes. Apply settings to the preview and copy the generated HTML.
|
|
615
169
|
|
|
616
|
-
### Configuration
|
|
617
170
|
|
|
618
|
-
|
|
171
|
+
### Embed in a web page
|
|
619
172
|
|
|
620
|
-
|
|
621
|
-
| --- | ---: | --- |
|
|
622
|
-
| `data-speed` | `9.5` | Base motion response speed; positive number. |
|
|
623
|
-
| `data-refraction` | `1.24` | Glass lens refraction strength; positive number. |
|
|
624
|
-
| `data-bezel` | `0.046` | Glass edge thickness ratio; positive number. |
|
|
625
|
-
| `data-start-night` | `false` | Start at night when exactly `true`. |
|
|
626
|
-
| `data-friction` | `0.6` | Release inertia damping, clamped to `0.1–0.9`. |
|
|
627
|
-
| `data-bounce` | `3.2` | Edge rebound, clamped to `0–12`. |
|
|
628
|
-
| `data-dispersion` | `0.05` | RGB edge dispersion, clamped to `0–0.25`. |
|
|
629
|
-
| `data-shine` | `0.44` | Daytime highlight intensity, clamped to `0–1.5`. |
|
|
630
|
-
| `data-time-speed` | `1` | World simulation speed, clamped to `0–8`; zero freezes world dynamics. |
|
|
631
|
-
| `data-weather` | `default` | `default` or `snow`. Unknown values use `default`. |
|
|
632
|
-
| `data-scene` | `countryside` | `countryside`, `japanese-street`, `apartment`, `seaside`, or `mountain-cabin`. |
|
|
633
|
-
|
|
634
|
-
Example:
|
|
173
|
+
For one basic day/night switch, no package installation is required. Paste this single line into your HTML:
|
|
635
174
|
|
|
636
175
|
```html
|
|
637
|
-
<
|
|
638
|
-
data-ld-part="toggle-daylight"
|
|
639
|
-
data-label="Day and night switch"
|
|
640
|
-
data-speed="12"
|
|
641
|
-
data-refraction="1.5"
|
|
642
|
-
data-bezel="0.05"
|
|
643
|
-
data-start-night="true"
|
|
644
|
-
data-friction="0.45"
|
|
645
|
-
data-bounce="4.2"
|
|
646
|
-
data-dispersion="0.12"
|
|
647
|
-
data-shine="0.6"
|
|
648
|
-
data-time-speed="1.5"
|
|
649
|
-
data-weather="snow"
|
|
650
|
-
data-scene="mountain-cabin"
|
|
651
|
-
></div>
|
|
652
|
-
```
|
|
653
|
-
|
|
654
|
-
Invalid numeric values fall back to defaults. Range-limited values are clamped. Unknown weather and scene values fall back to `default` and `countryside`, respectively.
|
|
655
|
-
|
|
656
|
-
### Events and page theme
|
|
657
|
-
|
|
658
|
-
The component updates `--night` on its root element: `0` means day, `1` means night, and values in between represent the transition.
|
|
659
|
-
|
|
660
|
-
It also dispatches a bubbling, composed `daylight:change` event from the component root when the day/night state changes. `event.detail.night` is a boolean:
|
|
661
|
-
|
|
662
|
-
```js
|
|
663
|
-
root.addEventListener('daylight:change', (event) => {
|
|
664
|
-
document.documentElement.classList.toggle('dark', event.detail.night);
|
|
665
|
-
});
|
|
666
|
-
```
|
|
667
|
-
|
|
668
|
-
### Theme customization
|
|
669
|
-
|
|
670
|
-
Override these CSS variables on the component root:
|
|
671
|
-
|
|
672
|
-
```css
|
|
673
|
-
[data-ld-part="toggle-daylight"] {
|
|
674
|
-
--ld-bg: #f5ecd9;
|
|
675
|
-
--ld-surface: #8c9a62;
|
|
676
|
-
--ld-fg: #1b2146;
|
|
677
|
-
--ld-muted: #7f97b3;
|
|
678
|
-
--ld-accent: #efa02c;
|
|
679
|
-
--ld-radius: 9999px;
|
|
680
|
-
--ld-font: system-ui, sans-serif;
|
|
681
|
-
}
|
|
682
|
-
```
|
|
683
|
-
|
|
684
|
-
Supported variables: `--ld-bg`, `--ld-surface`, `--ld-fg`, `--ld-muted`, `--ld-accent`, `--ld-radius`, `--ld-font`, `--ld-space`, `--ld-shadow`, and `--ld-motion`.
|
|
685
|
-
|
|
686
|
-
### Mounting and cleanup
|
|
687
|
-
|
|
688
|
-
Elements present when the script loads are mounted automatically. For elements created later:
|
|
689
|
-
|
|
690
|
-
```js
|
|
691
|
-
const destroy = PixelDaylightSwitch.mount(element);
|
|
692
|
-
|
|
693
|
-
// Before removing the root:
|
|
694
|
-
PixelDaylightSwitch.unmount(element);
|
|
695
|
-
element.remove();
|
|
176
|
+
<script src="https://gsvegetable.github.io/pixel-daylight-switch/embed.js"></script>
|
|
696
177
|
```
|
|
697
178
|
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
### Rendering and browser behavior
|
|
179
|
+
The loader injects its styles and one default-scene switch. For custom scenes, weather, multiple instances or full control over placement, use the npm API above and its `data-scene` / `data-weather` attributes.
|
|
701
180
|
|
|
702
|
-
|
|
703
|
-
- Canvas 2D is the rendering fallback when WebGL2 is unavailable.
|
|
704
|
-
- The component respects `prefers-reduced-motion`.
|
|
705
|
-
- Unnecessary drawing pauses when the page is hidden or the component is offscreen.
|
|
706
|
-
- The standalone runtime has no third-party dependencies.
|
|
181
|
+
### Integrate with your own Android / iOS Capacitor app
|
|
707
182
|
|
|
708
|
-
|
|
183
|
+
This repository currently ships a **Capacitor app template and build scripts**, not a separately installable native UI plugin. For an existing Capacitor 8 project, integrate this repository's `mobile/`, `app.js`, `style.css` and `scripts/prepare-mobile.cjs`, then run:
|
|
709
184
|
|
|
710
185
|
```bash
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
Open `index.html` in a modern browser. No build step is required.
|
|
716
|
-
|
|
717
|
-
Run package and SSR checks:
|
|
718
|
-
|
|
719
|
-
```bash
|
|
720
|
-
npm test
|
|
721
|
-
```
|
|
722
|
-
|
|
723
|
-
Run browser regression tests after installing Playwright and Chromium:
|
|
724
|
-
|
|
725
|
-
```bash
|
|
726
|
-
npm install --no-save @playwright/test@1.56.1
|
|
727
|
-
npx playwright install chromium
|
|
728
|
-
npm run test:browser
|
|
186
|
+
npm install
|
|
187
|
+
npm run mobile:prepare
|
|
188
|
+
npm run mobile:android:init # first-time Android project creation
|
|
189
|
+
npm run mobile:android # sync subsequent updates
|
|
729
190
|
```
|
|
730
191
|
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
- **v1.3.1** — lifecycle/remount stability fix and expanded automated regression coverage.
|
|
734
|
-
- **v1.3.0** — four additional pixel environments and scene selection in Playground.
|
|
735
|
-
- **v1.2.0** — motion, optics, world-speed, weather settings, and the standalone Playground.
|
|
736
|
-
- **v1.1.0** — initial HTML configuration options.
|
|
737
|
-
- **v1.0.0** — first public release.
|
|
192
|
+
For iOS, use `npm run mobile:ios:init` once and `npm run mobile:ios` for later syncs; macOS and Xcode are required. Open the native projects with `npm run mobile:open:android` or `npm run mobile:open:ios`. See [package.json](package.json) for the exact scripts.
|
|
738
193
|
|
|
739
|
-
|
|
194
|
+
## Repository map
|
|
740
195
|
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
196
|
+
```text
|
|
197
|
+
pixel-daylight-switch/
|
|
198
|
+
├── .github/workflows/ # CI, native mobile builds, npm publishing
|
|
199
|
+
├── assets/
|
|
200
|
+
│ └── scene-gallery.png # Five-scene overview image
|
|
201
|
+
├── builds/
|
|
202
|
+
│ └── README.md # Mobile artifact notes; binaries are workflow outputs
|
|
203
|
+
├── mobile/
|
|
204
|
+
│ ├── index.html # Capacitor app entry
|
|
205
|
+
│ └── mobile.css # Mobile-only layout
|
|
206
|
+
├── scripts/
|
|
207
|
+
│ └── prepare-mobile.cjs # Prepare the shared web runtime for Capacitor
|
|
208
|
+
├── tests/
|
|
209
|
+
│ ├── browser/ # Playwright interaction and mobile regressions
|
|
210
|
+
│ ├── fixture.html
|
|
211
|
+
│ ├── mobile-smoke.cjs
|
|
212
|
+
│ ├── package-smoke.cjs
|
|
213
|
+
│ └── server.cjs
|
|
214
|
+
├── app.js # Component runtime, scenes, input and rendering
|
|
215
|
+
├── style.css # Component styles
|
|
216
|
+
├── embed.js # One-script website embed loader
|
|
217
|
+
├── index.html # Live demo page
|
|
218
|
+
├── preview.html # Component preview
|
|
219
|
+
├── playground.html # Interactive parameter lab
|
|
220
|
+
├── index.mjs / index.cjs # ESM and CommonJS package entry points
|
|
221
|
+
├── package.json # Package metadata and scripts
|
|
222
|
+
├── capacitor.config.json # Capacitor configuration
|
|
223
|
+
├── playwright.config.cjs # Browser test configuration
|
|
224
|
+
├── CHANGELOG.md
|
|
225
|
+
├── llms.txt
|
|
226
|
+
├── LICENSE
|
|
227
|
+
└── README*.md # English, Simplified Chinese and Japanese docs
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## License
|
|
231
|
+
|
|
232
|
+
Released under [The Unlicense](LICENSE). You may copy, modify, publish, distribute and use the software for personal or commercial purposes without attribution. It is provided without warranty.
|