@longzai-intelligence-liquid-glass/react-native 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 +12 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.js +59 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# @longzai-intelligence-liquid-glass/react-native
|
|
2
|
+
|
|
3
|
+
Liquid Glass React Native 适配层:Skia RuntimeShader 真折射。
|
|
4
|
+
|
|
5
|
+
## 用法
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun run --cwd packages/adapters/react-native lint # 代码检查
|
|
9
|
+
bun run --cwd packages/adapters/react-native typecheck # 类型检查(tsgo)
|
|
10
|
+
bun run --cwd packages/adapters/react-native test # 单元测试
|
|
11
|
+
bun run --cwd packages/adapters/react-native build # 构建(lzi-builder → dist)
|
|
12
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { LiquidGlassParamsInput } from "@longzai-intelligence-liquid-glass/core";
|
|
2
|
+
//#region src/liquid-glass-view.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* LiquidGlassView 属性
|
|
5
|
+
*/
|
|
6
|
+
type LiquidGlassViewProps = {
|
|
7
|
+
/**
|
|
8
|
+
* 视图宽度(px)
|
|
9
|
+
*/
|
|
10
|
+
width: number;
|
|
11
|
+
/**
|
|
12
|
+
* 视图高度(px)
|
|
13
|
+
*/
|
|
14
|
+
height: number;
|
|
15
|
+
/**
|
|
16
|
+
* 强制使用降级路线(对比演示用)
|
|
17
|
+
*/
|
|
18
|
+
fallback?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* 叠加在玻璃之上的内容(Skia 图层)
|
|
21
|
+
*/
|
|
22
|
+
children?: React.ReactNode;
|
|
23
|
+
} & LiquidGlassParamsInput;
|
|
24
|
+
/**
|
|
25
|
+
* LiquidGlassView 组件
|
|
26
|
+
*
|
|
27
|
+
* @param props - 组件属性
|
|
28
|
+
* @returns 玻璃视图 JSX
|
|
29
|
+
*/
|
|
30
|
+
declare function LiquidGlassView(props: LiquidGlassViewProps): import("react").JSX.Element;
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/refraction-shader.constants.d.ts
|
|
33
|
+
/**
|
|
34
|
+
* SkSL 折射着色器
|
|
35
|
+
*
|
|
36
|
+
* Kyant0/AndroidLiquidGlass 的 AGSL 折射着色器移植(AGSL 源自 SkSL,语义一致):
|
|
37
|
+
* sdRoundedRect + circleMap 弧面高度 + SDF 梯度法线 + R/B 对称色散 + tint。
|
|
38
|
+
* uniform 与 core 参数模型对齐,由 <LiquidGlassView> 驱动。
|
|
39
|
+
*/
|
|
40
|
+
/**
|
|
41
|
+
* 折射着色器 SkSL 源码
|
|
42
|
+
*
|
|
43
|
+
* uniforms:
|
|
44
|
+
* - halfSize:形状半宽高(px)
|
|
45
|
+
* - radius:圆角半径(px)
|
|
46
|
+
* - refraction:基础折射强度 0..1
|
|
47
|
+
* - refractionHeight:折射带宽度(px)
|
|
48
|
+
* - bevel:bevel 强度 0..1
|
|
49
|
+
* - dispersion:色散强度 0..1
|
|
50
|
+
* - tint:着色(rgba)
|
|
51
|
+
*/
|
|
52
|
+
declare const REFRACTION_SKSL = "\nuniform shader content;\nuniform float2 halfSize;\nuniform float radius;\nuniform float refraction;\nuniform float refractionHeight;\nuniform float bevel;\nuniform float dispersion;\nuniform float4 tint;\n\n/**\n * 圆角矩形 SDF(局部坐标,形状中心为原点)\n */\nfloat sdRoundBox(float2 p, float2 b, float r) {\n float2 q = abs(p) - b + float2(r);\n float outside = length(max(q, float2(0.0)));\n float inside = min(max(q.x, q.y), 0.0);\n return outside + inside - r;\n}\n\n/**\n * SDF 数值梯度 → 单位外法线\n */\nfloat2 sdNormal(float2 p, float2 b, float r) {\n float e = 1.0;\n float dx = sdRoundBox(p + float2(e, 0.0), b, r) - sdRoundBox(p - float2(e, 0.0), b, r);\n float dy = sdRoundBox(p + float2(0.0, e), b, r) - sdRoundBox(p - float2(0.0, e), b, r);\n return normalize(float2(dx, dy) + float2(1e-6));\n}\n\n/**\n * circleMap:归一化深度 → 弧面高度\n */\nfloat circleMap(float x) {\n float c = clamp(x, 0.0, 1.0);\n return 1.0 - sqrt(1.0 - c * c);\n}\n\nhalf4 main(float2 coord) {\n float2 p = coord - halfSize;\n float sdf = sdRoundBox(p, halfSize, radius);\n float2 normal = sdNormal(p, halfSize, radius);\n\n float f = clamp(1.0 + sdf / max(refractionHeight, 1e-4), 0.0, 1.0);\n float height = refraction * circleMap(f) + bevel * pow(f, 10.0);\n float2 offset = -normal * height * refractionHeight;\n\n // R/B 沿折射方向对称缩放(蓝端更大,liquidGL 色散策略)\n half4 rSample = content.eval(coord + offset * (1.0 - 0.5 * dispersion));\n half4 gSample = content.eval(coord + offset);\n half4 bSample = content.eval(coord + offset * (1.0 + 0.7 * dispersion));\n\n half3 color = half3(rSample.r, gSample.g, bSample.b);\n color = mix(color, half3(tint.rgb), tint.a);\n\n float mask = 1.0 - smoothstep(-1.5, 1.5, sdf);\n return half4(color, mask);\n}\n";
|
|
53
|
+
//#endregion
|
|
54
|
+
export { LiquidGlassView, type LiquidGlassViewProps, REFRACTION_SKSL };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import{resolveParams as e}from"@longzai-intelligence-liquid-glass/core";import{BackdropBlur as t,BackdropFilter as n,Canvas as r,RoundedRect as i,RuntimeShader as a,Skia as o}from"@shopify/react-native-skia";import{useMemo as s}from"react";import{jsx as c,jsxs as l}from"react/jsx-runtime";const u=`
|
|
2
|
+
uniform shader content;
|
|
3
|
+
uniform float2 halfSize;
|
|
4
|
+
uniform float radius;
|
|
5
|
+
uniform float refraction;
|
|
6
|
+
uniform float refractionHeight;
|
|
7
|
+
uniform float bevel;
|
|
8
|
+
uniform float dispersion;
|
|
9
|
+
uniform float4 tint;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 圆角矩形 SDF(局部坐标,形状中心为原点)
|
|
13
|
+
*/
|
|
14
|
+
float sdRoundBox(float2 p, float2 b, float r) {
|
|
15
|
+
float2 q = abs(p) - b + float2(r);
|
|
16
|
+
float outside = length(max(q, float2(0.0)));
|
|
17
|
+
float inside = min(max(q.x, q.y), 0.0);
|
|
18
|
+
return outside + inside - r;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* SDF 数值梯度 → 单位外法线
|
|
23
|
+
*/
|
|
24
|
+
float2 sdNormal(float2 p, float2 b, float r) {
|
|
25
|
+
float e = 1.0;
|
|
26
|
+
float dx = sdRoundBox(p + float2(e, 0.0), b, r) - sdRoundBox(p - float2(e, 0.0), b, r);
|
|
27
|
+
float dy = sdRoundBox(p + float2(0.0, e), b, r) - sdRoundBox(p - float2(0.0, e), b, r);
|
|
28
|
+
return normalize(float2(dx, dy) + float2(1e-6));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* circleMap:归一化深度 → 弧面高度
|
|
33
|
+
*/
|
|
34
|
+
float circleMap(float x) {
|
|
35
|
+
float c = clamp(x, 0.0, 1.0);
|
|
36
|
+
return 1.0 - sqrt(1.0 - c * c);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
half4 main(float2 coord) {
|
|
40
|
+
float2 p = coord - halfSize;
|
|
41
|
+
float sdf = sdRoundBox(p, halfSize, radius);
|
|
42
|
+
float2 normal = sdNormal(p, halfSize, radius);
|
|
43
|
+
|
|
44
|
+
float f = clamp(1.0 + sdf / max(refractionHeight, 1e-4), 0.0, 1.0);
|
|
45
|
+
float height = refraction * circleMap(f) + bevel * pow(f, 10.0);
|
|
46
|
+
float2 offset = -normal * height * refractionHeight;
|
|
47
|
+
|
|
48
|
+
// R/B 沿折射方向对称缩放(蓝端更大,liquidGL 色散策略)
|
|
49
|
+
half4 rSample = content.eval(coord + offset * (1.0 - 0.5 * dispersion));
|
|
50
|
+
half4 gSample = content.eval(coord + offset);
|
|
51
|
+
half4 bSample = content.eval(coord + offset * (1.0 + 0.7 * dispersion));
|
|
52
|
+
|
|
53
|
+
half3 color = half3(rSample.r, gSample.g, bSample.b);
|
|
54
|
+
color = mix(color, half3(tint.rgb), tint.a);
|
|
55
|
+
|
|
56
|
+
float mask = 1.0 - smoothstep(-1.5, 1.5, sdf);
|
|
57
|
+
return half4(color, mask);
|
|
58
|
+
}
|
|
59
|
+
`;let d=null,f=!1;function p(){if(!f){f=!0;try{d=o.RuntimeEffect.Make(u)}catch{d=null}}return d}function m(o){let{width:u,height:d,fallback:f=!1,children:m,...h}=o,g=s(()=>e(h),[h]),_=g.shape===`circle`?Math.min(u,d)/2:Math.min(g.cornerRadius,Math.min(u,d)/2-.5),v=s(()=>({halfSize:[u/2,d/2],radius:_,refraction:g.refraction,refractionHeight:g.refractionHeight,bevel:g.bevel,dispersion:g.dispersion,tint:[g.tint.r,g.tint.g,g.tint.b,g.tint.a]}),[u,d,_,g]),y=p(),b=f||y===null,x=g.blur+g.refraction*2+g.frost*12,S=b?`rgba(${Math.round(g.tint.r*255)}, ${Math.round(g.tint.g*255)}, ${Math.round(g.tint.b*255)}, ${g.tint.a})`:`transparent`;return l(r,{style:{width:u,height:d},children:[c(n,{filter:b?c(t,{blur:x}):c(a,{source:y,uniforms:v}),children:c(i,{x:0,y:0,width:u,height:d,r:_,color:S})}),m]})}export{m as LiquidGlassView,u as REFRACTION_SKSL};
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@longzai-intelligence-liquid-glass/react-native",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Liquid Glass React Native 绑定(Skia RuntimeShader)",
|
|
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
|
+
"@longzai-intelligence-liquid-glass/core": "0.0.1"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@shopify/react-native-skia": "^1.5.0",
|
|
38
|
+
"@types/react": "^19.2.15",
|
|
39
|
+
"@types/react-native": "^0.73.0"
|
|
40
|
+
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"@shopify/react-native-skia": "^1.5.0",
|
|
43
|
+
"react": "^19.2.6",
|
|
44
|
+
"react-native": "^0.79.0"
|
|
45
|
+
},
|
|
46
|
+
"packageManager": "bun@1.3.14"
|
|
47
|
+
}
|