@edinstvo/glass 0.1.0-alpha.1 → 0.1.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -51,7 +51,7 @@ npm i @edinstvo/glass
51
51
  import "@edinstvo/glass/define";
52
52
  </script>
53
53
 
54
- <edinstvo-glass material="regular" interaction="calm">
54
+ <edinstvo-glass frost="0.4" refraction="0.5">
55
55
  Hello
56
56
  </edinstvo-glass>
57
57
  ```
@@ -63,14 +63,14 @@ Not a fan of custom elements? Attach glass to any node:
63
63
  ```js
64
64
  import { attachGlass } from "@edinstvo/glass";
65
65
 
66
- const glass = attachGlass(element, { material: "frost" });
66
+ const glass = attachGlass(element, { material: { frost: 0.7 } });
67
67
  glass.set({ material: { frost: 0.4 } });
68
68
  glass.destroy();
69
69
  ```
70
70
 
71
71
  ## Material
72
72
 
73
- Set a preset with `material`, then override anything with an attribute, a `--glass-*` CSS variable or a property.
73
+ There are no types of glass, only settings. Set anything with an attribute, a `--glass-*` CSS variable or the `material` property. The defaults are tuned against the system glass on macOS, pixel by pixel.
74
74
 
75
75
  | Attribute | Range | What it does |
76
76
  |---|---|---|
@@ -88,16 +88,37 @@ Set a preset with `material`, then override anything with an attribute, a `--gla
88
88
  | `light-angle` | -180 to 180° | Where the light comes from. 0 is the top |
89
89
  | `bloom` | 0 to 1 | Glow inside the glass and around it |
90
90
 
91
- ### Presets
91
+ ## Motion
92
92
 
93
- `pure` · `clear` · `regular` · `frost` · `lens` · `prism`
93
+ Change an element's size or position in CSS and the glass flows there with a spring, overshoot included.
94
+ Each of these is its own setting, on a group or on a single child. `prefers-reduced-motion` turns them all off.
94
95
 
95
- `regular` and `clear` are tuned against the system glass on macOS, pixel by pixel. `pure` is the same lens with no frost at all.
96
+ | Attribute | Range | What it does |
97
+ |---|---|---|
98
+ | `morph` | 0 to 1 | Softness of the flow. 0 jumps straight to the new shape |
99
+ | `jelly` | 0 to 1 | Stretch while moving and under a drag |
100
+ | `press` | 0 to 1 | How much the glass swells when held |
101
+ | `glow` | 0 to 1 | Light that spreads from under the finger |
102
+ | `follow` | 0 to 1 | How far the light chases the pointer |
103
+ | `merge` | 0 to 64 px | Melts this element into others that have it too. 0 stays separate |
104
+
105
+ ### Merge
106
+
107
+ Merging is opt-in, per element. Give `merge` to the pieces that should become one shape: they melt together when they get close and pull apart like liquid. Everything else in the group stays separate.
108
+
109
+ ```html
110
+ <edinstvo-glass-group>
111
+ <edinstvo-glass merge="28"></edinstvo-glass>
112
+ <edinstvo-glass merge="28"></edinstvo-glass>
113
+ <edinstvo-glass></edinstvo-glass>
114
+ </edinstvo-glass-group>
115
+ ```
116
+
117
+ Up to 8 shapes per group, all drawn in one pass. `merge` on the group sets it for every child, `merge="0"` on a child opts out.
96
118
 
97
- ### Interaction
119
+ ### Appear
98
120
 
99
- `none` · `calm` · `lively`, or your own `{ follow, press, stretch }`.
100
- Light follows the pointer, the surface swells under a press. `prefers-reduced-motion` turns all of it off.
121
+ Add `appear` to materialise on load, or call `show()` and `hide()`. Both return a promise.
101
122
 
102
123
  ## Backdrop
103
124
 
@@ -123,6 +144,7 @@ on top of `backdrop-filter`. The element falls back to the same look by itself w
123
144
 
124
145
  ## Limits
125
146
 
147
+ - Glass sees other glass under it. Later in the document means on top, `z-index` is not read yet.
126
148
  - Text and regular DOM behind the glass aren't refracted, only the sources listed above. Draw them to a canvas if you need them.
127
149
  - CSS gradients aren't read yet. Glass skips them and looks further down the stack.
128
150
  - Cross-origin images need CORS headers, otherwise that element falls back to CSS.
package/dist/element.d.ts CHANGED
@@ -1,26 +1,34 @@
1
1
  import type { GlassSource } from "./backdrop.js";
