@ax-design/reveal-highlight 0.3.0-alpha.7 → 0.4.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.
Files changed (92) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +76 -235
  3. package/build/BaseConfig.d.ts +43 -0
  4. package/build/BaseConfig.d.ts.map +1 -0
  5. package/build/CanvasConfig.d.ts +7 -92
  6. package/build/CanvasConfig.d.ts.map +1 -1
  7. package/build/CustomElements.d.ts +20 -4
  8. package/build/CustomElements.d.ts.map +1 -1
  9. package/build/RevealBoundryStore.d.ts +50 -10
  10. package/build/RevealBoundryStore.d.ts.map +1 -1
  11. package/build/RevealStateManager.d.ts +3 -0
  12. package/build/RevealStateManager.d.ts.map +1 -1
  13. package/build/SvgConfig.d.ts +17 -0
  14. package/build/SvgConfig.d.ts.map +1 -0
  15. package/build/index.d.ts.map +1 -1
  16. package/build/main.js +169 -17
  17. package/build/utils/extractRGBValue.d.ts +2 -0
  18. package/build/utils/extractRGBValue.d.ts.map +1 -0
  19. package/build/utils/isValidateBorderDecorationType.d.ts +3 -0
  20. package/build/utils/isValidateBorderDecorationType.d.ts.map +1 -0
  21. package/build/utils/types.d.ts +103 -0
  22. package/build/utils/types.d.ts.map +1 -0
  23. package/es/BaseConfig.d.ts +43 -0
  24. package/es/BaseConfig.d.ts.map +1 -0
  25. package/es/BaseConfig.js +220 -0
  26. package/es/BaseConfig.js.map +1 -0
  27. package/es/CanvasConfig.d.ts +7 -92
  28. package/es/CanvasConfig.d.ts.map +1 -1
  29. package/es/CanvasConfig.js +35 -233
  30. package/es/CanvasConfig.js.map +1 -1
  31. package/es/CustomElements.d.ts +20 -4
  32. package/es/CustomElements.d.ts.map +1 -1
  33. package/es/CustomElements.js +130 -33
  34. package/es/CustomElements.js.map +1 -1
  35. package/es/RevealBoundryStore.d.ts +50 -10
  36. package/es/RevealBoundryStore.d.ts.map +1 -1
  37. package/es/RevealBoundryStore.js +129 -35
  38. package/es/RevealBoundryStore.js.map +1 -1
  39. package/es/RevealStateManager.d.ts +3 -0
  40. package/es/RevealStateManager.d.ts.map +1 -1
  41. package/es/RevealStateManager.js +35 -8
  42. package/es/RevealStateManager.js.map +1 -1
  43. package/es/SvgConfig.d.ts +17 -0
  44. package/es/SvgConfig.d.ts.map +1 -0
  45. package/es/SvgConfig.js +346 -0
  46. package/es/SvgConfig.js.map +1 -0
  47. package/es/index.d.ts.map +1 -1
  48. package/es/index.js +12 -18
  49. package/es/index.js.map +1 -1
  50. package/es/tsconfig.tsbuildinfo +1 -0
  51. package/es/utils/extractRGBValue.d.ts +2 -0
  52. package/es/utils/extractRGBValue.d.ts.map +1 -0
  53. package/es/utils/extractRGBValue.js +48 -0
  54. package/es/utils/extractRGBValue.js.map +1 -0
  55. package/es/utils/isValidateBorderDecorationType.d.ts +3 -0
  56. package/es/utils/isValidateBorderDecorationType.d.ts.map +1 -0
  57. package/es/utils/isValidateBorderDecorationType.js +10 -0
  58. package/es/utils/isValidateBorderDecorationType.js.map +1 -0
  59. package/es/utils/types.d.ts +103 -0
  60. package/es/utils/types.d.ts.map +1 -0
  61. package/es/utils/types.js +2 -0
  62. package/es/utils/types.js.map +1 -0
  63. package/package.json +34 -30
  64. package/src/BaseConfig.ts +311 -0
  65. package/src/CanvasConfig.ts +415 -729
  66. package/src/ComputedStyleStorage.ts +89 -89
  67. package/src/CustomElements.ts +272 -164
  68. package/src/Profiler.ts +44 -44
  69. package/src/RevealBoundryStore.ts +291 -192
  70. package/src/RevealStateManager.ts +78 -48
  71. package/src/SvgConfig.ts +422 -0
  72. package/src/config.ts +26 -26
  73. package/src/cssTypedOM.d.ts +52 -52
  74. package/src/index.ts +219 -225
  75. package/src/utils/extractRGBValue.ts +58 -0
  76. package/src/utils/isValidateBorderDecorationType.ts +8 -0
  77. package/src/utils/types.ts +106 -0
  78. package/src/variables.ts +1 -1
  79. package/.prettierrc +0 -6
  80. package/.travis.yml +0 -26
  81. package/.yarnrc.yml +0 -1
  82. package/docs/demo/debug.html +0 -75
  83. package/docs/demo/index.html +0 -1065
  84. package/docs/demo/performance-inspector.html +0 -60
  85. package/docs/demo/shapes-demo.html +0 -93
  86. package/docs/demo/single-unit.html +0 -40
  87. package/docs/logo.png +0 -0
  88. package/docs/logo.svg +0 -1
  89. package/docs/screen-record.gif +0 -0
  90. package/docs/src/logo.afdesign +0 -0
  91. package/rollup.config.js +0 -14
  92. package/tsconfig.json +0 -18
