@longzai-intelligence-liquid-glass/core 0.0.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/README.md ADDED
@@ -0,0 +1,12 @@
1
+ # @longzai-intelligence-liquid-glass/core
2
+
3
+ Liquid Glass 框架无关核心:形状 SDF、光学剖面、参数模型与渲染器抽象接口。零平台依赖。
4
+
5
+ ## 用法
6
+
7
+ ```bash
8
+ bun run --cwd packages/core lint # 代码检查
9
+ bun run --cwd packages/core typecheck # 类型检查(tsgo)
10
+ bun run --cwd packages/core test # 单元测试
11
+ bun run --cwd packages/core build # 构建(lzi-builder → dist)
12
+ ```
@@ -0,0 +1,724 @@
1
+ //#region src/shapes/sdf.utils.d.ts
2
+ /**
3
+ * 形状符号距离函数(SDF)
4
+ *
5
+ * 全部渲染后端共享的几何底座:以形状中心为原点、屏幕坐标系(+y 向下)求值,
6
+ * 内部为负、边界为零、外部为正。圆角矩形支持 squircle 角平滑(superellipse 推广,
7
+ * 源自 Kyant0/AndroidLiquidGlass 与 AndrewPrifer/liquid-dom 的 squircle 处理思路)。
8
+ */
9
+ /**
10
+ * 形状类别
11
+ *
12
+ * - rounded-rect:圆角矩形(含 squircle 角平滑)
13
+ * - circle:圆形
14
+ * - pill:胶囊形(stadium)
15
+ */
16
+ type GlassShapeKind = 'rounded-rect' | 'circle' | 'pill';
17
+ /**
18
+ * 形状描述子
19
+ */
20
+ type GlassShapeDescriptor = {
21
+ /**
22
+ * 形状类别
23
+ */
24
+ kind: GlassShapeKind;
25
+ /**
26
+ * 形状外接宽度(px)
27
+ */
28
+ width: number;
29
+ /**
30
+ * 形状外接高度(px)
31
+ */
32
+ height: number;
33
+ /**
34
+ * 圆角半径(px),circle / pill 时由尺寸推导
35
+ */
36
+ radius: number;
37
+ /**
38
+ * squircle 角平滑度 0..1(0 = 圆角,1 = 最大平滑)
39
+ */
40
+ smoothing: number;
41
+ };
42
+ /**
43
+ * 圆形 SDF
44
+ *
45
+ * @param px - 采样点 x(相对圆心)
46
+ * @param py - 采样点 y(相对圆心)
47
+ * @param radius - 半径(px)
48
+ * @returns 符号距离(px)
49
+ */
50
+ declare function sdCircle(px: number, py: number, radius: number): number;
51
+ /**
52
+ * 胶囊形(stadium)SDF:点到中轴线段的距离减去胶囊半径
53
+ *
54
+ * @param px - 采样点 x(相对形状中心)
55
+ * @param py - 采样点 y(相对形状中心)
56
+ * @param width - 外接宽度(px)
57
+ * @param height - 外接高度(px)
58
+ * @returns 符号距离(px)
59
+ */
60
+ declare function sdPill(px: number, py: number, width: number, height: number): number;
61
+ /**
62
+ * 圆角矩形 SDF(Inigo Quilez 精确公式,smoothing = 0 时)
63
+ *
64
+ * @param px - 采样点 x(相对形状中心)
65
+ * @param py - 采样点 y(相对形状中心)
66
+ * @param halfWidth - 半宽(px)
67
+ * @param halfHeight - 半高(px)
68
+ * @param radius - 圆角半径(px)
69
+ * @returns 符号距离(px)
70
+ */
71
+ declare function sdRoundedRect(px: number, py: number, halfWidth: number, halfHeight: number, radius: number): number;
72
+ /**
73
+ * squircle 角平滑的圆角矩形 SDF
74
+ *
75
+ * 以 superellipse 范数推广圆角:指数 n = 2 时退化为精确圆角矩形,
76
+ * smoothing 增大时角部逐渐"饱满"(Apple 风格连续曲率角的近似)。
77
+ *
78
+ * @param px - 采样点 x(相对形状中心)
79
+ * @param py - 采样点 y(相对形状中心)
80
+ * @param halfWidth - 半宽(px)
81
+ * @param halfHeight - 半高(px)
82
+ * @param radius - 圆角半径(px)
83
+ * @param smoothing - 角平滑度 0..1
84
+ * @returns 符号距离(px)
85
+ */
86
+ declare function sdRoundedRectSmooth(px: number, py: number, halfWidth: number, halfHeight: number, radius: number, smoothing: number): number;
87
+ /**
88
+ * 按形状描述子求 SDF
89
+ *
90
+ * @param px - 采样点 x(相对形状中心)
91
+ * @param py - 采样点 y(相对形状中心)
92
+ * @param descriptor - 形状描述子
93
+ * @returns 符号距离(px)
94
+ */
95
+ declare function sdShape(px: number, py: number, descriptor: GlassShapeDescriptor): number;
96
+ //#endregion
97
+ //#region src/math/vec2.utils.d.ts
98
+ /**
99
+ * 二维向量工具
100
+ *
101
+ * 玻璃几何与光学计算所需的零依赖向量运算(SDF 梯度、折射位移方向等)。
102
+ */
103
+ /**
104
+ * 二维向量
105
+ */
106
+ type Vec2 = {
107
+ /**
108
+ * x 分量(屏幕坐标系下指向右)
109
+ */
110
+ x: number;
111
+ /**
112
+ * y 分量(屏幕坐标系下指向下)
113
+ */
114
+ y: number;
115
+ };
116
+ /**
117
+ * 构造二维向量
118
+ *
119
+ * @param x - x 分量
120
+ * @param y - y 分量
121
+ * @returns 二维向量
122
+ */
123
+ declare function vec2(x: number, y: number): Vec2;
124
+ /**
125
+ * 向量加法
126
+ *
127
+ * @param a - 左操作数
128
+ * @param b - 右操作数
129
+ * @returns a + b
130
+ */
131
+ declare function addVec2(a: Vec2, b: Vec2): Vec2;
132
+ /**
133
+ * 向量减法
134
+ *
135
+ * @param a - 左操作数
136
+ * @param b - 右操作数
137
+ * @returns a - b
138
+ */
139
+ declare function subVec2(a: Vec2, b: Vec2): Vec2;
140
+ /**
141
+ * 向量数乘
142
+ *
143
+ * @param v - 向量
144
+ * @param s - 缩放系数
145
+ * @returns s * v
146
+ */
147
+ declare function scaleVec2(v: Vec2, s: number): Vec2;
148
+ /**
149
+ * 向量点积
150
+ *
151
+ * @param a - 左操作数
152
+ * @param b - 右操作数
153
+ * @returns a · b
154
+ */
155
+ declare function dotVec2(a: Vec2, b: Vec2): number;
156
+ /**
157
+ * 向量长度
158
+ *
159
+ * @param v - 向量
160
+ * @returns |v|
161
+ */
162
+ declare function lengthVec2(v: Vec2): number;
163
+ /**
164
+ * 向量归一化(零向量安全,返回零向量)
165
+ *
166
+ * @param v - 向量
167
+ * @returns 单位向量;|v| = 0 时返回 (0, 0)
168
+ */
169
+ declare function normalizeVec2(v: Vec2): Vec2;
170
+ //#endregion
171
+ //#region src/shapes/gradient.utils.d.ts
172
+ /**
173
+ * 标量场采样函数(如 SDF)
174
+ */
175
+ type ScalarField = (x: number, y: number) => number;
176
+ /**
177
+ * 标量场梯度(中心差分)
178
+ *
179
+ * @param field - 标量场
180
+ * @param px - 采样点 x
181
+ * @param py - 采样点 y
182
+ * @param epsilon - 差分步长(px)
183
+ * @returns 梯度向量(未归一化,指向函数增长方向)
184
+ */
185
+ declare function fieldGradient(field: ScalarField, px: number, py: number, epsilon?: number): Vec2;
186
+ /**
187
+ * SDF 外法线(梯度归一化,边界内侧同样指向外侧)
188
+ *
189
+ * @param field - SDF 标量场
190
+ * @param px - 采样点 x
191
+ * @param py - 采样点 y
192
+ * @param epsilon - 差分步长(px)
193
+ * @returns 单位外法线;梯度为零时返回 (0, 0)
194
+ */
195
+ declare function sdfOutwardNormal(field: ScalarField, px: number, py: number, epsilon?: number): Vec2;
196
+ /**
197
+ * 玻璃高度场表面法线(二维投影)
198
+ *
199
+ * 高度场 h(x, y) 的表面法线在 xy 平面的投影为 -∇h,
200
+ * 归一化后即折射偏折方向(slope prepass 的位移方向来源)。
201
+ *
202
+ * @param heightField - 高度场
203
+ * @param px - 采样点 x
204
+ * @param py - 采样点 y
205
+ * @param epsilon - 差分步长(px)
206
+ * @returns 单位向量;梯度为零时返回 (0, 0)
207
+ */
208
+ declare function heightFieldNormal(heightField: ScalarField, px: number, py: number, epsilon?: number): Vec2;
209
+ //#endregion
210
+ //#region src/optics/height-profile.utils.d.ts
211
+ /**
212
+ * 边缘高度剖面
213
+ *
214
+ * 把"距边深度"映射为玻璃表面高度:中心平坦、边缘带隆起。
215
+ * circleMap 弧面映射源自 Kyant0/AndroidLiquidGlass;
216
+ * bevel 幂曲线源自 naughtyduk/liquidGL 的 pow(edge, N) bevel 项。
217
+ */
218
+ /**
219
+ * circleMap:归一化深度 x ∈ [0,1] → 弧面高度 [0,1]
220
+ *
221
+ * 把直角深度映射为圆弧高度(1 端对应边缘),使折射带呈现真实的凸透镜弧面。
222
+ *
223
+ * @param x - 归一化深度(0 = 折射带内边界,1 = 形状边界)
224
+ * @returns 弧面高度 [0, 1]
225
+ */
226
+ declare function circleMap(x: number): number;
227
+ /**
228
+ * 边缘因子:SDF 值 → [0, 1](1 = 形状边界,0 = 折射带内边界及更内侧)
229
+ *
230
+ * @param sdf - 符号距离(px,内部为负)
231
+ * @param band - 折射带宽度(px,从边界向内)
232
+ * @returns 边缘因子 [0, 1]
233
+ */
234
+ declare function edgeFactor(sdf: number, band: number): number;
235
+ /**
236
+ * 边缘高度剖面参数
237
+ */
238
+ type HeightProfileParams = {
239
+ /**
240
+ * 基础折射带弧面强度 0..1
241
+ */
242
+ refraction: number;
243
+ /**
244
+ * 折射带宽度(px)
245
+ */
246
+ refractionHeight: number;
247
+ /**
248
+ * bevel(斜面)强度 0..1:在边界处叠加更陡的斜边
249
+ */
250
+ bevel: number;
251
+ /**
252
+ * bevel 幂(越大斜边越集中在最边缘)
253
+ */
254
+ bevelExponent: number;
255
+ };
256
+ /**
257
+ * 边缘高度剖面:SDF → 表面高度 [0, refraction + bevel]
258
+ *
259
+ * h = refraction · circleMap(f) + bevel · f^bevelExponent,
260
+ * f 为边缘因子;中心区(f = 0)平坦为零,保证只有边缘带发生折射。
261
+ *
262
+ * @param sdf - 符号距离(px)
263
+ * @param params - 剖面参数
264
+ * @returns 表面高度(无量纲,量级 ≤ refraction + bevel)
265
+ */
266
+ declare function edgeHeightProfile(sdf: number, params: HeightProfileParams): number;
267
+ //#endregion
268
+ //#region src/optics/refraction.utils.d.ts
269
+ /**
270
+ * 折射位移参数
271
+ */
272
+ type RefractionParams = {
273
+ /**
274
+ * 整体位移缩放系数(像素级强度,默认 1 表示位移上限 ≈ refractionHeight · refraction)
275
+ */
276
+ displacementScale: number;
277
+ } & HeightProfileParams;
278
+ /**
279
+ * 折射位移向量
280
+ *
281
+ * @param sdf - 符号距离(px)
282
+ * @param outwardNormal - SDF 单位外法线
283
+ * @param params - 折射参数
284
+ * @returns 背景采样位移(px,指向形状内侧为负向外法线方向)
285
+ */
286
+ declare function refractionDisplacement(sdf: number, outwardNormal: Vec2, params: RefractionParams): Vec2;
287
+ /**
288
+ * 折射位移幅值(供调试与位移图编码范围评估)
289
+ *
290
+ * @param params - 折射参数
291
+ * @returns 理论最大位移幅值(px)
292
+ */
293
+ declare function maxDisplacement(params: RefractionParams): number;
294
+ //#endregion
295
+ //#region src/optics/dispersion.utils.d.ts
296
+ /**
297
+ * 三通道色散缩放系数
298
+ */
299
+ type SpectralDispersionScales = {
300
+ /**
301
+ * 红通道位移系数(相对基准位移)
302
+ */
303
+ r: number;
304
+ /**
305
+ * 绿通道位移系数(基准 1)
306
+ */
307
+ g: number;
308
+ /**
309
+ * 蓝通道位移系数
310
+ */
311
+ b: number;
312
+ };
313
+ /**
314
+ * 七光谱采样权重(归一化):R / O / Y / G / C / B / P
315
+ *
316
+ * 光谱两端的折射率偏差最大,边缘色散由两端权重贡献。
317
+ */
318
+ declare const SPECTRAL_WEIGHTS: readonly number[];
319
+ /**
320
+ * 三通道对称色散缩放(liquidGL 方案)
321
+ *
322
+ * R/B 沿折射方向对称缩放:dispersion = 0 时三通道一致(无色散),
323
+ * 增大时蓝端偏移更大(模拟真实玻璃的蓝光高折射率)。
324
+ *
325
+ * @param dispersion - 色散强度 0..1
326
+ * @returns 三通道位移系数
327
+ */
328
+ declare function channelDispersionScales(dispersion: number): SpectralDispersionScales;
329
+ /**
330
+ * 三通道位移结果
331
+ */
332
+ type ChannelDisplacements = {
333
+ /**
334
+ * 红通道位移
335
+ */
336
+ r: Vec2;
337
+ /**
338
+ * 绿通道位移
339
+ */
340
+ g: Vec2;
341
+ /**
342
+ * 蓝通道位移
343
+ */
344
+ b: Vec2;
345
+ };
346
+ /**
347
+ * 三通道色散位移
348
+ *
349
+ * @param displacement - 基准折射位移(px)
350
+ * @param dispersion - 色散强度 0..1
351
+ * @returns R/G/B 三通道位移向量
352
+ */
353
+ declare function channelDisplacements(displacement: Vec2, dispersion: number): ChannelDisplacements;
354
+ /**
355
+ * 七光谱合成位移(Kyant0 方案)
356
+ *
357
+ * 对基准位移按光谱折射率偏差插值采样并加权平均,
358
+ * 位移随光谱位置单调变化,产生平滑的彩虹边缘。
359
+ *
360
+ * @param displacement - 基准折射位移(px)
361
+ * @param dispersion - 色散强度 0..1
362
+ * @returns 光谱加权平均位移(px)
363
+ */
364
+ declare function spectralDisplacement(displacement: Vec2, dispersion: number): Vec2;
365
+ //#endregion
366
+ //#region src/optics/specular.utils.d.ts
367
+ /**
368
+ * 高光参数
369
+ */
370
+ type SpecularParams = {
371
+ /**
372
+ * 高光强度 0..1
373
+ */
374
+ specular: number;
375
+ /**
376
+ * 高光锐度(幂次,越大高光带越窄)
377
+ */
378
+ specularExponent: number;
379
+ };
380
+ /**
381
+ * rim 高光 falloff
382
+ *
383
+ * @param cosine - 法线与光方向夹角余弦
384
+ * @param exponent - 幂次
385
+ * @returns falloff 值 [0, 1]
386
+ */
387
+ declare function rimFalloff(cosine: number, exponent: number): number;
388
+ /**
389
+ * 单侧 rim 高光强度
390
+ *
391
+ * @param outwardNormal - SDF 单位外法线
392
+ * @param lightDirection - 光方向(单位向量,从表面指向光源)
393
+ * @param params - 高光参数
394
+ * @returns 高光强度 [0, specular]
395
+ */
396
+ declare function rimSpecular(outwardNormal: Vec2, lightDirection: Vec2, params: SpecularParams): number;
397
+ /**
398
+ * 双光斑 rim 高光(主光 + 镜像对侧光,liquidGL 双 specular 方案)
399
+ *
400
+ * @param outwardNormal - SDF 单位外法线
401
+ * @param lightDirection - 主光方向(单位向量)
402
+ * @param params - 高光参数
403
+ * @returns 两侧高光合成强度
404
+ */
405
+ declare function dualRimSpecular(outwardNormal: Vec2, lightDirection: Vec2, params: SpecularParams): number;
406
+ //#endregion
407
+ //#region src/params/params.types.d.ts
408
+ /**
409
+ * RGBA 颜色(各分量 0..1)
410
+ */
411
+ type RGBA = {
412
+ /**
413
+ * 红通道 0..1
414
+ */
415
+ r: number;
416
+ /**
417
+ * 绿通道 0..1
418
+ */
419
+ g: number;
420
+ /**
421
+ * 蓝通道 0..1
422
+ */
423
+ b: number;
424
+ /**
425
+ * 透明度 0..1(tint 语境下即着色浓度)
426
+ */
427
+ a: number;
428
+ };
429
+ /**
430
+ * 预设标识
431
+ *
432
+ * - apple:Apple 2025 默认观感(克制折射 + 细腻色散 + 明亮边缘高光)
433
+ * - standard:标准模式,均匀边缘折射带(rdev standard)
434
+ * - polar:极坐标模式,径向渐强的折射分布(rdev polar)
435
+ * - prominent:强烈模式,宽折射带 + 高位移(rdev prominent)
436
+ * - frosted:磨砂模式,强模糊 + 弱折射
437
+ * - lens:透镜模式,高折射 + 高色散的放大镜观感
438
+ */
439
+ type GlassPresetId = 'apple' | 'standard' | 'polar' | 'prominent' | 'frosted' | 'lens';
440
+ /**
441
+ * 液态玻璃完整参数(解析后的形态,字段全部必填)
442
+ */
443
+ type LiquidGlassParams = {
444
+ /**
445
+ * 形状类别
446
+ */
447
+ shape: GlassShapeKind;
448
+ /**
449
+ * 形状外接宽度(px)
450
+ */
451
+ width: number;
452
+ /**
453
+ * 形状外接高度(px)
454
+ */
455
+ height: number;
456
+ /**
457
+ * 圆角半径(px)
458
+ */
459
+ cornerRadius: number;
460
+ /**
461
+ * squircle 角平滑度 0..1
462
+ */
463
+ cornerSmoothing: number;
464
+ /**
465
+ * 基础折射强度 0..1
466
+ */
467
+ refraction: number;
468
+ /**
469
+ * 折射带宽度(px,从边界向内)
470
+ */
471
+ refractionHeight: number;
472
+ /**
473
+ * bevel 斜面强度 0..1
474
+ */
475
+ bevel: number;
476
+ /**
477
+ * bevel 幂次(边缘陡峭度)
478
+ */
479
+ bevelExponent: number;
480
+ /**
481
+ * 色散强度 0..1
482
+ */
483
+ dispersion: number;
484
+ /**
485
+ * 背景模糊半径(px)
486
+ */
487
+ blur: number;
488
+ /**
489
+ * 霜化(磨砂颗粒)强度 0..1
490
+ */
491
+ frost: number;
492
+ /**
493
+ * 着色(RGBA,a 为浓度)
494
+ */
495
+ tint: RGBA;
496
+ /**
497
+ * 背景饱和度系数(1 = 不变,>1 增饱和)
498
+ */
499
+ saturation: number;
500
+ /**
501
+ * 背景亮度系数(1 = 不变)
502
+ */
503
+ brightness: number;
504
+ /**
505
+ * 边缘高光强度 0..1
506
+ */
507
+ specular: number;
508
+ /**
509
+ * 边缘高光锐度(幂次)
510
+ */
511
+ specularExponent: number;
512
+ /**
513
+ * 弹性形变系数 0..1(指针交互的方向性拉伸,0 = 关闭)
514
+ */
515
+ elasticity: number;
516
+ };
517
+ /**
518
+ * 参数输入形态:预设 + 任意覆盖(适配层 props 直传)
519
+ */
520
+ type LiquidGlassParamsInput = Partial<LiquidGlassParams> & {
521
+ /**
522
+ * 预设标识(缺省 apple)
523
+ */
524
+ preset?: GlassPresetId;
525
+ };
526
+ //#endregion
527
+ //#region src/params/params.utils.d.ts
528
+ /**
529
+ * 解析参数输入为完整参数(预设 + 覆盖 + 钳制)
530
+ *
531
+ * @param input - 参数输入(缺省使用 apple 预设)
532
+ * @returns 字段完整的液态玻璃参数
533
+ */
534
+ declare function resolveParams(input?: LiquidGlassParamsInput): LiquidGlassParams;
535
+ /**
536
+ * 按文档范围钳制参数数值字段
537
+ *
538
+ * @param params - 待钳制参数
539
+ * @returns 钳制后的新参数对象(不修改入参)
540
+ */
541
+ declare function clampParams(params: LiquidGlassParams): LiquidGlassParams;
542
+ /**
543
+ * 参数浅比较(tint 深比较),供适配层判断是否需要热更新
544
+ *
545
+ * @param a - 左参数
546
+ * @param b - 右参数
547
+ * @returns 字段全等时为 true
548
+ */
549
+ declare function isParamsEqual(a: LiquidGlassParams, b: LiquidGlassParams): boolean;
550
+ //#endregion
551
+ //#region src/params/presets.constants.d.ts
552
+ /**
553
+ * 预设表:每个预设都是字段完整的参数对象
554
+ */
555
+ /**
556
+ * 默认预设(apple)
557
+ */
558
+ declare const DEFAULT_PRESET: LiquidGlassParams;
559
+ /**
560
+ * 预设表:每个预设都是字段完整的参数对象
561
+ */
562
+ declare const GLASS_PRESETS: Record<GlassPresetId, LiquidGlassParams>;
563
+ /**
564
+ * 默认预设标识
565
+ */
566
+ declare const DEFAULT_PRESET_ID: GlassPresetId;
567
+ //#endregion
568
+ //#region src/render/renderer.types.d.ts
569
+ /**
570
+ * 渲染后端标识
571
+ *
572
+ * - svg-filter:SVG feDisplacementMap 路线(最佳兼容)
573
+ * - webgl:WebGL 路线(最强表现力)
574
+ * - webgpu:WebGPU 路线(下一代,experimental)
575
+ * - css-backdrop:CSS backdrop-filter 降级路线(保底)
576
+ */
577
+ type RendererBackend = 'svg-filter' | 'webgl' | 'webgpu' | 'css-backdrop';
578
+ /**
579
+ * 容器尺寸(CSS 像素)
580
+ */
581
+ type LiquidGlassSize = {
582
+ /**
583
+ * 宽度(px)
584
+ */
585
+ width: number;
586
+ /**
587
+ * 高度(px)
588
+ */
589
+ height: number;
590
+ };
591
+ /**
592
+ * 渲染器能力描述(装配层能力检测报告的数据来源)
593
+ */
594
+ type RendererCapability = {
595
+ /**
596
+ * 后端标识
597
+ */
598
+ backend: RendererBackend;
599
+ /**
600
+ * 是否支持折射位移
601
+ */
602
+ supportsRefraction: boolean;
603
+ /**
604
+ * 是否支持色散
605
+ */
606
+ supportsDispersion: boolean;
607
+ /**
608
+ * 是否支持背景模糊
609
+ */
610
+ supportsBlur: boolean;
611
+ /**
612
+ * 是否支持边缘高光
613
+ */
614
+ supportsSpecular: boolean;
615
+ /**
616
+ * 是否支持直接采样 DOM 背景(无需显式背景源)
617
+ */
618
+ supportsDomBackdrop: boolean;
619
+ /**
620
+ * 实验性说明(非实验后端为 undefined)
621
+ */
622
+ experimental?: string;
623
+ };
624
+ /**
625
+ * 背景亮度统计(liquid-dom 的 adaptive tint 数据源)
626
+ */
627
+ type BackdropMetrics = {
628
+ /**
629
+ * 平均亮度(线性空间 0..1)
630
+ */
631
+ averageLuminance: number;
632
+ /**
633
+ * 亮度中位数 P50(抗抖动的自适应色调推荐输入)
634
+ */
635
+ luminanceP50: number;
636
+ /**
637
+ * 亮度 P90(高光参考)
638
+ */
639
+ luminanceP90: number;
640
+ };
641
+ /**
642
+ * 背景源策略:向渲染器供给玻璃背后的像素
643
+ *
644
+ * 帧类型由实现方与渲染器约定(如 HTMLCanvasElement / ImageBitmap / GPUTexture),
645
+ * core 不约束其形态(零平台依赖)。
646
+ *
647
+ * @typeParam TFrame - 背景帧句柄类型(由 BackdropSource 实现方与渲染器约定)
648
+ */
649
+ type BackdropSource<TFrame = unknown> = {
650
+ /**
651
+ * 背景源标识(调试与复用)
652
+ */
653
+ readonly id: string;
654
+ /**
655
+ * 捕获当前背景帧
656
+ *
657
+ * @returns 帧句柄(同步或异步)
658
+ */
659
+ capture(): TFrame | Promise<TFrame>;
660
+ /**
661
+ * 释放背景源持有的资源
662
+ */
663
+ dispose(): void;
664
+ };
665
+ /**
666
+ * 渲染上下文(工厂入参)
667
+ */
668
+ type LiquidGlassRenderContext = {
669
+ /**
670
+ * 初始参数(已解析的完整形态)
671
+ */
672
+ params: LiquidGlassParams;
673
+ /**
674
+ * 初始尺寸
675
+ */
676
+ size: LiquidGlassSize;
677
+ };
678
+ /**
679
+ * 液态玻璃渲染器(策略接口)
680
+ *
681
+ * @typeParam TTarget - 渲染目标句柄类型(如 DOM 元素或原生视图)
682
+ */
683
+ type LiquidGlassRenderer<TTarget = unknown> = {
684
+ /**
685
+ * 后端标识
686
+ */
687
+ readonly backend: RendererBackend;
688
+ /**
689
+ * 挂载到目标(DOM 元素 / 原生视图等平台句柄)
690
+ *
691
+ * @param target - 平台目标句柄
692
+ */
693
+ mount(target: TTarget): void;
694
+ /**
695
+ * 热更新参数(不重建实例)
696
+ *
697
+ * @param params - 完整参数
698
+ */
699
+ update(params: LiquidGlassParams): void;
700
+ /**
701
+ * 尺寸变化通知
702
+ *
703
+ * @param size - 新尺寸
704
+ */
705
+ resize(size: LiquidGlassSize): void;
706
+ /**
707
+ * 获取能力描述
708
+ *
709
+ * @returns 能力描述
710
+ */
711
+ getCapabilities(): RendererCapability;
712
+ /**
713
+ * 卸载并释放全部资源(幂等)
714
+ */
715
+ unmount(): void;
716
+ };
717
+ /**
718
+ * 渲染器工厂(后端包的导出形态)
719
+ *
720
+ * @typeParam TTarget - 渲染目标句柄类型(如 DOM 元素或原生视图)
721
+ */
722
+ type LiquidGlassRendererFactory<TTarget = unknown> = (context: LiquidGlassRenderContext) => LiquidGlassRenderer<TTarget>;
723
+ //#endregion
724
+ export { type BackdropMetrics, type BackdropSource, type ChannelDisplacements, DEFAULT_PRESET, DEFAULT_PRESET_ID, GLASS_PRESETS, type GlassPresetId, type GlassShapeDescriptor, type GlassShapeKind, type HeightProfileParams, type LiquidGlassParams, type LiquidGlassParamsInput, type LiquidGlassRenderContext, type LiquidGlassRenderer, type LiquidGlassRendererFactory, type LiquidGlassSize, type RGBA, type RefractionParams, type RendererBackend, type RendererCapability, SPECTRAL_WEIGHTS, type ScalarField, type SpectralDispersionScales, type SpecularParams, type Vec2, addVec2, channelDispersionScales, channelDisplacements, circleMap, clampParams, dotVec2, dualRimSpecular, edgeFactor, edgeHeightProfile, fieldGradient, heightFieldNormal, isParamsEqual, lengthVec2, maxDisplacement, normalizeVec2, refractionDisplacement, resolveParams, rimFalloff, rimSpecular, scaleVec2, sdCircle, sdPill, sdRoundedRect, sdRoundedRectSmooth, sdShape, sdfOutwardNormal, spectralDisplacement, subVec2, vec2 };
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ const e=1e-6;function t(e,t,n){return Math.hypot(e,t)-n}function n(t,n,r,i){let a=Math.max(Math.min(r,i)/2,e),o=Math.max(Math.abs(r-i)/2,0);if(r>=i){let e=Math.min(Math.max(t,-o),o);return Math.hypot(t-e,n)-a}let s=Math.min(Math.max(n,-o),o);return Math.hypot(t,n-s)-a}function r(e,t,n,r,i){let a=Math.abs(e)-(n-i),o=Math.abs(t)-(r-i);return Math.hypot(Math.max(a,0),Math.max(o,0))+Math.min(Math.max(a,o),0)-i}function i(e,t,n,r,i,a){let o=Math.min(Math.max(a,0),1),s=2+o*6,c=Math.abs(e)-(n-i),l=Math.abs(t)-(r-i),u=Math.max(c,0),d=Math.max(l,0);return(o===0?Math.hypot(u,d):(u**+s+d**+s)**(1/s))+Math.min(Math.max(c,l),0)-i}function a(r,a,o){switch(o.kind){case`circle`:return t(r,a,Math.min(o.width,o.height)/2);case`pill`:return n(r,a,o.width,o.height);default:{let t=o.width/2,n=o.height/2;return i(r,a,t,n,Math.min(o.radius,Math.min(t,n)-e),o.smoothing)}}}function o(e,t){return{x:e,y:t}}function s(e,t){return{x:e.x+t.x,y:e.y+t.y}}function c(e,t){return{x:e.x-t.x,y:e.y-t.y}}function l(e,t){return{x:e.x*t,y:e.y*t}}function u(e,t){return e.x*t.x+e.y*t.y}function d(e){return Math.hypot(e.x,e.y)}function f(e){let t=d(e);return t===0?{x:0,y:0}:{x:e.x/t,y:e.y/t}}const p=.5;function m(e,t,n,r=p){return o((e(t+r,n)-e(t-r,n))/(2*r),(e(t,n+r)-e(t,n-r))/(2*r))}function h(e,t,n,r=p){return f(m(e,t,n,r))}function g(e,t,n,r=p){let i=m(e,t,n,r);return f(o(-i.x,-i.y))}function _(e){let t=Math.min(Math.max(e,0),1);return 1-Math.sqrt(1-t*t)}function v(e,t){if(t<=0)return+(e>=0);let n=1+e/t;return Math.min(Math.max(n,0),1)}function y(e,t){let n=v(e,t.refractionHeight);return t.refraction*_(n)+t.bevel*n**+t.bevelExponent}function b(e,t,n){return l(t,-(y(e,n)*n.refractionHeight*n.displacementScale))}function x(e){return(e.refraction+e.bevel)*e.refractionHeight*e.displacementScale}const S=[.175,.15,.145,.14,.135,.13,.125];function C(e){let t=Math.min(Math.max(e,0),1);return{r:1-.5*t,g:1,b:1+.7*t}}function w(e,t){let n=C(t);return{r:l(e,n.r),g:l(e,n.g),b:l(e,n.b)}}function T(e,t){let n=Math.min(Math.max(t,0),1),r=o(0,0);for(let t=0;t<S.length;t+=1){let i=1+(-.5+1.2*(t/(S.length-1)))*n;r=s(r,l(e,i*(S[t]??0)))}return r}function E(e,t){return Math.min(Math.max(e,0),1)**+t}function D(e,t,n){let r=f(t);return n.specular*E(u(e,r),n.specularExponent)}function O(e,t,n){return D(e,t,n)+D(e,{x:-t.x,y:-t.y},{...n,specular:n.specular*.5})}const k={shape:`rounded-rect`,width:320,height:200,cornerRadius:32,cornerSmoothing:.6,refraction:.35,refractionHeight:70,bevel:.25,bevelExponent:10,dispersion:.12,blur:2,frost:0,tint:{r:1,g:1,b:1,a:.08},saturation:1.4,brightness:1.05,specular:.6,specularExponent:24,elasticity:.15},A={apple:k,standard:{shape:`rounded-rect`,width:320,height:200,cornerRadius:24,cornerSmoothing:0,refraction:.3,refractionHeight:60,bevel:.15,bevelExponent:8,dispersion:.08,blur:1,frost:0,tint:{r:1,g:1,b:1,a:.05},saturation:1.25,brightness:1.02,specular:.45,specularExponent:20,elasticity:.1},polar:{shape:`rounded-rect`,width:320,height:200,cornerRadius:40,cornerSmoothing:.3,refraction:.45,refractionHeight:96,bevel:.2,bevelExponent:10,dispersion:.14,blur:2,frost:0,tint:{r:1,g:1,b:1,a:.06},saturation:1.35,brightness:1.04,specular:.5,specularExponent:22,elasticity:.15},prominent:{shape:`rounded-rect`,width:320,height:200,cornerRadius:28,cornerSmoothing:.2,refraction:.7,refractionHeight:110,bevel:.4,bevelExponent:9,dispersion:.22,blur:3,frost:.05,tint:{r:1,g:1,b:1,a:.08},saturation:1.5,brightness:1.08,specular:.65,specularExponent:18,elasticity:.2},frosted:{shape:`rounded-rect`,width:320,height:200,cornerRadius:24,cornerSmoothing:.4,refraction:.15,refractionHeight:40,bevel:.1,bevelExponent:8,dispersion:.04,blur:14,frost:.6,tint:{r:1,g:1,b:1,a:.12},saturation:1.2,brightness:1.1,specular:.3,specularExponent:16,elasticity:.08},lens:{shape:`circle`,width:220,height:220,cornerRadius:110,cornerSmoothing:0,refraction:.85,refractionHeight:90,bevel:.3,bevelExponent:12,dispersion:.3,blur:0,frost:0,tint:{r:1,g:1,b:1,a:.02},saturation:1.15,brightness:1,specular:.75,specularExponent:30,elasticity:0}},j=`apple`;function M(e,t,n){return Math.min(Math.max(e,t),n)}function N(e){let t=A[e?.preset??`apple`]??k,{preset:n,...r}=e??{};return P({...t,...r})}function P(e){return{...e,width:Math.max(e.width,1),height:Math.max(e.height,1),cornerRadius:Math.max(e.cornerRadius,0),cornerSmoothing:M(e.cornerSmoothing,0,1),refraction:M(e.refraction,0,1),refractionHeight:Math.max(e.refractionHeight,0),bevel:M(e.bevel,0,1),bevelExponent:M(e.bevelExponent,1,32),dispersion:M(e.dispersion,0,1),blur:Math.max(e.blur,0),frost:M(e.frost,0,1),tint:{r:M(e.tint.r,0,1),g:M(e.tint.g,0,1),b:M(e.tint.b,0,1),a:M(e.tint.a,0,1)},saturation:Math.max(e.saturation,0),brightness:Math.max(e.brightness,0),specular:M(e.specular,0,1),specularExponent:M(e.specularExponent,1,64),elasticity:M(e.elasticity,0,1)}}function F(e,t){return e.shape!==t.shape||e.width!==t.width||e.height!==t.height||e.cornerRadius!==t.cornerRadius||e.cornerSmoothing!==t.cornerSmoothing||e.refraction!==t.refraction||e.refractionHeight!==t.refractionHeight||e.bevel!==t.bevel||e.bevelExponent!==t.bevelExponent||e.dispersion!==t.dispersion||e.blur!==t.blur||e.frost!==t.frost||e.saturation!==t.saturation||e.brightness!==t.brightness||e.specular!==t.specular||e.specularExponent!==t.specularExponent||e.elasticity!==t.elasticity?!1:e.tint.r===t.tint.r&&e.tint.g===t.tint.g&&e.tint.b===t.tint.b&&e.tint.a===t.tint.a}export{k as DEFAULT_PRESET,j as DEFAULT_PRESET_ID,A as GLASS_PRESETS,S as SPECTRAL_WEIGHTS,s as addVec2,C as channelDispersionScales,w as channelDisplacements,_ as circleMap,P as clampParams,u as dotVec2,O as dualRimSpecular,v as edgeFactor,y as edgeHeightProfile,m as fieldGradient,g as heightFieldNormal,F as isParamsEqual,d as lengthVec2,x as maxDisplacement,f as normalizeVec2,b as refractionDisplacement,N as resolveParams,E as rimFalloff,D as rimSpecular,l as scaleVec2,t as sdCircle,n as sdPill,r as sdRoundedRect,i as sdRoundedRectSmooth,a as sdShape,h as sdfOutwardNormal,T as spectralDisplacement,c as subVec2,o as vec2};
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@longzai-intelligence-liquid-glass/core",
3
+ "version": "0.0.1",
4
+ "description": "Liquid Glass 框架无关核心:形状 SDF、光学剖面、参数模型与渲染器抽象接口",
5
+ "license": "UNLICENSED",
6
+ "files": [
7
+ "dist"
8
+ ],
9
+ "type": "module",
10
+ "main": "./dist/index.js",
11
+ "types": "./dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js"
16
+ }
17
+ },
18
+ "scripts": {
19
+ "build": "lzi-builder",
20
+ "build:prod": "NODE_ENV=production bun run build",
21
+ "prepublishOnly": "bun run build:prod",
22
+ "typecheck": "bun run typecheck:app && bun run typecheck:node && bun run typecheck:test",
23
+ "typecheck:app": "lzi-tsgo typecheck tsconfig/app.json",
24
+ "typecheck:node": "lzi-tsgo typecheck tsconfig/node.json",
25
+ "typecheck:test": "lzi-tsgo typecheck tsconfig/test.json",
26
+ "lint": "oxlint && oxfmt --check",
27
+ "lint:fix": "oxlint --fix && oxfmt",
28
+ "test": "lzi-bun-cli test",
29
+ "test:watch": "lzi-bun-cli test --watch",
30
+ "test:coverage": "lzi-bun-cli test --coverage",
31
+ "clean": "lzi-dev-cli clean"
32
+ },
33
+ "dependencies": {},
34
+ "packageManager": "bun@1.3.14"
35
+ }