@ax-design/reveal-highlight 0.3.0-alpha.8 → 0.4.2
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 +8 -167
- package/build/BaseConfig.d.ts +43 -0
- package/build/BaseConfig.d.ts.map +1 -0
- package/build/CanvasConfig.d.ts +7 -92
- package/build/CanvasConfig.d.ts.map +1 -1
- package/build/CustomElements.d.ts +20 -4
- package/build/CustomElements.d.ts.map +1 -1
- package/build/RevealBoundryStore.d.ts +50 -10
- package/build/RevealBoundryStore.d.ts.map +1 -1
- package/build/RevealStateManager.d.ts +3 -0
- package/build/RevealStateManager.d.ts.map +1 -1
- package/build/SvgConfig.d.ts +17 -0
- package/build/SvgConfig.d.ts.map +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/main.js +169 -17
- package/build/utils/extractRGBValue.d.ts +2 -0
- package/build/utils/extractRGBValue.d.ts.map +1 -0
- package/build/utils/isValidateBorderDecorationType.d.ts +3 -0
- package/build/utils/isValidateBorderDecorationType.d.ts.map +1 -0
- package/build/utils/types.d.ts +103 -0
- package/build/utils/types.d.ts.map +1 -0
- package/es/BaseConfig.d.ts +43 -0
- package/es/BaseConfig.d.ts.map +1 -0
- package/es/BaseConfig.js +220 -0
- package/es/BaseConfig.js.map +1 -0
- package/es/CanvasConfig.d.ts +7 -92
- package/es/CanvasConfig.d.ts.map +1 -1
- package/es/CanvasConfig.js +35 -233
- package/es/CanvasConfig.js.map +1 -1
- package/es/CustomElements.d.ts +20 -4
- package/es/CustomElements.d.ts.map +1 -1
- package/es/CustomElements.js +115 -18
- package/es/CustomElements.js.map +1 -1
- package/es/RevealBoundryStore.d.ts +50 -10
- package/es/RevealBoundryStore.d.ts.map +1 -1
- package/es/RevealBoundryStore.js +129 -35
- package/es/RevealBoundryStore.js.map +1 -1
- package/es/RevealStateManager.d.ts +3 -0
- package/es/RevealStateManager.d.ts.map +1 -1
- package/es/RevealStateManager.js +43 -8
- package/es/RevealStateManager.js.map +1 -1
- package/es/SvgConfig.d.ts +17 -0
- package/es/SvgConfig.d.ts.map +1 -0
- package/es/SvgConfig.js +346 -0
- package/es/SvgConfig.js.map +1 -0
- package/es/index.d.ts.map +1 -1
- package/es/index.js +10 -16
- package/es/index.js.map +1 -1
- package/es/tsconfig.tsbuildinfo +1 -0
- package/es/utils/extractRGBValue.d.ts +2 -0
- package/es/utils/extractRGBValue.d.ts.map +1 -0
- package/es/utils/extractRGBValue.js +48 -0
- package/es/utils/extractRGBValue.js.map +1 -0
- package/es/utils/isValidateBorderDecorationType.d.ts +3 -0
- package/es/utils/isValidateBorderDecorationType.d.ts.map +1 -0
- package/es/utils/isValidateBorderDecorationType.js +10 -0
- package/es/utils/isValidateBorderDecorationType.js.map +1 -0
- package/es/utils/types.d.ts +103 -0
- package/es/utils/types.d.ts.map +1 -0
- package/es/utils/types.js +2 -0
- package/es/utils/types.js.map +1 -0
- package/package.json +35 -30
- package/src/BaseConfig.ts +311 -0
- package/src/CanvasConfig.ts +66 -380
- package/src/CustomElements.ts +137 -29
- package/src/RevealBoundryStore.ts +138 -39
- package/src/RevealStateManager.ts +48 -10
- package/src/SvgConfig.ts +422 -0
- package/src/index.ts +10 -16
- package/src/utils/extractRGBValue.ts +58 -0
- package/src/utils/isValidateBorderDecorationType.ts +8 -0
- package/src/utils/types.ts +106 -0
- package/.prettierrc +0 -6
- package/.travis.yml +0 -26
- package/.yarnrc.yml +0 -1
- package/docs/demo/debug.html +0 -73
- package/docs/demo/index.html +0 -1065
- package/docs/demo/performance-inspector.html +0 -60
- package/docs/demo/shapes-demo.html +0 -93
- package/docs/demo/single-unit.html +0 -39
- package/docs/logo.png +0 -0
- package/docs/logo.svg +0 -1
- package/docs/screen-record.gif +0 -0
- package/docs/src/logo.afdesign +0 -0
- package/rollup.config.js +0 -14
- package/tsconfig.json +0 -18
package/src/SvgConfig.ts
ADDED
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
import { RevealBoundaryStore } from './RevealBoundryStore.js';
|
|
2
|
+
|
|
3
|
+
import type { CachedRevealPath } from './utils/types.js';
|
|
4
|
+
|
|
5
|
+
import { BaseConfig } from './BaseConfig.js';
|
|
6
|
+
|
|
7
|
+
export class SvgConfig extends BaseConfig<SVGSVGElement> {
|
|
8
|
+
protected cachedImg: CachedRevealPath;
|
|
9
|
+
|
|
10
|
+
constructor(store: RevealBoundaryStore, $svg: SVGSVGElement, $container: HTMLElement) {
|
|
11
|
+
super(store, $svg, $container);
|
|
12
|
+
this._store = store;
|
|
13
|
+
|
|
14
|
+
const cachedPath = {
|
|
15
|
+
borderReveal: $svg.querySelector('#borderPath') as SVGPathElement,
|
|
16
|
+
fillReveal: $svg.querySelector('#fillPath') as SVGPathElement,
|
|
17
|
+
rippleReveal: $svg.querySelector('#ripplePath') as SVGPathElement,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const cachedGradient = {
|
|
21
|
+
borderReveal: $svg.querySelector('#borderGrad') as SVGRadialGradientElement,
|
|
22
|
+
fillReveal: $svg.querySelector('#fillGrad') as SVGRadialGradientElement,
|
|
23
|
+
rippleReveal: $svg.querySelector('#rippleGrad') as SVGRadialGradientElement,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const cachedGradientStop = {
|
|
27
|
+
borderReveal: [
|
|
28
|
+
$svg.querySelector('#borderCenter') as SVGStopElement,
|
|
29
|
+
$svg.querySelector('#borderOut') as SVGStopElement,
|
|
30
|
+
] as const,
|
|
31
|
+
fillReveal: [
|
|
32
|
+
$svg.querySelector('#fillCenter') as SVGStopElement,
|
|
33
|
+
$svg.querySelector('#fillOut') as SVGStopElement,
|
|
34
|
+
] as const,
|
|
35
|
+
rippleReveal: [
|
|
36
|
+
$svg.querySelector('#rippleCenter') as SVGStopElement,
|
|
37
|
+
$svg.querySelector('#rippleMiddle') as SVGStopElement,
|
|
38
|
+
$svg.querySelector('#rippleOut') as SVGStopElement,
|
|
39
|
+
] as const,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
this.cachedImg = {
|
|
43
|
+
cachedReveal: {
|
|
44
|
+
borderReveal: {
|
|
45
|
+
radiusFactor: -1,
|
|
46
|
+
radius: -1,
|
|
47
|
+
color: 'INVALID',
|
|
48
|
+
opacity: 0,
|
|
49
|
+
pattern: null,
|
|
50
|
+
},
|
|
51
|
+
fillReveal: {
|
|
52
|
+
radiusFactor: -1,
|
|
53
|
+
radius: -1,
|
|
54
|
+
color: 'INVALID',
|
|
55
|
+
opacity: 0,
|
|
56
|
+
pattern: null,
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
cachedPath,
|
|
60
|
+
cachedGradient,
|
|
61
|
+
cachedGradientStop,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
updateCachedBitmap = () => {
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
updateCachedReveal = () => {
|
|
69
|
+
const c = this.cachedStyle;
|
|
70
|
+
const stops = this.cachedImg.cachedGradientStop;
|
|
71
|
+
stops.borderReveal[0].style.stopColor = c.borderColor;
|
|
72
|
+
stops.borderReveal[1].style.stopColor = c.borderColor;
|
|
73
|
+
stops.borderReveal[0].style.stopOpacity = c.opacity.toString();
|
|
74
|
+
stops.borderReveal[1].style.stopOpacity = '0';
|
|
75
|
+
|
|
76
|
+
stops.fillReveal[0].style.stopColor = c.hoverLightColor;
|
|
77
|
+
stops.fillReveal[1].style.stopColor = c.hoverLightColor;
|
|
78
|
+
stops.fillReveal[0].style.stopOpacity = (c.opacity * 0.5).toString();
|
|
79
|
+
stops.fillReveal[1].style.stopOpacity = '0';
|
|
80
|
+
|
|
81
|
+
stops.rippleReveal[0].style.stopColor = c.pressAnimationColor;
|
|
82
|
+
stops.rippleReveal[1].style.stopColor = c.pressAnimationColor;
|
|
83
|
+
stops.rippleReveal[2].style.stopColor = c.pressAnimationColor;
|
|
84
|
+
|
|
85
|
+
const grads = this.cachedImg.cachedGradient;
|
|
86
|
+
const isAbsoluteFill = c.trueFillRadius[0] === -1;
|
|
87
|
+
grads.borderReveal.r.baseVal.value = isAbsoluteFill
|
|
88
|
+
? c.borderFillRadius
|
|
89
|
+
: c.borderFillRadius * c.trueFillRadius[1];
|
|
90
|
+
grads.fillReveal.r.baseVal.value = isAbsoluteFill
|
|
91
|
+
? c.hoverLightFillRadius
|
|
92
|
+
: c.hoverLightFillRadius * c.trueFillRadius[0];
|
|
93
|
+
|
|
94
|
+
this.fillDirty = false;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
private updateAnimateGrd = (frame: number, x: number, y: number, radius: number) => {
|
|
98
|
+
const { opacity } = this.cachedStyle;
|
|
99
|
+
|
|
100
|
+
const _innerAlpha = opacity * (0.2 - frame);
|
|
101
|
+
const _outerAlpha = opacity * (0.1 - frame * 0.07);
|
|
102
|
+
const _outerBorder = 0.1 + frame * 0.8;
|
|
103
|
+
|
|
104
|
+
const innerAlpha = _innerAlpha < 0 ? 0 : _innerAlpha;
|
|
105
|
+
const outerAlpha = _outerAlpha < 0 ? 0 : _outerAlpha;
|
|
106
|
+
let outerBorder = 0;
|
|
107
|
+
outerBorder = _outerBorder > 1 ? 1 : _outerBorder;
|
|
108
|
+
outerBorder = _outerBorder < 0 ? 0 : _outerBorder;
|
|
109
|
+
|
|
110
|
+
const stops = this.cachedImg.cachedGradientStop;
|
|
111
|
+
stops.rippleReveal[0].style.stopOpacity = innerAlpha.toString();
|
|
112
|
+
stops.rippleReveal[1].style.stopOpacity = outerAlpha.toString();
|
|
113
|
+
stops.rippleReveal[2].style.stopOpacity = '0';
|
|
114
|
+
|
|
115
|
+
stops.rippleReveal[0].offset.baseVal = 0;
|
|
116
|
+
stops.rippleReveal[1].offset.baseVal = outerBorder * 0.55;
|
|
117
|
+
stops.rippleReveal[2].offset.baseVal = outerBorder;
|
|
118
|
+
|
|
119
|
+
const grads = this.cachedImg.cachedGradient;
|
|
120
|
+
grads.rippleReveal.r.baseVal.value = radius;
|
|
121
|
+
grads.rippleReveal.cx.baseVal.value = x;
|
|
122
|
+
grads.rippleReveal.cy.baseVal.value = y;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
private updateGradientPosition = (x: number, y: number) => {
|
|
126
|
+
const grads = this.cachedImg.cachedGradient;
|
|
127
|
+
|
|
128
|
+
grads.borderReveal.cx.baseVal.value = x;
|
|
129
|
+
grads.borderReveal.cy.baseVal.value = y;
|
|
130
|
+
|
|
131
|
+
grads.fillReveal.cx.baseVal.value = x;
|
|
132
|
+
grads.fillReveal.cy.baseVal.value = y;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
private drawShape = (hollow: boolean, $target: SVGPathElement) => {
|
|
136
|
+
const b = this.cachedBoundingRect;
|
|
137
|
+
const w = b.width;
|
|
138
|
+
const h = b.height;
|
|
139
|
+
|
|
140
|
+
const c = this.cachedStyle;
|
|
141
|
+
const bw = c.borderWidth;
|
|
142
|
+
|
|
143
|
+
const tl = c.topLeftBorderDecorationRadius;
|
|
144
|
+
const tr = c.topRightBorderDecorationRadius;
|
|
145
|
+
const bl = c.bottomLeftBorderDecorationRadius;
|
|
146
|
+
const br = c.bottomRightBorderDecorationRadius;
|
|
147
|
+
|
|
148
|
+
const wlf = c.withLeftBorderFactor;
|
|
149
|
+
const wrf = c.withRightBorderFactor;
|
|
150
|
+
const wtf = c.withTopBorderFactor;
|
|
151
|
+
const wbf = c.withBottomBorderFactor;
|
|
152
|
+
|
|
153
|
+
const rwlf = c.withLeftBorderFactor ? 0 : 1;
|
|
154
|
+
const rwrf = c.withRightBorderFactor ? 0 : 1;
|
|
155
|
+
const rwtf = c.withTopBorderFactor ? 0 : 1;
|
|
156
|
+
const rwbf = c.withBottomBorderFactor ? 0 : 1;
|
|
157
|
+
|
|
158
|
+
const ntlc = !c.withTopBorderFactor && !c.withLeftBorderFactor;
|
|
159
|
+
const ntrc = !c.withTopBorderFactor && !c.withRightBorderFactor;
|
|
160
|
+
const nblc = !c.withBottomBorderFactor && !c.withLeftBorderFactor;
|
|
161
|
+
const nbrc = !c.withBottomBorderFactor && !c.withRightBorderFactor;
|
|
162
|
+
|
|
163
|
+
const tl2 = bw < tl ? tl - bw : 0;
|
|
164
|
+
const tr2 = bw < tr ? tr - bw : 0;
|
|
165
|
+
const bl2 = bw < bl ? bl - bw : 0;
|
|
166
|
+
const br2 = bw < br ? br - bw : 0;
|
|
167
|
+
|
|
168
|
+
let d = '';
|
|
169
|
+
|
|
170
|
+
// Step 1: Starting point
|
|
171
|
+
d += hollow ? `M ${tl}, 0 ` : `M ${bw}, ${tl2 + bw} `;
|
|
172
|
+
|
|
173
|
+
switch (c.borderDecorationType) {
|
|
174
|
+
// Oh... Fuck again...
|
|
175
|
+
case 'round':
|
|
176
|
+
// Step 2: Draw shape
|
|
177
|
+
if (hollow) {
|
|
178
|
+
// Step 2-1: This is outer path, drawing clockwise
|
|
179
|
+
d += `
|
|
180
|
+
h ${w - tl - tr}
|
|
181
|
+
a ${tr}, ${tr} 0 0 1 ${tr}, ${tr}
|
|
182
|
+
v ${h - tr - br}
|
|
183
|
+
a ${br}, ${br} 0 0 1 ${-br}, ${br}
|
|
184
|
+
h ${-w + bl + br}
|
|
185
|
+
a ${bl}, ${bl} 0 0 1 ${-bl}, ${-bl}
|
|
186
|
+
v ${-h + tr + br}
|
|
187
|
+
a ${tl}, ${tl} 0 0 1 ${tl}, ${-tl}
|
|
188
|
+
Z
|
|
189
|
+
`;
|
|
190
|
+
}
|
|
191
|
+
// Step 2-2: This is the inner path, drawing anti-clockwise
|
|
192
|
+
d += `
|
|
193
|
+
M ${bw * wlf}, ${tl2 + bw}
|
|
194
|
+
v ${h - tl2 - bl2 - bw * 2 + rwbf * bw}
|
|
195
|
+
a ${bl2}, ${bl2} 0 0 0 ${bl2}, ${bl2}
|
|
196
|
+
h ${w - bl2 - br2 - bw * 2 + rwlf * bw + rwrf * bw}
|
|
197
|
+
a ${br2}, ${br2} 0 0 0 ${br2}, ${-br2}
|
|
198
|
+
v ${-h + tr2 + br2 + bw * 2 - rwtf * bw - rwbf * bw}
|
|
199
|
+
a ${tr2}, ${tr2} 0 0 0 ${-tr2}, ${-tr2}
|
|
200
|
+
h ${-w + bl2 + br2 + bw * 2 - rwlf * bw - rwrf * bw}
|
|
201
|
+
a ${tl2}, ${tl2} 0 0 0 ${-tl2}, ${tl2}
|
|
202
|
+
L ${bw * wlf}, ${tl2 + bw}
|
|
203
|
+
`;
|
|
204
|
+
break;
|
|
205
|
+
case 'bevel':
|
|
206
|
+
if (hollow) {
|
|
207
|
+
// Step 2-1: This is outer path, drawing clockwise
|
|
208
|
+
d += `
|
|
209
|
+
h ${w - tl - tr}
|
|
210
|
+
l ${tr} ${tr}
|
|
211
|
+
v ${h - tr - br}
|
|
212
|
+
l ${-br} ${br}
|
|
213
|
+
h ${-w + tr + br}
|
|
214
|
+
l ${-bl} ${-bl}
|
|
215
|
+
v ${-h + tr + br}
|
|
216
|
+
l ${tl} ${-tl}
|
|
217
|
+
Z
|
|
218
|
+
`;
|
|
219
|
+
}
|
|
220
|
+
// // Step 2-2: This is the inner path, drawing anti-clockwise
|
|
221
|
+
d += `
|
|
222
|
+
M ${bw}, ${tl2 + bw}
|
|
223
|
+
${rwlf ? `h ${-bw}` : ''}
|
|
224
|
+
v ${h - tl2 - bl2 - bw * 2}
|
|
225
|
+
${rwlf ? `h ${bw}` : ''}
|
|
226
|
+
${nblc ? `l ${-bw} 0` : ''}
|
|
227
|
+
l ${bl2} ${bl2}
|
|
228
|
+
${nblc ? `l ${bw} 0` : ''}
|
|
229
|
+
${rwbf ? `v ${bw}` : ''}
|
|
230
|
+
h ${w - bl2 - br2 - bw * 2}
|
|
231
|
+
${rwbf ? `v ${-bw}` : ''}
|
|
232
|
+
${nbrc ? `l ${bw} 0` : ''}
|
|
233
|
+
l ${br2} ${-br2}
|
|
234
|
+
${nbrc ? `l ${-bw} 0` : ''}
|
|
235
|
+
${rwrf ? `h ${bw}` : ''}
|
|
236
|
+
v ${-h + tl2 + bl2 + bw * 2}
|
|
237
|
+
${rwrf ? `h ${-bw}` : ''}
|
|
238
|
+
${ntrc ? `l 0 ${-bw}` : ''}
|
|
239
|
+
l ${-tr2} ${-tr2}
|
|
240
|
+
${ntrc ? `l 0 ${bw}` : ''}
|
|
241
|
+
${rwtf ? `v ${-bw}` : ''}
|
|
242
|
+
h ${-w + bl2 + br2 + bw * 2}
|
|
243
|
+
${rwtf ? `v ${bw}` : ''}
|
|
244
|
+
${ntlc ? `l 0 ${-bw}` : ''}
|
|
245
|
+
l ${-tl2} ${tl2}
|
|
246
|
+
${ntlc ? `l 0 ${bw}` : ''}
|
|
247
|
+
`;
|
|
248
|
+
break;
|
|
249
|
+
case 'miter':
|
|
250
|
+
// Step 2: Draw shape
|
|
251
|
+
if (hollow) {
|
|
252
|
+
// Step 2-1: This is outer path, drawing clockwise
|
|
253
|
+
d += `
|
|
254
|
+
M 0, 0
|
|
255
|
+
h ${w}
|
|
256
|
+
v ${h}
|
|
257
|
+
h ${0 - w}
|
|
258
|
+
v ${0 - h}
|
|
259
|
+
Z
|
|
260
|
+
`;
|
|
261
|
+
}
|
|
262
|
+
// Step 2-2: This is the inner path, drawing anti-clockwise
|
|
263
|
+
d += `
|
|
264
|
+
M ${bw * wlf}, ${bw * wtf}
|
|
265
|
+
v ${h - wtf * bw - wbf * bw}
|
|
266
|
+
h ${w - wlf * bw - wrf * bw}
|
|
267
|
+
v ${-h + wtf * bw + wbf * bw}
|
|
268
|
+
h ${-w + wlf * bw + wrf * bw}
|
|
269
|
+
`;
|
|
270
|
+
}
|
|
271
|
+
// Step 3: Close the path
|
|
272
|
+
if (c.borderDecorationType === 'miter') {
|
|
273
|
+
d += hollow ? `L ${bw}, ${bw}` : `z`;
|
|
274
|
+
} else {
|
|
275
|
+
d += hollow ? `L ${tl2 + bw}, ${tl2 + bw}` : `z`;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
$target.setAttribute('d', d);
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
syncSizeToElement = (x: SVGSVGElement) => {
|
|
282
|
+
const b = this.cachedBoundingRect;
|
|
283
|
+
const width = x.width.baseVal;
|
|
284
|
+
const height = x.height.baseVal;
|
|
285
|
+
|
|
286
|
+
if (width.value !== b.width || height.value !== b.height) {
|
|
287
|
+
width.value = b.width;
|
|
288
|
+
height.value = b.height;
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
clear = (forAnimation: boolean) => {
|
|
293
|
+
if (!forAnimation) {
|
|
294
|
+
this.internalClear();
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
private internalClear = () => {
|
|
299
|
+
if (!this.dirty) return false;
|
|
300
|
+
|
|
301
|
+
const paths = this.cachedImg.cachedPath;
|
|
302
|
+
|
|
303
|
+
paths.borderReveal.style.fill = 'transparent';
|
|
304
|
+
paths.fillReveal.style.fill = 'transparent';
|
|
305
|
+
paths.rippleReveal.style.fill = 'transparent';
|
|
306
|
+
|
|
307
|
+
this.dirty = false;
|
|
308
|
+
return true;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
paint = (skipSamePointerPositionCheck?: boolean): boolean => {
|
|
312
|
+
const store = this._store;
|
|
313
|
+
|
|
314
|
+
const animationPlaying = store.animationQueue.includes(this);
|
|
315
|
+
const samePosition = store.clientX === store.paintedClientX && store.clientY === store.paintedClientY;
|
|
316
|
+
|
|
317
|
+
if (samePosition && !skipSamePointerPositionCheck && !animationPlaying) {
|
|
318
|
+
return false;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (!store.mouseInBoundary && !animationPlaying) {
|
|
322
|
+
this.internalClear();
|
|
323
|
+
return false;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
this.syncSizeToElement(this.element);
|
|
327
|
+
this.cacheBoundingRect();
|
|
328
|
+
|
|
329
|
+
const b = this.cachedBoundingRect;
|
|
330
|
+
|
|
331
|
+
const relativeX = store.clientX - b.left;
|
|
332
|
+
const relativeY = store.clientY - b.top;
|
|
333
|
+
|
|
334
|
+
if (Number.isNaN(relativeX) || Number.isNaN(relativeY)) {
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const c = this.cachedStyle;
|
|
339
|
+
this.getTrueFillRadius(c.trueFillRadius);
|
|
340
|
+
|
|
341
|
+
this.paintedWidth = b.width;
|
|
342
|
+
this.paintedHeight = b.height;
|
|
343
|
+
|
|
344
|
+
const grads = this.cachedImg.cachedGradient;
|
|
345
|
+
const maxRadius = Math.max(
|
|
346
|
+
grads.borderReveal.r.baseVal.value,
|
|
347
|
+
grads.fillReveal.r.baseVal.value
|
|
348
|
+
);
|
|
349
|
+
|
|
350
|
+
this._store.updateMaxRadius(maxRadius);
|
|
351
|
+
this.cacheCanvasPaintingStyle();
|
|
352
|
+
|
|
353
|
+
if (this.fillDirty) {
|
|
354
|
+
this.updateCachedReveal();
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
const inLeftBound = relativeX + maxRadius > 0;
|
|
358
|
+
const inRightBound = relativeX - maxRadius < b.width;
|
|
359
|
+
const inTopBound = relativeY + maxRadius > 0;
|
|
360
|
+
const inBottomBound = relativeY - maxRadius < b.height;
|
|
361
|
+
const mouseInRenderArea = inLeftBound && inRightBound && inTopBound && inBottomBound;
|
|
362
|
+
|
|
363
|
+
if (!mouseInRenderArea && !animationPlaying) {
|
|
364
|
+
this.internalClear();
|
|
365
|
+
return false;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
this.dirty = true;
|
|
369
|
+
|
|
370
|
+
this.updateGradientPosition(relativeX, relativeY);
|
|
371
|
+
|
|
372
|
+
if (this.shapeDirty) {
|
|
373
|
+
this.drawShape(true, this.cachedImg.cachedPath.borderReveal);
|
|
374
|
+
this.drawShape(false, this.cachedImg.cachedPath.fillReveal);
|
|
375
|
+
this.drawShape(false, this.cachedImg.cachedPath.rippleReveal);
|
|
376
|
+
this.shapeDirty = false;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
if (store.mouseInBoundary) {
|
|
380
|
+
const mouseInElement = relativeX > 0 && relativeY > 0 && relativeX < b.width && relativeY < b.height;
|
|
381
|
+
|
|
382
|
+
if (c.hoverLight && mouseInElement) {
|
|
383
|
+
// draw fill.
|
|
384
|
+
this.cachedImg.cachedPath.fillReveal.style.fill = 'url(#fillGrad)';
|
|
385
|
+
} else if (this.cachedImg.cachedPath.fillReveal.style.fill !== 'transparent') {
|
|
386
|
+
this.cachedImg.cachedPath.fillReveal.style.fill = 'transparent';
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
const diffuse = (c.diffuse && mouseInRenderArea) || mouseInElement;
|
|
390
|
+
if (c.borderWidth !== 0 && diffuse) {
|
|
391
|
+
// Draw border.
|
|
392
|
+
this.cachedImg.cachedPath.borderReveal.style.fill = 'url(#borderGrad)';
|
|
393
|
+
} else if (this.cachedImg.cachedPath.borderReveal.style.fill !== 'transparent') {
|
|
394
|
+
this.cachedImg.cachedPath.borderReveal.style.fill = 'transparent';
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (c.pressAnimation && this.mousePressed && this.mouseDownAnimateLogicFrame) {
|
|
399
|
+
const grdRadius =
|
|
400
|
+
c.pressAnimationFillMode === 'constrained' ? c.trueFillRadius[1] : Math.max(b.width, b.height);
|
|
401
|
+
|
|
402
|
+
this.mouseReleased && this.mouseUpClientX && this.mouseUpClientY
|
|
403
|
+
? this.updateAnimateGrd(
|
|
404
|
+
this.mouseDownAnimateLogicFrame,
|
|
405
|
+
this.mouseUpClientX - b.left,
|
|
406
|
+
this.mouseUpClientY - b.top,
|
|
407
|
+
grdRadius
|
|
408
|
+
)
|
|
409
|
+
: this.updateAnimateGrd(
|
|
410
|
+
this.mouseDownAnimateLogicFrame,
|
|
411
|
+
relativeX,
|
|
412
|
+
relativeY,
|
|
413
|
+
grdRadius
|
|
414
|
+
)
|
|
415
|
+
this.cachedImg.cachedPath.rippleReveal.style.fill = 'url(#rippleGrad)';
|
|
416
|
+
} else if (this.cachedImg.cachedPath.rippleReveal.style.fill !== 'transparent') {
|
|
417
|
+
this.cachedImg.cachedPath.rippleReveal.style.fill = 'transparent';
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
return true;
|
|
421
|
+
};
|
|
422
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AxRevealProvider, AxRevealBoundary, AxReveal } from './CustomElements.js';
|
|
1
|
+
import { AxRevealProvider, AxRevealBoundary, AxReveal, AxRevealNg } from './CustomElements.js';
|
|
2
2
|
import { config } from './config.js';
|
|
3
3
|
import { MAGIC_DEFAULT_COLOR } from './variables.js';
|
|
4
4
|
|
|
@@ -6,6 +6,7 @@ function registerCustomElements() {
|
|
|
6
6
|
customElements.define(AxRevealProvider.ElementName, AxRevealProvider);
|
|
7
7
|
customElements.define(AxRevealBoundary.ElementName, AxRevealBoundary);
|
|
8
8
|
customElements.define(AxReveal.ElementName, AxReveal);
|
|
9
|
+
customElements.define(AxRevealNg.ElementName, AxRevealNg);
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
export interface AxRevealHighlightRegisterOptions {
|
|
@@ -41,12 +42,6 @@ export function register({
|
|
|
41
42
|
initialValue: '0.26',
|
|
42
43
|
inherits: true,
|
|
43
44
|
});
|
|
44
|
-
window.CSS.registerProperty({
|
|
45
|
-
name: '--reveal-border-style',
|
|
46
|
-
syntax: '<custom-ident>',
|
|
47
|
-
initialValue: 'full',
|
|
48
|
-
inherits: true,
|
|
49
|
-
});
|
|
50
45
|
window.CSS.registerProperty({
|
|
51
46
|
name: '--reveal-border-color',
|
|
52
47
|
syntax: `<color>|${MAGIC_DEFAULT_COLOR}`,
|
|
@@ -102,25 +97,25 @@ export function register({
|
|
|
102
97
|
inherits: true,
|
|
103
98
|
});
|
|
104
99
|
window.CSS.registerProperty({
|
|
105
|
-
name: '--reveal-border-left',
|
|
100
|
+
name: '--reveal-border-left-type',
|
|
106
101
|
syntax: '<custom-ident>',
|
|
107
102
|
initialValue: 'line',
|
|
108
103
|
inherits: true,
|
|
109
104
|
});
|
|
110
105
|
window.CSS.registerProperty({
|
|
111
|
-
name: '--reveal-border-right',
|
|
106
|
+
name: '--reveal-border-right-type',
|
|
112
107
|
syntax: '<custom-ident>',
|
|
113
108
|
initialValue: 'line',
|
|
114
109
|
inherits: true,
|
|
115
110
|
});
|
|
116
111
|
window.CSS.registerProperty({
|
|
117
|
-
name: '--reveal-border-top',
|
|
112
|
+
name: '--reveal-border-top-type',
|
|
118
113
|
syntax: '<custom-ident>',
|
|
119
114
|
initialValue: 'line',
|
|
120
115
|
inherits: true,
|
|
121
116
|
});
|
|
122
117
|
window.CSS.registerProperty({
|
|
123
|
-
name: '--reveal-border-bottom',
|
|
118
|
+
name: '--reveal-border-bottom-type',
|
|
124
119
|
syntax: '<custom-ident>',
|
|
125
120
|
initialValue: 'line',
|
|
126
121
|
inherits: true,
|
|
@@ -192,7 +187,6 @@ export function register({
|
|
|
192
187
|
|
|
193
188
|
root.style.setProperty('--reveal-color', 'rgb(0, 0, 0)');
|
|
194
189
|
root.style.setProperty('--reveal-opacity', '0.26');
|
|
195
|
-
root.style.setProperty('--reveal-border-style', 'full');
|
|
196
190
|
root.style.setProperty('--reveal-border-color', MAGIC_DEFAULT_COLOR);
|
|
197
191
|
root.style.setProperty('--reveal-border-width', '1px');
|
|
198
192
|
root.style.setProperty('--reveal-border-fill-radius', '1.5');
|
|
@@ -202,10 +196,10 @@ export function register({
|
|
|
202
196
|
root.style.setProperty('--reveal-border-decoration-top-right-radius', '-1');
|
|
203
197
|
root.style.setProperty('--reveal-border-decoration-bottom-left-radius', '-1');
|
|
204
198
|
root.style.setProperty('--reveal-border-decoration-bottom-right-radius', '-1');
|
|
205
|
-
root.style.setProperty('--reveal-border-left', 'line');
|
|
206
|
-
root.style.setProperty('--reveal-border-right', 'line');
|
|
207
|
-
root.style.setProperty('--reveal-border-top', 'line');
|
|
208
|
-
root.style.setProperty('--reveal-border-bottom', 'line');
|
|
199
|
+
root.style.setProperty('--reveal-border-left-type', 'line');
|
|
200
|
+
root.style.setProperty('--reveal-border-right-type', 'line');
|
|
201
|
+
root.style.setProperty('--reveal-border-top-type', 'line');
|
|
202
|
+
root.style.setProperty('--reveal-border-bottom-type', 'line');
|
|
209
203
|
root.style.setProperty('--reveal-hover-light', 'true');
|
|
210
204
|
root.style.setProperty('--reveal-hover-light-color', MAGIC_DEFAULT_COLOR);
|
|
211
205
|
root.style.setProperty('--reveal-hover-light-fill-radius', '1.5');
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export const extractRGBValue = (x: string) => {
|
|
2
|
+
if (x === '') {
|
|
3
|
+
return '';
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
if (x[0] === '#') {
|
|
7
|
+
// Thanks bro:
|
|
8
|
+
// https://stackoverflow.com/a/11508164/3931936
|
|
9
|
+
const hexVal = parseInt(x.substring(1), 16);
|
|
10
|
+
|
|
11
|
+
var r = (hexVal >> 16) & 255;
|
|
12
|
+
var g = (hexVal >> 8) & 255;
|
|
13
|
+
var b = hexVal & 255;
|
|
14
|
+
|
|
15
|
+
return r + ',' + g + ',' + b;
|
|
16
|
+
} else {
|
|
17
|
+
let result = '';
|
|
18
|
+
let beginSearch = false;
|
|
19
|
+
let numberPointer = 0;
|
|
20
|
+
|
|
21
|
+
for (let i = 0; i < x.length; i++) {
|
|
22
|
+
const char = x[i];
|
|
23
|
+
const charCode = char.charCodeAt(0) - 48;
|
|
24
|
+
const charIsNumber = charCode >= 0 && charCode < 10;
|
|
25
|
+
|
|
26
|
+
if (char === ' ') {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (beginSearch && !charIsNumber && char !== ',' && char !== ')') {
|
|
31
|
+
throw new SyntaxError(`${x} is not a validate color value!`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (!beginSearch && char === '(') {
|
|
35
|
+
beginSearch = true;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (numberPointer < 2 && char === ')') {
|
|
40
|
+
throw new SyntaxError(`${x} should have at least three color channel`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (char === ',') {
|
|
44
|
+
numberPointer++;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (char === ')') {
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (beginSearch) {
|
|
52
|
+
result += char;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
export type BorderDecoration = 'round' | 'bevel' | 'miter';
|
|
2
|
+
|
|
3
|
+
export interface CachedBoundingRect {
|
|
4
|
+
top: number;
|
|
5
|
+
left: number;
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface CachedStyle {
|
|
11
|
+
color: string;
|
|
12
|
+
opacity: number;
|
|
13
|
+
trueFillRadius: [number, number];
|
|
14
|
+
borderColor: string;
|
|
15
|
+
borderFillRadius: number;
|
|
16
|
+
borderDecorationType: BorderDecoration;
|
|
17
|
+
borderDecorationRadius: number;
|
|
18
|
+
topLeftBorderDecorationRadius: number;
|
|
19
|
+
topRightBorderDecorationRadius: number;
|
|
20
|
+
bottomLeftBorderDecorationRadius: number;
|
|
21
|
+
bottomRightBorderDecorationRadius: number;
|
|
22
|
+
/**
|
|
23
|
+
* @param withLeftBorderFactor
|
|
24
|
+
* If the left border is shown, this value is 1, or the value is 0.
|
|
25
|
+
*/
|
|
26
|
+
withLeftBorderFactor: number;
|
|
27
|
+
/**
|
|
28
|
+
* @param withRightBorderFactor
|
|
29
|
+
* If the right border is shown, this value is 1, or the value is 0.
|
|
30
|
+
*/
|
|
31
|
+
withRightBorderFactor: number;
|
|
32
|
+
/**
|
|
33
|
+
* @param withTopBorderFactor
|
|
34
|
+
* If the top border is shown, this value is 1, or the value is 0.
|
|
35
|
+
*/
|
|
36
|
+
withTopBorderFactor: number;
|
|
37
|
+
/**
|
|
38
|
+
* @param withBottomBorderFactor
|
|
39
|
+
* If the bottom border is shown, this value is 1, or the value is 0.
|
|
40
|
+
*/
|
|
41
|
+
withBottomBorderFactor: number;
|
|
42
|
+
borderWidth: number;
|
|
43
|
+
hoverLight: boolean;
|
|
44
|
+
hoverLightColor: string;
|
|
45
|
+
hoverLightFillMode: string;
|
|
46
|
+
hoverLightFillRadius: number;
|
|
47
|
+
diffuse: boolean;
|
|
48
|
+
pressAnimation: boolean;
|
|
49
|
+
pressAnimationFillMode: string;
|
|
50
|
+
pressAnimationColor: string;
|
|
51
|
+
pressAnimationSpeed: number;
|
|
52
|
+
releaseAnimationAccelerateRate: number;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
interface CachedReveal {
|
|
56
|
+
radius: number;
|
|
57
|
+
radiusFactor: number;
|
|
58
|
+
color: string;
|
|
59
|
+
opacity: number;
|
|
60
|
+
pattern: CanvasPattern | null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Cached border and body pattern, for faster painting on the canvas.
|
|
65
|
+
* @interface CachedRevealBitmap
|
|
66
|
+
*/
|
|
67
|
+
export interface CachedRevealBitmap {
|
|
68
|
+
cachedReveal: {
|
|
69
|
+
borderReveal: CachedReveal;
|
|
70
|
+
fillReveal: CachedReveal;
|
|
71
|
+
};
|
|
72
|
+
cachedCanvas: {
|
|
73
|
+
borderReveal: HTMLCanvasElement;
|
|
74
|
+
fillReveal: HTMLCanvasElement;
|
|
75
|
+
};
|
|
76
|
+
cachedCtx: {
|
|
77
|
+
borderReveal: CanvasRenderingContext2D | null;
|
|
78
|
+
fillReveal: CanvasRenderingContext2D | null;
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Cached border and body pattern, just to store something in similar way.
|
|
84
|
+
* @interface CachedRevealPath
|
|
85
|
+
*/
|
|
86
|
+
export interface CachedRevealPath {
|
|
87
|
+
cachedReveal: {
|
|
88
|
+
readonly borderReveal: CachedReveal;
|
|
89
|
+
readonly fillReveal: CachedReveal;
|
|
90
|
+
};
|
|
91
|
+
cachedPath: {
|
|
92
|
+
readonly borderReveal: SVGPathElement;
|
|
93
|
+
readonly fillReveal: SVGPathElement;
|
|
94
|
+
readonly rippleReveal: SVGPathElement;
|
|
95
|
+
};
|
|
96
|
+
cachedGradient: {
|
|
97
|
+
readonly borderReveal: SVGRadialGradientElement;
|
|
98
|
+
readonly fillReveal: SVGRadialGradientElement;
|
|
99
|
+
readonly rippleReveal: SVGRadialGradientElement;
|
|
100
|
+
};
|
|
101
|
+
cachedGradientStop: {
|
|
102
|
+
readonly borderReveal: Readonly<[SVGStopElement, SVGStopElement]>;
|
|
103
|
+
readonly fillReveal: Readonly<[SVGStopElement, SVGStopElement]>;
|
|
104
|
+
readonly rippleReveal: Readonly<[SVGStopElement, SVGStopElement, SVGStopElement]>;
|
|
105
|
+
};
|
|
106
|
+
}
|