2
- import type { Interaction, InteractionName } from "./interaction.js";
3
- import { type Material, type PresetName } from "./material.js";
2
+ import { type Material } from "./material.js";
3
+ import { GlassSurface } from "./surface.js";
4
4
  declare const Base: typeof HTMLElement;
5
5
  export declare class EdinstvoGlass extends Base {
6
6
  static observedAttributes: string[];
7
- private surface;
7
+ protected surface: GlassSurface;
8
+ private group;
8
9
  private sourceValue;
9
10
  private materialValue;
10
- private interactionValue;
11
11
  constructor();
12
+ protected get isGroup(): boolean;
12
13
  connectedCallback(): void;
13
14
  disconnectedCallback(): void;
15
+ show(): Promise<void>;
16
+ hide(): Promise<void>;
14
17
  attributeChangedCallback(): void;
15
18
  get source(): GlassSource;
16
19
  set source(value: GlassSource);
17
- get material(): PresetName | Partial<Material>;
18
- set material(value: PresetName | Partial<Material>);
19
- get interaction(): InteractionName | Interaction;
20
- set interaction(value: InteractionName | Interaction);
20
+ get material(): Partial<Material>;
21
+ set material(value: Partial<Material>);
21
22
  invalidate(): void;
22
- private sync;
23
+ protected sync(): void;
23
24
  private composeMaterial;
24
25
  }
26
+ export declare class EdinstvoGlassGroup extends EdinstvoGlass {
27
+ protected get isGroup(): boolean;
28
+ connectedCallback(): void;
29
+ adopt(child: EdinstvoGlass): void;
30
+ release(child: EdinstvoGlass): void;
31
+ refresh(): void;
32
+ }
25
33
  export declare function defineGlass(tag?: string): void;
26
34
  export {};
package/dist/element.js CHANGED
@@ -1,4 +1,5 @@
1
- import { kebab, numericKeys, presets } from "./material.js";
1
+ import { motionKeys } from "./interaction.js";
2
+ import { kebab, numericKeys } from "./material.js";
2
3
  import { GlassSurface, placeCanvas } from "./surface.js";
3
4
  const Base = (globalThis.HTMLElement ?? class {
4
5
  });
@@ -15,20 +16,39 @@ const css = `
15
16
  -webkit-backdrop-filter: blur(16px) saturate(1.6);
16
17
  backdrop-filter: blur(16px) saturate(1.6);
17
18
  }
19
+ :host([data-grouped]) {
20
+ box-shadow: none;
21
+ background: none;
22
+ -webkit-backdrop-filter: none;
23
+ backdrop-filter: none;
24
+ }
25
+ :host([data-grouped]) > canvas {
26
+ display: none;
27
+ }
28
+ :host([data-glass-group]) {
29
+ display: block;
30
+ box-shadow: none;
31
+ border-radius: 0;
32
+ background: none;
33
+ -webkit-backdrop-filter: none;
34
+ backdrop-filter: none;
35
+ }
18
36
  .content {
19
37
  display: block;
20
38
  position: relative;
21
39
  z-index: 1;
22
40
  border-radius: inherit;
41
+ scale: var(--glass-scale, 1);
42
+ opacity: var(--glass-appear, 1);
23
43
  }
24
44
  `;
25
45
  const materialAttributes = new Map(numericKeys.map((key) => [kebab(key), key]));
