kmcom-nuxt-layers 2.2.12 → 2.2.13

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.
Files changed (98) hide show
  1. package/docs/FEEDS.md +1 -2
  2. package/layers/animations/app/composables/useMagneticElement.ts +11 -9
  3. package/layers/animations/app/composables/useTiltEffect.ts +11 -9
  4. package/layers/animations/app/utils/pointerMotion.ts +31 -0
  5. package/layers/canvas/app/components/ShaderCanvas.vue +2 -2
  6. package/layers/content/app/composables/useCollectionItems.ts +28 -0
  7. package/layers/content/app/composables/useGalleryItems.ts +8 -14
  8. package/layers/content/app/composables/usePortfolioItems.ts +10 -18
  9. package/layers/core/app/composables/useBrowser.ts +9 -82
  10. package/layers/core/app/composables/useFeatures.ts +3 -27
  11. package/layers/core/app/plugins/init.ts +157 -135
  12. package/layers/core/app/utils/browserInfo.ts +115 -0
  13. package/layers/core/app/utils/featureClasses.ts +40 -0
  14. package/layers/core/app/utils/helpers.test.ts +51 -0
  15. package/layers/feeds/app/components/Feeds/Index.vue +1 -1
  16. package/layers/feeds/app/components/Feeds/RouteCard.vue +3 -9
  17. package/layers/feeds/app/utils/feed-catalog.ts +9 -4
  18. package/layers/feeds/nuxt.config.ts +0 -1
  19. package/layers/feeds/server/utils/content-adapter.test.ts +68 -0
  20. package/layers/feeds/server/utils/content-adapter.ts +2 -22
  21. package/layers/feeds/server/utils/feed-author.ts +32 -0
  22. package/layers/feeds/server/utils/feed-config.ts +88 -0
  23. package/layers/feeds/server/utils/feed-service.ts +11 -30
  24. package/layers/feeds/server/utils/feed-xml.ts +26 -0
  25. package/layers/feeds/server/utils/formats/rss.ts +10 -15
  26. package/layers/feeds/server/utils/formats.test.ts +71 -0
  27. package/layers/forms/app/components/Form/Field.vue +42 -30
  28. package/layers/forms/app/utils/fieldProps.ts +65 -0
  29. package/layers/layout/app/components/Layout/Grid/Item.vue +29 -146
  30. package/layers/layout/app/utils/gridPlacementStyle.ts +195 -0
  31. package/layers/mailer/app/types/mailer.ts +7 -25
  32. package/layers/mailer/server/utils/email.ts +28 -13
  33. package/layers/mailer/server/utils/hooks.ts +1 -20
  34. package/layers/navigation/app/composables/useSite.ts +2 -9
  35. package/layers/navigation/app/utils/site.ts +26 -0
  36. package/layers/routing/app/utils/resolveRoute.test.ts +47 -0
  37. package/layers/routing/app/utils/resolveRoute.ts +19 -10
  38. package/layers/scripts/app/composables/useAnalytics.ts +8 -41
  39. package/layers/scripts/app/composables/useGtm.ts +6 -13
  40. package/layers/scripts/app/utils/scriptClients.ts +70 -0
  41. package/layers/scroll/app/composables/useSmoothScroll.ts +9 -43
  42. package/layers/scroll/app/utils/scroll.ts +103 -0
  43. package/layers/seo/app/composables/useSeoConfig.ts +3 -9
  44. package/layers/seo/app/utils/seoConfig.ts +38 -0
  45. package/layers/shader/app/components/Material/AmbientAurora.client.vue +11 -33
  46. package/layers/shader/app/components/Material/AmbientFlow.client.vue +10 -37
  47. package/layers/shader/app/components/Material/AmbientGradientMesh.client.vue +10 -37
  48. package/layers/shader/app/components/Material/AmbientNebula.client.vue +12 -37
  49. package/layers/shader/app/components/Material/AmbientOcean.client.vue +9 -33
  50. package/layers/shader/app/components/Material/Gradient.client.vue +25 -46
  51. package/layers/shader/app/components/Material/Image.client.vue +10 -55
  52. package/layers/shader/app/components/Material/Node.client.vue +18 -5
  53. package/layers/shader/app/components/Material/Noise.client.vue +9 -43
  54. package/layers/shader/app/components/Preset/ThemeBubble.client.vue +2 -1
  55. package/layers/shader/app/components/Preset/ThemeFlow.client.vue +2 -1
  56. package/layers/shader/app/components/Preset/ThemeGradient.client.vue +2 -1
  57. package/layers/shader/app/components/Preset/ThemeLavaLamp.client.vue +2 -1
  58. package/layers/shader/app/components/Preset/ThemePlasma.client.vue +2 -1
  59. package/layers/shader/app/components/Preset/ThemeWave.client.vue +2 -1
  60. package/layers/shader/app/components/Shader/Background.client.vue +44 -24
  61. package/layers/shader/app/composables/useAmbientMaterials.ts +5 -1
  62. package/layers/shader/app/composables/useShader.ts +38 -23
  63. package/layers/shader/app/composables/useShaderGraph.ts +11 -6
  64. package/layers/shader/app/composables/useShaderMixBlend.ts +4 -4
  65. package/layers/shader/app/composables/useShaderRuntime.ts +0 -1
  66. package/layers/shader/app/composables/useShaderVec2.ts +2 -4
  67. package/layers/shader/app/composables/useThemePreset.ts +34 -8
  68. package/layers/shader/app/composables/useUniformWatchers.ts +15 -0
  69. package/layers/shader/app/composables/useUniforms.ts +0 -1
  70. package/layers/shader/app/shaders/common/blend.ts +4 -4
  71. package/layers/shader/app/shaders/common/effects.ts +38 -21
  72. package/layers/shader/app/shaders/common/grain.ts +46 -49
  73. package/layers/shader/app/shaders/common/lighting.ts +17 -15
  74. package/layers/shader/app/shaders/common/math.ts +2 -4
  75. package/layers/shader/app/shaders/common/nodes.ts +17 -0
  76. package/layers/shader/app/shaders/common/palette.ts +21 -11
  77. package/layers/shader/app/shaders/common/patterns.ts +25 -14
  78. package/layers/shader/app/shaders/common/shapes.ts +97 -88
  79. package/layers/shader/app/shaders/common/uv.ts +33 -34
  80. package/layers/shader/app/shaders/createMaterial.ts +92 -78
  81. package/layers/shader/app/shaders/layers/paperShading.ts +22 -10
  82. package/layers/shader/app/shaders/layers/shaderGradient.ts +46 -21
  83. package/layers/shader/app/utils/tsl/tween.ts +2 -4
  84. package/layers/shader/package.json +5 -1
  85. package/layers/theme/app/components/ThemePicker/Menu.vue +3 -25
  86. package/layers/theme/app/composables/useThemePreferenceModels.ts +39 -0
  87. package/layers/theme/server/plugins/theme-fouc.ts +1 -92
  88. package/layers/theme/server/utils/accent-css.ts +75 -0
  89. package/layers/typography/app/composables/typography.ts +3 -7
  90. package/layers/visual/app/composables/accent.ts +2 -9
  91. package/layers/visual/app/composables/gradient.ts +33 -46
  92. package/layers/visual/app/composables/picture.ts +2 -79
  93. package/layers/visual/app/utils/colorTokens.ts +23 -0
  94. package/layers/visual/app/utils/gradientStyle.ts +41 -0
  95. package/layers/visual/app/utils/responsiveSizes.ts +49 -0
  96. package/package.json +15 -4
  97. package/layers/feeds/app/utils/feed-catalog.test.ts +0 -71
  98. package/layers/feeds/server/routes/feed/discovery.get.ts +0 -31
