ngx-glassy-effect 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  This project is an Angular directive that applies a glassy effect to your html elements.
4
4
 
5
+ - V3 : 3rd time's the charm, the V2 was not bad, but it only worked on Chrome & the refractions didn't zoom out until a certain distance as they go further away from the borders so they just disappeared, & refractions on corners broke into pixels not handling antialiasing properly. This time it's using WebGL instead of backdrop-filter giving a clean near-perfect glassy effect (closer to apple's liquid glass), & it supports more browsers like Safari & Mozilla.
6
+ - V4 : V3 is perfect, If there's gonna be a v4, it's going to be about glass on top of a glass, say apple ios app-store's navbar when you hover an item & it shows a refraction of the refraction of the background. Feel free to contribute.
7
+
5
8
  ## Installation
6
9
 
7
10
  ```shell
@@ -25,21 +28,13 @@ export class App {
25
28
  ```
26
29
 
27
30
  ```html
28
- <!-- Use in your html element as a directive, & configure it as your wish -->
29
- <div class="content"
30
- ngxGlassyEffect
31
- [blur]="1.5"
32
- [scale]="50"
33
- [bezel]="10"
34
- [profile]="'squircle'"
35
- [showBorder]="true"
36
- [lensRange]="100"
37
- [reflectionMidpoint]="0.2">
31
+ <!-- Use in your html element as a directive -->
32
+ <div class="content" ngxGlassyEffect>
38
33
  Hello - Bonjour - مرحبا
39
34
  </div>
40
35
  ```
41
36
 
42
- > Tip 1 **: If your div (.content for example) text is white & the background behind the div is light, give your div a semi-transparent background, like rgba(0, 0, 0, 0.35), to keep your text visible & readable, all without losing the glassy effect.
37
+ > Tip : If your div's text is white & the background behind it is light, give your div a semi-transparent background, like rgba (0, 0, 0, 0.35), to keep your text visible & readable, all without losing the glassy effect.
43
38
 
44
39
  ```css
45
40
  /* Tip 1 */
@@ -50,30 +45,35 @@ export class App {
50
45
  }
51
46
  ```
52
47
 
53
- > Tip 2 : If the default borders & shadows aren't working for you, you can just remove [showBorder] or make it 'false', & give the element of ngxGlassyEffect the border & shadows you like using css.
54
-
55
- ```css
56
- /* Tip 2 */
57
- .content {
58
- /* ... */
59
- border: turquoise 2px solid;
60
- }
61
- ```
62
-
63
48
  ## Demo
64
49
 