26
46
  export class EdinstvoGlass extends Base {
27
- static observedAttributes = ["material", "interaction", "source", "live", "tint", ...materialAttributes.keys()];
47
+ static observedAttributes = ["source", "live", "tint", "appear", ...motionKeys, ...materialAttributes.keys()];
28
48
  surface;
49
+ group = null;
29
50
  sourceValue;
30
51
  materialValue;
31
- interactionValue;
32
52
  constructor() {
33
53
  super();
34
54
  const root = this.attachShadow({ mode: "open" });
@@ -42,17 +62,40 @@ export class EdinstvoGlass extends Base {
42
62
  content.setAttribute("part", "content");
43
63
  content.append(document.createElement("slot"));
44
64
  root.append(style, canvas, content);
45
- this.surface = new GlassSurface(this, canvas);
65
+ this.surface = new GlassSurface(this, canvas, {}, this.isGroup);
66
+ }
67
+ get isGroup() {
68
+ return false;
46
69
  }
47
70
  connectedCallback() {
71
+ this.group = this.parentElement?.closest("[data-glass-group]") ?? null;
72
+ if (this.group) {
73
+ this.dataset.grouped = "";
74
+ this.group.adopt(this);
75
+ return;
76
+ }
48
77
  this.sync();
49
78
  this.surface.connect();
50
79
  }
51
80
  disconnectedCallback() {
81
+ if (this.group) {
82
+ this.group.release(this);
83
+ this.group = null;
84
+ delete this.dataset.grouped;
85
+ return;
86
+ }
52
87
  this.surface.disconnect();
53
88
  }
89
+ show() {
90
+ return this.surface.show();
91
+ }
92
+ hide() {
93
+ return this.surface.hide();
94
+ }
54
95
  attributeChangedCallback() {
55
- if (this.isConnected)
96
+ if (this.group)
97
+ this.group.refresh();
98
+ else if (this.isConnected)
56
99
  this.sync();
57
100
  }
58
101
  get source() {
@@ -63,19 +106,12 @@ export class EdinstvoGlass extends Base {
63
106
  this.sync();
64
107
  }
65
108
  get material() {
66
- return this.materialValue ?? (this.getAttribute("material") ?? "regular");
109
+ return this.materialValue ?? {};
67
110
  }
68
111
  set material(value) {
69
112
  this.materialValue = value;
70
113
  this.sync();
71
114
  }
72
- get interaction() {
73
- return this.interactionValue ?? (this.getAttribute("interaction") ?? "none");
74
- }
75
- set interaction(value) {
76
- this.interactionValue = value;
77
- this.sync();
78
- }
79
115
  invalidate() {
80
116
  this.surface.invalidate();
81
117
  }
@@ -83,9 +119,9 @@ export class EdinstvoGlass extends Base {
83
119
  const live = this.getAttribute("live");
84
120
  this.surface.set({
85
121
  material: this.composeMaterial(),
86
- interaction: this.interaction,
87
122
  source: this.source,
88
123
  live: live === null ? undefined : live !== "false",
124
+ appear: this.hasAttribute("appear"),
89
125
  });
90
126
  }
91
127
  composeMaterial() {
@@ -98,14 +134,31 @@ export class EdinstvoGlass extends Base {
98
134
  const tint = this.getAttribute("tint");
99
135
  if (tint)
100
136
  overrides.tint = tint;
101
- if (!Object.keys(overrides).length)
102
- return this.material;
103
- const base = this.material;
104
- return typeof base === "string" ? { ...presetOf(base), ...overrides } : { ...base, ...overrides };
137
+ return { ...this.material, ...overrides };
138
+ }
139
+ }
140
+ export class EdinstvoGlassGroup extends EdinstvoGlass {
141
+ get isGroup() {
142
+ return true;
143
+ }
144
+ connectedCallback() {
145
+ this.dataset.glassGroup = "";
146
+ super.connectedCallback();
147
+ }
148
+ adopt(child) {
149
+ this.surface.track(child);
150
+ }
151
+ release(child) {
152
+ this.surface.untrack(child);
153
+ }
154
+ refresh() {
155
+ this.surface.restyle();
105
156
  }
106
157
  }
107
- const presetOf = (name) => presets[name] ?? presets.regular;
108
158
  export function defineGlass(tag = "edinstvo-glass") {
159
+ if (!customElements.get(`${tag}-group`))
160
+ customElements.define(`${tag}-group`, class extends EdinstvoGlassGroup {
161
+ });
109
162
  if (!customElements.get(tag))
110
163
  customElements.define(tag, class extends EdinstvoGlass {
111
164
  });
@@ -1 +1 @@
1
- {"version":3,"file":"element.js","sourceRoot":"","sources":["../src/element.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"element.js","sourceRoot":"","sources":["../src/element.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAiB,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEzD,MAAM,IAAI,GAAG,CAAC,UAAU,CAAC,WAAW,IAAI;CAAQ,CAAuB,CAAC;AAExE,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsCX,CAAC;AAEF,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AAEhF,MAAM,OAAO,aAAc,SAAQ,IAAI;IACrC,MAAM,CAAC,kBAAkB,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,UAAU,EAAE,GAAG,kBAAkB,CAAC,IAAI,EAAE,CAAC,CAAC;IAEpG,OAAO,CAAe;IACxB,KAAK,GAA8B,IAAI,CAAC;IACxC,WAAW,CAA0B;IACrC,aAAa,CAAgC;IAErD;QACE,KAAK,EAAE,CAAC;QACR,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAC9C,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC;QACxB,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACrC,WAAW,CAAC,MAAM,CAAC,CAAC;QACpB,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC/C,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;QAC9B,OAAO,CAAC,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QACxC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/C,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,IAAI,CAAC,OAAO,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAClE,CAAC;IAED,IAAc,OAAO;QACnB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,iBAAiB;QACf,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,aAAa,EAAE,OAAO,CAAqB,oBAAoB,CAAC,IAAI,IAAI,CAAC;QAC3F,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,EAAE,CAAC;YAC1B,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACvB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC;IAED,oBAAoB;QAClB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACzB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YAClB,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;YAC5B,OAAO;QACT,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;IAC5B,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED,wBAAwB;QACtB,IAAI,IAAI,CAAC,KAAK;YAAE,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;aAChC,IAAI,IAAI,CAAC,WAAW;YAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IACzC,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC;IACnE,CAAC;IAED,IAAI,MAAM,CAAC,KAAkB;QAC3B,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC;IAClC,CAAC;IAED,IAAI,QAAQ,CAAC,KAAwB;QACnC,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAC3B,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAED,UAAU;QACR,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;IAC5B,CAAC;IAES,IAAI;QACZ,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;YACf,QAAQ,EAAE,IAAI,CAAC,eAAe,EAAE;YAChC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO;YAClD,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC;SACpC,CAAC,CAAC;IACL,CAAC;IAEO,eAAe;QACrB,MAAM,SAAS,GAAsB,EAAE,CAAC;QACxC,KAAK,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,IAAI,kBAAkB,EAAE,CAAC;YAClD,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;YAC3C,IAAI,KAAK,KAAK,IAAI;gBAAE,SAAS,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,IAAI;YAAE,SAAS,CAAC,IAAI,GAAG,IAAI,CAAC;QAChC,OAAO,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,SAAS,EAAE,CAAC;IAC5C,CAAC;;AAGH,MAAM,OAAO,kBAAmB,SAAQ,aAAa;IACnD,IAAc,OAAO;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,iBAAiB;QACf,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,EAAE,CAAC;QAC7B,KAAK,CAAC,iBAAiB,EAAE,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,KAAoB;QACxB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAED,OAAO,CAAC,KAAoB;QAC1B,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO;QACL,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC;CACF;AAED,MAAM,UAAU,WAAW,CAAC,GAAG,GAAG,gBAAgB;IAChD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,GAAG,QAAQ,CAAC;QAAE,cAAc,CAAC,MAAM,CAAC,GAAG,GAAG,QAAQ,EAAE,KAAM,SAAQ,kBAAkB;SAAG,CAAC,CAAC;IACpH,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,cAAc,CAAC,MAAM,CAAC,GAAG,EAAE,KAAM,SAAQ,aAAa;SAAG,CAAC,CAAC;AAC3F,CAAC"}
@@ -15,3 +15,4 @@ export declare function uvTransform(rect: {
15
15
  };
16
16
  export declare function cornerRadius(value: string, w: number, h: number): number;
17
17
  export declare function lightVector(angle: number): [number, number];
18
+ export declare function softPeak(halfW: number, halfH: number, radius: number): number;
package/dist/geometry.js CHANGED
@@ -24,4 +24,10 @@ export function lightVector(angle) {
24
24
  const radians = (angle * Math.PI) / 180;
25
25
  return [Math.sin(radians), -Math.cos(radians)];
26
26
  }
27
+ export function softPeak(halfW, halfH, radius) {
28
+ const a = halfW + radius;
29
+ const b = halfH + radius;
30
+ const lo = Math.min(a, b);
31
+ return lo * (1 + (lo / Math.max(a, b)) ** 2.7) ** (-1 / 2.7) - radius;
32
+ }
27
33
  //# sourceMappingURL=geometry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"geometry.js","sourceRoot":"","sources":["../src/geometry.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,MAAM,CAAC,GAAQ,EAAE,QAAgB,EAAE,QAAgB,EAAE,GAAQ;IAC3E,IAAI,GAAG,KAAK,MAAM,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ;QAAE,OAAO,GAAG,CAAC;IACzD,IAAI,GAAG,KAAK,MAAM;QAAE,OAAO,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC5E,MAAM,IAAI,GAAG,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;IACnD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,QAAQ,EAAE,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC;IACvD,MAAM,CAAC,GAAG,QAAQ,GAAG,KAAK,CAAC;IAC3B,MAAM,CAAC,GAAG,QAAQ,GAAG,KAAK,CAAC;IAC3B,OAAO,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAmC,EAAE,GAAQ,EAAE,MAAc,EAAE,MAAc,EAAE,GAAW;IACpH,OAAO;QACL,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAU;QAC1E,QAAQ,EAAE,CAAC,MAAM,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAU;KACpE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,CAAS,EAAE,CAAS;IAC9D,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACjF,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,MAAM,OAAO,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC;IACxC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;AACjD,CAAC"}
1
+ {"version":3,"file":"geometry.js","sourceRoot":"","sources":["../src/geometry.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- export { EdinstvoGlass, defineGlass } from "./element.js";
1
+ export { EdinstvoGlass, EdinstvoGlassGroup, defineGlass } from "./element.js";
2
2
  export { GlassSurface, attachGlass, type GlassOptions } from "./surface.js";
3
- export { type Material, type PresetName, presets, ranges, resolveMaterial } from "./material.js";
4
- export { type Interaction, type InteractionName, interactions } from "./interaction.js";
3
+ export { type Material, defaults, ranges, resolveMaterial } from "./material.js";
4
+ export { type Motion, motionDefaults, motionRanges, resolveMotion } from "./interaction.js";
5
5
  export type { GlassImage, GlassSource } from "./backdrop.js";
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- export { EdinstvoGlass, defineGlass } from "./element.js";
1
+ export { EdinstvoGlass, EdinstvoGlassGroup, defineGlass } from "./element.js";
2
2
  export { GlassSurface, attachGlass } from "./surface.js";
3
- export { presets, ranges, resolveMaterial } from "./material.js";
4
- export { interactions } from "./interaction.js";
3
+ export { defaults, ranges, resolveMaterial } from "./material.js";
4
+ export { motionDefaults, motionRanges, resolveMotion } from "./interaction.js";
5
5
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,WAAW,EAAqB,MAAM,cAAc,CAAC;AAC5E,OAAO,EAAkC,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACjG,OAAO,EAA0C,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,WAAW,EAAqB,MAAM,cAAc,CAAC;AAC5E,OAAO,EAAiB,QAAQ,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACjF,OAAO,EAAe,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC"}
@@ -1,47 +1,61 @@
1
- export interface Interaction {
1
+ export interface Motion {
2
2
  follow: number;
3
3
  press: number;
4
- stretch: number;
4
+ jelly: number;
5
+ glow: number;
6
+ morph: number;
7
+ merge: number;
5
8
  }
6
- export declare const interactions: {
7
- readonly none: {
8
- readonly follow: 0;
9
- readonly press: 0;
10
- readonly stretch: 0;
11
- };
12
- readonly calm: {
13
- readonly follow: 0.5;
14
- readonly press: 0.4;
15
- readonly stretch: 0;
16
- };
17
- readonly lively: {
18
- readonly follow: 1;
19
- readonly press: 1;
20
- readonly stretch: 1;
21
- };
22
- };
23
- export type InteractionName = keyof typeof interactions;
9
+ export declare const motionRanges: Record<keyof Motion, readonly [number, number]>;
10
+ export declare const motionKeys: (keyof Motion)[];
11
+ export declare const motionDefaults: Motion;
12
+ export declare const still: Motion;
13
+ export declare function resolveMotion(...layers: (Partial<Motion> | undefined)[]): Motion;
24
14
  export declare class Spring {
25
15
  private stiffness;
26
16
  private damping;
27
17
  value: number;
28
18
  target: number;
29
- private velocity;
19
+ velocity: number;
30
20
  constructor(value?: number, stiffness?: number, damping?: number);
31
21
  step(dt: number): void;
22
+ tune(stiffness: number): void;
23
+ snap(value: number): void;
24
+ shift(delta: number): void;
32
25
  get settled(): boolean;
33
26
  }
34
- export declare class Motion {
35
- private host;
27
+ export interface ShapeBox {
28
+ x: number;
29
+ y: number;
30
+ halfW: number;
31
+ halfH: number;
32
+ radius: number;
33
+ join: number;
34
+ }
35
+ export declare class Shape {
36
+ readonly element: HTMLElement;
36
37
  private wake;
37
38
  x: Spring;
38
39
  y: Spring;
40
+ w: Spring;
41
+ h: Spring;
42
+ pointerX: Spring;
43
+ pointerY: Spring;
39
44
  held: Spring;
45
+ glow: Spring;
46
+ touchX: number;
47
+ touchY: number;
48
+ radius: number;
49
+ placed: boolean;
50
+ motion: Motion;
40
51
  private springs;
41
52
  private cleanup;
42
- constructor(host: HTMLElement, wake: () => void);
53
+ constructor(element: HTMLElement, wake: () => void);
43
54
  get moving(): boolean;
55
+ get pressed(): boolean;
44
56
  attach(): void;
45
57
  detach(): void;
46
- step(dt: number, interaction: Interaction): void;
58
+ read(rect: DOMRect, scrolled: boolean, grow: boolean): void;
59
+ step(dt: number): void;
60
+ box(scale: number): ShapeBox;
47
61
  }