@@ -19,6 +19,7 @@ import {
19
19
 
20
20
  import type { TSLNode } from '../types'
21
21
  import { fbm3dSimplex, simplexNoise3d } from './noise'
22
+ import { toScalarNode, toVec2Node } from './nodes'
22
23
 
23
24
  // ============================================
24
25
  // Canvas Weave Pattern
@@ -64,6 +65,13 @@ export type LEDPatternOptions = {
64
65
  edgeSoftness?: TSLNode | number
65
66
  }
66
67
 
68
+ const DEFAULT_LED_PATTERN_OPTIONS = {
69
+ cellSize: 10,
70
+ intensity: 0.5,
71
+ intensityFalloff: 1.8,
72
+ edgeSoftness: 0.2,
73
+ } as const
74
+
67
75
  /**
68
76
  * LED screen pattern with configurable parameters
69
77
  * Creates a grid of circular LED dots
@@ -76,12 +84,15 @@ export function ledPattern(
76
84
  resolution: TSLNode = screenSize,
77
85
  options: LEDPatternOptions = {}
78
86
  ): TSLNode {
79
- const { cellSize = 10, intensity = 0.5, intensityFalloff = 1.8, edgeSoftness = 0.2 } = options
87
+ const { cellSize, intensity, intensityFalloff, edgeSoftness } = {
88
+ ...DEFAULT_LED_PATTERN_OPTIONS,
89
+ ...options,
90
+ }
80
91
 
81
- const _cellSize = typeof cellSize === 'number' ? float(cellSize) : cellSize
82
- const _intensity = typeof intensity === 'number' ? float(intensity) : intensity
83
- const _falloff = typeof intensityFalloff === 'number' ? float(intensityFalloff) : intensityFalloff
84
- const _softness = typeof edgeSoftness === 'number' ? float(edgeSoftness) : edgeSoftness
92
+ const _cellSize = toScalarNode(cellSize)
93
+ const _intensity = toScalarNode(intensity)
94
+ const _falloff = toScalarNode(intensityFalloff)
95
+ const _softness = toScalarNode(edgeSoftness)
85
96
 
86
97
  const _uv = uv.toVar()
87
98
 
@@ -115,8 +126,8 @@ export type SpeckledPatternOptions = {
115
126
  export function speckledNoisePattern(uv: TSLNode, options: SpeckledPatternOptions = {}): TSLNode {
116
127
  const { density = 0.75, warpAmount = [80, 120] } = options
117
128
 
118
- const _density = typeof density === 'number' ? float(density) : density
119
- const _warpAmount = Array.isArray(warpAmount) ? vec2(warpAmount[0], warpAmount[1]) : warpAmount
129
+ const _density = toScalarNode(density)
130
+ const _warpAmount = toVec2Node(warpAmount)
120
131
 
121
132
  // Warp the UVs for organic distribution
122
133
  const warpX = fbm3dSimplex(vec3(uv.mul(3.0), 0.0))
@@ -153,9 +164,9 @@ export type DotGridOptions = {
153
164
  export function dotGridPattern(uv: TSLNode, options: DotGridOptions = {}): TSLNode {
154
165
  const { scale = 10, dotSize = 0.3, softness = 0.1 } = options
155
166
 
156
- const _scale = typeof scale === 'number' ? float(scale) : scale
157
- const _dotSize = typeof dotSize === 'number' ? float(dotSize) : dotSize
158
- const _softness = typeof softness === 'number' ? float(softness) : softness
167
+ const _scale = toScalarNode(scale)
168
+ const _dotSize = toScalarNode(dotSize)
169
+ const _softness = toScalarNode(softness)
159
170
 
160
171
  const grid = fract(uv.mul(_scale)).sub(0.5)
161
172
  const dist = length(grid)
@@ -198,10 +209,10 @@ export type StripeOptions = {
198
209
  export function stripePattern(uv: TSLNode, options: StripeOptions = {}): TSLNode {
199
210
  const { scale = 10, thickness = 0.5, angle = 0, softness = 0.01 } = options
200
211
 
201
- const _scale = typeof scale === 'number' ? float(scale) : scale
202
- const _thickness = typeof thickness === 'number' ? float(thickness) : thickness
203
- const _angle = typeof angle === 'number' ? float(angle) : angle
204
- const _softness = typeof softness === 'number' ? float(softness) : softness
212
+ const _scale = toScalarNode(scale)
213
+ const _thickness = toScalarNode(thickness)
214
+ const _angle = toScalarNode(angle)
215
+ const _softness = toScalarNode(softness)
205
216
 
206
217
  // Rotate UV
207
218
  const cosA = _angle.cos()
@@ -16,10 +16,10 @@ import {
16
16
  sin,
17
17
  smoothstep,
18
18
  step,
19
- vec2,
20
19
  } from 'three/tsl'
21
20
 
22
21
  import type { TSLNode } from '../types'
22
+ import { toScalarNode, toVec2Node } from './nodes'
23
23
 
24
24
  // ============================================
25
25
  // Basic Shapes
@@ -30,13 +30,16 @@ import type { TSLNode } from '../types'
30
30
  */
31
31
  export function blob(
32
32
  uv: TSLNode,
33
- center: TSLNode | [number, number] = [0.5, 0.5],
34
- radius: TSLNode | number = 0.3,
35
- softness: TSLNode | number = 0.1
33
+ ...args: [
34
+ center?: TSLNode | [number, number],
35
+ radius?: TSLNode | number,
36
+ softness?: TSLNode | number,
37
+ ]
36
38
  ): TSLNode {
37
- const c = Array.isArray(center) ? vec2(center[0], center[1]) : center
38
- const r = typeof radius === 'number' ? float(radius) : radius
39
- const s = typeof softness === 'number' ? float(softness) : softness
39
+ const [center = [0.5, 0.5], radius = 0.3, softness = 0.1] = args
40
+ const c = toVec2Node(center)
41
+ const r = toScalarNode(radius)
42
+ const s = toScalarNode(softness)
40
43
 
41
44
  const d = length(uv.sub(c))
42
45
  return smoothstep(r.add(s), r.sub(s), d)
@@ -47,11 +50,11 @@ export function blob(
47
50
  */
48
51
  export function circle(
49
52
  uv: TSLNode,
50
- center: TSLNode | [number, number] = [0.5, 0.5],
51
- radius: TSLNode | number = 0.3
53
+ ...args: [center?: TSLNode | [number, number], radius?: TSLNode | number]
52
54
  ): TSLNode {
53
- const c = Array.isArray(center) ? vec2(center[0], center[1]) : center
54
- const r = typeof radius === 'number' ? float(radius) : radius
55
+ const [center = [0.5, 0.5], radius = 0.3] = args
56
+ const c = toVec2Node(center)
57
+ const r = toScalarNode(radius)
55
58
 
56
59
  const d = length(uv.sub(c))
57
60
  return step(d, r)
@@ -62,15 +65,18 @@ export function circle(
62
65
  */
63
66
  export function ring(
64
67
  uv: TSLNode,
65
- center: TSLNode | [number, number] = [0.5, 0.5],
66
- innerRadius: TSLNode | number = 0.2,
67
- outerRadius: TSLNode | number = 0.3,
68
- softness: TSLNode | number = 0.02
68
+ ...args: [
69
+ center?: TSLNode | [number, number],
70
+ innerRadius?: TSLNode | number,
71
+ outerRadius?: TSLNode | number,
72
+ softness?: TSLNode | number,
73
+ ]
69
74
  ): TSLNode {
70
- const c = Array.isArray(center) ? vec2(center[0], center[1]) : center
71
- const inner = typeof innerRadius === 'number' ? float(innerRadius) : innerRadius
72
- const outer = typeof outerRadius === 'number' ? float(outerRadius) : outerRadius
73
- const s = typeof softness === 'number' ? float(softness) : softness
75
+ const [center = [0.5, 0.5], innerRadius = 0.2, outerRadius = 0.3, softness = 0.02] = args
76
+ const c = toVec2Node(center)
77
+ const inner = toScalarNode(innerRadius)
78
+ const outer = toScalarNode(outerRadius)
79
+ const s = toScalarNode(softness)
74
80
 
75
81
  const d = length(uv.sub(c))
76
82
  const outerEdge = smoothstep(outer.add(s), outer.sub(s), d)
@@ -84,11 +90,11 @@ export function ring(
84
90
  */
85
91
  export function radialGradient(
86
92
  uv: TSLNode,
87
- center: TSLNode | [number, number] = [0.5, 0.5],
88
- scale: TSLNode | number = 1
93
+ ...args: [center?: TSLNode | [number, number], scale?: TSLNode | number]
89
94
  ): TSLNode {
90
- const c = Array.isArray(center) ? vec2(center[0], center[1]) : center
91
- const s = typeof scale === 'number' ? float(scale) : scale
95
+ const [center = [0.5, 0.5], scale = 1] = args
96
+ const c = toVec2Node(center)
97
+ const s = toScalarNode(scale)
92
98
 
93
99
  return max(float(0), float(1).sub(length(uv.sub(c)).mul(s)))
94
100
  }
@@ -98,15 +104,18 @@ export function radialGradient(
98
104
  */
99
105
  export function roundedRect(
100
106
  uv: TSLNode,
101
- center: TSLNode | [number, number] = [0.5, 0.5],
102
- size: TSLNode | [number, number] = [0.4, 0.3],
103
- cornerRadius: TSLNode | number = 0.05,
104
- softness: TSLNode | number = 0.01
107
+ ...args: [
108
+ center?: TSLNode | [number, number],
109
+ size?: TSLNode | [number, number],
110
+ cornerRadius?: TSLNode | number,
111
+ softness?: TSLNode | number,
112
+ ]
105
113
  ): TSLNode {
106
- const c = Array.isArray(center) ? vec2(center[0], center[1]) : center
107
- const sz = Array.isArray(size) ? vec2(size[0], size[1]) : size
108
- const r = typeof cornerRadius === 'number' ? float(cornerRadius) : cornerRadius
109
- const s = typeof softness === 'number' ? float(softness) : softness
114
+ const [center = [0.5, 0.5], size = [0.4, 0.3], cornerRadius = 0.05, softness = 0.01] = args
115
+ const c = toVec2Node(center)
116
+ const sz = toVec2Node(size)
117
+ const r = toScalarNode(cornerRadius)
118
+ const s = toScalarNode(softness)
110
119
 
111
120
  const p: TSLNode = abs(uv.sub(c)).sub(sz.div(2)).add(r)
112
121
  const d = length(max(p, 0))
@@ -121,11 +130,11 @@ export function roundedRect(
121
130
  */
122
131
  export function rect(
123
132
  uv: TSLNode,
124
- center: TSLNode | [number, number] = [0.5, 0.5],
125
- size: TSLNode | [number, number] = [0.4, 0.3]
133
+ ...args: [center?: TSLNode | [number, number], size?: TSLNode | [number, number]]
126
134
  ): TSLNode {
127
- const c = Array.isArray(center) ? vec2(center[0], center[1]) : center
128
- const sz = Array.isArray(size) ? vec2(size[0], size[1]) : size
135
+ const [center = [0.5, 0.5], size = [0.4, 0.3]] = args
136
+ const c = toVec2Node(center)
137
+ const sz = toVec2Node(size)
129
138
 
130
139
  const p: TSLNode = abs(uv.sub(c))
131
140
  const halfSize = sz.div(2)
@@ -142,13 +151,12 @@ export function rect(
142
151
  */
143
152
  export function horizontalLine(
144
153
  uv: TSLNode,
145
- y: TSLNode | number = 0.5,
146
- thickness: TSLNode | number = 0.02,
147
- softness: TSLNode | number = 0.005
154
+ ...args: [y?: TSLNode | number, thickness?: TSLNode | number, softness?: TSLNode | number]
148
155
  ): TSLNode {
149
- const yPos = typeof y === 'number' ? float(y) : y
150
- const t = typeof thickness === 'number' ? float(thickness) : thickness
151
- const s = typeof softness === 'number' ? float(softness) : softness
156
+ const [y = 0.5, thickness = 0.02, softness = 0.005] = args
157
+ const yPos = toScalarNode(y)
158
+ const t = toScalarNode(thickness)
159
+ const s = toScalarNode(softness)
152
160
 
153
161
  const d = abs(uv.y.sub(yPos))
154
162
  return smoothstep(t.div(2).add(s), t.div(2).sub(s), d)
@@ -159,13 +167,12 @@ export function horizontalLine(
159
167
  */
160
168
  export function verticalLine(
161
169
  uv: TSLNode,
162
- x: TSLNode | number = 0.5,
163
- thickness: TSLNode | number = 0.02,
164
- softness: TSLNode | number = 0.005
170
+ ...args: [x?: TSLNode | number, thickness?: TSLNode | number, softness?: TSLNode | number]
165
171
  ): TSLNode {
166
- const xPos = typeof x === 'number' ? float(x) : x
167
- const t = typeof thickness === 'number' ? float(thickness) : thickness
168
- const s = typeof softness === 'number' ? float(softness) : softness
172
+ const [x = 0.5, thickness = 0.02, softness = 0.005] = args
173
+ const xPos = toScalarNode(x)
174
+ const t = toScalarNode(thickness)
175
+ const s = toScalarNode(softness)
169
176
 
170
177
  const d = abs(uv.x.sub(xPos))
171
178
  return smoothstep(t.div(2).add(s), t.div(2).sub(s), d)
@@ -176,13 +183,12 @@ export function verticalLine(
176
183
  */
177
184
  export function stripes(
178
185
  uv: TSLNode,
179
- frequency: TSLNode | number = 10,
180
- thickness: TSLNode | number = 0.5,
181
- angle: TSLNode | number = 0
186
+ ...args: [frequency?: TSLNode | number, thickness?: TSLNode | number, angle?: TSLNode | number]
182
187
  ): TSLNode {
183
- const freq = typeof frequency === 'number' ? float(frequency) : frequency
184
- const t = typeof thickness === 'number' ? float(thickness) : thickness
185
- const a = typeof angle === 'number' ? float(angle) : angle
188
+ const [frequency = 10, thickness = 0.5, angle = 0] = args
189
+ const freq = toScalarNode(frequency)
190
+ const t = toScalarNode(thickness)
191
+ const a = toScalarNode(angle)
186
192
 
187
193
  // Rotate UV
188
194
  const cosA = cos(a)
@@ -242,19 +248,18 @@ export function grid(
242
248
  */
243
249
  export function dots(
244
250
  uv: TSLNode,
245
- cellSize: TSLNode | number = 0.1,
246
- dotRadius: TSLNode | number = 0.03,
247
- softness?: TSLNode | number
251
+ ...args: [cellSize?: TSLNode | number, dotRadius?: TSLNode | number, softness?: TSLNode | number]
248
252
  ): TSLNode {
249
- const size = typeof cellSize === 'number' ? float(cellSize) : cellSize
250
- const radius = typeof dotRadius === 'number' ? float(dotRadius) : dotRadius
253
+ const [cellSize = 0.1, dotRadius = 0.03, softness] = args
254
+ const size = toScalarNode(cellSize)
255
+ const radius = toScalarNode(dotRadius)
251
256
 
252
257
  const gridUV: TSLNode = fract(uv.div(size)).sub(0.5)
253
258
  const d = length(gridUV.mul(size))
254
259
 
255
260
  if (softness === undefined) return step(d, radius)
256
261
 
257
- const soft = typeof softness === 'number' ? float(softness) : softness
262
+ const soft = toScalarNode(softness)
258
263
  return float(1).sub(smoothstep(radius.sub(soft), radius.add(soft), d))
259
264
  }
260
265
 
@@ -276,15 +281,18 @@ export function checker(uv: TSLNode, scale: TSLNode | number = 10): TSLNode {
276
281
  */
277
282
  export function star(
278
283
  uv: TSLNode,
279
- center: TSLNode | [number, number] = [0.5, 0.5],
280
- points: number = 5,
281
- innerRadius: TSLNode | number = 0.1,
282
- outerRadius: TSLNode | number = 0.3,
283
- softness?: TSLNode | number
284
+ ...args: [
285
+ center?: TSLNode | [number, number],
286
+ points?: number,
287
+ innerRadius?: TSLNode | number,
288
+ outerRadius?: TSLNode | number,
289
+ softness?: TSLNode | number,
290
+ ]
284
291
  ): TSLNode {
285
- const c = Array.isArray(center) ? vec2(center[0], center[1]) : center
286
- const inner = typeof innerRadius === 'number' ? float(innerRadius) : innerRadius
287
- const outer = typeof outerRadius === 'number' ? float(outerRadius) : outerRadius
292
+ const [center = [0.5, 0.5], points = 5, innerRadius = 0.1, outerRadius = 0.3, softness] = args
293
+ const c = toVec2Node(center)
294
+ const inner = toScalarNode(innerRadius)
295
+ const outer = toScalarNode(outerRadius)
288
296
 
289
297
  const p = uv.sub(c)
290
298
  const angle = atan(p.y, p.x)
@@ -302,7 +310,7 @@ export function star(
302
310
 
303
311
  if (softness === undefined) return step(dist, targetRadius)
304
312
 
305
- const soft = typeof softness === 'number' ? float(softness) : softness
313
+ const soft = toScalarNode(softness)
306
314
  return float(1).sub(smoothstep(targetRadius.sub(soft), targetRadius.add(soft), dist))
307
315
  }
308
316
 
@@ -311,12 +319,11 @@ export function star(
311
319
  */
312
320
  export function radialLines(
313
321
  uv: TSLNode,
314
- center: TSLNode | [number, number] = [0.5, 0.5],
315
- numLines: number = 12,
316
- thickness: TSLNode | number = 0.5
322
+ ...args: [center?: TSLNode | [number, number], numLines?: number, thickness?: TSLNode | number]
317
323
  ): TSLNode {
318
- const c = Array.isArray(center) ? vec2(center[0], center[1]) : center
319
- const t = typeof thickness === 'number' ? float(thickness) : thickness
324
+ const [center = [0.5, 0.5], numLines = 12, thickness = 0.5] = args
325
+ const c = toVec2Node(center)
326
+ const t = toScalarNode(thickness)
320
327
 
321
328
  const p = uv.sub(c)
322
329
  const angle = atan(p.y, p.x).add(Math.PI)
@@ -331,13 +338,12 @@ export function radialLines(
331
338
  */
332
339
  export function concentricCircles(
333
340
  uv: TSLNode,
334
- center: TSLNode | [number, number] = [0.5, 0.5],
335
- frequency: TSLNode | number = 10,
336
- thickness: TSLNode | number = 0.5
341
+ ...args: [center?: TSLNode | [number, number], frequency?: TSLNode | number, thickness?: TSLNode | number]
337
342
  ): TSLNode {
338
- const c = Array.isArray(center) ? vec2(center[0], center[1]) : center
339
- const freq = typeof frequency === 'number' ? float(frequency) : frequency
340
- const t = typeof thickness === 'number' ? float(thickness) : thickness
343
+ const [center = [0.5, 0.5], frequency = 10, thickness = 0.5] = args
344
+ const c = toVec2Node(center)
345
+ const freq = toScalarNode(frequency)
346
+ const t = toScalarNode(thickness)
341
347
 
342
348
  const d: TSLNode = length(uv.sub(c))
343
349
  return step(fract(d.mul(freq)), t)
@@ -352,15 +358,18 @@ export function concentricCircles(
352
358
  */
353
359
  export function polygon(
354
360
  uv: TSLNode,
355
- center: TSLNode | [number, number] = [0.5, 0.5],
356
- sides: number = 6,
357
- radius: TSLNode | number = 0.3,
358
- rotation: TSLNode | number = 0,
359
- softness?: TSLNode | number
361
+ ...args: [
362
+ center?: TSLNode | [number, number],
363
+ sides?: number,
364
+ radius?: TSLNode | number,
365
+ rotation?: TSLNode | number,
366
+ softness?: TSLNode | number,
367
+ ]
360
368
  ): TSLNode {
361
- const c = Array.isArray(center) ? vec2(center[0], center[1]) : center
362
- const r = typeof radius === 'number' ? float(radius) : radius
363
- const rot = typeof rotation === 'number' ? float(rotation) : rotation
369
+ const [center = [0.5, 0.5], sides = 6, radius = 0.3, rotation = 0, softness] = args
370
+ const c = toVec2Node(center)
371
+ const r = toScalarNode(radius)
372
+ const rot = toScalarNode(rotation)
364
373
 
365
374
  const p = uv.sub(c)
366
375
  const angle = atan(p.y, p.x).add(rot)
@@ -374,6 +383,6 @@ export function polygon(
374
383
 
375
384
  if (softness === undefined) return step(dist, edgeDist)
376
385
 
377
- const soft = typeof softness === 'number' ? float(softness) : softness
386
+ const soft = toScalarNode(softness)
378
387
  return float(1).sub(smoothstep(edgeDist.sub(soft), edgeDist.add(soft), dist))
379
388
  }
@@ -5,12 +5,7 @@
5
5
  import { abs, atan, cos, float, floor, fract, length, mix, pow, sin, smoothstep, vec2 } from 'three/tsl'
6
6
 
7
7
  import type { TSLNode } from '../types'
8
-
9
- function toVec2Node(val: TSLNode | number | [number, number]): TSLNode {
10
- if (typeof val === 'number') return vec2(val, val)
11
- if (Array.isArray(val)) return vec2(val[0], val[1])
12
- return val
13
- }
8
+ import { toScalarNode, toVec2Node } from './nodes'
14
9
 
15
10
  // ============================================
16
11
  // Basic Transformations
@@ -124,14 +119,17 @@ export function fromPolar(
124
119
  */
125
120
  export function waveUV(
126
121
  uv: TSLNode,
127
- frequency: TSLNode | number = 10,
128
- amplitude: TSLNode | number = 0.05,
129
- time: TSLNode | number = 0,
130
- direction: 'x' | 'y' | 'both' = 'y'
122
+ ...args: [
123
+ frequency?: TSLNode | number,
124
+ amplitude?: TSLNode | number,
125
+ time?: TSLNode | number,
126
+ direction?: 'x' | 'y' | 'both',
127
+ ]
131
128
  ): TSLNode {
132
- const freq = typeof frequency === 'number' ? float(frequency) : frequency
133
- const amp = typeof amplitude === 'number' ? float(amplitude) : amplitude
134
- const t = typeof time === 'number' ? float(time) : time
129
+ const [frequency = 10, amplitude = 0.05, time = 0, direction = 'y'] = args
130
+ const freq = toScalarNode(frequency)
131
+ const amp = toScalarNode(amplitude)
132
+ const t = toScalarNode(time)
135
133
 
136
134
  if (direction === 'x') {
137
135
  const offset = sin(uv.y.mul(freq).add(t)).mul(amp)
@@ -151,17 +149,20 @@ export function waveUV(
151
149
  */
152
150
  export function rippleUV(
153
151
  uv: TSLNode,
154
- center: TSLNode | [number, number] = [0.5, 0.5],
155
- frequency: TSLNode | number = 10,
156
- amplitude: TSLNode | number = 0.05,
157
- time: TSLNode | number = 0,
158
- falloff: TSLNode | number = 1
152
+ ...args: [
153
+ center?: TSLNode | [number, number],
154
+ frequency?: TSLNode | number,
155
+ amplitude?: TSLNode | number,
156
+ time?: TSLNode | number,
157
+ falloff?: TSLNode | number,
158
+ ]
159
159
  ): TSLNode {
160
- const c = Array.isArray(center) ? vec2(center[0], center[1]) : center
161
- const freq = typeof frequency === 'number' ? float(frequency) : frequency
162
- const amp = typeof amplitude === 'number' ? float(amplitude) : amplitude
163
- const t = typeof time === 'number' ? float(time) : time
164
- const fall = typeof falloff === 'number' ? float(falloff) : falloff
160
+ const [center = [0.5, 0.5], frequency = 10, amplitude = 0.05, time = 0, falloff = 1] = args
161
+ const c = toVec2Node(center)
162
+ const freq = toScalarNode(frequency)
163
+ const amp = toScalarNode(amplitude)
164
+ const t = toScalarNode(time)
165
+ const fall = toScalarNode(falloff)
165
166
 
166
167
  const diff = uv.sub(c)
167
168
  const dist: TSLNode = length(diff)
@@ -178,13 +179,12 @@ export function rippleUV(
178
179
  */
179
180
  export function swirlUV(
180
181
  uv: TSLNode,
181
- center: TSLNode | [number, number] = [0.5, 0.5],
182
- strength: TSLNode | number = 1,
183
- radius: TSLNode | number = 0.5
182
+ ...args: [center?: TSLNode | [number, number], strength?: TSLNode | number, radius?: TSLNode | number]
184
183
  ): TSLNode {
185
- const c = Array.isArray(center) ? vec2(center[0], center[1]) : center
186
- const str = typeof strength === 'number' ? float(strength) : strength
187
- const r = typeof radius === 'number' ? float(radius) : radius
184
+ const [center = [0.5, 0.5], strength = 1, radius = 0.5] = args
185
+ const c = toVec2Node(center)
186
+ const str = toScalarNode(strength)
187
+ const r = toScalarNode(radius)
188
188
 
189
189
  const diff = uv.sub(c)
190
190
  const dist = length(diff)
@@ -238,12 +238,11 @@ export function pincushionUV(
238
238
  */
239
239
  export function kaleidoscopeUV(
240
240
  uv: TSLNode,
241
- segments: number = 6,
242
- center: TSLNode | [number, number] = [0.5, 0.5],
243
- rotation: TSLNode | number = 0
241
+ ...args: [segments?: number, center?: TSLNode | [number, number], rotation?: TSLNode | number]
244
242
  ): TSLNode {
245
- const c = Array.isArray(center) ? vec2(center[0], center[1]) : center
246
- const rot = typeof rotation === 'number' ? float(rotation) : rotation
243
+ const [segments = 6, center = [0.5, 0.5], rotation = 0] = args
244
+ const c = toVec2Node(center)
245
+ const rot = toScalarNode(rotation)
247
246
 
248
247
  const polar = toPolar(uv, c)
249
248
  const segmentAngle = float(1 / segments)