65
50
  > To see a visual Demo visit the git repository of this project : [Github Repository](https://github.com/anassmdi/ngx-glassy-effect)
66
51
 
67
52
  ## Configuration
68
53
 
69
- - If you wish to customize the inputs values, here's a full description of all the variables :
70
-
71
- | Input | Type | Default | Description |
72
- |--------------------|-----------------------|-----------|-----------------------------------------------------------------------------------------------------|
73
- | bezel | number | 10 | The width of the refractive edge bevel in pixels. |
74
- | scale | number | 50 | The intensity of the glass refraction distortion map. |
75
- | blur | number | 1.5 | The backdrop blur intensity factor applied to the substrate. |
76
- | profile | 'circle' / 'squircle' | 'squircle | The geometric falloff curve used to generate the edge normals. |
77
- | showBorder | boolean | false | Dynamically injects an anti-aliased pseudo-border running a dynamic light-angle alignment gradient. |
78
- | lensRange | number | 100 | The spatial scope/influence bounding box of the border lens effect. |
79
- | reflectionMidpoint | number | 0.2 | The turning midpoint ratio where edge glare achieves peak reflection values. |
54
+ - If you wish to customize the input values, here's a full description of all the variables :
55
+ - NB : Avoid customizing *** inputs unless you know what you're doing.
56
+
57
+ | Input | Type | Default | Description |
58
+ |-------------------|---------------------|-----------------------------------|----------------------------------------------------------------------------------------------------------|
59
+ | refraction | number | Height - 10px (if Height < 110px) | The intensity/depth of the refraction displacement map (auto-calculated from element height if omitted). |
60
+ | blur | number | 0 | The backdrop blur intensity factor applied to the substrate beneath the lens. |
61
+ | radius *** | number \| undefined | undefined | The corner radius of the glass effect (falls back to the element's computed CSS `border-radius`). |
62
+ | bezel *** | number | 0.7 | The relative width of the refractive edge bevel transition zone. |
63
+ | curvature *** | number | 4 | The exponential falloff curve exponent used to calculate the lens profile normals. |
64
+ | ior *** | number | 1.5 | The Index of Refraction (IOR) determining the degree of light bending through the lens. |
65
+ | specular *** | number | 0.2 | The intensity multiplier for the specular rim highlight and edge glow effect. |
66
+ | specularWidth *** | number | 1 | The crispness and width of the specular rim highlight line. |
67
+ | lightAngle *** | number | -120 | The directional angle of the virtual light source in degrees for rim lighting calculations. |
68
+ | invert *** | boolean | false | Inverts the lens distortion direction (switching between convex magnification and concave depth). |
69
+ | chroma | number | 0.12 | The chromatic aberration (RGB color splitting) intensity factor across refracted channels. |
70
+
71
+ ## Contribute
72
+
73
+ - Contributions, bug reports, and structural feature requests are welcome! Feel free to open an issue or submit a pull request on the official GitHub repository.
74
+
75
+ ## Author
76
+
77
+ - Anassmdi
78
+ - GitHub: @anassmdi
79
+ - NPM Package: ngx-glassy-effect
@@ -1,250 +1,575 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, ElementRef, DestroyRef, PLATFORM_ID, input, signal, effect, Directive } from '@angular/core';
2
+ import { inject, ElementRef, DestroyRef, PLATFORM_ID, input, effect, Directive } from '@angular/core';
3
3
  import { isPlatformBrowser } from '@angular/common';
4
4
 
5
+ const NS = 'http://www.w3.org/2000/svg';
6
+ const XLINK = 'http://www.w3.org/1999/xlink';
7
+ const NEUTRAL = 128;
8
+ const MAP_CACHE_SIZE = 48;
9
+ const DEFAULTS = Object.freeze({
10
+ x: 0,
11
+ y: 0,
12
+ width: 120,
13
+ height: 64,
14
+ radius: 32,
15
+ refraction: 18,
16
+ bezel: 0.6,
17
+ curvature: 4,
18
+ ior: 1.5,
19
+ invert: false,
20
+ chroma: 0.12,
21
+ blur: 0,
22
+ specular: 0.45,
23
+ specularWidth: 2,
24
+ lightAngle: -120,
25
+ mapScale: 0,
26
+ });
27
+ const MAP_KEYS = [
28
+ 'width',
29
+ 'height',
30
+ 'radius',
31
+ 'bezel',
32
+ 'curvature',
33
+ 'ior',
34
+ 'invert',
35
+ 'specular',
36
+ 'specularWidth',
37
+ 'lightAngle',
38
+ ];
39
+ function detectEngine() {
40
+ if (typeof navigator === 'undefined')
41
+ return 'unknown';
42
+ const brands = navigator.userAgentData?.brands;
43
+ if (brands?.some((b) => /Chromium/.test(b.brand)))
44
+ return 'blink';
45
+ const ua = navigator.userAgent;
46
+ if (/Firefox\//.test(ua))
47
+ return 'gecko';
48
+ if (/AppleWebKit\//.test(ua) && !/Chrome\/|Chromium\/|Edg\//.test(ua))
49
+ return 'webkit';
50
+ return /Chrome\//.test(ua) ? 'blink' : 'unknown';
51
+ }
52
+ const engine = detectEngine();
53
+ const profileCache = new Map();
54
+ function profileTable(curvature, ior) {
55
+ const key = `${curvature}|${ior}`;
56
+ let table = profileCache.get(key);
57
+ if (table)
58
+ return table;
59
+ const N = 512;
60
+ table = new Float32Array(N + 1);
61
+ let max = 0;
62
+ for (let i = 0; i <= N; i++) {
63
+ const s = Math.min(i / N, 1 - 1e-6);
64
+ const a = Math.pow(1 - s, curvature);
65
+ const slope = Math.pow(1 - s, curvature - 1) * Math.pow(Math.max(1 - a, 1e-9), 1 / curvature - 1);
66
+ const theta = Math.atan(slope);
67
+ const refracted = Math.asin(Math.sin(theta) / ior);
68
+ const bend = Math.tan(theta - refracted);
69
+ table[i] = bend;
70
+ if (bend > max)
71
+ max = bend;
72
+ }
73
+ for (let i = 0; i <= N; i++)
74
+ table[i] /= max || 1;
75
+ table[N] = 0;
76
+ profileCache.set(key, table);
77
+ return table;
78
+ }
79
+ function renderLensMap(options = {}, scale = 1) {
80
+ const p = { ...DEFAULTS, ...options };
81
+ const w = Math.max(2, Math.round(p.width * scale));
82
+ const h = Math.max(2, Math.round(p.height * scale));
83
+ const canvas = document.createElement('canvas');
84
+ canvas.width = w;
85
+ canvas.height = h;
86
+ const ctx = canvas.getContext('2d');
87
+ const image = ctx.createImageData(w, h);
88
+ const px = image.data;
89
+ const sx = p.width / w;
90
+ const sy = p.height / h;
91
+ const hw = p.width / 2;
92
+ const hh = p.height / 2;
93
+ const r = Math.max(0, Math.min(p.radius, hw, hh));
94
+ const bezel = Math.max(0.5, p.bezel * Math.min(hw, hh));
95
+ const table = profileTable(p.curvature, p.ior);
96
+ const N = table.length - 1;
97
+ const rimWidth = Math.max(0.5, p.specularWidth);
98
+ const aa = Math.max(sx, sy);
99
+ const angle = (p.lightAngle * Math.PI) / 180;
100
+ const lx = Math.cos(angle);
101
+ const ly = Math.sin(angle);
102
+ const dir = p.invert ? -1 : 1;
103
+ const qw = Math.ceil(w / 2);
104
+ const qh = Math.ceil(h / 2);
105
+ for (let j = 0; j < qh; j++) {
106
+ const y = (j + 0.5) * sy - hh;
107
+ for (let i = 0; i < qw; i++) {
108
+ const x = (i + 0.5) * sx - hw;
109
+ const qx = -x - (hw - r);
110
+ const qy = -y - (hh - r);
111
+ const ox = Math.max(qx, 0);
112
+ const oy = Math.max(qy, 0);
113
+ const corner = Math.hypot(ox, oy);
114
+ const dist = corner + Math.min(Math.max(qx, qy), 0) - r;
115
+ const alpha = Math.min(1, Math.max(0, 0.5 - dist / aa));
116
+ if (alpha <= 0)
117
+ continue;
118
+ let nx, ny;
119
+ if (qx > 0 && qy > 0) {
120
+ nx = ox / corner;
121
+ ny = oy / corner;
122
+ }
123
+ else if (qx > qy) {
124
+ nx = 1;
125
+ ny = 0;
126
+ }
127
+ else {
128
+ nx = 0;
129
+ ny = 1;
130
+ }
131
+ const inset = Math.max(0, -dist);
132
+ const s = inset / bezel;
133
+ const m = s >= 1 ? 0 : table[Math.min(N, Math.round(s * N))];
134
+ const bx = Math.round(127 * m * nx * dir);
135
+ const by = Math.round(127 * m * ny * dir);
136
+ const crisp = Math.max(0, 1 - inset / rimWidth);
137
+ const glow = Math.max(0, 1 - inset / (rimWidth * 5));
138
+ const rim = p.specular * (crisp * crisp + 0.3 * glow * glow);
139
+ const a = Math.round(alpha * 255);
140
+ const i2 = w - 1 - i;
141
+ const j2 = h - 1 - j;
142
+ write(px, (j * w + i) * 4, NEUTRAL + bx, NEUTRAL + by, rimLight(rim, -nx * lx - ny * ly), a);
143
+ if (i2 !== i)
144
+ write(px, (j * w + i2) * 4, NEUTRAL - bx, NEUTRAL + by, rimLight(rim, nx * lx - ny * ly), a);
145
+ if (j2 !== j)
146
+ write(px, (j2 * w + i) * 4, NEUTRAL + bx, NEUTRAL - by, rimLight(rim, -nx * lx + ny * ly), a);
147
+ if (i2 !== i && j2 !== j)
148
+ write(px, (j2 * w + i2) * 4, NEUTRAL - bx, NEUTRAL - by, rimLight(rim, nx * lx + ny * ly), a);
149
+ }
150
+ }
151
+ ctx.putImageData(image, 0, 0);
152
+ return { canvas, width: w, height: h, scale };
153
+ }
154
+ function rimLight(rim, facing) {
155
+ const shade = 0.12 + 0.88 * (facing > 0 ? facing : -0.4 * facing);
156
+ return NEUTRAL + Math.round(127 * Math.min(1, rim * shade));
157
+ }
158
+ function write(px, o, r, g, b, a) {
159
+ px[o] = r;
160
+ px[o + 1] = g;
161
+ px[o + 2] = b;
162
+ px[o + 3] = a;
163
+ }
164
+ const mapCache = new Map();
165
+ function mapKeyOf(p, scale) {
166
+ return MAP_KEYS.map((k) => p[k]).join('|') + '|' + scale;
167
+ }
168
+ function lensMap(p, scale, key) {
169
+ let entry = mapCache.get(key);
170
+ if (entry) {
171
+ mapCache.delete(key);
172
+ }
173
+ else {
174
+ const url = renderLensMap(p, scale).canvas.toDataURL('image/png');
175
+ entry = { key, url, decoded: false, ready: null };
176
+ const img = new Image();
177
+ img.src = url;
178
+ entry.ready = img
179
+ .decode()
180
+ .catch(() => { })
181
+ .then(() => {
182
+ entry.decoded = true;
183
+ });
184
+ if (mapCache.size >= MAP_CACHE_SIZE)
185
+ mapCache.delete(mapCache.keys().next().value);
186
+ }
187
+ mapCache.set(key, entry);
188
+ return entry;
189
+ }
190
+ let svgRoot = null;
191
+ function defsNode() {
192
+ if (svgRoot?.isConnected)
193
+ return svgRoot.firstChild;
194
+ svgRoot = document.createElementNS(NS, 'svg');
195
+ svgRoot.setAttribute('aria-hidden', 'true');
196
+ svgRoot.setAttribute('width', '0');
197
+ svgRoot.setAttribute('height', '0');
198
+ svgRoot.style.cssText = 'position:absolute;width:0;height:0;overflow:hidden;pointer-events:none';
199
+ svgRoot.appendChild(document.createElementNS(NS, 'defs'));
200
+ document.body.appendChild(svgRoot);
201
+ return svgRoot.firstChild;
202
+ }
203
+ function node(name, attrs) {
204
+ const n = document.createElementNS(NS, name);
205
+ for (const k in attrs)
206
+ n.setAttribute(k, attrs[k]);
207
+ return n;
208
+ }
209
+ const CHANNELS = [
210
+ '1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0',
211
+ '0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0',
212
+ '0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0',
213
+ ];
214
+ function buildGraph(filter, p) {
215
+ filter.replaceChildren();
216
+ const lensRect = [];
217
+ const add = (name, attrs, inLens) => {
218
+ const n = node(name, attrs);
219
+ filter.appendChild(n);
220
+ if (inLens)
221
+ lensRect.push(n);
222
+ return n;
223
+ };
224
+ add('feFlood', { 'flood-color': 'rgb(128,128,128)', 'flood-opacity': '1', result: 'neutral' }, true);
225
+ const image = add('feImage', { preserveAspectRatio: 'none', result: 'lensShape' }, true);
226
+ add('feComposite', { in: 'lensShape', in2: 'neutral', operator: 'over', result: 'map' }, true);
227
+ const aspect = engine === 'webkit'
228
+ ? add('feColorMatrix', { in: 'map', type: 'matrix', result: 'bend' }, true)
229
+ : null;
230
+ const bendMap = aspect ? 'bend' : 'map';
231
+ let source = 'SourceGraphic';
232
+ let blur = null;
233
+ if (p.blur > 0) {
234
+ blur = add('feGaussianBlur', { in: 'SourceGraphic', result: 'frosted' });
235
+ source = 'frosted';
236
+ }
237
+ const displace = [];
238
+ if (p.chroma > 0) {
239
+ CHANNELS.forEach((values, i) => {
240
+ displace.push(add('feDisplacementMap', { in: source, in2: bendMap, xChannelSelector: 'R', yChannelSelector: 'G' }, true));
241
+ add('feColorMatrix', { type: 'matrix', values, result: `ch${i}` }, true);
242
+ });
243
+ add('feComposite', {
244
+ in: 'ch0',
245
+ in2: 'ch1',
246
+ operator: 'arithmetic',
247
+ k1: '0',
248
+ k2: '1',
249
+ k3: '1',
250
+ k4: '0',
251
+ result: 'rg',
252
+ }, true);
253
+ add('feComposite', {
254
+ in: 'rg',
255
+ in2: 'ch2',
256
+ operator: 'arithmetic',
257
+ k1: '0',
258
+ k2: '1',
259
+ k3: '1',
260
+ k4: '0',
261
+ result: 'refracted',
262
+ }, true);
263
+ }
264
+ else {
265
+ displace.push(add('feDisplacementMap', {
266
+ in: source,
267
+ in2: bendMap,
268
+ xChannelSelector: 'R',
269
+ yChannelSelector: 'G',
270
+ result: 'refracted',
271
+ }, true));
272
+ }
273
+ let lit = 'refracted';
274
+ if (p.specular > 0) {
275
+ add('feColorMatrix', {
276
+ in: 'map',
277
+ type: 'matrix',
278
+ values: `0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 2 0 ${-(2 * NEUTRAL) / 255}`,
279
+ result: 'rim',
280
+ }, true);
281
+ add('feComposite', {
282
+ in: 'rim',
283
+ in2: 'refracted',
284
+ operator: 'arithmetic',
285
+ k1: '0',
286
+ k2: '1',
287
+ k3: '1',
288
+ k4: '0',
289
+ result: 'lit',
290
+ }, true);
291
+ lit = 'lit';
292
+ }
293
+ add('feComposite', { in: lit, in2: 'lensShape', operator: 'in', result: 'lens' }, true);
294
+ add('feComposite', { in: 'SourceGraphic', in2: 'lensShape', operator: 'out', result: 'outside' });
295
+ add('feComposite', { in: 'lens', in2: 'outside', operator: 'over' });
296
+ return { image, aspect, blur, displace, lensRect };
297
+ }
298
+ function bendScale(px, w, h) {
299
+ if (engine === 'webkit') {
300
+ const m = Math.min(w, h);
301
+ return { scale: (2 * px) / m, kx: m / w, ky: m / h };
302
+ }
303
+ if (engine === 'gecko')
304
+ return { scale: (2 * px) / Math.sqrt((w * w + h * h) / 2), kx: 1, ky: 1 };
305
+ return { scale: (2 * px) / w, kx: 1, ky: 1 };
306
+ }
307
+ function setRect(n, x, y, w, h) {
308
+ n.setAttribute('x', String(x));
309
+ n.setAttribute('y', String(y));
310
+ n.setAttribute('width', String(w));
311
+ n.setAttribute('height', String(h));
312
+ }
313
+ let uid = 0;
314
+ function createGlass(target, options = {}) {
315
+ const base = `lg${++uid}`;
316
+ const mode = options.mode ?? 'content';
317
+ const fallback = options.fallback ?? 'blur(12px) saturate(1.6)';
318
+ const p = { ...DEFAULTS, ...pickOpts(options) };
319
+ const flags = {
320
+ fit: !!options.fit,
321
+ clip: !!options.clip,
322
+ sync: !!options.sync,
323
+ hidden: !!options.hidden,
324
+ };
325
+ const useBackdropURL = mode === 'backdrop' && engine === 'blink';
326
+ const active = mode !== 'backdrop' || useBackdropURL;
327
+ if (!active) {
328
+ target.style.backdropFilter = fallback;
329
+ target.style.webkitBackdropFilter = fallback;
330
+ }
331
+ const filter = node('filter', {
332
+ filterUnits: 'objectBoundingBox',
333
+ x: '0',
334
+ y: '0',
335
+ width: '1',
336
+ height: '1',
337
+ primitiveUnits: 'objectBoundingBox',
338
+ 'color-interpolation-filters': 'sRGB',
339
+ });
340
+ if (active)
341
+ defsNode().appendChild(filter);
342
+ let graph = null;
343
+ let structure = '';
344
+ let wanted = '';
345
+ let requested = 0;
346
+ let shown = { key: '', seq: -1 };
347
+ let version = 0;
348
+ let frame = 0;
349
+ let settleTimers = [];
350
+ let destroyed = false;
351
+ let box = { width: target.offsetWidth, height: target.offsetHeight };
352
+ const observer = active
353
+ ? new ResizeObserver(() => {
354
+ box = { width: target.offsetWidth, height: target.offsetHeight };
355
+ schedule();
356
+ })
357
+ : null;
358
+ observer?.observe(target);
359
+ function settle() {
360
+ settleTimers.forEach(clearTimeout);
361
+ settleTimers = [60, 250].map((ms) => setTimeout(schedule, ms));
362
+ }
363
+ function show(entry, seq) {
364
+ if (seq <= shown.seq || !graph)
365
+ return false;
366
+ graph.image.setAttribute('href', entry.url);
367
+ graph.image.setAttributeNS(XLINK, 'xlink:href', entry.url);
368
+ shown = { key: entry.key, seq };
369
+ settle();
370
+ return true;
371
+ }
372
+ function flush() {
373
+ frame = 0;
374
+ if (destroyed || !active)
375
+ return;
376
+ if (flags.hidden) {
377
+ if (useBackdropURL)
378
+ target.style.backdropFilter = '';
379
+ else
380
+ target.style.filter = '';
381
+ if (flags.clip)
382
+ target.style.clipPath = 'inset(50%)';
383
+ return;
384
+ }
385
+ const W = box.width;
386
+ const H = box.height;
387
+ if (W < 1 || H < 1)
388
+ return;
389
+ if (flags.fit) {
390
+ p.x = 0;
391
+ p.y = 0;
392
+ p.width = W;
393
+ p.height = H;
394
+ }
395
+ if (p.width < 1 || p.height < 1)
396
+ return;
397
+ const s = `${p.chroma > 0}|${p.blur > 0}|${p.specular > 0}`;
398
+ if (s !== structure) {
399
+ graph = buildGraph(filter, p);
400
+ structure = s;
401
+ shown = { key: '', seq: -1 };
402
+ wanted = '';
403
+ }
404
+ const dpr = window.devicePixelRatio || 1;
405
+ const scale = p.mapScale > 0 ? p.mapScale : Math.min(dpr, 2);
406
+ const snap = (v) => Math.round(v * dpr) / dpr;
407
+ const x = snap(p.x);
408
+ const y = snap(p.y);
409
+ const w = snap(p.width);
410
+ const h = snap(p.height);
411
+ const key = mapKeyOf(p, scale);
412
+ if (wanted !== key) {
413
+ wanted = key;
414
+ const entry = lensMap(p, scale, key);
415
+ const seq = ++requested;
416
+ if (entry.decoded)
417
+ show(entry, seq);
418
+ else
419
+ entry.ready.then(() => !destroyed && show(entry, seq) && schedule());
420
+ }
421
+ if (flags.clip) {
422
+ const r = Math.min(p.radius, w / 2, h / 2);
423
+ target.style.clipPath = `inset(${y}px ${W - x - w}px ${H - y - h}px ${x}px round ${r}px)`;
424
+ }
425
+ if (!shown.key)
426
+ return;
427
+ for (const n of graph.lensRect)
428
+ setRect(n, x / W, y / H, w / W, h / H);
429
+ const { scale: k, kx, ky } = bendScale(p.refraction, W, H);
430
+ const scales = graph.displace.length === 3 ? [k, k * (1 + p.chroma / 2), k * (1 + p.chroma)] : [k];
431
+ graph.displace.forEach((n, i) => n.setAttribute('scale', String(scales[i])));
432
+ if (graph.aspect) {
433
+ graph.aspect.setAttribute('values', `${kx} 0 0 0 ${(1 - kx) / 2} 0 ${ky} 0 0 ${(1 - ky) / 2} 0 0 1 0 0 0 0 0 1 0`);
434
+ }
435
+ if (graph.blur) {
436
+ graph.blur.setAttribute('stdDeviation', `${p.blur / W} ${p.blur / H}`);
437
+ const pad = Math.ceil(p.refraction * (1 + p.chroma) + 3 * p.blur);
438
+ setRect(graph.blur, (x - pad) / W, (y - pad) / H, (w + 2 * pad) / W, (h + 2 * pad) / H);
439
+ }
440
+ filter.id = `${base}-v${++version}`;
441
+ const ref = `url(#${filter.id})`;
442
+ if (useBackdropURL)
443
+ target.style.backdropFilter = ref;
444
+ else
445
+ target.style.filter = ref;
446
+ }
447
+ function schedule() {
448
+ if (flags.sync)
449
+ flush();
450
+ else if (!frame)
451
+ frame = requestAnimationFrame(flush);
452
+ }
453
+ schedule();
454
+ return {
455
+ update(next = {}) {
456
+ const changes = pickOpts(next);
457
+ const hidden = next.hidden === undefined ? flags.hidden : !!next.hidden;
458
+ if (hidden === flags.hidden &&
459
+ Object.keys(changes).every((k) => changes[k] === p[k]))
460
+ return;
461
+ Object.assign(p, changes);
462
+ flags.hidden = hidden;
463
+ schedule();
464
+ },
465
+ flush() {
466
+ if (frame)
467
+ cancelAnimationFrame(frame);
468
+ flush();
469
+ },
470
+ destroy() {
471
+ destroyed = true;
472
+ if (frame)
473
+ cancelAnimationFrame(frame);
474
+ settleTimers.forEach(clearTimeout);
475
+ observer?.disconnect();
476
+ filter.remove();
477
+ target.style.filter = '';
478
+ target.style.backdropFilter = '';
479
+ target.style.webkitBackdropFilter = '';
480
+ if (flags.clip)
481
+ target.style.clipPath = '';
482
+ },
483
+ };
484
+ }
485
+ function pickOpts(o) {
486
+ const out = {};
487
+ for (const k in DEFAULTS)
488
+ if (o[k] !== undefined)
489
+ out[k] = o[k];
490
+ return out;
491
+ }
5
492
  class GlassyEffect {
6
493
  el = inject((ElementRef));
7
494
  destroyRef = inject(DestroyRef);
8
495
  platformId = inject(PLATFORM_ID);
9
496
  isBrowser = isPlatformBrowser(this.platformId);
10
- bezel = input(10, /* @ts-ignore */
11
- ...(ngDevMode ? [{ debugName: "bezel" }] : /* istanbul ignore next */ []));
12
- scale = input(50, /* @ts-ignore */
13
- ...(ngDevMode ? [{ debugName: "scale" }] : /* istanbul ignore next */ []));
14
- blur = input(1.5, /* @ts-ignore */
497
+ refraction = input(/* @ts-ignore */
498
+ ...(ngDevMode ? [undefined, { debugName: "refraction" }] : /* istanbul ignore next */ []));
499
+ blur = input(0, /* @ts-ignore */
15
500
  ...(ngDevMode ? [{ debugName: "blur" }] : /* istanbul ignore next */ []));
16
- profile = input('squircle', /* @ts-ignore */
17
- ...(ngDevMode ? [{ debugName: "profile" }] : /* istanbul ignore next */ []));
18
- showBorder = input(false, /* @ts-ignore */
19
- ...(ngDevMode ? [{ debugName: "showBorder" }] : /* istanbul ignore next */ []));
20
- lensRange = input(100, /* @ts-ignore */
21
- ...(ngDevMode ? [{ debugName: "lensRange" }] : /* istanbul ignore next */ []));
22
- reflectionMidpoint = input(0.2, /* @ts-ignore */
23
- ...(ngDevMode ? [{ debugName: "reflectionMidpoint" }] : /* istanbul ignore next */ []));
24
- width = signal(0, /* @ts-ignore */
25
- ...(ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ []));
26
- height = signal(0, /* @ts-ignore */
27
- ...(ngDevMode ? [{ debugName: "height" }] : /* istanbul ignore next */ []));
28
- filterId = `glassy-effect-${Math.random().toString(36).substring(2, 9)}`;
29
- resizeObserver;
30
- sharedCanvas = this.isBrowser ? document.createElement('canvas') : null;
31
- borderLayer = null;
32
- animationFrameId = null;
501
+ radius = input(undefined, /* @ts-ignore */
502
+ ...(ngDevMode ? [{ debugName: "radius" }] : /* istanbul ignore next */ []));
503
+ bezel = input(0.7, /* @ts-ignore */
504
+ ...(ngDevMode ? [{ debugName: "bezel" }] : /* istanbul ignore next */ []));
505
+ curvature = input(4, /* @ts-ignore */
506
+ ...(ngDevMode ? [{ debugName: "curvature" }] : /* istanbul ignore next */ []));
507
+ ior = input(1.5, /* @ts-ignore */
508
+ ...(ngDevMode ? [{ debugName: "ior" }] : /* istanbul ignore next */ []));
509
+ specular = input(0.2, /* @ts-ignore */
510
+ ...(ngDevMode ? [{ debugName: "specular" }] : /* istanbul ignore next */ []));
511
+ specularWidth = input(1, /* @ts-ignore */
512
+ ...(ngDevMode ? [{ debugName: "specularWidth" }] : /* istanbul ignore next */ []));
513
+ lightAngle = input(-120, /* @ts-ignore */
514
+ ...(ngDevMode ? [{ debugName: "lightAngle" }] : /* istanbul ignore next */ []));
515
+ invert = input(false, /* @ts-ignore */
516
+ ...(ngDevMode ? [{ debugName: "invert" }] : /* istanbul ignore next */ []));
517
+ chroma = input(0.12, /* @ts-ignore */
518
+ ...(ngDevMode ? [{ debugName: "chroma" }] : /* istanbul ignore next */ []));
519
+ glassInstance = null;
33
520
  constructor() {
34
521
  if (!this.isBrowser)
35
522
  return;
36
- this.setupResizeObserver();
37
523
  effect(() => {
38
- const w = Math.floor(this.width());
39
- const h = Math.floor(this.height());
40
- const scale = this.scale();
41
- const blur = this.blur();
42
- const profile = this.profile();
43
- const lensRange = this.lensRange();
44
- const reflectionMidpoint = this.reflectionMidpoint();
45
- if (w === 0 || h === 0)
46
- return;
47
524
  const nativeEl = this.el.nativeElement;
48
- const computedStyle = window.getComputedStyle(nativeEl);
49
- const maxPossibleRadius = Math.min(w / 2, h / 2);
50
- const rawRadius = parseFloat(computedStyle.borderRadius) || 0;
51
- const borderRadius = Math.min(rawRadius, maxPossibleRadius);
52
- const dataUrl = this.generateDisplacementMap(w, h, profile, borderRadius, lensRange, reflectionMidpoint);
53
- this.syncSvgFilter(dataUrl, w, h, scale, blur);
54
- nativeEl.style.backdropFilter = `url(#${this.filterId})`;
55
- if (this.showBorder()) {
56
- this.applyBorderLighting(w, h, borderRadius);
525
+ const currentRadius = this.radius() ?? this.getComputedRadius();
526
+ const H = nativeEl.offsetHeight || nativeEl.getBoundingClientRect().height || 64;
527
+ const calculatedRefraction = H < 110 ? Math.max(1, H - 10) : 100;
528
+ const options = {
529
+ refraction: this.refraction() ? this.refraction() : calculatedRefraction,
530
+ blur: this.blur(),
531
+ radius: currentRadius,
532
+ bezel: this.bezel(),
533
+ curvature: this.curvature(),
534
+ ior: this.ior(),
535
+ specular: this.specular(),
536
+ specularWidth: this.specularWidth(),
537
+ lightAngle: this.lightAngle(),
538
+ invert: this.invert(),
539
+ chroma: this.chroma(),
540
+ mode: 'backdrop',
541
+ fit: true,
542
+ clip: undefined,
543
+ hidden: false,
544
+ };
545
+ if (!this.glassInstance) {
546
+ this.glassInstance = createGlass(nativeEl, options);
57
547
  }
58
- else if (this.borderLayer) {
59
- this.borderLayer.remove();
60
- this.borderLayer = null;
548
+ else {
549
+ this.glassInstance.update(options);
61
550
  }
62
551
  });
63
552
  this.destroyRef.onDestroy(() => {
64
- if (this.resizeObserver)
65
- this.resizeObserver.disconnect();
66
- if (this.animationFrameId)
67
- cancelAnimationFrame(this.animationFrameId);
68
- const svgEl = document.getElementById(`svg-container-${this.filterId}`);
69
- if (svgEl)
70
- svgEl.remove();
71
- });
72
- }
73
- applyBorderLighting(w, h, r) {
74
- const nativeEl = this.el.nativeElement;
75
- const computedStyle = window.getComputedStyle(nativeEl);
76
- if (computedStyle.position === 'static') {
77
- nativeEl.style.position = 'relative';
78
- }
79
- nativeEl.style.border = 'none';
80
- nativeEl.style.boxShadow = 'none';
81
- if (!this.borderLayer) {
82
- this.borderLayer = document.createElement('div');
83
- this.borderLayer.style.position = 'absolute';
84
- this.borderLayer.style.inset = '0px';
85
- this.borderLayer.style.pointerEvents = 'none';
86
- this.borderLayer.style.zIndex = '1';
87
- this.borderLayer.style.webkitMask =
88
- 'linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)';
89
- this.borderLayer.style.webkitMaskComposite = 'xor';
90
- this.borderLayer.style.maskComposite = 'exclude';
91
- this.borderLayer.style.padding = '1px';
92
- nativeEl.appendChild(this.borderLayer);
93
- }
94
- this.borderLayer.style.borderRadius = computedStyle.borderRadius || 'inherit';
95
- this.borderLayer.style.opacity = '1';
96
- const dx = w - 2 * r + r * Math.sqrt(2);
97
- const dy = h - 2 * r + r * Math.sqrt(2);
98
- const angle = 90 + (Math.atan2(dx, dy) * 180) / Math.PI;
99
- this.borderLayer.style.background = `
100
- linear-gradient(${angle}deg,
101
- rgba(255, 255, 255, 0.22) 0%,
102
- rgba(255, 255, 255, 0.18) 20%,
103
- rgba(255, 255, 255, 0.12) 35%,
104
- rgba(255, 255, 255, 0.07) 45%,
105
- rgba(255, 255, 255, 0.07) 55%,
106
- rgba(255, 255, 255, 0.12) 65%,
107
- rgba(255, 255, 255, 0.18) 80%,
108
- rgba(255, 255, 255, 0.22) 100%
109
- )
110
- `;
111
- }
112
- setupResizeObserver() {
113
- this.resizeObserver = new ResizeObserver(() => {
114
- if (this.animationFrameId)
115
- cancelAnimationFrame(this.animationFrameId);
116
- this.animationFrameId = requestAnimationFrame(() => {
117
- const rect = this.el.nativeElement.getBoundingClientRect();
118
- this.width.set(rect.width);
119
- this.height.set(rect.height);
120
- });
121
- });
122
- this.resizeObserver.observe(this.el.nativeElement);
123
- }
124
- generateDisplacementMap(w, h, profile, borderRadius, lensRange, reflectionMidpoint) {
125
- const canvas = this.sharedCanvas;
126
- if (!canvas)
127
- return '';
128
- canvas.width = w;
129
- canvas.height = h;
130
- const ctx = canvas.getContext('2d');
131
- if (!ctx)
132
- return '';
133
- const imgData = ctx.createImageData(w, h);
134
- const data = imgData.data;
135
- const activeRange = lensRange * reflectionMidpoint;
136
- for (let y = 0; y < h; y++) {
137
- for (let x = 0; x < w; x++) {
138
- const distL = x;
139
- const distR = w - x;
140
- const distT = y;
141
- const distB = h - y;
142
- let minDist = Math.min(distL, distR, distT, distB);
143
- let nx = 0;
144
- let ny = 0;
145
- if (minDist === distL)
146
- nx = 1;
147
- else if (minDist === distR)
148
- nx = -1;
149
- else if (minDist === distT)
150
- ny = 1;
151
- else if (minDist === distB)
152
- ny = -1;
153
- if (x < borderRadius && y < borderRadius) {
154
- const dist = Math.sqrt(Math.pow(borderRadius - x, 2) + Math.pow(borderRadius - y, 2));
155
- minDist = borderRadius - dist;
156
- if (dist > 0) {
157
- nx = (borderRadius - x) / dist;
158
- ny = (borderRadius - y) / dist;
159
- }
160
- }
161
- else if (x > w - borderRadius && y < borderRadius) {
162
- const dist = Math.sqrt(Math.pow(x - (w - borderRadius), 2) + Math.pow(borderRadius - y, 2));
163
- minDist = borderRadius - dist;
164
- if (dist > 0) {
165
- nx = -(x - (w - borderRadius)) / dist;
166
- ny = (borderRadius - y) / dist;
167
- }
168
- }
169
- else if (x < borderRadius && y > h - borderRadius) {
170
- const dist = Math.sqrt(Math.pow(borderRadius - x, 2) + Math.pow(y - (h - borderRadius), 2));
171
- minDist = borderRadius - dist;
172
- if (dist > 0) {
173
- nx = (borderRadius - x) / dist;
174
- ny = -(y - (h - borderRadius)) / dist;
175
- }
176
- }
177
- else if (x > w - borderRadius && y > h - borderRadius) {
178
- const dist = Math.sqrt(Math.pow(x - (w - borderRadius), 2) + Math.pow(y - (h - borderRadius), 2));
179
- minDist = borderRadius - dist;
180
- if (dist > 0) {
181
- nx = -(x - (w - borderRadius)) / dist;
182
- ny = -(y - (h - borderRadius)) / dist;
183
- }
184
- }
185
- let magnitude = 0;
186
- if (minDist >= 0 && minDist < activeRange) {
187
- const tActive = minDist / activeRange;
188
- magnitude = Math.pow(1 - tActive, 2);
189
- }
190
- else {
191
- magnitude = 0;
192
- }
193
- let finalMagX = nx * magnitude;
194
- let finalMagY = ny * magnitude;
195
- if (profile === 'squircle') {
196
- finalMagX *= 0.95;
197
- finalMagY *= 0.95;
198
- }
199
- const rVal = Math.floor(128 + finalMagX * 127);
200
- const gVal = Math.floor(128 + finalMagY * 127);
201
- const idx = (y * w + x) * 4;
202
- data[idx] = Math.max(0, Math.min(255, rVal));
203
- data[idx + 1] = Math.max(0, Math.min(255, gVal));
204
- data[idx + 2] = 128;
205
- data[idx + 3] = 255;
553
+ if (this.glassInstance) {
554
+ this.glassInstance.destroy();
555
+ this.glassInstance = null;
206
556
  }
207
- }
208
- ctx.putImageData(imgData, 0, 0);
209
- return canvas.toDataURL();
557
+ });
210
558
  }
211
- syncSvgFilter(dataUrl, w, h, scale, blur) {
212
- let container = document.getElementById(`svg-container-${this.filterId}`);
213
- if (!container) {
214
- container = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
215
- container.id = `svg-container-${this.filterId}`;
216
- container.setAttribute('style', 'position: absolute; width: 0; height: 0; pointer-events: none;');
217
- document.body.appendChild(container);
218
- }
219
- container.innerHTML = `
220
- <filter id="${this.filterId}"
221
- x="-30%" y="-30%" width="160%" height="160%"
222
- primitiveUnits="userSpaceOnUse"
223
- color-interpolation-filters="sRGB">
224
-
225
- <feImage href="${dataUrl}" x="0" y="0" width="${w}" height="${h}" preserveAspectRatio="none" result="glass_map" />
226
- <feGaussianBlur in="SourceGraphic" stdDeviation="${blur}" result="blurred_substrate" />
227
-
228
- <feDisplacementMap
229
- in="blurred_substrate"
230
- in2="glass_map"
231
- scale="${scale}"
232
- xChannelSelector="R"
233
- yChannelSelector="G"
234
- />
235
- </filter>
236
- `;
559
+ getComputedRadius() {
560
+ const computed = window.getComputedStyle(this.el.nativeElement);
561
+ return parseFloat(computed.borderRadius) || 32;
237
562
  }
238
563
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: GlassyEffect, deps: [], target: i0.ɵɵFactoryTarget.Directive });
239
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.0", type: GlassyEffect, isStandalone: true, selector: "[ngxGlassyEffect]", inputs: { bezel: { classPropertyName: "bezel", publicName: "bezel", isSignal: true, isRequired: false, transformFunction: null }, scale: { classPropertyName: "scale", publicName: "scale", isSignal: true, isRequired: false, transformFunction: null }, blur: { classPropertyName: "blur", publicName: "blur", isSignal: true, isRequired: false, transformFunction: null }, profile: { classPropertyName: "profile", publicName: "profile", isSignal: true, isRequired: false, transformFunction: null }, showBorder: { classPropertyName: "showBorder", publicName: "showBorder", isSignal: true, isRequired: false, transformFunction: null }, lensRange: { classPropertyName: "lensRange", publicName: "lensRange", isSignal: true, isRequired: false, transformFunction: null }, reflectionMidpoint: { classPropertyName: "reflectionMidpoint", publicName: "reflectionMidpoint", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
564
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.0", type: GlassyEffect, isStandalone: true, selector: "[ngxGlassyEffect]", inputs: { refraction: { classPropertyName: "refraction", publicName: "refraction", isSignal: true, isRequired: false, transformFunction: null }, blur: { classPropertyName: "blur", publicName: "blur", isSignal: true, isRequired: false, transformFunction: null }, radius: { classPropertyName: "radius", publicName: "radius", isSignal: true, isRequired: false, transformFunction: null }, bezel: { classPropertyName: "bezel", publicName: "bezel", isSignal: true, isRequired: false, transformFunction: null }, curvature: { classPropertyName: "curvature", publicName: "curvature", isSignal: true, isRequired: false, transformFunction: null }, ior: { classPropertyName: "ior", publicName: "ior", isSignal: true, isRequired: false, transformFunction: null }, specular: { classPropertyName: "specular", publicName: "specular", isSignal: true, isRequired: false, transformFunction: null }, specularWidth: { classPropertyName: "specularWidth", publicName: "specularWidth", isSignal: true, isRequired: false, transformFunction: null }, lightAngle: { classPropertyName: "lightAngle", publicName: "lightAngle", isSignal: true, isRequired: false, transformFunction: null }, invert: { classPropertyName: "invert", publicName: "invert", isSignal: true, isRequired: false, transformFunction: null }, chroma: { classPropertyName: "chroma", publicName: "chroma", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
240
565
  }
241
566
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: GlassyEffect, decorators: [{
242
567
  type: Directive,
243
568
  args: [{
244
569
  selector: '[ngxGlassyEffect]',
245
- standalone: true
570
+ standalone: true,
246
571
  }]
247
- }], ctorParameters: () => [], propDecorators: { bezel: [{ type: i0.Input, args: [{ isSignal: true, alias: "bezel", required: false }] }], scale: [{ type: i0.Input, args: [{ isSignal: true, alias: "scale", required: false }] }], blur: [{ type: i0.Input, args: [{ isSignal: true, alias: "blur", required: false }] }], profile: [{ type: i0.Input, args: [{ isSignal: true, alias: "profile", required: false }] }], showBorder: [{ type: i0.Input, args: [{ isSignal: true, alias: "showBorder", required: false }] }], lensRange: [{ type: i0.Input, args: [{ isSignal: true, alias: "lensRange", required: false }] }], reflectionMidpoint: [{ type: i0.Input, args: [{ isSignal: true, alias: "reflectionMidpoint", required: false }] }] } });
572
+ }], ctorParameters: () => [], propDecorators: { refraction: [{ type: i0.Input, args: [{ isSignal: true, alias: "refraction", required: false }] }], blur: [{ type: i0.Input, args: [{ isSignal: true, alias: "blur", required: false }] }], radius: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], bezel: [{ type: i0.Input, args: [{ isSignal: true, alias: "bezel", required: false }] }], curvature: [{ type: i0.Input, args: [{ isSignal: true, alias: "curvature", required: false }] }], ior: [{ type: i0.Input, args: [{ isSignal: true, alias: "ior", required: false }] }], specular: [{ type: i0.Input, args: [{ isSignal: true, alias: "specular", required: false }] }], specularWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "specularWidth", required: false }] }], lightAngle: [{ type: i0.Input, args: [{ isSignal: true, alias: "lightAngle", required: false }] }], invert: [{ type: i0.Input, args: [{ isSignal: true, alias: "invert", required: false }] }], chroma: [{ type: i0.Input, args: [{ isSignal: true, alias: "chroma", required: false }] }] } });
248
573
 
