pixel-daylight-switch-gsvegetable 1.3.0 → 2.0.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.md +484 -174
- package/app.js +594 -258
- package/package.json +21 -2
package/README.md
CHANGED
|
@@ -1,66 +1,186 @@
|
|
|
1
1
|
# Pixel Daylight Switch
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<p align="center">
|
|
4
|
+
<strong>A tiny pixel world inside a draggable glass day/night switch.</strong>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
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>
|
|
4
13
|
|
|
5
14
|
<p align="center">
|
|
6
|
-
<
|
|
7
|
-
<
|
|
8
|
-
<a href="https://github.com/GSvegetable/pixel-daylight-switch/releases">版本发布</a>
|
|
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" />
|
|
9
17
|
</p>
|
|
10
18
|
|
|
11
19
|
<p align="center">
|
|
12
|
-
<
|
|
13
|
-
<img src="https://github.com/user-attachments/assets/b2e24e65-a378-4ac6-be7b-efd3070e4da8" width="49%" alt="夜晚模式" />
|
|
20
|
+
<em>Drag the glass control. Watch a small world move from day to dusk to night.</em>
|
|
14
21
|
</p>
|
|
15
22
|
|
|
16
|
-
|
|
23
|
+
**中文文档在前。** [English documentation](#english)
|
|
24
|
+
|
|
25
|
+
---
|
|
17
26
|
|
|
18
27
|
## 目录
|
|
19
28
|
|
|
29
|
+
- [项目简介](#项目简介)
|
|
20
30
|
- [快速开始](#快速开始)
|
|
21
|
-
- [
|
|
22
|
-
- [
|
|
23
|
-
- [
|
|
24
|
-
- [
|
|
25
|
-
- [
|
|
26
|
-
- [
|
|
27
|
-
- [
|
|
31
|
+
- [Android 与 iOS 应用](#android-与-ios-应用)
|
|
32
|
+
- [NPM 安装](#npm-安装)
|
|
33
|
+
- [框架集成](#框架集成)
|
|
34
|
+
- [参数实验室 Playground](#参数实验室-playground)
|
|
35
|
+
- [配置参数](#配置参数)
|
|
36
|
+
- [交互与事件](#交互与事件)
|
|
37
|
+
- [自定义主题](#自定义主题)
|
|
38
|
+
- [动态挂载与卸载](#动态挂载与卸载)
|
|
39
|
+
- [渲染与兼容性](#渲染与兼容性)
|
|
40
|
+
- [项目目录结构](#项目目录结构)
|
|
41
|
+
- [本地开发与测试](#本地开发与测试)
|
|
42
|
+
- [版本记录](#版本记录)
|
|
28
43
|
- [许可证](#许可证)
|
|
29
44
|
|
|
45
|
+
## 项目简介
|
|
46
|
+
|
|
47
|
+
**Pixel Daylight Switch** 是一个可拖动的昼夜切换组件。它把一个持续变化的像素世界放进玻璃开关中:拖动滑块,场景会经过白天、黄昏并进入夜晚;点击或使用键盘也可以切换昼夜。
|
|
48
|
+
|
|
49
|
+
### 特性
|
|
50
|
+
|
|
51
|
+
- **像素世界**:场景中有持续活动的像素角色与环境细节。
|
|
52
|
+
- **玻璃质感**:使用 WebGL2 绘制折射玻璃效果。
|
|
53
|
+
- **五种场景**:乡村小屋、日本街道、现代公寓、海边灯塔、山间木屋。
|
|
54
|
+
- **昼夜过渡**:不是简单的二态换色,而是连续的昼夜变化。
|
|
55
|
+
- **可配置**:通过 HTML `data-*` 属性配置运动、玻璃、天气和场景。
|
|
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
|
+
|
|
30
66
|
## 快速开始
|
|
31
67
|
|
|
32
|
-
|
|
68
|
+
不使用 NPM,也不需要安装依赖。把容器和脚本放进 HTML:
|
|
33
69
|
|
|
34
70
|
```html
|
|
35
71
|
<div data-ld-part="toggle-daylight"></div>
|
|
36
|
-
|
|
72
|
+
|
|
73
|
+
<script
|
|
74
|
+
defer
|
|
75
|
+
src="https://gsvegetable.github.io/pixel-daylight-switch/app.js"
|
|
76
|
+
></script>
|
|
37
77
|
```
|
|
38
78
|
|
|
39
|
-
|
|
79
|
+
脚本会自动为每个匹配的容器创建 Canvas、交互按钮和状态播报元素。容器宽度会自适应父级,组件保持约 **1.6439:1** 的宽高比。
|
|
80
|
+
|
|
81
|
+
如果需要自行托管,可以下载仓库中的 `app.js`,将脚本地址替换为自己的静态资源地址。
|
|
82
|
+
|
|
83
|
+
## Android 与 iOS 应用
|
|
84
|
+
|
|
85
|
+
从 **v2.0.0** 开始,项目提供 Capacitor 原生应用构建路径。Web 版本继续独立运行;Android 与 iOS 使用同一份核心渲染器,不复制或重写场景、WebGL shader 和交互物理逻辑。
|
|
86
|
+
|
|
87
|
+
### 技术结构
|
|
40
88
|
|
|
41
|
-
|
|
89
|
+
- **共享核心**:根目录的 `app.js` 与 `style.css` 是唯一渲染实现。
|
|
90
|
+
- **原生容器**:Capacitor 8 将同一套 Web 资源装入 Android WebView 和 iOS WKWebView。
|
|
91
|
+
- **移动外壳**:`mobile/` 只负责全屏布局、安全区域和移动端 viewport,不包含第二套场景引擎。
|
|
92
|
+
- **构建产物**:`mobile/www/` 由脚本生成并被 Git 忽略,避免提交重复的渲染资源。
|
|
42
93
|
|
|
43
|
-
###
|
|
94
|
+
### 环境要求
|
|
44
95
|
|
|
45
|
-
|
|
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
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
首次创建 Android / iOS 工程(每个平台只需初始化一次):
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
npm run mobile:android:init
|
|
115
|
+
npm run mobile:ios:init
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
同步后续 Web 资源变更:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
npm run mobile:android
|
|
122
|
+
npm run mobile:ios
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
在 Android Studio 或 Xcode 中打开工程:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
npm run mobile:open:android
|
|
129
|
+
npm run mobile:open:ios
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
原生工程目录 `android/` 与 `ios/` 是本地生成目录,不纳入 Git。这样可以避免提交大量 IDE 生成文件;CI 会从锁定的 Capacitor 主版本配置重新生成工程并验证构建。
|
|
133
|
+
|
|
134
|
+
### 自动构建
|
|
135
|
+
|
|
136
|
+
`.github/workflows/mobile-build.yml` 提供 Android Debug APK 与 iOS Simulator 构建。可在 GitHub Actions 手动运行;推送 `v2.*` 标签也会触发构建。Android APK 会作为 Actions artifact 保存。iOS Simulator 构建用于验证编译,不等同于已签名、可提交 App Store 的 IPA。
|
|
137
|
+
|
|
138
|
+
**发布边界:** App Store / Google Play 上架仍需要开发者账号、应用图标与商店素材、签名证书及隐私合规信息。此仓库的 CI 不会伪造签名或自动代表开发者提交商店。
|
|
139
|
+
|
|
140
|
+
## NPM 安装
|
|
46
141
|
|
|
47
142
|
```bash
|
|
48
143
|
npm install pixel-daylight-switch-gsvegetable
|
|
49
144
|
```
|
|
50
145
|
|
|
51
|
-
|
|
146
|
+
### 原生 JavaScript / ESM
|
|
52
147
|
|
|
53
148
|
```js
|
|
54
149
|
import PixelDaylightSwitch from 'pixel-daylight-switch-gsvegetable';
|
|
55
150
|
|
|
56
|
-
const root = document.querySelector(
|
|
57
|
-
|
|
151
|
+
const root = document.querySelector(
|
|
152
|
+
'[data-ld-part="toggle-daylight"]'
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
// 页面加载后动态创建的元素需要手动挂载
|
|
156
|
+
const destroy = PixelDaylightSwitch.mount(root);
|
|
58
157
|
|
|
59
|
-
//
|
|
158
|
+
// 不再使用时,在移除元素前卸载
|
|
60
159
|
PixelDaylightSwitch.unmount(root);
|
|
61
160
|
```
|
|
62
161
|
|
|
63
|
-
|
|
162
|
+
也可以使用命名导入:
|
|
163
|
+
|
|
164
|
+
```js
|
|
165
|
+
import { mount, unmount } from 'pixel-daylight-switch-gsvegetable';
|
|
166
|
+
|
|
167
|
+
mount(root);
|
|
168
|
+
unmount(root);
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### CommonJS
|
|
172
|
+
|
|
173
|
+
```js
|
|
174
|
+
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
|
|
64
184
|
|
|
65
185
|
```jsx
|
|
66
186
|
import { useEffect, useRef } from 'react';
|
|
@@ -71,6 +191,8 @@ export function DaylightSwitch() {
|
|
|
71
191
|
|
|
72
192
|
useEffect(() => {
|
|
73
193
|
const root = rootRef.current;
|
|
194
|
+
if (!root) return;
|
|
195
|
+
|
|
74
196
|
PixelDaylightSwitch.mount(root);
|
|
75
197
|
return () => PixelDaylightSwitch.unmount(root);
|
|
76
198
|
}, []);
|
|
@@ -79,7 +201,7 @@ export function DaylightSwitch() {
|
|
|
79
201
|
}
|
|
80
202
|
```
|
|
81
203
|
|
|
82
|
-
|
|
204
|
+
### Vue 3
|
|
83
205
|
|
|
84
206
|
```vue
|
|
85
207
|
<script setup>
|
|
@@ -87,8 +209,14 @@ import { ref, onMounted, onBeforeUnmount } from 'vue';
|
|
|
87
209
|
import PixelDaylightSwitch from 'pixel-daylight-switch-gsvegetable';
|
|
88
210
|
|
|
89
211
|
const root = ref(null);
|
|
90
|
-
|
|
91
|
-
|
|
212
|
+
|
|
213
|
+
onMounted(() => {
|
|
214
|
+
PixelDaylightSwitch.mount(root.value);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
onBeforeUnmount(() => {
|
|
218
|
+
PixelDaylightSwitch.unmount(root.value);
|
|
219
|
+
});
|
|
92
220
|
</script>
|
|
93
221
|
|
|
94
222
|
<template>
|
|
@@ -96,45 +224,75 @@ onBeforeUnmount(() => PixelDaylightSwitch.unmount(root.value));
|
|
|
96
224
|
</template>
|
|
97
225
|
```
|
|
98
226
|
|
|
99
|
-
|
|
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)`。不要在同一个容器上重复创建自己的实例。
|
|
100
246
|
|
|
101
247
|
## 参数实验室 Playground
|
|
102
248
|
|
|
103
|
-
|
|
249
|
+
打开 [Pixel Daylight Playground](https://gsvegetable.github.io/pixel-daylight-switch/playground.html),可以在浏览器中试验组件配置。
|
|
104
250
|
|
|
105
|
-
-
|
|
106
|
-
-
|
|
107
|
-
-
|
|
108
|
-
-
|
|
109
|
-
-
|
|
251
|
+
- 拖动预览区中的开关,直接体验交互。
|
|
252
|
+
- 按运动反馈、玻璃光学、世界节奏和场景环境调整参数。
|
|
253
|
+
- 在五种像素场景之间切换。
|
|
254
|
+
- 选择天气、初始昼夜状态与世界时间倍率。
|
|
255
|
+
- 先调整参数,再点击「应用参数」更新预览。
|
|
256
|
+
- 复制生成的 HTML 配置,放入自己的项目。
|
|
110
257
|
|
|
111
|
-
Playground
|
|
258
|
+
Playground 是独立页面。它用于探索配置,不是组件运行时的依赖。
|
|
112
259
|
|
|
113
|
-
##
|
|
260
|
+
## 配置参数
|
|
114
261
|
|
|
115
|
-
|
|
262
|
+
所有配置都写在组件根元素的 HTML `data-*` 属性上。每个实例可以使用不同参数;未填写的参数使用默认值。
|
|
116
263
|
|
|
117
|
-
###
|
|
264
|
+
### 完整参数表
|
|
118
265
|
|
|
119
|
-
| HTML 属性 | 默认值 |
|
|
266
|
+
| HTML 属性 | 默认值 | 说明 |
|
|
120
267
|
| --- | ---: | --- |
|
|
121
|
-
| `data-speed` | `9.5` |
|
|
122
|
-
| `data-refraction` | `1.24` |
|
|
123
|
-
| `data-bezel` | `0.046` |
|
|
124
|
-
| `data-start-night` | `false` |
|
|
125
|
-
| `data-friction` | `0.6` | 松手后的惯性阻尼,范围 `0.1–0.9
|
|
126
|
-
| `data-bounce` | `3.2` |
|
|
127
|
-
| `data-dispersion` | `0.05` | 玻璃边缘 RGB 色散强度,范围 `0–0.25
|
|
128
|
-
| `data-shine` | `0.44` | 白天玻璃表面高光强度,范围 `0–1.5
|
|
129
|
-
| `data-time-speed` | `1
|
|
130
|
-
| `data-weather` | `default` | 天气预设:`default` 或 `snow
|
|
131
|
-
| `data-scene` | `countryside` |
|
|
268
|
+
| `data-speed` | `9.5` | 开关运动的基础响应速度,必须为正数。 |
|
|
269
|
+
| `data-refraction` | `1.24` | 玻璃镜片折射强度,必须为正数。 |
|
|
270
|
+
| `data-bezel` | `0.046` | 玻璃边缘厚度系数,必须为正数。 |
|
|
271
|
+
| `data-start-night` | `false` | 精确设置为 `true` 时,从夜晚状态开始。 |
|
|
272
|
+
| `data-friction` | `0.6` | 松手后的惯性阻尼,范围 `0.1–0.9`;值越低,滑动越持久。 |
|
|
273
|
+
| `data-bounce` | `3.2` | 边缘回弹力度,范围 `0–12`。 |
|
|
274
|
+
| `data-dispersion` | `0.05` | 玻璃边缘 RGB 色散强度,范围 `0–0.25`;`0` 关闭色散。 |
|
|
275
|
+
| `data-shine` | `0.44` | 白天玻璃表面高光强度,范围 `0–1.5`。 |
|
|
276
|
+
| `data-time-speed` | `1` | 像素世界时间倍率,范围 `0–8`;`0` 冻结世界动态,`2` 为两倍速度。 |
|
|
277
|
+
| `data-weather` | `default` | 天气预设:`default` 或 `snow`。 |
|
|
278
|
+
| `data-scene` | `countryside` | 场景:`countryside`、`japanese-street`、`apartment`、`seaside`、`mountain-cabin`。 |
|
|
279
|
+
|
|
280
|
+
### 场景选项
|
|
281
|
+
|
|
282
|
+
| 值 | 场景 |
|
|
283
|
+
| --- | --- |
|
|
284
|
+
| `countryside` | 乡村小屋(默认) |
|
|
285
|
+
| `japanese-street` | 日本街道 |
|
|
286
|
+
| `apartment` | 现代公寓 |
|
|
287
|
+
| `seaside` | 海边灯塔 |
|
|
288
|
+
| `mountain-cabin` | 山间木屋 |
|
|
132
289
|
|
|
133
290
|
### 完整配置示例
|
|
134
291
|
|
|
135
292
|
```html
|
|
136
293
|
<div
|
|
137
294
|
data-ld-part="toggle-daylight"
|
|
295
|
+
data-label="昼夜环境切换"
|
|
138
296
|
data-speed="12"
|
|
139
297
|
data-refraction="1.5"
|
|
140
298
|
data-bezel="0.05"
|
|
@@ -148,58 +306,39 @@ Playground 是独立页面,不会改变组件本身的零依赖接入方式。
|
|
|
148
306
|
data-scene="mountain-cabin"
|
|
149
307
|
></div>
|
|
150
308
|
|
|
151
|
-
<script
|
|
309
|
+
<script
|
|
310
|
+
defer
|
|
311
|
+
src="https://gsvegetable.github.io/pixel-daylight-switch/app.js"
|
|
312
|
+
></script>
|
|
152
313
|
```
|
|
153
314
|
|
|
154
|
-
###
|
|
155
|
-
|
|
156
|
-
**运动反馈 / Motion**
|
|
157
|
-
|
|
158
|
-
- `data-speed` 控制开关运动的基础速度。
|
|
159
|
-
- `data-friction` 控制松手后的惯性衰减。较小的值更滑,较大的值更黏。
|
|
160
|
-
- `data-bounce` 控制滑块触及边缘时的回弹力度。
|
|
161
|
-
|
|
162
|
-
**玻璃光学 / Glass Optics**
|
|
163
|
-
|
|
164
|
-
- `data-refraction` 控制镜片折射强度。
|
|
165
|
-
- `data-bezel` 控制镜片外框厚度。
|
|
166
|
-
- `data-dispersion` 控制边缘色散。数值越大,彩虹色边缘越明显。
|
|
167
|
-
- `data-shine` 控制白天镜片高光。
|
|
315
|
+
### 参数校验规则
|
|
168
316
|
|
|
169
|
-
|
|
317
|
+
- 数值参数为空、不是有限数字或不符合正数要求时,会回退到默认值。
|
|
318
|
+
- `friction`、`bounce`、`dispersion`、`shine` 和 `time-speed` 会限制在表格所示范围内。
|
|
319
|
+
- 未知的 `weather` 值回退为 `default`。
|
|
320
|
+
- 未知的 `scene` 值回退为 `countryside`。
|
|
321
|
+
- `data-start-night` 只有值为字符串 `true` 时才启用。
|
|
170
322
|
|
|
171
|
-
|
|
172
|
-
- `data-time-speed="2"` 会让世界模拟以两倍速度运行。
|
|
173
|
-
- `data-weather="snow"` 开启飘雪;省略或填写其他值时使用默认天气。
|
|
174
|
-
- `data-scene` 选择完整的像素环境:乡村、日本街道、公寓室内、海边或山间木屋。
|
|
175
|
-
- `data-start-night="true"` 让组件从夜晚开始。
|
|
323
|
+
## 交互与事件
|
|
176
324
|
|
|
177
|
-
###
|
|
325
|
+
### 用户交互
|
|
178
326
|
|
|
179
|
-
|
|
327
|
+
- **拖动**:连续控制昼夜进度。
|
|
328
|
+
- **点击**:在白天和夜晚之间切换。
|
|
329
|
+
- **键盘**:聚焦开关后可使用方向键操作。
|
|
330
|
+
- **无障碍**:交互按钮使用 `role="switch"` 与 `aria-checked`;状态变化通过 live region 播报。
|
|
331
|
+
- **减少动态效果**:尊重系统的 `prefers-reduced-motion` 设置。
|
|
180
332
|
|
|
181
|
-
|
|
333
|
+
### 读取昼夜进度
|
|
182
334
|
|
|
183
|
-
|
|
184
|
-
<div data-ld-part="toggle-daylight"></div>
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
组件会使用默认参数。v1.2.0 的新增参数默认值与 v1.1.0 的原有参数保持一致,未配置新属性时不会主动改变原有视觉设定。数值参数会进行数字转换、有效性检查和范围限制;未知天气值回退到 `default`。
|
|
188
|
-
|
|
189
|
-
## 交互与页面主题
|
|
335
|
+
组件会在根元素上更新 CSS 自定义属性 `--night`:
|
|
190
336
|
|
|
191
|
-
-
|
|
192
|
-
-
|
|
193
|
-
-
|
|
194
|
-
- **无障碍**:使用 switch 语义,并尊重系统的减少动态效果偏好。
|
|
337
|
+
- `0`:白天。
|
|
338
|
+
- `1`:夜晚。
|
|
339
|
+
- `0` 到 `1` 之间:昼夜过渡。
|
|
195
340
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
- `0` 表示白天;
|
|
199
|
-
- `1` 表示夜晚;
|
|
200
|
-
- 中间值表示昼夜过渡。
|
|
201
|
-
|
|
202
|
-
例如,让页面背景跟随开关变化:
|
|
341
|
+
可以用它联动页面其他部分:
|
|
203
342
|
|
|
204
343
|
```css
|
|
205
344
|
body {
|
|
@@ -211,17 +350,30 @@ body {
|
|
|
211
350
|
}
|
|
212
351
|
```
|
|
213
352
|
|
|
214
|
-
|
|
353
|
+
### 监听状态事件
|
|
354
|
+
|
|
355
|
+
组件在昼夜状态发生变化时,会在组件根元素上派发可冒泡的 `daylight:change` 事件。事件的 `detail.night` 是布尔值。
|
|
215
356
|
|
|
216
357
|
```js
|
|
217
358
|
document.addEventListener('daylight:change', (event) => {
|
|
218
|
-
document.documentElement.classList.toggle(
|
|
359
|
+
document.documentElement.classList.toggle(
|
|
360
|
+
'dark',
|
|
361
|
+
event.detail.night
|
|
362
|
+
);
|
|
219
363
|
});
|
|
220
364
|
```
|
|
221
365
|
|
|
222
|
-
|
|
366
|
+
如果页面有多个实例,建议在单个根元素上监听,以区分具体是哪一个开关触发了事件:
|
|
223
367
|
|
|
224
|
-
|
|
368
|
+
```js
|
|
369
|
+
root.addEventListener('daylight:change', (event) => {
|
|
370
|
+
console.log('当前是否为夜晚:', event.detail.night);
|
|
371
|
+
});
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
## 自定义主题
|
|
375
|
+
|
|
376
|
+
在组件根元素上覆盖以下 CSS 自定义属性:
|
|
225
377
|
|
|
226
378
|
```css
|
|
227
379
|
[data-ld-part="toggle-daylight"] {
|
|
@@ -230,142 +382,261 @@ document.addEventListener('daylight:change', (event) => {
|
|
|
230
382
|
--ld-fg: #1b2146;
|
|
231
383
|
--ld-muted: #7f97b3;
|
|
232
384
|
--ld-accent: #efa02c;
|
|
385
|
+
--ld-radius: 9999px;
|
|
386
|
+
--ld-font: system-ui, sans-serif;
|
|
233
387
|
}
|
|
234
388
|
```
|
|
235
389
|
|
|
236
390
|
| CSS 变量 | 默认值 | 用途 |
|
|
237
391
|
| --- | --- | --- |
|
|
238
|
-
| `--ld-bg` | `#f5ecd9` |
|
|
239
|
-
| `--ld-surface` | `#8c9a62` |
|
|
240
|
-
| `--ld-fg` | `#1b2146` |
|
|
392
|
+
| `--ld-bg` | `#f5ecd9` | 背景调色输入 |
|
|
393
|
+
| `--ld-surface` | `#8c9a62` | 表面与场景调色输入 |
|
|
394
|
+
| `--ld-fg` | `#1b2146` | 前景颜色 |
|
|
241
395
|
| `--ld-muted` | `#7f97b3` | 次要颜色 |
|
|
242
|
-
| `--ld-accent` | `#efa02c` |
|
|
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` | 焦点轮廓过渡时长 |
|
|
243
402
|
|
|
244
|
-
##
|
|
403
|
+
## 动态挂载与卸载
|
|
245
404
|
|
|
246
|
-
|
|
405
|
+
页面加载时,脚本会自动查找已有的 `[data-ld-part="toggle-daylight"]` 元素并挂载。对于之后动态创建的元素,调用公开 API:
|
|
247
406
|
|
|
248
407
|
```js
|
|
249
|
-
const
|
|
408
|
+
const root = document.createElement('div');
|
|
409
|
+
root.dataset.ldPart = 'toggle-daylight';
|
|
410
|
+
document.querySelector('#app').appendChild(root);
|
|
250
411
|
|
|
251
|
-
|
|
252
|
-
|
|
412
|
+
const destroy = PixelDaylightSwitch.mount(root);
|
|
413
|
+
|
|
414
|
+
// 需要移除时:
|
|
415
|
+
PixelDaylightSwitch.unmount(root);
|
|
416
|
+
root.remove();
|
|
253
417
|
```
|
|
254
418
|
|
|
255
|
-
|
|
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
|
+
```
|
|
256
474
|
|
|
257
|
-
|
|
258
|
-
- 支持减少动态效果偏好。
|
|
259
|
-
- 页面不可见或组件离开视口时会暂停不必要的绘制。
|
|
260
|
-
- 不需要构建工具。
|
|
475
|
+
### 关键目录说明
|
|
261
476
|
|
|
262
|
-
|
|
477
|
+
- **`app.js`**:组件主体,包含昼夜状态、Canvas/WebGL 渲染、输入交互和实例生命周期管理。
|
|
478
|
+
- **`playground.html`**:可视化调整参数、切换场景并生成 HTML 配置。
|
|
479
|
+
- **`embed.js`**:面向嵌入式使用场景的入口脚本。
|
|
480
|
+
- **`tests/`**:包加载、SSR、挂载卸载、多实例、指针/触控和移动端回归测试。
|
|
481
|
+
- **`.github/workflows/`**:自动执行持续集成,并在版本标签触发时执行发布流程。
|
|
482
|
+
|
|
483
|
+
## 本地开发与测试
|
|
484
|
+
|
|
485
|
+
克隆项目:
|
|
263
486
|
|
|
264
487
|
```bash
|
|
265
488
|
git clone https://github.com/GSvegetable/pixel-daylight-switch.git
|
|
266
489
|
cd pixel-daylight-switch
|
|
267
490
|
```
|
|
268
491
|
|
|
269
|
-
|
|
492
|
+
直接用浏览器打开 `index.html` 即可查看基础演示。项目无需打包构建。
|
|
493
|
+
|
|
494
|
+
### 自动化测试
|
|
495
|
+
|
|
496
|
+
运行包入口、CommonJS / ESM 和 SSR 安全检查:
|
|
497
|
+
|
|
498
|
+
```bash
|
|
499
|
+
npm test
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
浏览器回归测试使用 Playwright。安装测试运行器和 Chromium 后执行:
|
|
270
503
|
|
|
271
|
-
|
|
272
|
-
-
|
|
273
|
-
|
|
504
|
+
```bash
|
|
505
|
+
npm install --no-save @playwright/test@1.56.1
|
|
506
|
+
npx playwright install chromium
|
|
507
|
+
npm run test:browser
|
|
508
|
+
```
|
|
274
509
|
|
|
275
|
-
|
|
510
|
+
CI 会在 Node.js 18、20、22 下执行包与 SSR 检查,并在 Chromium 中运行交互、重复挂载/卸载、多实例、事件监听器清理和移动端回归测试。
|
|
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 发布前置检查。
|
|
276
521
|
|
|
277
522
|
### v1.3.0
|
|
278
523
|
|
|
279
|
-
-
|
|
280
|
-
-
|
|
524
|
+
- 新增日本街道、现代公寓、海边灯塔和山间木屋四种像素环境。
|
|
525
|
+
- 保留乡村小屋作为默认场景。
|
|
526
|
+
- Playground 支持切换场景并组合调整天气、昼夜和玻璃参数。
|
|
281
527
|
|
|
282
528
|
### v1.2.0
|
|
283
529
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
-
|
|
287
|
-
- 新增液态玻璃参数:色散与表面高光。
|
|
288
|
-
- 新增世界时间倍率和像素飘雪天气。
|
|
289
|
-
- 新增独立 Playground,可实时调节参数、套用预设并复制 HTML。
|
|
290
|
-
- 重组 README,将中文说明置于文档顶部,并提供中英文跳转。
|
|
530
|
+
- 新增惯性阻尼、边缘回弹、玻璃色散和表面高光参数。
|
|
531
|
+
- 新增世界时间倍率与飘雪天气。
|
|
532
|
+
- 新增独立 Playground,支持参数分组、场景预设和 HTML 代码复制。
|
|
291
533
|
|
|
292
534
|
### v1.1.0
|
|
293
535
|
|
|
294
|
-
-
|
|
536
|
+
- 新增运动速度、镜片折射、外框厚度和初始夜晚状态配置。
|
|
295
537
|
|
|
296
538
|
### v1.0.0
|
|
297
539
|
|
|
298
540
|
- 首个公开版本。
|
|
299
541
|
|
|
542
|
+
详细记录见 [CHANGELOG.md](./CHANGELOG.md)。
|
|
543
|
+
|
|
300
544
|
## 许可证
|
|
301
545
|
|
|
302
|
-
[Unlicense](https://unlicense.org/)
|
|
546
|
+
本项目使用 [Unlicense](https://unlicense.org/) 公有领域协议。允许个人和商业用途,无需署名。
|
|
303
547
|
|
|
304
548
|
---
|
|
305
549
|
|
|
550
|
+
<a id="english"></a>
|
|
551
|
+
|
|
306
552
|
## English
|
|
307
553
|
|
|
308
|
-
|
|
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
|
|
309
557
|
|
|
310
|
-
|
|
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.
|
|
311
566
|
|
|
312
567
|
### Quick start
|
|
313
568
|
|
|
314
|
-
No
|
|
569
|
+
No package manager or build step is required:
|
|
315
570
|
|
|
316
571
|
```html
|
|
317
572
|
<div data-ld-part="toggle-daylight"></div>
|
|
318
|
-
|
|
573
|
+
|
|
574
|
+
<script
|
|
575
|
+
defer
|
|
576
|
+
src="https://gsvegetable.github.io/pixel-daylight-switch/app.js"
|
|
577
|
+
></script>
|
|
319
578
|
```
|
|
320
579
|
|
|
321
|
-
The script creates the internal canvas, interaction
|
|
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**.
|
|
322
581
|
|
|
323
|
-
### NPM
|
|
582
|
+
### NPM
|
|
324
583
|
|
|
325
584
|
```bash
|
|
326
585
|
npm install pixel-daylight-switch-gsvegetable
|
|
327
586
|
```
|
|
328
587
|
|
|
329
|
-
ESM
|
|
588
|
+
ESM:
|
|
330
589
|
|
|
331
590
|
```js
|
|
332
591
|
import PixelDaylightSwitch from 'pixel-daylight-switch-gsvegetable';
|
|
333
592
|
|
|
334
593
|
const root = document.querySelector('[data-ld-part="toggle-daylight"]');
|
|
335
594
|
PixelDaylightSwitch.mount(root);
|
|
336
|
-
|
|
595
|
+
|
|
596
|
+
// Before removing the element:
|
|
337
597
|
PixelDaylightSwitch.unmount(root);
|
|
338
598
|
```
|
|
339
599
|
|
|
340
|
-
|
|
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.
|
|
341
607
|
|
|
342
|
-
###
|
|
608
|
+
### Framework integration
|
|
343
609
|
|
|
344
|
-
|
|
610
|
+
For React, Vue 3, and Svelte, mount the component in the client-side lifecycle and call `unmount(element)` during cleanup. See the complete examples in the [Chinese documentation above](#框架集成).
|
|
345
611
|
|
|
346
|
-
###
|
|
612
|
+
### Playground
|
|
347
613
|
|
|
348
|
-
|
|
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
|
+
|
|
616
|
+
### Configuration
|
|
617
|
+
|
|
618
|
+
All settings are optional and belong on the component root.
|
|
349
619
|
|
|
350
620
|
| Attribute | Default | Description |
|
|
351
621
|
| --- | ---: | --- |
|
|
352
|
-
| `data-speed` | `9.5` | Base
|
|
353
|
-
| `data-refraction` | `1.24` | Glass lens refraction strength. |
|
|
354
|
-
| `data-bezel` | `0.046` |
|
|
355
|
-
| `data-start-night` | `false` |
|
|
356
|
-
| `data-friction` | `0.6` | Release inertia damping
|
|
357
|
-
| `data-bounce` | `3.2` |
|
|
358
|
-
| `data-dispersion` | `0.05` | RGB
|
|
359
|
-
| `data-shine` | `0.44` | Daytime
|
|
360
|
-
| `data-time-speed` | `1
|
|
361
|
-
| `data-weather` | `default` |
|
|
362
|
-
| `data-scene` | `countryside` |
|
|
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`. |
|
|
363
633
|
|
|
364
634
|
Example:
|
|
365
635
|
|
|
366
636
|
```html
|
|
367
637
|
<div
|
|
368
638
|
data-ld-part="toggle-daylight"
|
|
639
|
+
data-label="Day and night switch"
|
|
369
640
|
data-speed="12"
|
|
370
641
|
data-refraction="1.5"
|
|
371
642
|
data-bezel="0.05"
|
|
@@ -380,54 +651,93 @@ Example:
|
|
|
380
651
|
></div>
|
|
381
652
|
```
|
|
382
653
|
|
|
383
|
-
|
|
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.
|
|
384
655
|
|
|
385
|
-
###
|
|
656
|
+
### Events and page theme
|
|
386
657
|
|
|
387
|
-
The component
|
|
658
|
+
The component updates `--night` on its root element: `0` means day, `1` means night, and values in between represent the transition.
|
|
388
659
|
|
|
389
|
-
|
|
390
|
-
body {
|
|
391
|
-
background: color-mix(in srgb, #f5ecd9, #1b2146 calc(var(--night, 0) * 100%));
|
|
392
|
-
}
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
Listen for state changes with:
|
|
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:
|
|
396
661
|
|
|
397
662
|
```js
|
|
398
|
-
|
|
663
|
+
root.addEventListener('daylight:change', (event) => {
|
|
399
664
|
document.documentElement.classList.toggle('dark', event.detail.night);
|
|
400
665
|
});
|
|
401
666
|
```
|
|
402
667
|
|
|
403
|
-
### Theme
|
|
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`.
|
|
404
685
|
|
|
405
|
-
|
|
686
|
+
### Mounting and cleanup
|
|
406
687
|
|
|
407
|
-
|
|
688
|
+
Elements present when the script loads are mounted automatically. For elements created later:
|
|
408
689
|
|
|
409
690
|
```js
|
|
410
|
-
PixelDaylightSwitch.mount(element);
|
|
691
|
+
const destroy = PixelDaylightSwitch.mount(element);
|
|
692
|
+
|
|
693
|
+
// Before removing the root:
|
|
411
694
|
PixelDaylightSwitch.unmount(element);
|
|
695
|
+
element.remove();
|
|
412
696
|
```
|
|
413
697
|
|
|
414
|
-
|
|
698
|
+
Mounting the same element more than once is safe and does not create duplicate instances. A successful `mount()` returns a cleanup function; a failed mount returns `null`. `unmount()` stops rendering and removes the component's listeners and observers without removing the root element.
|
|
699
|
+
|
|
700
|
+
### Rendering and browser behavior
|
|
415
701
|
|
|
416
|
-
WebGL2 is used for the glass effect
|
|
702
|
+
- WebGL2 is used for the refractive glass effect.
|
|
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.
|
|
417
707
|
|
|
418
|
-
### Development
|
|
708
|
+
### Development and tests
|
|
419
709
|
|
|
420
710
|
```bash
|
|
421
711
|
git clone https://github.com/GSvegetable/pixel-daylight-switch.git
|
|
422
712
|
cd pixel-daylight-switch
|
|
423
713
|
```
|
|
424
714
|
|
|
425
|
-
Open `index.html` in a modern browser. No build step is
|
|
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
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
### Version history
|
|
426
732
|
|
|
427
|
-
|
|
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.
|
|
428
738
|
|
|
429
|
-
|
|
739
|
+
See [CHANGELOG.md](./CHANGELOG.md) for details.
|
|
430
740
|
|
|
431
741
|
### License
|
|
432
742
|
|
|
433
|
-
[Unlicense](https://unlicense.org/) — public
|
|
743
|
+
[Unlicense](https://unlicense.org/) — public-domain dedication. Free for personal and commercial use without attribution.
|