@@ -1,89 +1,89 @@
1
- import { config } from './config.js';
2
-
3
- export interface ComputedStyleStorage {
4
- el: HTMLElement;
5
- size(): number;
6
- get(propertyName: string): string;
7
- getColor(propertyName: string): string;
8
- getNumber(propertyName: string): number;
9
- }
10
-
11
- class ComputedStyleCompat implements ComputedStyleStorage {
12
- protected static colorParser: HTMLDivElement;
13
- protected static colorParserStyle: CSSStyleDeclaration;
14
-
15
- el: HTMLElement;
16
- style: CSSStyleDeclaration;
17
-
18
- constructor(el: HTMLElement) {
19
- if (!ComputedStyleCompat.colorParser) {
20
- const el = document.createElement('div');
21
- el.style.display = 'none !important';
22
- document.body.appendChild(el);
23
-
24
- ComputedStyleCompat.colorParser = el;
25
- ComputedStyleCompat.colorParserStyle = window.getComputedStyle(el);
26
- }
27
-
28
- this.el = el;
29
- this.style = window.getComputedStyle(el);
30
- }
31
-
32
- size() {
33
- return this.style.length;
34
- }
35
-
36
- get(propertyName: string) {
37
- return this.style.getPropertyValue(propertyName).trim();
38
- }
39
-
40
- getColor(propertyName: string) {
41
- ComputedStyleCompat.colorParser.style.color = this.get(propertyName);
42
- return ComputedStyleCompat.colorParserStyle.color || 'rgb(0, 0, 0)';
43
- }
44
-
45
- getNumber(propertyName: string) {
46
- // Length values in computed style will always in the unit of px
47
- // Maybe NaN
48
- return parseFloat(this.get(propertyName));
49
- }
50
- }
51
-
52
- class ComputedStyleExperimental implements ComputedStyleStorage {
53
- el: HTMLElement;
54
- style: StylePropertyMap;
55
-
56
- constructor(el: HTMLElement) {
57
- this.el = el;
58
- this.style = el.computedStyleMap();
59
- }
60
-
61
- size() {
62
- return this.style.size;
63
- }
64
-
65
- get(propertyName: string) {
66
- return this.style.get(propertyName).toString();
67
- }
68
-
69
- getColor(propertyName: string) {
70
- return this.get(propertyName);
71
- }
72
-
73
- getNumber(propertyName: string) {
74
- const value = this.style.get(propertyName).value;
75
- if (typeof value === 'number') {
76
- // Length values in computed style will always in the unit of px
77
- return value;
78
- }
79
-
80
- // Maybe NaN
81
- return parseFloat(value as string);
82
- }
83
- }
84
-
85
- export function createStorage(el: HTMLElement): ComputedStyleStorage {
86
- return config.compat
87
- ? new ComputedStyleCompat(el)
88
- : new ComputedStyleExperimental(el);
89
- }
1
+ import { config } from './config.js';
2
+
3
+ export interface ComputedStyleStorage {
4
+ el: HTMLElement;
5
+ size(): number;
6
+ get(propertyName: string): string;
7
+ getColor(propertyName: string): string;
8
+ getNumber(propertyName: string): number;
9
+ }
10
+
11
+ class ComputedStyleCompat implements ComputedStyleStorage {
12
+ protected static colorParser: HTMLDivElement;
13
+ protected static colorParserStyle: CSSStyleDeclaration;
14
+
15
+ el: HTMLElement;
16
+ style: CSSStyleDeclaration;
17
+
18
+ constructor(el: HTMLElement) {
19
+ if (!ComputedStyleCompat.colorParser) {
20
+ const el = document.createElement('div');
21
+ el.style.display = 'none !important';
22
+ document.body.appendChild(el);
23
+
24
+ ComputedStyleCompat.colorParser = el;
25
+ ComputedStyleCompat.colorParserStyle = window.getComputedStyle(el);
26
+ }
27
+
28
+ this.el = el;
29
+ this.style = window.getComputedStyle(el);
30
+ }
31
+
32
+ size() {
33
+ return this.style.length;
34
+ }
35
+
36
+ get(propertyName: string) {
37
+ return this.style.getPropertyValue(propertyName).trim();
38
+ }
39
+
40
+ getColor(propertyName: string) {
41
+ ComputedStyleCompat.colorParser.style.color = this.get(propertyName);
42
+ return ComputedStyleCompat.colorParserStyle.color || 'rgb(0, 0, 0)';
43
+ }
44
+
45
+ getNumber(propertyName: string) {
46
+ // Length values in computed style will always in the unit of px
47
+ // Maybe NaN
48
+ return parseFloat(this.get(propertyName));
49
+ }
50
+ }
51
+
52
+ class ComputedStyleExperimental implements ComputedStyleStorage {
53
+ el: HTMLElement;
54
+ style: StylePropertyMap;
55
+
56
+ constructor(el: HTMLElement) {
57
+ this.el = el;
58
+ this.style = el.computedStyleMap();
59
+ }
60
+
61
+ size() {
62
+ return this.style.size;
63
+ }
64
+
65
+ get(propertyName: string) {
66
+ return this.style.get(propertyName).toString();
67
+ }
68
+
69
+ getColor(propertyName: string) {
70
+ return this.get(propertyName);
71
+ }
72
+
73
+ getNumber(propertyName: string) {
74
+ const value = this.style.get(propertyName).value;
75
+ if (typeof value === 'number') {
76
+ // Length values in computed style will always in the unit of px
77
+ return value;
78
+ }
79
+
80
+ // Maybe NaN
81
+ return parseFloat(value as string);
82
+ }
83
+ }
84
+
85
+ export function createStorage(el: HTMLElement): ComputedStyleStorage {
86
+ return config.compat
87
+ ? new ComputedStyleCompat(el)
88
+ : new ComputedStyleExperimental(el);
89
+ }
@@ -1,164 +1,272 @@
1
- import { RevealStateManager } from './RevealStateManager.js';
2
- import { RevealBoundaryStore } from './RevealBoundryStore.js';
3
- import { config } from './config.js';
4
-
5
- class ServerSideHTMLElement {
6
- root = {
7
- innerHTML: '',
8
- querySelector: (_x: string) => null,
9
- }
10
-
11
- attachShadow = () => null;
12
- }
13
-
14
- const PatchedHTMLElement =
15
- typeof globalThis.Window === 'undefined'
16
- ? ServerSideHTMLElement as unknown as typeof HTMLElement
17
- : HTMLElement;
18
-
19
- export class AxRevealProvider extends PatchedHTMLElement {
20
- static readonly ElementName = 'ax-reveal-provider';
21
- readonly stateManager = new RevealStateManager();
22
- }
23
-
24
- export class AxRevealBoundary extends PatchedHTMLElement {
25
- static readonly ElementName = 'ax-reveal-bound';
26
-
27
- static readonly removeStorageEvent = 'removeStorage';
28
- static readonly attachStorageEvent = 'attachStorage';
29
- static readonly replaceStorageEvent = 'replaceStorage';
30
-
31
- private root = this.attachShadow({ mode: 'open' });
32
-
33
- static readonly stateManager = new RevealStateManager();
34
-
35
- private _storage!: RevealBoundaryStore | undefined;
36
-
37
- private get storage() {
38
- return this._storage;
39
- }
40
-
41
- private set storage(newStorage) {
42
- const oldStorage = this._storage;
43
-
44
- if (oldStorage) {
45
- this.dispatchEvent(new CustomEvent(AxRevealBoundary.removeStorageEvent, { detail: oldStorage }));
46
- AxRevealBoundary.stateManager.removeBoundary(oldStorage);
47
- }
48
-
49
- if (newStorage) {
50
- this._storage = newStorage;
51
- this.dispatchEvent(new CustomEvent(AxRevealBoundary.attachStorageEvent, { detail: newStorage }));
52
- }
53
-
54
- if (oldStorage && newStorage) {
55
- this.dispatchEvent(new CustomEvent(AxRevealBoundary.replaceStorageEvent, {
56
- detail: { old: oldStorage, new: newStorage },
57
- }));
58
- }
59
- }
60
-
61
- public waitForStorage(f: (storage: RevealBoundaryStore) => void) {
62
- if (this.storage === undefined) {
63
- this.addEventListener(AxRevealBoundary.attachStorageEvent, () => f(this.storage!), { once: true });
64
- } else {
65
- f(this.storage);
66
- }
67
- }
68
-
69
- private appendStorage(force = false) {
70
- if (!force && this.storage) {
71
- return;
72
- }
73
-
74
- const parent = this.closest(AxRevealProvider.ElementName) as AxRevealProvider;
75
- const stateManager = parent ? parent.stateManager : AxRevealBoundary.stateManager;
76
-
77
- this.storage = stateManager.newBoundary(this);
78
- }
79
-
80
- updatePointerPosition = (ev: MouseEvent) => {
81
- this.waitForStorage(storage => {
82
- storage.clientX = ev.clientX;
83
- storage.clientY = ev.clientY;
84
- });
85
- };
86
-
87
- handlePointerEnter = () => this.waitForStorage(storage => storage.onPointerEnterBoundary());
88
- handlePointerLeave = () => this.waitForStorage(storage => storage.onPointerLeaveBoundary());
89
- handlePointerMove = (ev: MouseEvent) => this.updatePointerPosition(ev);
90
- handlePointerUp = () => this.waitForStorage(storage => storage.switchAnimation());
91
- handlePointerDown = (ev: MouseEvent) => this.waitForStorage(storage => {
92
- this.updatePointerPosition(ev);
93
- storage.initializeAnimation();
94
- });
95
-
96
- connectedCallback() {
97
- this.appendStorage(true);
98
- if (config.borderDetectionMode === 'strictEdge') {
99
- this.addEventListener('pointerenter', this.handlePointerEnter);
100
- this.addEventListener('pointerleave', this.handlePointerLeave);
101
- this.addEventListener('pointermove', this.handlePointerMove);
102
- }
103
- this.addEventListener('pointerdown', this.handlePointerDown);
104
- this.addEventListener('pointerup', this.handlePointerUp);
105
- }
106
-
107
- disconnectedCallback() {
108
- this.storage = undefined;
109
- }
110
-
111
- constructor() {
112
- super();
113
- this.root.innerHTML = `
114
- <div>
115
- <slot></slot>
116
- </div>`
117
- }
118
- }
119
-
120
- export class AxReveal extends PatchedHTMLElement {
121
- static readonly ElementName = 'ax-reveal';
122
- private root = this.attachShadow({ mode: 'open' });
123
- private canvas: HTMLCanvasElement;
124
- private boundary!: AxRevealBoundary;
125
-
126
- adoptedCallback() {
127
- this.disconnectedCallback();
128
- this.connectedCallback();
129
- }
130
-
131
- disconnectedCallback() {
132
- this.boundary && this.boundary.waitForStorage(storage => storage.removeReveal(this.canvas));
133
- }
134
-
135
- connectedCallback() {
136
- this.boundary = this.closest(AxRevealBoundary.ElementName) as AxRevealBoundary;
137
- if (!this.boundary)
138
- throw new SyntaxError('You must use ' + AxRevealBoundary.ElementName + ' as the boundary of acrylic!');
139
-
140
- this.boundary.waitForStorage(storage => setTimeout(() => storage.addReveal(this.canvas, this), 0));
141
- }
142
-
143
- constructor() {
144
- super();
145
- this.root.innerHTML = `
146
- <div>
147
- <slot></slot>
148
- <canvas></canvas>
149
- </div>
150
- <style>
151
- div { display: content; }
152
- canvas { top: 0; left: 0; pointer-events: none; width: 100%; height: 100%; position: absolute; }
153
- :host { display: inline-block; position: relative; }
154
- :host([block]) { display: block; }
155
- :host([inline-block]) { display: inline-block; }
156
- :host([flex]) { display: flex; }
157
- :host([inline-flex]) { display: inline-flex; }
158
- :host([grid]) { display: grid; }
159
- :host([inline-grid]) { display: inline-grid; }
160
- ::slotted(button) { outline:none; }
161
- </style>`;
162
- this.canvas = this.root.querySelector('canvas')!;
163
- }
164
- }
1
+ import { RevealStateManager } from './RevealStateManager.js';
2
+ import { RevealBoundaryStore } from './RevealBoundryStore.js';
3
+ import { config } from './config.js';
4
+
5
+ function closest(dom: Element, selector: string): Element | null {
6
+ const r = dom.closest(selector);
7
+ if (r) return r;
8
+ const host = findParentShadowRoot(dom)?.host;
9
+ if (!host) return null;
10
+ return closest(host, selector)
11
+ }
12
+ function findParentShadowRoot(x: Node | undefined | null): ShadowRoot | null {
13
+ if (!x) return null;
14
+ if (x.parentNode && x.parentNode.nodeType === document.DOCUMENT_FRAGMENT_NODE) return x.parentNode as ShadowRoot;
15
+ return findParentShadowRoot(x.parentNode);
16
+ }
17
+ class ServerSideHTMLElement {
18
+ root = {
19
+ innerHTML: '',
20
+ querySelector: (_x: string) => null,
21
+ };
22
+
23
+ attachShadow = () => null;
24
+ }
25
+
26
+ const PatchedHTMLElement =
27
+ typeof globalThis.Window === 'undefined' ? ((ServerSideHTMLElement as unknown) as typeof HTMLElement) : HTMLElement;
28
+
29
+ export class AxRevealProvider extends PatchedHTMLElement {
30
+ static readonly ElementName = 'ax-reveal-provider';
31
+ readonly stateManager = new RevealStateManager();
32
+ }
33
+
34
+ export class AxRevealBoundary extends PatchedHTMLElement {
35
+ static readonly ElementName = 'ax-reveal-bound';
36
+
37
+ static readonly removeStorageEvent = 'removeStorage';
38
+ static readonly attachStorageEvent = 'attachStorage';
39
+ static readonly replaceStorageEvent = 'replaceStorage';
40
+
41
+ private root = this.attachShadow({ mode: 'open' });
42
+
43
+ static readonly stateManager = new RevealStateManager();
44
+
45
+ private _storage!: RevealBoundaryStore | undefined;
46
+
47
+ private get storage() {
48
+ return this._storage;
49
+ }
50
+
51
+ private set storage(newStorage) {
52
+ const oldStorage = this._storage;
53
+
54
+ if (oldStorage) {
55
+ this.dispatchEvent(new CustomEvent(AxRevealBoundary.removeStorageEvent, { detail: oldStorage }));
56
+ AxRevealBoundary.stateManager.removeBoundary(oldStorage);
57
+ }
58
+
59
+ if (newStorage) {
60
+ this._storage = newStorage;
61
+ this.dispatchEvent(new CustomEvent(AxRevealBoundary.attachStorageEvent, { detail: newStorage }));
62
+ }
63
+
64
+ if (oldStorage && newStorage) {
65
+ this.dispatchEvent(
66
+ new CustomEvent(AxRevealBoundary.replaceStorageEvent, {
67
+ detail: { old: oldStorage, new: newStorage },
68
+ })
69
+ );
70
+ }
71
+ }
72
+
73
+ public waitForStorage(f: (storage: RevealBoundaryStore) => void) {
74
+ if (this.storage === undefined) {
75
+ this.addEventListener(AxRevealBoundary.attachStorageEvent, () => f(this.storage!), { once: true });
76
+ } else {
77
+ f(this.storage);
78
+ }
79
+ }
80
+
81
+ private appendStorage(force = false) {
82
+ if (!force && this.storage) {
83
+ return;
84
+ }
85
+
86
+ const parent = closest(this, AxRevealProvider.ElementName) as AxRevealProvider;
87
+ const stateManager = parent ? parent.stateManager : AxRevealBoundary.stateManager;
88
+
89
+ this.storage = stateManager.newBoundary(this);
90
+ }
91
+
92
+ /**
93
+ * Update the position of your pointer.
94
+ * @param ev Pointer event from the listener.
95
+ */
96
+ updatePointerPosition = (ev: PointerEvent) => {
97
+ this.waitForStorage((storage) => {
98
+ storage.clientX = ev.clientX;
99
+ storage.clientY = ev.clientY;
100
+ });
101
+ };
102
+
103
+ handlePointerEnter = () => this.waitForStorage((storage) => storage.onPointerEnterBoundary());
104
+ handlePointerLeave = () => this.waitForStorage((storage) => storage.onPointerLeaveBoundary());
105
+ handlePointerMove = this.updatePointerPosition;
106
+ handlePointerUp = (ev: PointerEvent) => {
107
+ if (ev.pointerType === 'mouse') {
108
+ this.waitForStorage((storage) => storage.switchAnimation());
109
+ } else {
110
+ this.waitForStorage((storage) => storage.clearAll(false));
111
+ }
112
+ };
113
+ handlePointerDown = (ev: PointerEvent) =>
114
+ this.waitForStorage((storage) => {
115
+ this.updatePointerPosition(ev);
116
+ storage.initializeAnimation();
117
+ });
118
+
119
+ connectedCallback() {
120
+ this.appendStorage(true);
121
+ if (config.borderDetectionMode === 'strictEdge') {
122
+ this.addEventListener('pointerenter', this.handlePointerEnter);
123
+ this.addEventListener('pointerleave', this.handlePointerLeave);
124
+ this.addEventListener('pointermove', this.handlePointerMove);
125
+ }
126
+ this.addEventListener('pointerdown', this.handlePointerDown);
127
+ this.addEventListener('pointerup', this.handlePointerUp);
128
+ }
129
+
130
+ disconnectedCallback() {
131
+ this.storage = undefined;
132
+ }
133
+
134
+ constructor() {
135
+ super();
136
+ this.root.innerHTML = `
137
+ <div>
138
+ <slot></slot>
139
+ </div>`;
140
+ }
141
+ }
142
+
143
+ export class AxReveal extends PatchedHTMLElement {
144
+ static readonly ElementName = 'ax-reveal';
145
+ private root = this.attachShadow({ mode: 'open' });
146
+ private canvas: HTMLCanvasElement;
147
+ private boundary!: AxRevealBoundary;
148
+
149
+ adoptedCallback() {
150
+ this.disconnectedCallback();
151
+ this.connectedCallback();
152
+ }
153
+
154
+ handlePointerDown = (ev: PointerEvent) => {
155
+ this.setPointerCapture(ev.pointerId);
156
+ };
157
+
158
+ disconnectedCallback() {
159
+ this.boundary && this.boundary.waitForStorage((storage) => storage.removeReveal(this.canvas));
160
+ }
161
+
162
+ connectedCallback() {
163
+ this.boundary = closest(this, AxRevealBoundary.ElementName) as AxRevealBoundary;
164
+ if (!this.boundary)
165
+ throw new SyntaxError(
166
+ 'You must use ' + AxRevealBoundary.ElementName + ' as the boundary of reveal highlight!'
167
+ );
168
+
169
+ this.boundary.waitForStorage((storage) => setTimeout(() => storage.addReveal(this.canvas, this), 0));
170
+ this.addEventListener('pointerdown', this.handlePointerDown);
171
+ }
172
+
173
+ constructor() {
174
+ super();
175
+ this.root.innerHTML = `
176
+ <div class="ax-reveal">
177
+ <canvas></canvas>
178
+ <div class="content"><slot></slot></div>
179
+ </div>
180
+ <style>
181
+ .ax-reveal { display: content; }
182
+ .ax-reveal * { user-drag: none; -webkit-user-drag: none; touch-action: none; user-select: none; }
183
+ .content { position: relative; }
184
+ canvas { top: 0; left: 0; pointer-events: none; width: 100%; height: 100%; position: absolute; }
185
+ :host { display: inline-block; position: relative; }
186
+ :host([block]) { display: block; }
187
+ :host([inline-block]) { display: inline-block; }
188
+ :host([flex]) { display: flex; }
189
+ :host([inline-flex]) { display: inline-flex; }
190
+ :host([grid]) { display: grid; }
191
+ :host([inline-grid]) { display: inline-grid; }
192
+ ::slotted(*) { user-drag: none; -webkit-user-drag: none; touch-action: none; user-select: none; }
193
+ ::slotted(button) { outline:none; }
194
+ </style>`;
195
+ this.canvas = this.root.querySelector('canvas')!;
196
+ }
197
+ }
198
+
199
+ export class AxRevealNg extends PatchedHTMLElement {
200
+ static readonly ElementName = 'ax-reveal-ng';
201
+ private root = this.attachShadow({ mode: 'open' });
202
+ private svg: SVGElement;
203
+ private boundary!: AxRevealBoundary;
204
+
205
+ adoptedCallback() {
206
+ this.disconnectedCallback();
207
+ this.connectedCallback();
208
+ }
209
+
210
+ handlePointerDown = (ev: PointerEvent) => {
211
+ this.setPointerCapture(ev.pointerId);
212
+ };
213
+
214
+ disconnectedCallback() {
215
+ this.boundary && this.boundary.waitForStorage((storage) => storage.removeReveal(this.svg));
216
+ }
217
+
218
+ connectedCallback() {
219
+ this.boundary = closest(this, AxRevealBoundary.ElementName) as AxRevealBoundary;
220
+ if (!this.boundary)
221
+ throw new SyntaxError(
222
+ 'You must use ' + AxRevealBoundary.ElementName + ' as the boundary of reveal highlight!'
223
+ );
224
+
225
+ this.boundary.waitForStorage((storage) => setTimeout(() => storage.addReveal(this.svg, this), 0));
226
+ this.addEventListener('pointerdown', this.handlePointerDown);
227
+ }
228
+
229
+ constructor() {
230
+ super();
231
+ this.root.innerHTML = `
232
+ <div class="ax-reveal">
233
+ <svg>
234
+ <defs>
235
+ <radialGradient id="borderGrad" gradientUnits="userSpaceOnUse" r="10">
236
+ <stop id="borderCenter" offset="0%" />
237
+ <stop id="borderOut" offset="100%" />
238
+ </radialGradient>
239
+ <radialGradient id="fillGrad" gradientUnits="userSpaceOnUse" r="10">
240
+ <stop id="fillCenter" offset="0%" />
241
+ <stop id="fillOut" offset="100%" />
242
+ </radialGradient>
243
+ <radialGradient id="rippleGrad" gradientUnits="userSpaceOnUse" r="10">
244
+ <stop id="rippleCenter" offset="0%" />
245
+ <stop id="rippleMiddle" offset="0%" />
246
+ <stop id="rippleOut" offset="0%" />
247
+ </radialGradient>
248
+ </defs>
249
+ <path id="borderPath" fill="url(#borderGrad)" />
250
+ <path id="fillPath" fill="url(#fillGrad)" />
251
+ <path id="ripplePath" fill="url(#rippleGrad)" />
252
+ </svg>
253
+ <div class="content"><slot></slot></div>
254
+ </div>
255
+ <style>
256
+ .ax-reveal { display: contents; }
257
+ .ax-reveal * { user-drag: none; -webkit-user-drag: none; touch-action: none; user-select: none; }
258
+ .content { position: relative; }
259
+ svg { top: 0; left: 0; pointer-events: none; width: 100%; height: 100%; position: absolute; }
260
+ :host { display: inline-block; position: relative; }
261
+ :host([block]) { display: block; }
262
+ :host([inline-block]) { display: inline-block; }
263
+ :host([flex]) { display: flex; }
264
+ :host([inline-flex]) { display: inline-flex; }
265
+ :host([grid]) { display: grid; }
266
+ :host([inline-grid]) { display: inline-grid; }
267
+ ::slotted(*) { user-drag: none; -webkit-user-drag: none; touch-action: none; user-select: none; }
268
+ ::slotted(button) { outline:none; }
269
+ </style>`;
270
+ this.svg = this.root.querySelector('svg')!;
271
+ }
272
+ }