shaders 2.3.69 → 2.3.71
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/dist/svelte/index.js +76 -76
- package/dist/svelte/source/components/AngularBlur.svelte +287 -0
- package/dist/svelte/source/components/Ascii.svelte +288 -0
- package/dist/svelte/source/components/Aurora.svelte +292 -0
- package/dist/svelte/source/components/Beam.svelte +290 -0
- package/dist/svelte/source/components/Blob.svelte +289 -0
- package/dist/svelte/source/components/Blur.svelte +287 -0
- package/dist/svelte/source/components/BrightnessContrast.svelte +288 -0
- package/dist/svelte/source/components/Bulge.svelte +289 -0
- package/dist/svelte/source/components/CRTScreen.svelte +294 -0
- package/dist/svelte/source/components/ChannelBlur.svelte +289 -0
- package/dist/svelte/source/components/Checkerboard.svelte +288 -0
- package/dist/svelte/source/components/ChromaFlow.svelte +286 -0
- package/dist/svelte/source/components/ChromaticAberration.svelte +291 -0
- package/dist/svelte/source/components/Circle.svelte +289 -0
- package/dist/svelte/source/components/ConcentricSpin.svelte +290 -0
- package/dist/svelte/source/components/ContourLines.svelte +289 -0
- package/dist/svelte/source/components/CursorRipples.svelte +288 -0
- package/dist/svelte/source/components/CursorTrail.svelte +286 -0
- package/dist/svelte/source/components/DiffuseBlur.svelte +287 -0
- package/dist/svelte/source/components/Dither.svelte +288 -0
- package/dist/svelte/source/components/DotGrid.svelte +288 -0
- package/dist/svelte/source/components/Duotone.svelte +287 -0
- package/dist/svelte/source/components/FilmGrain.svelte +287 -0
- package/dist/svelte/source/components/FloatingParticles.svelte +290 -0
- package/dist/svelte/source/components/FlowField.svelte +288 -0
- package/dist/svelte/source/components/GlassTiles.svelte +290 -0
- package/dist/svelte/source/components/Glitch.svelte +292 -0
- package/dist/svelte/source/components/Glow.svelte +289 -0
- package/dist/svelte/source/components/Godrays.svelte +289 -0
- package/dist/svelte/source/components/Grayscale.svelte +286 -0
- package/dist/svelte/source/components/Grid.svelte +288 -0
- package/dist/svelte/source/components/GridDistortion.svelte +287 -0
- package/dist/svelte/source/components/Group.svelte +286 -0
- package/dist/svelte/source/components/Halftone.svelte +289 -0
- package/dist/svelte/source/components/HueShift.svelte +287 -0
- package/dist/svelte/source/components/ImageTexture.svelte +286 -0
- package/dist/svelte/source/components/Invert.svelte +286 -0
- package/dist/svelte/source/components/Kaleidoscope.svelte +288 -0
- package/dist/svelte/source/components/LensFlare.svelte +299 -0
- package/dist/svelte/source/components/LinearBlur.svelte +288 -0
- package/dist/svelte/source/components/LinearGradient.svelte +287 -0
- package/dist/svelte/source/components/Liquify.svelte +286 -0
- package/dist/svelte/source/components/Mirror.svelte +287 -0
- package/dist/svelte/source/components/Perspective.svelte +290 -0
- package/dist/svelte/source/components/Pixelate.svelte +287 -0
- package/dist/svelte/source/components/Plasma.svelte +290 -0
- package/dist/svelte/source/components/PolarCoordinates.svelte +289 -0
- package/dist/svelte/source/components/Posterize.svelte +287 -0
- package/dist/svelte/source/components/ProgressiveBlur.svelte +289 -0
- package/dist/svelte/source/components/RadialGradient.svelte +287 -0
- package/dist/svelte/source/components/RectangularCoordinates.svelte +288 -0
- package/dist/svelte/source/components/Ripples.svelte +290 -0
- package/dist/svelte/source/components/Saturation.svelte +287 -0
- package/dist/svelte/source/components/Sharpness.svelte +287 -0
- package/dist/svelte/source/components/Shatter.svelte +289 -0
- package/dist/svelte/source/components/SimplexNoise.svelte +288 -0
- package/dist/svelte/source/components/SineWave.svelte +291 -0
- package/dist/svelte/source/components/SolidColor.svelte +286 -0
- package/dist/svelte/source/components/Spherize.svelte +290 -0
- package/dist/svelte/source/components/Spiral.svelte +290 -0
- package/dist/svelte/source/components/Strands.svelte +289 -0
- package/dist/svelte/source/components/Stretch.svelte +289 -0
- package/dist/svelte/source/components/Stripes.svelte +291 -0
- package/dist/svelte/source/components/StudioBackground.svelte +298 -0
- package/dist/svelte/source/components/Swirl.svelte +288 -0
- package/dist/svelte/source/components/TiltShift.svelte +290 -0
- package/dist/svelte/source/components/Tint.svelte +287 -0
- package/dist/svelte/source/components/Tritone.svelte +287 -0
- package/dist/svelte/source/components/Twirl.svelte +287 -0
- package/dist/svelte/source/components/Vibrance.svelte +287 -0
- package/dist/svelte/source/components/VideoTexture.svelte +286 -0
- package/dist/svelte/source/components/WaveDistortion.svelte +289 -0
- package/dist/svelte/source/components/WebcamTexture.svelte +286 -0
- package/dist/svelte/source/components/ZoomBlur.svelte +287 -0
- package/dist/svelte/source/engine/Preview.svelte +320 -0
- package/dist/svelte/source/engine/PreviewRenderComponent.svelte +27 -0
- package/dist/svelte/source/engine/Shader.svelte +263 -0
- package/dist/svelte/source/index.js +77 -0
- package/package.json +2 -1
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onMount } from 'svelte'
|
|
3
|
+
|
|
4
|
+
import Shader from './Shader.svelte'
|
|
5
|
+
// <<< SHADERS_PREVIEW_MAP:START >>>
|
|
6
|
+
import AngularBlur from '../components/AngularBlur.svelte'
|
|
7
|
+
import Ascii from '../components/Ascii.svelte'
|
|
8
|
+
import Aurora from '../components/Aurora.svelte'
|
|
9
|
+
import Beam from '../components/Beam.svelte'
|
|
10
|
+
import Blob from '../components/Blob.svelte'
|
|
11
|
+
import Blur from '../components/Blur.svelte'
|
|
12
|
+
import BrightnessContrast from '../components/BrightnessContrast.svelte'
|
|
13
|
+
import Bulge from '../components/Bulge.svelte'
|
|
14
|
+
import CRTScreen from '../components/CRTScreen.svelte'
|
|
15
|
+
import ChannelBlur from '../components/ChannelBlur.svelte'
|
|
16
|
+
import Checkerboard from '../components/Checkerboard.svelte'
|
|
17
|
+
import ChromaFlow from '../components/ChromaFlow.svelte'
|
|
18
|
+
import ChromaticAberration from '../components/ChromaticAberration.svelte'
|
|
19
|
+
import Circle from '../components/Circle.svelte'
|
|
20
|
+
import ConcentricSpin from '../components/ConcentricSpin.svelte'
|
|
21
|
+
import ContourLines from '../components/ContourLines.svelte'
|
|
22
|
+
import CursorRipples from '../components/CursorRipples.svelte'
|
|
23
|
+
import CursorTrail from '../components/CursorTrail.svelte'
|
|
24
|
+
import DiffuseBlur from '../components/DiffuseBlur.svelte'
|
|
25
|
+
import Dither from '../components/Dither.svelte'
|
|
26
|
+
import DotGrid from '../components/DotGrid.svelte'
|
|
27
|
+
import Duotone from '../components/Duotone.svelte'
|
|
28
|
+
import FilmGrain from '../components/FilmGrain.svelte'
|
|
29
|
+
import FloatingParticles from '../components/FloatingParticles.svelte'
|
|
30
|
+
import FlowField from '../components/FlowField.svelte'
|
|
31
|
+
import GlassTiles from '../components/GlassTiles.svelte'
|
|
32
|
+
import Glitch from '../components/Glitch.svelte'
|
|
33
|
+
import Glow from '../components/Glow.svelte'
|
|
34
|
+
import Godrays from '../components/Godrays.svelte'
|
|
35
|
+
import Grayscale from '../components/Grayscale.svelte'
|
|
36
|
+
import Grid from '../components/Grid.svelte'
|
|
37
|
+
import GridDistortion from '../components/GridDistortion.svelte'
|
|
38
|
+
import Group from '../components/Group.svelte'
|
|
39
|
+
import Halftone from '../components/Halftone.svelte'
|
|
40
|
+
import HueShift from '../components/HueShift.svelte'
|
|
41
|
+
import ImageTexture from '../components/ImageTexture.svelte'
|
|
42
|
+
import Invert from '../components/Invert.svelte'
|
|
43
|
+
import Kaleidoscope from '../components/Kaleidoscope.svelte'
|
|
44
|
+
import LensFlare from '../components/LensFlare.svelte'
|
|
45
|
+
import LinearBlur from '../components/LinearBlur.svelte'
|
|
46
|
+
import LinearGradient from '../components/LinearGradient.svelte'
|
|
47
|
+
import Liquify from '../components/Liquify.svelte'
|
|
48
|
+
import Mirror from '../components/Mirror.svelte'
|
|
49
|
+
import Perspective from '../components/Perspective.svelte'
|
|
50
|
+
import Pixelate from '../components/Pixelate.svelte'
|
|
51
|
+
import Plasma from '../components/Plasma.svelte'
|
|
52
|
+
import PolarCoordinates from '../components/PolarCoordinates.svelte'
|
|
53
|
+
import Posterize from '../components/Posterize.svelte'
|
|
54
|
+
import ProgressiveBlur from '../components/ProgressiveBlur.svelte'
|
|
55
|
+
import RadialGradient from '../components/RadialGradient.svelte'
|
|
56
|
+
import RectangularCoordinates from '../components/RectangularCoordinates.svelte'
|
|
57
|
+
import Ripples from '../components/Ripples.svelte'
|
|
58
|
+
import Saturation from '../components/Saturation.svelte'
|
|
59
|
+
import Sharpness from '../components/Sharpness.svelte'
|
|
60
|
+
import Shatter from '../components/Shatter.svelte'
|
|
61
|
+
import SimplexNoise from '../components/SimplexNoise.svelte'
|
|
62
|
+
import SineWave from '../components/SineWave.svelte'
|
|
63
|
+
import SolidColor from '../components/SolidColor.svelte'
|
|
64
|
+
import Spherize from '../components/Spherize.svelte'
|
|
65
|
+
import Spiral from '../components/Spiral.svelte'
|
|
66
|
+
import Strands from '../components/Strands.svelte'
|
|
67
|
+
import Stretch from '../components/Stretch.svelte'
|
|
68
|
+
import Stripes from '../components/Stripes.svelte'
|
|
69
|
+
import StudioBackground from '../components/StudioBackground.svelte'
|
|
70
|
+
import Swirl from '../components/Swirl.svelte'
|
|
71
|
+
import TiltShift from '../components/TiltShift.svelte'
|
|
72
|
+
import Tint from '../components/Tint.svelte'
|
|
73
|
+
import Tritone from '../components/Tritone.svelte'
|
|
74
|
+
import Twirl from '../components/Twirl.svelte'
|
|
75
|
+
import Vibrance from '../components/Vibrance.svelte'
|
|
76
|
+
import VideoTexture from '../components/VideoTexture.svelte'
|
|
77
|
+
import WaveDistortion from '../components/WaveDistortion.svelte'
|
|
78
|
+
import WebcamTexture from '../components/WebcamTexture.svelte'
|
|
79
|
+
import ZoomBlur from '../components/ZoomBlur.svelte'
|
|
80
|
+
|
|
81
|
+
// --- Component Map ---
|
|
82
|
+
|
|
83
|
+
const componentMap: Record<string, any> = {
|
|
84
|
+
AngularBlur,
|
|
85
|
+
Ascii,
|
|
86
|
+
Aurora,
|
|
87
|
+
Beam,
|
|
88
|
+
Blob,
|
|
89
|
+
Blur,
|
|
90
|
+
BrightnessContrast,
|
|
91
|
+
Bulge,
|
|
92
|
+
CRTScreen,
|
|
93
|
+
ChannelBlur,
|
|
94
|
+
Checkerboard,
|
|
95
|
+
ChromaFlow,
|
|
96
|
+
ChromaticAberration,
|
|
97
|
+
Circle,
|
|
98
|
+
ConcentricSpin,
|
|
99
|
+
ContourLines,
|
|
100
|
+
CursorRipples,
|
|
101
|
+
CursorTrail,
|
|
102
|
+
DiffuseBlur,
|
|
103
|
+
Dither,
|
|
104
|
+
DotGrid,
|
|
105
|
+
Duotone,
|
|
106
|
+
FilmGrain,
|
|
107
|
+
FloatingParticles,
|
|
108
|
+
FlowField,
|
|
109
|
+
GlassTiles,
|
|
110
|
+
Glitch,
|
|
111
|
+
Glow,
|
|
112
|
+
Godrays,
|
|
113
|
+
Grayscale,
|
|
114
|
+
Grid,
|
|
115
|
+
GridDistortion,
|
|
116
|
+
Group,
|
|
117
|
+
Halftone,
|
|
118
|
+
HueShift,
|
|
119
|
+
ImageTexture,
|
|
120
|
+
Invert,
|
|
121
|
+
Kaleidoscope,
|
|
122
|
+
LensFlare,
|
|
123
|
+
LinearBlur,
|
|
124
|
+
LinearGradient,
|
|
125
|
+
Liquify,
|
|
126
|
+
Mirror,
|
|
127
|
+
Perspective,
|
|
128
|
+
Pixelate,
|
|
129
|
+
Plasma,
|
|
130
|
+
PolarCoordinates,
|
|
131
|
+
Posterize,
|
|
132
|
+
ProgressiveBlur,
|
|
133
|
+
RadialGradient,
|
|
134
|
+
RectangularCoordinates,
|
|
135
|
+
Ripples,
|
|
136
|
+
Saturation,
|
|
137
|
+
Sharpness,
|
|
138
|
+
Shatter,
|
|
139
|
+
SimplexNoise,
|
|
140
|
+
SineWave,
|
|
141
|
+
SolidColor,
|
|
142
|
+
Spherize,
|
|
143
|
+
Spiral,
|
|
144
|
+
Strands,
|
|
145
|
+
Stretch,
|
|
146
|
+
Stripes,
|
|
147
|
+
StudioBackground,
|
|
148
|
+
Swirl,
|
|
149
|
+
TiltShift,
|
|
150
|
+
Tint,
|
|
151
|
+
Tritone,
|
|
152
|
+
Twirl,
|
|
153
|
+
Vibrance,
|
|
154
|
+
VideoTexture,
|
|
155
|
+
WaveDistortion,
|
|
156
|
+
WebcamTexture,
|
|
157
|
+
ZoomBlur,
|
|
158
|
+
}
|
|
159
|
+
// <<< SHADERS_PREVIEW_MAP:END >>>
|
|
160
|
+
|
|
161
|
+
// --- Inlined Types ---
|
|
162
|
+
|
|
163
|
+
interface ShaderComponent {
|
|
164
|
+
type: string
|
|
165
|
+
id?: string
|
|
166
|
+
props?: Record<string, any>
|
|
167
|
+
children?: ShaderComponent[]
|
|
168
|
+
blendMode?: string
|
|
169
|
+
opacity?: number
|
|
170
|
+
renderOrder?: number
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
interface ShaderDefinition {
|
|
174
|
+
components: ShaderComponent[]
|
|
175
|
+
structureVersion?: number
|
|
176
|
+
colorSpace?: 'p3-linear' | 'srgb'
|
|
177
|
+
devicePreview?: string
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// --- Preview Decode Logic ---
|
|
181
|
+
// No name mapping — preview definitions contain readable JSON.
|
|
182
|
+
|
|
183
|
+
function xorCrypt(data: Uint8Array, key: string): Uint8Array {
|
|
184
|
+
const keyBytes = new TextEncoder().encode(key)
|
|
185
|
+
const result = new Uint8Array(data.length)
|
|
186
|
+
for (let i = 0; i < data.length; i++) {
|
|
187
|
+
result[i] = data[i] ^ keyBytes[i % keyBytes.length]
|
|
188
|
+
}
|
|
189
|
+
return result
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function decodePreviewDefinition(encoded: string, key: string): ShaderDefinition {
|
|
193
|
+
const binaryString = atob(encoded)
|
|
194
|
+
const encrypted = new Uint8Array(binaryString.length)
|
|
195
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
196
|
+
encrypted[i] = binaryString.charCodeAt(i)
|
|
197
|
+
}
|
|
198
|
+
const decrypted = xorCrypt(encrypted, key)
|
|
199
|
+
const json = new TextDecoder().decode(decrypted)
|
|
200
|
+
try {
|
|
201
|
+
return JSON.parse(json)
|
|
202
|
+
} catch {
|
|
203
|
+
throw new Error('Failed to decode shader definition: invalid data or incorrect key')
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Fetch from API and decode response
|
|
208
|
+
function fetchAndDecode(url: string, key: string): Promise<ShaderDefinition | null> {
|
|
209
|
+
return fetch(url)
|
|
210
|
+
.then(res => {
|
|
211
|
+
if (!res.ok) throw new Error(`Failed to fetch: ${res.status}`)
|
|
212
|
+
return res.json()
|
|
213
|
+
})
|
|
214
|
+
.then(data => {
|
|
215
|
+
const item = data.preset || data.shader
|
|
216
|
+
if (item?.definition && typeof item.definition === 'string') {
|
|
217
|
+
return decodePreviewDefinition(item.definition, key)
|
|
218
|
+
}
|
|
219
|
+
return null
|
|
220
|
+
})
|
|
221
|
+
.catch(err => {
|
|
222
|
+
console.error('[Shaders Preview] Failed to fetch preview:', err)
|
|
223
|
+
return null
|
|
224
|
+
})
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// --- Props ---
|
|
228
|
+
|
|
229
|
+
export let shader: string | undefined = undefined
|
|
230
|
+
export let presetId: string | undefined = undefined
|
|
231
|
+
export let apiBaseUrl: string = 'https://shaders.com'
|
|
232
|
+
export let obfuscationKey: string = 'shaders-preview-key'
|
|
233
|
+
export let watermarkText: string = 'Unlock your Shaders Pro license'
|
|
234
|
+
export let watermarkLink: string = 'https://shaders.com/dashboard?pricing=true'
|
|
235
|
+
export let style: string | undefined = undefined
|
|
236
|
+
|
|
237
|
+
// --- Decode & Resolve ---
|
|
238
|
+
|
|
239
|
+
let resolvedDefinition: ShaderDefinition | null = null
|
|
240
|
+
let fetchedDefinition: ShaderDefinition | null = null
|
|
241
|
+
let watermarkHovered = false
|
|
242
|
+
|
|
243
|
+
// Fetch shader by token
|
|
244
|
+
$: if (shader) {
|
|
245
|
+
fetchedDefinition = null
|
|
246
|
+
fetchAndDecode(`${apiBaseUrl}/api/preview/shader/${shader}`, obfuscationKey)
|
|
247
|
+
.then(def => { fetchedDefinition = def })
|
|
248
|
+
} else if (!presetId) {
|
|
249
|
+
fetchedDefinition = null
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Fetch preset by ID
|
|
253
|
+
$: if (presetId) {
|
|
254
|
+
fetchedDefinition = null
|
|
255
|
+
fetchAndDecode(`${apiBaseUrl}/api/preview/preset/${presetId}`, obfuscationKey)
|
|
256
|
+
.then(def => { fetchedDefinition = def })
|
|
257
|
+
} else if (!shader) {
|
|
258
|
+
fetchedDefinition = null
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
$: resolvedDefinition = fetchedDefinition ?? null
|
|
262
|
+
|
|
263
|
+
// --- Licensing Warning ---
|
|
264
|
+
|
|
265
|
+
onMount(() => {
|
|
266
|
+
console.warn(
|
|
267
|
+
'[Shaders] Preview component is intended for use with a Shaders license. ' +
|
|
268
|
+
'Visit https://shaders.com for more information.'
|
|
269
|
+
)
|
|
270
|
+
})
|
|
271
|
+
|
|
272
|
+
</script>
|
|
273
|
+
|
|
274
|
+
<script lang="ts" context="module">
|
|
275
|
+
// Recursive component for rendering nested shader components
|
|
276
|
+
import { default as RenderComponent } from './PreviewRenderComponent.svelte'
|
|
277
|
+
</script>
|
|
278
|
+
|
|
279
|
+
{#if resolvedDefinition}
|
|
280
|
+
<div class="shaders-preview" style="position: relative; width: 100%; height: 100%;{style ? ' ' + style : ''}" {...$$restProps}>
|
|
281
|
+
<Shader
|
|
282
|
+
colorSpace={resolvedDefinition.colorSpace || 'p3-linear'}
|
|
283
|
+
isPreview={true}
|
|
284
|
+
enablePerformanceTracking={true}
|
|
285
|
+
style="width: 100%; height: 100%;"
|
|
286
|
+
>
|
|
287
|
+
{#each resolvedDefinition.components as config, index (config.id || `root_${index}_v${resolvedDefinition.structureVersion || 0}`)}
|
|
288
|
+
<RenderComponent
|
|
289
|
+
config={{ ...config, renderOrder: config.renderOrder ?? index }}
|
|
290
|
+
{componentMap}
|
|
291
|
+
structureVersion={resolvedDefinition.structureVersion}
|
|
292
|
+
/>
|
|
293
|
+
{/each}
|
|
294
|
+
</Shader>
|
|
295
|
+
{#if watermarkText}
|
|
296
|
+
<a
|
|
297
|
+
href={watermarkLink}
|
|
298
|
+
target="_blank"
|
|
299
|
+
rel="noopener noreferrer"
|
|
300
|
+
style="
|
|
301
|
+
position: absolute;
|
|
302
|
+
bottom: 8px;
|
|
303
|
+
right: 12px;
|
|
304
|
+
font-size: 11px;
|
|
305
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
306
|
+
color: {watermarkHovered ? 'rgba(255, 255, 255, 0.8)' : 'rgba(255, 255, 255, 0.5)'};
|
|
307
|
+
text-decoration: none;
|
|
308
|
+
pointer-events: auto;
|
|
309
|
+
z-index: 10;
|
|
310
|
+
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
|
|
311
|
+
transition: color 0.2s ease;
|
|
312
|
+
"
|
|
313
|
+
on:mouseenter={() => watermarkHovered = true}
|
|
314
|
+
on:mouseleave={() => watermarkHovered = false}
|
|
315
|
+
>
|
|
316
|
+
{watermarkText}
|
|
317
|
+
</a>
|
|
318
|
+
{/if}
|
|
319
|
+
</div>
|
|
320
|
+
{/if}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export let config: any
|
|
3
|
+
export let componentMap: Record<string, any>
|
|
4
|
+
export let structureVersion: number | undefined = undefined
|
|
5
|
+
|
|
6
|
+
$: Component = componentMap[config.type]
|
|
7
|
+
$: componentProps = config.props ? { ...config.props } : {}
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
{#if Component}
|
|
11
|
+
<svelte:component
|
|
12
|
+
this={Component}
|
|
13
|
+
id={config.id}
|
|
14
|
+
renderOrder={config.renderOrder}
|
|
15
|
+
{...componentProps}
|
|
16
|
+
>
|
|
17
|
+
{#if config.children}
|
|
18
|
+
{#each config.children as child, index (child.id || `child_${index}_v${structureVersion || 0}`)}
|
|
19
|
+
<svelte:self
|
|
20
|
+
config={{ ...child, renderOrder: child.renderOrder ?? index }}
|
|
21
|
+
{componentMap}
|
|
22
|
+
{structureVersion}
|
|
23
|
+
/>
|
|
24
|
+
{/each}
|
|
25
|
+
{/if}
|
|
26
|
+
</svelte:component>
|
|
27
|
+
{/if}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { setContext, onMount, onDestroy } from 'svelte';
|
|
3
|
+
import { shaderRenderer } from '../../../core/index.js';
|
|
4
|
+
import { vec4 } from 'three/tsl';
|
|
5
|
+
import type { UniformsMap, BlendMode, NodeMetadata } from '../../../core/index.js';
|
|
6
|
+
import { shouldCollectTelemetry, isExternalUser, startTelemetry } from '../../../core/telemetry/index.js';
|
|
7
|
+
import { setColorSpaceMode } from '../../../core/utilities/transformations/index.js';
|
|
8
|
+
|
|
9
|
+
declare const __SHADERS_VERSION__: string;
|
|
10
|
+
|
|
11
|
+
interface Props {
|
|
12
|
+
disableTelemetry?: boolean;
|
|
13
|
+
colorSpace?: 'p3-linear' | 'srgb';
|
|
14
|
+
isPreview?: boolean;
|
|
15
|
+
children?: import('svelte').Snippet;
|
|
16
|
+
[key: string]: any;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const { disableTelemetry = false, colorSpace = 'p3-linear', isPreview = false, children, ...rest }: Props = $props();
|
|
20
|
+
|
|
21
|
+
// DOM references to the container and canvas
|
|
22
|
+
let containerRef: HTMLDivElement;
|
|
23
|
+
let canvasRef: HTMLCanvasElement;
|
|
24
|
+
|
|
25
|
+
// SSR guard — renderer and children are deferred until mount
|
|
26
|
+
let mounted = $state(false);
|
|
27
|
+
|
|
28
|
+
// Unique ID for this root component
|
|
29
|
+
const rootId = 'shader-root-' + Math.random().toString(36).substring(7);
|
|
30
|
+
|
|
31
|
+
// Renderer instance — created in onMount (deferred for SSR compatibility)
|
|
32
|
+
let rendererInstance: ReturnType<typeof shaderRenderer> | null = null;
|
|
33
|
+
|
|
34
|
+
// Telemetry collector reference for cleanup
|
|
35
|
+
let telemetryCollector: any = null;
|
|
36
|
+
let telemetryStartTimeout: number | null = null;
|
|
37
|
+
let shouldSendTelemetry: boolean | null = null;
|
|
38
|
+
|
|
39
|
+
// Set context for child components - provide parent ID
|
|
40
|
+
setContext('shaderParentId', rootId);
|
|
41
|
+
|
|
42
|
+
// Provide color space to child components (function getter for reactivity)
|
|
43
|
+
setContext('shaderColorSpace', () => colorSpace);
|
|
44
|
+
|
|
45
|
+
// Provide node registration function for child components
|
|
46
|
+
// Callbacks capture `rendererInstance` by reference — they see the live value after onMount sets it
|
|
47
|
+
setContext('shaderNodeRegister', (id: string, fragmentNodeFunc: any, parentId: string | null, metadata: any, uniforms: any = null, componentDef: any = null) => {
|
|
48
|
+
if (!rendererInstance) return
|
|
49
|
+
// If fragmentNodeFunc is null, the component is being unmounted, so remove it
|
|
50
|
+
if (fragmentNodeFunc === null) {
|
|
51
|
+
rendererInstance.removeNode(id);
|
|
52
|
+
} else {
|
|
53
|
+
rendererInstance.registerNode(id, fragmentNodeFunc, parentId, metadata, uniforms, componentDef);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Provide optimized uniform update function
|
|
58
|
+
setContext('shaderUniformUpdate', (nodeId: string, uniformName: string, value: any) => {
|
|
59
|
+
if (!rendererInstance) return
|
|
60
|
+
rendererInstance.updateUniformValue(nodeId, uniformName, value);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Provide optimized metadata update function
|
|
64
|
+
setContext('shaderMetadataUpdate', (nodeId: string, metadata: any) => {
|
|
65
|
+
if (!rendererInstance) return
|
|
66
|
+
rendererInstance.updateNodeMetadata(nodeId, metadata);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Track visibility state
|
|
70
|
+
let wasVisible = false;
|
|
71
|
+
let visibilityObserver: IntersectionObserver | null = null;
|
|
72
|
+
|
|
73
|
+
// Wait for active rendering before starting telemetry collection
|
|
74
|
+
const startTelemetryWhenReady = () => {
|
|
75
|
+
const checkRendering = () => {
|
|
76
|
+
if (!rendererInstance) return
|
|
77
|
+
const stats = rendererInstance.getPerformanceStats();
|
|
78
|
+
if (stats.fps > 0) {
|
|
79
|
+
const version = typeof __SHADERS_VERSION__ !== 'undefined' ? __SHADERS_VERSION__ : 'unknown';
|
|
80
|
+
telemetryCollector = startTelemetry(
|
|
81
|
+
rendererInstance,
|
|
82
|
+
version,
|
|
83
|
+
disableTelemetry,
|
|
84
|
+
isPreview
|
|
85
|
+
);
|
|
86
|
+
if (telemetryCollector) {
|
|
87
|
+
telemetryCollector.start();
|
|
88
|
+
}
|
|
89
|
+
telemetryStartTimeout = null;
|
|
90
|
+
} else {
|
|
91
|
+
telemetryStartTimeout = window.setTimeout(checkRendering, 500);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
telemetryStartTimeout = window.setTimeout(checkRendering, 500);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
// Function to initialize renderer with visibility check
|
|
99
|
+
const initializeRenderer = async () => {
|
|
100
|
+
if (!canvasRef || !rendererInstance) return;
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
// Check if renderer is already initialized to avoid double initialization
|
|
104
|
+
if (!rendererInstance.isInitialized()) {
|
|
105
|
+
await rendererInstance.initialize({
|
|
106
|
+
canvas: canvasRef,
|
|
107
|
+
colorSpace: colorSpace,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Register the root node
|
|
112
|
+
rendererInstance.registerNode(
|
|
113
|
+
rootId,
|
|
114
|
+
({ childNode }) => childNode || vec4(0, 0, 0, 0), // Root node that passes through children
|
|
115
|
+
null, // No parent (this is the root)
|
|
116
|
+
null, // No metadata to pass
|
|
117
|
+
{}
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
// Compute sampling decision once (includes random sampling roll)
|
|
121
|
+
if (shouldSendTelemetry === null) {
|
|
122
|
+
shouldSendTelemetry = isExternalUser() && shouldCollectTelemetry(disableTelemetry, isPreview);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (shouldSendTelemetry && !telemetryCollector) {
|
|
126
|
+
startTelemetryWhenReady();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
} catch (err) {
|
|
130
|
+
console.error('[Shader] Initialization failed:', err);
|
|
131
|
+
throw err;
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
// Setup visibility observer for container hide/show detection
|
|
136
|
+
const setupVisibilityObserver = () => {
|
|
137
|
+
if (!containerRef || visibilityObserver) return;
|
|
138
|
+
|
|
139
|
+
visibilityObserver = new IntersectionObserver((entries) => {
|
|
140
|
+
const entry = entries[0];
|
|
141
|
+
if (!entry) return;
|
|
142
|
+
|
|
143
|
+
const rect = containerRef?.getBoundingClientRect();
|
|
144
|
+
const isCurrentlyVisible = entry.isIntersecting && rect && rect.width > 0 && rect.height > 0;
|
|
145
|
+
|
|
146
|
+
if (isCurrentlyVisible && !wasVisible) {
|
|
147
|
+
// Canvas became visible - resume animation
|
|
148
|
+
if (rendererInstance?.isInitialized()) {
|
|
149
|
+
rendererInstance.startAnimation();
|
|
150
|
+
// Start telemetry if conditions are met and not already started
|
|
151
|
+
if (shouldSendTelemetry && !telemetryCollector && !telemetryStartTimeout) {
|
|
152
|
+
startTelemetryWhenReady();
|
|
153
|
+
}
|
|
154
|
+
} else {
|
|
155
|
+
// First time visible, need to initialize
|
|
156
|
+
initializeRenderer().catch(console.error);
|
|
157
|
+
}
|
|
158
|
+
wasVisible = true;
|
|
159
|
+
} else if (!isCurrentlyVisible && wasVisible) {
|
|
160
|
+
// Canvas became hidden - pause animation but keep renderer alive
|
|
161
|
+
rendererInstance?.stopAnimation();
|
|
162
|
+
wasVisible = false;
|
|
163
|
+
}
|
|
164
|
+
}, { threshold: 0 });
|
|
165
|
+
|
|
166
|
+
visibilityObserver.observe(containerRef);
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
// Initialize renderer on mount - with visibility awareness
|
|
170
|
+
onMount(async () => {
|
|
171
|
+
// Create the renderer instance (deferred from module scope for SSR compatibility)
|
|
172
|
+
rendererInstance = shaderRenderer();
|
|
173
|
+
mounted = true;
|
|
174
|
+
|
|
175
|
+
// Wait for Svelte to render the canvas + children before proceeding
|
|
176
|
+
await new Promise((resolve) => requestAnimationFrame(resolve));
|
|
177
|
+
|
|
178
|
+
if (!canvasRef || !containerRef) {
|
|
179
|
+
console.error('Canvas or container ref is null in Shader onMount');
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Check if container is visible on mount
|
|
184
|
+
const rect = containerRef.getBoundingClientRect();
|
|
185
|
+
const isVisible = rect.width > 0 && rect.height > 0;
|
|
186
|
+
|
|
187
|
+
if (isVisible) {
|
|
188
|
+
// Container is visible, initialize immediately
|
|
189
|
+
await initializeRenderer();
|
|
190
|
+
wasVisible = true;
|
|
191
|
+
} else {
|
|
192
|
+
// Container is hidden, set up observer for when it becomes visible
|
|
193
|
+
wasVisible = false;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Always set up observer to handle show/hide cycles
|
|
197
|
+
setupVisibilityObserver();
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// Cleanup on component destroy
|
|
201
|
+
onDestroy(() => {
|
|
202
|
+
// Stop telemetry collection if active
|
|
203
|
+
if (telemetryCollector) {
|
|
204
|
+
telemetryCollector.stop();
|
|
205
|
+
telemetryCollector = null;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Clear telemetry start timeout if pending
|
|
209
|
+
if (telemetryStartTimeout !== null) {
|
|
210
|
+
clearTimeout(telemetryStartTimeout);
|
|
211
|
+
telemetryStartTimeout = null;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Clean up visibility observer
|
|
215
|
+
if (visibilityObserver) {
|
|
216
|
+
visibilityObserver.disconnect();
|
|
217
|
+
visibilityObserver = null;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Only cleanup if renderer was initialized
|
|
221
|
+
if (rendererInstance?.isInitialized()) {
|
|
222
|
+
try {
|
|
223
|
+
rendererInstance.cleanup();
|
|
224
|
+
} catch (err) {
|
|
225
|
+
console.warn('[Shader] Error during cleanup:', err);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
// Watch for colorSpace changes and update the renderer
|
|
231
|
+
// Skip the initial execution since colorSpace is set during initialization
|
|
232
|
+
let isFirstEffect = true;
|
|
233
|
+
$effect(() => {
|
|
234
|
+
// Access colorSpace to make it reactive
|
|
235
|
+
const currentColorSpace = colorSpace;
|
|
236
|
+
|
|
237
|
+
if (isFirstEffect) {
|
|
238
|
+
isFirstEffect = false;
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (rendererInstance?.isInitialized()) {
|
|
243
|
+
// Update the global color space mode
|
|
244
|
+
setColorSpaceMode(currentColorSpace);
|
|
245
|
+
|
|
246
|
+
// Force re-initialization to apply color space changes
|
|
247
|
+
rendererInstance.cleanup();
|
|
248
|
+
initializeRenderer().catch(console.error);
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
</script>
|
|
253
|
+
|
|
254
|
+
<div class="shader" bind:this={containerRef} {...rest}>
|
|
255
|
+
{#if mounted}
|
|
256
|
+
<canvas
|
|
257
|
+
data-renderer="shaders"
|
|
258
|
+
bind:this={canvasRef}
|
|
259
|
+
style="width: 100%; height: 100%; display: block;"
|
|
260
|
+
></canvas>
|
|
261
|
+
{@render children?.()}
|
|
262
|
+
{/if}
|
|
263
|
+
</div>
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
export { default as AngularBlur } from './components/AngularBlur.svelte';
|
|
2
|
+
export { default as Ascii } from './components/Ascii.svelte';
|
|
3
|
+
export { default as Aurora } from './components/Aurora.svelte';
|
|
4
|
+
export { default as Beam } from './components/Beam.svelte';
|
|
5
|
+
export { default as Blob } from './components/Blob.svelte';
|
|
6
|
+
export { default as Blur } from './components/Blur.svelte';
|
|
7
|
+
export { default as BrightnessContrast } from './components/BrightnessContrast.svelte';
|
|
8
|
+
export { default as Bulge } from './components/Bulge.svelte';
|
|
9
|
+
export { default as CRTScreen } from './components/CRTScreen.svelte';
|
|
10
|
+
export { default as ChannelBlur } from './components/ChannelBlur.svelte';
|
|
11
|
+
export { default as Checkerboard } from './components/Checkerboard.svelte';
|
|
12
|
+
export { default as ChromaFlow } from './components/ChromaFlow.svelte';
|
|
13
|
+
export { default as ChromaticAberration } from './components/ChromaticAberration.svelte';
|
|
14
|
+
export { default as Circle } from './components/Circle.svelte';
|
|
15
|
+
export { default as ConcentricSpin } from './components/ConcentricSpin.svelte';
|
|
16
|
+
export { default as ContourLines } from './components/ContourLines.svelte';
|
|
17
|
+
export { default as CursorRipples } from './components/CursorRipples.svelte';
|
|
18
|
+
export { default as CursorTrail } from './components/CursorTrail.svelte';
|
|
19
|
+
export { default as DiffuseBlur } from './components/DiffuseBlur.svelte';
|
|
20
|
+
export { default as Dither } from './components/Dither.svelte';
|
|
21
|
+
export { default as DotGrid } from './components/DotGrid.svelte';
|
|
22
|
+
export { default as Duotone } from './components/Duotone.svelte';
|
|
23
|
+
export { default as FilmGrain } from './components/FilmGrain.svelte';
|
|
24
|
+
export { default as FloatingParticles } from './components/FloatingParticles.svelte';
|
|
25
|
+
export { default as FlowField } from './components/FlowField.svelte';
|
|
26
|
+
export { default as GlassTiles } from './components/GlassTiles.svelte';
|
|
27
|
+
export { default as Glitch } from './components/Glitch.svelte';
|
|
28
|
+
export { default as Glow } from './components/Glow.svelte';
|
|
29
|
+
export { default as Godrays } from './components/Godrays.svelte';
|
|
30
|
+
export { default as Grayscale } from './components/Grayscale.svelte';
|
|
31
|
+
export { default as Grid } from './components/Grid.svelte';
|
|
32
|
+
export { default as GridDistortion } from './components/GridDistortion.svelte';
|
|
33
|
+
export { default as Group } from './components/Group.svelte';
|
|
34
|
+
export { default as Halftone } from './components/Halftone.svelte';
|
|
35
|
+
export { default as HueShift } from './components/HueShift.svelte';
|
|
36
|
+
export { default as ImageTexture } from './components/ImageTexture.svelte';
|
|
37
|
+
export { default as Invert } from './components/Invert.svelte';
|
|
38
|
+
export { default as Kaleidoscope } from './components/Kaleidoscope.svelte';
|
|
39
|
+
export { default as LensFlare } from './components/LensFlare.svelte';
|
|
40
|
+
export { default as LinearBlur } from './components/LinearBlur.svelte';
|
|
41
|
+
export { default as LinearGradient } from './components/LinearGradient.svelte';
|
|
42
|
+
export { default as Liquify } from './components/Liquify.svelte';
|
|
43
|
+
export { default as Mirror } from './components/Mirror.svelte';
|
|
44
|
+
export { default as Perspective } from './components/Perspective.svelte';
|
|
45
|
+
export { default as Pixelate } from './components/Pixelate.svelte';
|
|
46
|
+
export { default as Plasma } from './components/Plasma.svelte';
|
|
47
|
+
export { default as PolarCoordinates } from './components/PolarCoordinates.svelte';
|
|
48
|
+
export { default as Posterize } from './components/Posterize.svelte';
|
|
49
|
+
export { default as ProgressiveBlur } from './components/ProgressiveBlur.svelte';
|
|
50
|
+
export { default as RadialGradient } from './components/RadialGradient.svelte';
|
|
51
|
+
export { default as RectangularCoordinates } from './components/RectangularCoordinates.svelte';
|
|
52
|
+
export { default as Ripples } from './components/Ripples.svelte';
|
|
53
|
+
export { default as Saturation } from './components/Saturation.svelte';
|
|
54
|
+
export { default as Sharpness } from './components/Sharpness.svelte';
|
|
55
|
+
export { default as Shatter } from './components/Shatter.svelte';
|
|
56
|
+
export { default as SimplexNoise } from './components/SimplexNoise.svelte';
|
|
57
|
+
export { default as SineWave } from './components/SineWave.svelte';
|
|
58
|
+
export { default as SolidColor } from './components/SolidColor.svelte';
|
|
59
|
+
export { default as Spherize } from './components/Spherize.svelte';
|
|
60
|
+
export { default as Spiral } from './components/Spiral.svelte';
|
|
61
|
+
export { default as Strands } from './components/Strands.svelte';
|
|
62
|
+
export { default as Stretch } from './components/Stretch.svelte';
|
|
63
|
+
export { default as Stripes } from './components/Stripes.svelte';
|
|
64
|
+
export { default as StudioBackground } from './components/StudioBackground.svelte';
|
|
65
|
+
export { default as Swirl } from './components/Swirl.svelte';
|
|
66
|
+
export { default as TiltShift } from './components/TiltShift.svelte';
|
|
67
|
+
export { default as Tint } from './components/Tint.svelte';
|
|
68
|
+
export { default as Tritone } from './components/Tritone.svelte';
|
|
69
|
+
export { default as Twirl } from './components/Twirl.svelte';
|
|
70
|
+
export { default as Vibrance } from './components/Vibrance.svelte';
|
|
71
|
+
export { default as VideoTexture } from './components/VideoTexture.svelte';
|
|
72
|
+
export { default as WaveDistortion } from './components/WaveDistortion.svelte';
|
|
73
|
+
export { default as WebcamTexture } from './components/WebcamTexture.svelte';
|
|
74
|
+
export { default as ZoomBlur } from './components/ZoomBlur.svelte';
|
|
75
|
+
export { default as Shader } from './engine/Shader.svelte';
|
|
76
|
+
export { default as Preview } from './engine/Preview.svelte';
|
|
77
|
+
export { generatePresetCode } from '../utils/generatePresetCode.js';
|