249
574
  /*
250
575
  * Public API Surface of ngx-glassy-effect
@@ -1 +1 @@
1
- {"version":3,"file":"ngx-glassy-effect.mjs","sources":["../../../projects/ngx-glassy-effect/src/lib/glassy-effect.ts","../../../projects/ngx-glassy-effect/src/public-api.ts","../../../projects/ngx-glassy-effect/src/ngx-glassy-effect.ts"],"sourcesContent":["import { DestroyRef, Directive, ElementRef, inject, input, signal, effect, PLATFORM_ID } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\n\n@Directive({\n selector: '[ngxGlassyEffect]',\n standalone: true\n})\nexport class GlassyEffect {\n private el = inject(ElementRef<HTMLElement>);\n private destroyRef = inject(DestroyRef);\n private platformId = inject(PLATFORM_ID);\n private isBrowser = isPlatformBrowser(this.platformId);\n\n bezel = input<number>(10);\n scale = input<number>(50);\n blur = input<number>(1.5);\n profile = input<'circle' | 'squircle'>('squircle');\n showBorder = input<boolean>(false);\n\n lensRange = input<number>(100);\n reflectionMidpoint = input<number>(0.2);\n\n private width = signal<number>(0);\n private height = signal<number>(0);\n\n private filterId = `glassy-effect-${Math.random().toString(36).substring(2, 9)}`;\n private resizeObserver!: ResizeObserver;\n\n private sharedCanvas = this.isBrowser ? document.createElement('canvas') : null;\n private borderLayer: HTMLDivElement | null = null;\n private animationFrameId: number | null = null;\n\n constructor() {\n if (!this.isBrowser) return;\n\n this.setupResizeObserver();\n\n effect(() => {\n const w = Math.floor(this.width());\n const h = Math.floor(this.height());\n const scale = this.scale();\n const blur = this.blur();\n const profile = this.profile();\n const lensRange = this.lensRange();\n const reflectionMidpoint = this.reflectionMidpoint();\n\n if (w === 0 || h === 0) return;\n\n const nativeEl = this.el.nativeElement;\n const computedStyle = window.getComputedStyle(nativeEl);\n\n const maxPossibleRadius = Math.min(w / 2, h / 2);\n const rawRadius = parseFloat(computedStyle.borderRadius) || 0;\n const borderRadius = Math.min(rawRadius, maxPossibleRadius);\n\n const dataUrl = this.generateDisplacementMap(w, h, profile, borderRadius, lensRange, reflectionMidpoint);\n this.syncSvgFilter(dataUrl, w, h, scale, blur);\n\n nativeEl.style.backdropFilter = `url(#${this.filterId})`;\n\n if (this.showBorder()) {\n this.applyBorderLighting(w, h, borderRadius);\n } else if (this.borderLayer) {\n this.borderLayer.remove();\n this.borderLayer = null;\n }\n });\n\n this.destroyRef.onDestroy(() => {\n if (this.resizeObserver) this.resizeObserver.disconnect();\n if (this.animationFrameId) cancelAnimationFrame(this.animationFrameId);\n\n const svgEl = document.getElementById(`svg-container-${this.filterId}`);\n if (svgEl) svgEl.remove();\n });\n }\n\n private applyBorderLighting(w: number, h: number, r: number): void {\n const nativeEl = this.el.nativeElement;\n const computedStyle = window.getComputedStyle(nativeEl);\n\n if (computedStyle.position === 'static') {\n nativeEl.style.position = 'relative';\n }\n\n nativeEl.style.border = 'none';\n nativeEl.style.boxShadow = 'none';\n\n if (!this.borderLayer) {\n this.borderLayer = document.createElement('div');\n this.borderLayer.style.position = 'absolute';\n this.borderLayer.style.inset = '0px';\n this.borderLayer.style.pointerEvents = 'none';\n this.borderLayer.style.zIndex = '1';\n this.borderLayer.style.webkitMask =\n 'linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)';\n this.borderLayer.style.webkitMaskComposite = 'xor';\n this.borderLayer.style.maskComposite = 'exclude';\n this.borderLayer.style.padding = '1px';\n nativeEl.appendChild(this.borderLayer);\n }\n\n this.borderLayer.style.borderRadius = computedStyle.borderRadius || 'inherit';\n this.borderLayer.style.opacity = '1';\n\n const dx = w - 2 * r + r * Math.sqrt(2);\n const dy = h - 2 * r + r * Math.sqrt(2);\n const angle = 90 + (Math.atan2(dx, dy) * 180) / Math.PI;\n\n this.borderLayer.style.background = `\n linear-gradient(${angle}deg,\n rgba(255, 255, 255, 0.22) 0%,\n rgba(255, 255, 255, 0.18) 20%,\n rgba(255, 255, 255, 0.12) 35%,\n rgba(255, 255, 255, 0.07) 45%,\n rgba(255, 255, 255, 0.07) 55%,\n rgba(255, 255, 255, 0.12) 65%,\n rgba(255, 255, 255, 0.18) 80%,\n rgba(255, 255, 255, 0.22) 100%\n )\n `;\n }\n\n private setupResizeObserver(): void {\n this.resizeObserver = new ResizeObserver(() => {\n if (this.animationFrameId) cancelAnimationFrame(this.animationFrameId);\n\n this.animationFrameId = requestAnimationFrame(() => {\n const rect = this.el.nativeElement.getBoundingClientRect();\n this.width.set(rect.width);\n this.height.set(rect.height);\n });\n });\n this.resizeObserver.observe(this.el.nativeElement);\n }\n\n private generateDisplacementMap(\n w: number,\n h: number,\n profile: 'circle' | 'squircle',\n borderRadius: number,\n lensRange: number,\n reflectionMidpoint: number\n ): string {\n const canvas = this.sharedCanvas;\n if (!canvas) return '';\n\n canvas.width = w;\n canvas.height = h;\n const ctx = canvas.getContext('2d');\n if (!ctx) return '';\n\n const imgData = ctx.createImageData(w, h);\n const data = imgData.data;\n\n const activeRange = lensRange * reflectionMidpoint;\n\n for (let y = 0; y < h; y++) {\n for (let x = 0; x < w; x++) {\n const distL = x;\n const distR = w - x;\n const distT = y;\n const distB = h - y;\n\n let minDist = Math.min(distL, distR, distT, distB);\n let nx = 0;\n let ny = 0;\n\n if (minDist === distL) nx = 1;\n else if (minDist === distR) nx = -1;\n else if (minDist === distT) ny = 1;\n else if (minDist === distB) ny = -1;\n\n if (x < borderRadius && y < borderRadius) {\n const dist = Math.sqrt(Math.pow(borderRadius - x, 2) + Math.pow(borderRadius - y, 2));\n minDist = borderRadius - dist;\n if (dist > 0) {\n nx = (borderRadius - x) / dist;\n ny = (borderRadius - y) / dist;\n }\n } else if (x > w - borderRadius && y < borderRadius) {\n const dist = Math.sqrt(\n Math.pow(x - (w - borderRadius), 2) + Math.pow(borderRadius - y, 2),\n );\n minDist = borderRadius - dist;\n if (dist > 0) {\n nx = -(x - (w - borderRadius)) / dist;\n ny = (borderRadius - y) / dist;\n }\n } else if (x < borderRadius && y > h - borderRadius) {\n const dist = Math.sqrt(\n Math.pow(borderRadius - x, 2) + Math.pow(y - (h - borderRadius), 2),\n );\n minDist = borderRadius - dist;\n if (dist > 0) {\n nx = (borderRadius - x) / dist;\n ny = -(y - (h - borderRadius)) / dist;\n }\n } else if (x > w - borderRadius && y > h - borderRadius) {\n const dist = Math.sqrt(\n Math.pow(x - (w - borderRadius), 2) + Math.pow(y - (h - borderRadius), 2),\n );\n minDist = borderRadius - dist;\n if (dist > 0) {\n nx = -(x - (w - borderRadius)) / dist;\n ny = -(y - (h - borderRadius)) / dist;\n }\n }\n\n let magnitude = 0;\n\n if (minDist >= 0 && minDist < activeRange) {\n const tActive = minDist / activeRange;\n magnitude = Math.pow(1 - tActive, 2);\n } else {\n magnitude = 0;\n }\n\n let finalMagX = nx * magnitude;\n let finalMagY = ny * magnitude;\n\n if (profile === 'squircle') {\n finalMagX *= 0.95;\n finalMagY *= 0.95;\n }\n\n const rVal = Math.floor(128 + finalMagX * 127);\n const gVal = Math.floor(128 + finalMagY * 127);\n\n const idx = (y * w + x) * 4;\n data[idx] = Math.max(0, Math.min(255, rVal));\n data[idx + 1] = Math.max(0, Math.min(255, gVal));\n data[idx + 2] = 128;\n data[idx + 3] = 255;\n }\n }\n\n ctx.putImageData(imgData, 0, 0);\n return canvas.toDataURL();\n }\n\n private syncSvgFilter(dataUrl: string, w: number, h: number, scale: number, blur: number): void {\n let container: Element | null = document.getElementById(`svg-container-${this.filterId}`);\n\n if (!container) {\n container = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n container.id = `svg-container-${this.filterId}`;\n container.setAttribute(\n 'style',\n 'position: absolute; width: 0; height: 0; pointer-events: none;',\n );\n document.body.appendChild(container);\n }\n\n container.innerHTML = `\n <filter id=\"${this.filterId}\"\n x=\"-30%\" y=\"-30%\" width=\"160%\" height=\"160%\"\n primitiveUnits=\"userSpaceOnUse\"\n color-interpolation-filters=\"sRGB\">\n\n <feImage href=\"${dataUrl}\" x=\"0\" y=\"0\" width=\"${w}\" height=\"${h}\" preserveAspectRatio=\"none\" result=\"glass_map\" />\n <feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"${blur}\" result=\"blurred_substrate\" />\n\n <feDisplacementMap\n in=\"blurred_substrate\"\n in2=\"glass_map\"\n scale=\"${scale}\"\n xChannelSelector=\"R\"\n yChannelSelector=\"G\"\n />\n </filter>\n `;\n }\n}\n","/*\n * Public API Surface of ngx-glassy-effect\n */\n\nexport * from './lib/glassy-effect';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngx-glassy-effect.mjs","sources":["../../../projects/ngx-glassy-effect/src/lib/glassy-effect.ts","../../../projects/ngx-glassy-effect/src/public-api.ts","../../../projects/ngx-glassy-effect/src/ngx-glassy-effect.ts"],"sourcesContent":["import {\n DestroyRef,\n Directive,\n effect,\n ElementRef,\n inject,\n input,\n PLATFORM_ID,\n} from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\n\nconst NS = 'http://www.w3.org/2000/svg';\nconst XLINK = 'http://www.w3.org/1999/xlink';\nconst NEUTRAL = 128;\nconst MAP_CACHE_SIZE = 48;\n\nconst DEFAULTS = Object.freeze({\n x: 0,\n y: 0,\n width: 120,\n height: 64,\n radius: 32,\n refraction: 18,\n bezel: 0.6,\n curvature: 4,\n ior: 1.5,\n invert: false,\n chroma: 0.12,\n blur: 0,\n specular: 0.45,\n specularWidth: 2,\n lightAngle: -120,\n mapScale: 0,\n});\n\nconst MAP_KEYS = [\n 'width',\n 'height',\n 'radius',\n 'bezel',\n 'curvature',\n 'ior',\n 'invert',\n 'specular',\n 'specularWidth',\n 'lightAngle',\n];\n\nfunction detectEngine(): string {\n if (typeof navigator === 'undefined') return 'unknown';\n const brands = (navigator as any).userAgentData?.brands;\n if (brands?.some((b: any) => /Chromium/.test(b.brand))) return 'blink';\n const ua = navigator.userAgent;\n if (/Firefox\\//.test(ua)) return 'gecko';\n if (/AppleWebKit\\//.test(ua) && !/Chrome\\/|Chromium\\/|Edg\\//.test(ua)) return 'webkit';\n return /Chrome\\//.test(ua) ? 'blink' : 'unknown';\n}\n\nconst engine = detectEngine();\nconst profileCache = new Map<string, Float32Array>();\n\nfunction profileTable(curvature: number, ior: number): Float32Array {\n const key = `${curvature}|${ior}`;\n let table = profileCache.get(key);\n if (table) return table;\n const N = 512;\n table = new Float32Array(N + 1);\n let max = 0;\n for (let i = 0; i <= N; i++) {\n const s = Math.min(i / N, 1 - 1e-6);\n const a = Math.pow(1 - s, curvature);\n const slope =\n Math.pow(1 - s, curvature - 1) * Math.pow(Math.max(1 - a, 1e-9), 1 / curvature - 1);\n const theta = Math.atan(slope);\n const refracted = Math.asin(Math.sin(theta) / ior);\n const bend = Math.tan(theta - refracted);\n table[i] = bend;\n if (bend > max) max = bend;\n }\n for (let i = 0; i <= N; i++) table[i] /= max || 1;\n table[N] = 0;\n profileCache.set(key, table);\n return table;\n}\n\nfunction renderLensMap(options = {}, scale = 1) {\n const p: any = { ...DEFAULTS, ...options };\n const w = Math.max(2, Math.round(p.width * scale));\n const h = Math.max(2, Math.round(p.height * scale));\n const canvas = document.createElement('canvas');\n canvas.width = w;\n canvas.height = h;\n const ctx = canvas.getContext('2d')!;\n const image = ctx.createImageData(w, h);\n const px = image.data;\n\n const sx = p.width / w;\n const sy = p.height / h;\n const hw = p.width / 2;\n const hh = p.height / 2;\n const r = Math.max(0, Math.min(p.radius, hw, hh));\n const bezel = Math.max(0.5, p.bezel * Math.min(hw, hh));\n const table = profileTable(p.curvature, p.ior);\n const N = table.length - 1;\n const rimWidth = Math.max(0.5, p.specularWidth);\n const aa = Math.max(sx, sy);\n const angle = (p.lightAngle * Math.PI) / 180;\n const lx = Math.cos(angle);\n const ly = Math.sin(angle);\n const dir = p.invert ? -1 : 1;\n\n const qw = Math.ceil(w / 2);\n const qh = Math.ceil(h / 2);\n for (let j = 0; j < qh; j++) {\n const y = (j + 0.5) * sy - hh;\n for (let i = 0; i < qw; i++) {\n const x = (i + 0.5) * sx - hw;\n const qx = -x - (hw - r);\n const qy = -y - (hh - r);\n const ox = Math.max(qx, 0);\n const oy = Math.max(qy, 0);\n const corner = Math.hypot(ox, oy);\n const dist = corner + Math.min(Math.max(qx, qy), 0) - r;\n const alpha = Math.min(1, Math.max(0, 0.5 - dist / aa));\n if (alpha <= 0) continue;\n\n let nx, ny;\n if (qx > 0 && qy > 0) {\n nx = ox / corner;\n ny = oy / corner;\n } else if (qx > qy) {\n nx = 1;\n ny = 0;\n } else {\n nx = 0;\n ny = 1;\n }\n\n const inset = Math.max(0, -dist);\n const s = inset / bezel;\n const m = s >= 1 ? 0 : table[Math.min(N, Math.round(s * N))];\n const bx = Math.round(127 * m * nx * dir);\n const by = Math.round(127 * m * ny * dir);\n\n const crisp = Math.max(0, 1 - inset / rimWidth);\n const glow = Math.max(0, 1 - inset / (rimWidth * 5));\n const rim = p.specular * (crisp * crisp + 0.3 * glow * glow);\n const a = Math.round(alpha * 255);\n\n const i2 = w - 1 - i;\n const j2 = h - 1 - j;\n write(px, (j * w + i) * 4, NEUTRAL + bx, NEUTRAL + by, rimLight(rim, -nx * lx - ny * ly), a);\n if (i2 !== i)\n write(\n px,\n (j * w + i2) * 4,\n NEUTRAL - bx,\n NEUTRAL + by,\n rimLight(rim, nx * lx - ny * ly),\n a,\n );\n if (j2 !== j)\n write(\n px,\n (j2 * w + i) * 4,\n NEUTRAL + bx,\n NEUTRAL - by,\n rimLight(rim, -nx * lx + ny * ly),\n a,\n );\n if (i2 !== i && j2 !== j)\n write(\n px,\n (j2 * w + i2) * 4,\n NEUTRAL - bx,\n NEUTRAL - by,\n rimLight(rim, nx * lx + ny * ly),\n a,\n );\n }\n }\n ctx.putImageData(image, 0, 0);\n return { canvas, width: w, height: h, scale };\n}\n\nfunction rimLight(rim: number, facing: number) {\n const shade = 0.12 + 0.88 * (facing > 0 ? facing : -0.4 * facing);\n return NEUTRAL + Math.round(127 * Math.min(1, rim * shade));\n}\n\nfunction write(px: Uint8ClampedArray, o: number, r: number, g: number, b: number, a: number) {\n px[o] = r;\n px[o + 1] = g;\n px[o + 2] = b;\n px[o + 3] = a;\n}\n\nconst mapCache = new Map<string, any>();\n\nfunction mapKeyOf(p: any, scale: number) {\n return MAP_KEYS.map((k) => p[k]).join('|') + '|' + scale;\n}\n\nfunction lensMap(p: any, scale: number, key: string) {\n let entry = mapCache.get(key);\n if (entry) {\n mapCache.delete(key);\n } else {\n const url = renderLensMap(p, scale).canvas.toDataURL('image/png');\n entry = { key, url, decoded: false, ready: null };\n const img = new Image();\n img.src = url;\n entry.ready = img\n .decode()\n .catch(() => {})\n .then(() => {\n entry.decoded = true;\n });\n if (mapCache.size >= MAP_CACHE_SIZE) mapCache.delete(mapCache.keys().next().value!);\n }\n mapCache.set(key, entry);\n return entry;\n}\n\nlet svgRoot: SVGSVGElement | null = null;\n\nfunction defsNode() {\n if (svgRoot?.isConnected) return svgRoot.firstChild!;\n svgRoot = document.createElementNS(NS, 'svg');\n svgRoot.setAttribute('aria-hidden', 'true');\n svgRoot.setAttribute('width', '0');\n svgRoot.setAttribute('height', '0');\n svgRoot.style.cssText = 'position:absolute;width:0;height:0;overflow:hidden;pointer-events:none';\n svgRoot.appendChild(document.createElementNS(NS, 'defs'));\n document.body.appendChild(svgRoot);\n return svgRoot.firstChild!;\n}\n\nfunction node(name: string, attrs: Record<string, string>) {\n const n = document.createElementNS(NS, name);\n for (const k in attrs) n.setAttribute(k, attrs[k]);\n return n;\n}\n\nconst CHANNELS = [\n '1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0',\n '0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0',\n '0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0',\n];\n\nfunction buildGraph(filter: SVGFilterElement, p: any) {\n filter.replaceChildren();\n const lensRect: Element[] = [];\n const add = (name: string, attrs: Record<string, string>, inLens?: boolean) => {\n const n = node(name, attrs);\n filter.appendChild(n);\n if (inLens) lensRect.push(n);\n return n;\n };\n\n add(\n 'feFlood',\n { 'flood-color': 'rgb(128,128,128)', 'flood-opacity': '1', result: 'neutral' },\n true,\n );\n const image = add('feImage', { preserveAspectRatio: 'none', result: 'lensShape' }, true);\n add('feComposite', { in: 'lensShape', in2: 'neutral', operator: 'over', result: 'map' }, true);\n const aspect =\n engine === 'webkit'\n ? add('feColorMatrix', { in: 'map', type: 'matrix', result: 'bend' }, true)\n : null;\n const bendMap = aspect ? 'bend' : 'map';\n\n let source = 'SourceGraphic';\n let blur: Element | null = null;\n if (p.blur > 0) {\n blur = add('feGaussianBlur', { in: 'SourceGraphic', result: 'frosted' });\n source = 'frosted';\n }\n\n const displace: Element[] = [];\n if (p.chroma > 0) {\n CHANNELS.forEach((values, i) => {\n displace.push(\n add(\n 'feDisplacementMap',\n { in: source, in2: bendMap, xChannelSelector: 'R', yChannelSelector: 'G' },\n true,\n ),\n );\n add('feColorMatrix', { type: 'matrix', values, result: `ch${i}` }, true);\n });\n add(\n 'feComposite',\n {\n in: 'ch0',\n in2: 'ch1',\n operator: 'arithmetic',\n k1: '0',\n k2: '1',\n k3: '1',\n k4: '0',\n result: 'rg',\n },\n true,\n );\n add(\n 'feComposite',\n {\n in: 'rg',\n in2: 'ch2',\n operator: 'arithmetic',\n k1: '0',\n k2: '1',\n k3: '1',\n k4: '0',\n result: 'refracted',\n },\n true,\n );\n } else {\n displace.push(\n add(\n 'feDisplacementMap',\n {\n in: source,\n in2: bendMap,\n xChannelSelector: 'R',\n yChannelSelector: 'G',\n result: 'refracted',\n },\n true,\n ),\n );\n }\n\n let lit = 'refracted';\n if (p.specular > 0) {\n add(\n 'feColorMatrix',\n {\n in: 'map',\n type: 'matrix',\n values: `0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 2 0 ${-(2 * NEUTRAL) / 255}`,\n result: 'rim',\n },\n true,\n );\n add(\n 'feComposite',\n {\n in: 'rim',\n in2: 'refracted',\n operator: 'arithmetic',\n k1: '0',\n k2: '1',\n k3: '1',\n k4: '0',\n result: 'lit',\n },\n true,\n );\n lit = 'lit';\n }\n\n add('feComposite', { in: lit, in2: 'lensShape', operator: 'in', result: 'lens' }, true);\n add('feComposite', { in: 'SourceGraphic', in2: 'lensShape', operator: 'out', result: 'outside' });\n add('feComposite', { in: 'lens', in2: 'outside', operator: 'over' });\n return { image, aspect, blur, displace, lensRect };\n}\n\nfunction bendScale(px: number, w: number, h: number) {\n if (engine === 'webkit') {\n const m = Math.min(w, h);\n return { scale: (2 * px) / m, kx: m / w, ky: m / h };\n }\n if (engine === 'gecko') return { scale: (2 * px) / Math.sqrt((w * w + h * h) / 2), kx: 1, ky: 1 };\n return { scale: (2 * px) / w, kx: 1, ky: 1 };\n}\n\nfunction setRect(n: Element, x: number, y: number, w: number, h: number) {\n n.setAttribute('x', String(x));\n n.setAttribute('y', String(y));\n n.setAttribute('width', String(w));\n n.setAttribute('height', String(h));\n}\n\nlet uid = 0;\n\nfunction createGlass(target: HTMLElement, options: any = {}) {\n const base = `lg${++uid}`;\n const mode = options.mode ?? 'content';\n const fallback = options.fallback ?? 'blur(12px) saturate(1.6)';\n const p = { ...DEFAULTS, ...pickOpts(options) };\n const flags = {\n fit: !!options.fit,\n clip: !!options.clip,\n sync: !!options.sync,\n hidden: !!options.hidden,\n };\n const useBackdropURL = mode === 'backdrop' && engine === 'blink';\n const active = mode !== 'backdrop' || useBackdropURL;\n\n if (!active) {\n target.style.backdropFilter = fallback;\n (target.style as any).webkitBackdropFilter = fallback;\n }\n\n const filter = node('filter', {\n filterUnits: 'objectBoundingBox',\n x: '0',\n y: '0',\n width: '1',\n height: '1',\n primitiveUnits: 'objectBoundingBox',\n 'color-interpolation-filters': 'sRGB',\n }) as SVGFilterElement;\n if (active) defsNode().appendChild(filter);\n\n let graph: any = null;\n let structure = '';\n let wanted = '';\n let requested = 0;\n let shown = { key: '', seq: -1 };\n let version = 0;\n let frame = 0;\n let settleTimers: any[] = [];\n let destroyed = false;\n let box = { width: target.offsetWidth, height: target.offsetHeight };\n\n const observer = active\n ? new ResizeObserver(() => {\n box = { width: target.offsetWidth, height: target.offsetHeight };\n schedule();\n })\n : null;\n observer?.observe(target);\n\n function settle() {\n settleTimers.forEach(clearTimeout);\n settleTimers = [60, 250].map((ms) => setTimeout(schedule, ms));\n }\n\n function show(entry: any, seq: number) {\n if (seq <= shown.seq || !graph) return false;\n graph.image.setAttribute('href', entry.url);\n graph.image.setAttributeNS(XLINK, 'xlink:href', entry.url);\n shown = { key: entry.key, seq };\n settle();\n return true;\n }\n\n function flush() {\n frame = 0;\n if (destroyed || !active) return;\n if (flags.hidden) {\n if (useBackdropURL) target.style.backdropFilter = '';\n else target.style.filter = '';\n if (flags.clip) target.style.clipPath = 'inset(50%)';\n return;\n }\n const W = box.width;\n const H = box.height;\n if (W < 1 || H < 1) return;\n if (flags.fit) {\n p.x = 0;\n p.y = 0;\n p.width = W;\n p.height = H;\n }\n if (p.width < 1 || p.height < 1) return;\n\n const s = `${p.chroma > 0}|${p.blur > 0}|${p.specular > 0}`;\n if (s !== structure) {\n graph = buildGraph(filter, p);\n structure = s;\n shown = { key: '', seq: -1 };\n wanted = '';\n }\n\n const dpr = window.devicePixelRatio || 1;\n const scale = p.mapScale > 0 ? p.mapScale : Math.min(dpr, 2);\n const snap = (v: number) => Math.round(v * dpr) / dpr;\n const x = snap(p.x);\n const y = snap(p.y);\n const w = snap(p.width);\n const h = snap(p.height);\n\n const key = mapKeyOf(p, scale);\n if (wanted !== key) {\n wanted = key;\n const entry = lensMap(p, scale, key);\n const seq = ++requested;\n if (entry.decoded) show(entry, seq);\n else entry.ready.then(() => !destroyed && show(entry, seq) && schedule());\n }\n if (flags.clip) {\n const r = Math.min(p.radius, w / 2, h / 2);\n target.style.clipPath = `inset(${y}px ${W - x - w}px ${H - y - h}px ${x}px round ${r}px)`;\n }\n if (!shown.key) return;\n\n for (const n of graph.lensRect) setRect(n, x / W, y / H, w / W, h / H);\n const { scale: k, kx, ky } = bendScale(p.refraction, W, H);\n const scales =\n graph.displace.length === 3 ? [k, k * (1 + p.chroma / 2), k * (1 + p.chroma)] : [k];\n graph.displace.forEach((n: Element, i: number) => n.setAttribute('scale', String(scales[i])));\n if (graph.aspect) {\n graph.aspect.setAttribute(\n 'values',\n `${kx} 0 0 0 ${(1 - kx) / 2} 0 ${ky} 0 0 ${(1 - ky) / 2} 0 0 1 0 0 0 0 0 1 0`,\n );\n }\n if (graph.blur) {\n graph.blur.setAttribute('stdDeviation', `${p.blur / W} ${p.blur / H}`);\n const pad = Math.ceil(p.refraction * (1 + p.chroma) + 3 * p.blur);\n setRect(graph.blur, (x - pad) / W, (y - pad) / H, (w + 2 * pad) / W, (h + 2 * pad) / H);\n }\n\n filter.id = `${base}-v${++version}`;\n const ref = `url(#${filter.id})`;\n if (useBackdropURL) target.style.backdropFilter = ref;\n else target.style.filter = ref;\n }\n\n function schedule() {\n if (flags.sync) flush();\n else if (!frame) frame = requestAnimationFrame(flush);\n }\n\n schedule();\n\n return {\n update(next: any = {}) {\n const changes = pickOpts(next);\n const hidden = next.hidden === undefined ? flags.hidden : !!next.hidden;\n if (\n hidden === flags.hidden &&\n Object.keys(changes).every((k) => (changes as any)[k] === (p as any)[k])\n )\n return;\n Object.assign(p, changes);\n flags.hidden = hidden;\n schedule();\n },\n flush() {\n if (frame) cancelAnimationFrame(frame);\n flush();\n },\n destroy() {\n destroyed = true;\n if (frame) cancelAnimationFrame(frame);\n settleTimers.forEach(clearTimeout);\n observer?.disconnect();\n filter.remove();\n target.style.filter = '';\n target.style.backdropFilter = '';\n (target.style as any).webkitBackdropFilter = '';\n if (flags.clip) target.style.clipPath = '';\n },\n };\n}\n\nfunction pickOpts(o: any) {\n const out: any = {};\n for (const k in DEFAULTS) if (o[k] !== undefined) out[k] = o[k];\n return out;\n}\n\n@Directive({\n selector: '[ngxGlassyEffect]',\n standalone: true,\n})\nexport class GlassyEffect {\n private el = inject(ElementRef<HTMLElement>);\n private destroyRef = inject(DestroyRef);\n private platformId = inject(PLATFORM_ID);\n private isBrowser = isPlatformBrowser(this.platformId);\n\n refraction = input<number>();\n blur = input<number>(0);\n radius = input<number | undefined>(undefined);\n bezel = input<number>(0.7);\n curvature = input<number>(4);\n ior = input<number>(1.5);\n specular = input<number>(0.2);\n specularWidth = input<number>(1);\n lightAngle = input<number>(-120);\n invert = input<boolean>(false);\n chroma = input<number>(0.12);\n\n private glassInstance: ReturnType<typeof createGlass> | null = null;\n\n constructor() {\n if (!this.isBrowser) return;\n\n effect(() => {\n const nativeEl = this.el.nativeElement;\n const currentRadius = this.radius() ?? this.getComputedRadius();\n const H = nativeEl.offsetHeight || nativeEl.getBoundingClientRect().height || 64;\n\n const calculatedRefraction = H < 110 ? Math.max(1, H - 10) : 100;\n\n const options = {\n refraction: this.refraction() ? this.refraction() : calculatedRefraction,\n blur: this.blur(),\n radius: currentRadius,\n bezel: this.bezel(),\n curvature: this.curvature(),\n ior: this.ior(),\n specular: this.specular(),\n specularWidth: this.specularWidth(),\n lightAngle: this.lightAngle(),\n invert: this.invert(),\n chroma: this.chroma(),\n mode: 'backdrop',\n fit: true,\n clip: undefined,\n hidden: false,\n };\n\n if (!this.glassInstance) {\n this.glassInstance = createGlass(nativeEl, options);\n } else {\n this.glassInstance.update(options);\n }\n });\n\n this.destroyRef.onDestroy(() => {\n if (this.glassInstance) {\n this.glassInstance.destroy();\n this.glassInstance = null;\n }\n });\n }\n\n private getComputedRadius(): number {\n const computed = window.getComputedStyle(this.el.nativeElement);\n return parseFloat(computed.borderRadius) || 32;\n }\n}\n","/*\n * Public API Surface of ngx-glassy-effect\n */\n\nexport * from './lib/glassy-effect';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ngx-glassy-effect",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "author": {
5
5
  "name": "anassmdi",
6
6
  "url": "https://github.com/anassmdi"
@@ -5,27 +5,22 @@ declare class GlassyEffect {
5
5
  private destroyRef;
6
6
  private platformId;
7
7
  private isBrowser;
8
- bezel: _angular_core.InputSignal<number>;
9
- scale: _angular_core.InputSignal<number>;
8
+ refraction: _angular_core.InputSignal<number | undefined>;
10
9
  blur: _angular_core.InputSignal<number>;
11
- profile: _angular_core.InputSignal<"circle" | "squircle">;
12
- showBorder: _angular_core.InputSignal<boolean>;
13
- lensRange: _angular_core.InputSignal<number>;
14
- reflectionMidpoint: _angular_core.InputSignal<number>;
15
- private width;
16
- private height;
17
- private filterId;
18
- private resizeObserver;
19
- private sharedCanvas;
20
- private borderLayer;
21
- private animationFrameId;
10
+ radius: _angular_core.InputSignal<number | undefined>;
11
+ bezel: _angular_core.InputSignal<number>;
12
+ curvature: _angular_core.InputSignal<number>;
13
+ ior: _angular_core.InputSignal<number>;
14
+ specular: _angular_core.InputSignal<number>;
15
+ specularWidth: _angular_core.InputSignal<number>;
16
+ lightAngle: _angular_core.InputSignal<number>;
17
+ invert: _angular_core.InputSignal<boolean>;
18
+ chroma: _angular_core.InputSignal<number>;
19
+ private glassInstance;
22
20
  constructor();
23
- private applyBorderLighting;
24
- private setupResizeObserver;
25
- private generateDisplacementMap;
26
- private syncSvgFilter;
21
+ private getComputedRadius;
27
22
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<GlassyEffect, never>;
28
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<GlassyEffect, "[ngxGlassyEffect]", never, { "bezel": { "alias": "bezel"; "required": false; "isSignal": true; }; "scale": { "alias": "scale"; "required": false; "isSignal": true; }; "blur": { "alias": "blur"; "required": false; "isSignal": true; }; "profile": { "alias": "profile"; "required": false; "isSignal": true; }; "showBorder": { "alias": "showBorder"; "required": false; "isSignal": true; }; "lensRange": { "alias": "lensRange"; "required": false; "isSignal": true; }; "reflectionMidpoint": { "alias": "reflectionMidpoint"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
23
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<GlassyEffect, "[ngxGlassyEffect]", never, { "refraction": { "alias": "refraction"; "required": false; "isSignal": true; }; "blur": { "alias": "blur"; "required": false; "isSignal": true; }; "radius": { "alias": "radius"; "required": false; "isSignal": true; }; "bezel": { "alias": "bezel"; "required": false; "isSignal": true; }; "curvature": { "alias": "curvature"; "required": false; "isSignal": true; }; "ior": { "alias": "ior"; "required": false; "isSignal": true; }; "specular": { "alias": "specular"; "required": false; "isSignal": true; }; "specularWidth": { "alias": "specularWidth"; "required": false; "isSignal": true; }; "lightAngle": { "alias": "lightAngle"; "required": false; "isSignal": true; }; "invert": { "alias": "invert"; "required": false; "isSignal": true; }; "chroma": { "alias": "chroma"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
29
24
  }
30
25
 
31
26
  export { GlassyEffect };