@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.
- package/LICENSE +21 -21
- package/README.md +76 -235
- 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 +130 -33
- 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 +35 -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 +12 -18
- 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 +34 -30
- package/src/BaseConfig.ts +311 -0
- package/src/CanvasConfig.ts +415 -729
- package/src/ComputedStyleStorage.ts +89 -89
- package/src/CustomElements.ts +272 -164
- package/src/Profiler.ts +44 -44
- package/src/RevealBoundryStore.ts +291 -192
- package/src/RevealStateManager.ts +78 -48
- package/src/SvgConfig.ts +422 -0
- package/src/config.ts +26 -26
- package/src/cssTypedOM.d.ts +52 -52
- package/src/index.ts +219 -225
- package/src/utils/extractRGBValue.ts +58 -0
- package/src/utils/isValidateBorderDecorationType.ts +8 -0
- package/src/utils/types.ts +106 -0
- package/src/variables.ts +1 -1
- package/.prettierrc +0 -6
- package/.travis.yml +0 -26
- package/.yarnrc.yml +0 -1
- package/docs/demo/debug.html +0 -75
- 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 -40
- 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
|
@@ -1,48 +1,78 @@
|
|
|
1
|
-
import { RevealBoundaryStore } from './RevealBoundryStore.js';
|
|
2
|
-
|
|
3
|
-
import { config } from './config.js';
|
|
4
|
-
|
|
5
|
-
export class RevealStateManager {
|
|
6
|
-
private _currentHashId = 0;
|
|
7
|
-
private _storage: RevealBoundaryStore[] = [];
|
|
8
|
-
|
|
9
|
-
private requestedTraverseBoundaries = false;
|
|
10
|
-
cachedMouseX = -1;
|
|
11
|
-
cachedMouseY = -1;
|
|
12
|
-
|
|
13
|
-
constructor() {
|
|
14
|
-
if (config.borderDetectionMode === 'experimentalAutoFit') {
|
|
15
|
-
if (typeof Window === 'undefined') return;
|
|
16
|
-
|
|
17
|
-
window.addEventListener('pointermove',
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
|
|
1
|
+
import { RevealBoundaryStore } from './RevealBoundryStore.js';
|
|
2
|
+
|
|
3
|
+
import { config } from './config.js';
|
|
4
|
+
|
|
5
|
+
export class RevealStateManager {
|
|
6
|
+
private _currentHashId = 0;
|
|
7
|
+
private _storage: RevealBoundaryStore[] = [];
|
|
8
|
+
|
|
9
|
+
private requestedTraverseBoundaries = false;
|
|
10
|
+
cachedMouseX = -1;
|
|
11
|
+
cachedMouseY = -1;
|
|
12
|
+
|
|
13
|
+
constructor() {
|
|
14
|
+
if (config.borderDetectionMode === 'experimentalAutoFit') {
|
|
15
|
+
if (typeof Window === 'undefined') return;
|
|
16
|
+
|
|
17
|
+
window.addEventListener('pointermove', this.handlePointerMove);
|
|
18
|
+
// This is for touch screen
|
|
19
|
+
// Window.pointerleave won't be triggered if the finger
|
|
20
|
+
// leave the screen, so we use pointer up here.
|
|
21
|
+
window.addEventListener('pointerup', (ev) => {
|
|
22
|
+
if (ev.pointerType !== 'mouse') this.handlePointerLeave();
|
|
23
|
+
});
|
|
24
|
+
// This is for desktop
|
|
25
|
+
// If the mouse leave the window, we need to terminate
|
|
26
|
+
// all animations and clean up the canvas.
|
|
27
|
+
window.addEventListener('pointerleave', (ev) => {
|
|
28
|
+
if (ev.pointerType === 'mouse') this.handlePointerLeave();
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
pointerLeaveScheduled = false;
|
|
34
|
+
|
|
35
|
+
handlePointerLeave = () => {
|
|
36
|
+
if (this.pointerLeaveScheduled) return;
|
|
37
|
+
|
|
38
|
+
this.pointerLeaveScheduled = true;
|
|
39
|
+
|
|
40
|
+
window.requestAnimationFrame(() => {
|
|
41
|
+
for (let i = 0; i < this._storage.length; i++) {
|
|
42
|
+
this._storage[i].onPointerLeaveBoundary();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
this.pointerLeaveScheduled = false;
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
handlePointerMove = (event: PointerEvent) => {
|
|
50
|
+
this.cachedMouseX = event.clientX;
|
|
51
|
+
this.cachedMouseY = event.clientY;
|
|
52
|
+
|
|
53
|
+
if (!this.requestedTraverseBoundaries) {
|
|
54
|
+
window.requestAnimationFrame(this.traverseBoundaries);
|
|
55
|
+
this.requestedTraverseBoundaries = true;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
traverseBoundaries = () => {
|
|
60
|
+
this.requestedTraverseBoundaries = false;
|
|
61
|
+
for (let i = 0; i < this._storage.length; i++) {
|
|
62
|
+
this._storage[i].onPointerMoveOnScreen(this.cachedMouseX, this.cachedMouseY);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
newBoundary = ($el: HTMLElement) => {
|
|
67
|
+
const hashId = this._currentHashId++;
|
|
68
|
+
|
|
69
|
+
const store = new RevealBoundaryStore(hashId, $el);
|
|
70
|
+
this._storage.push(store);
|
|
71
|
+
|
|
72
|
+
return store;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
removeBoundary = (store: RevealBoundaryStore) => {
|
|
76
|
+
this._storage = this._storage.filter((x) => x !== store);
|
|
77
|
+
};
|
|
78
|
+
}
|
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/config.ts
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
let borderDetectionMode: 'strictEdge' | 'experimentalAutoFit' = 'strictEdge';
|
|
2
|
-
|
|
3
|
-
let borderDetectionModeInitialized = false;
|
|
4
|
-
|
|
5
|
-
class InitializedError extends Error {
|
|
6
|
-
name = 'InitializedError';
|
|
7
|
-
|
|
8
|
-
constructor() {
|
|
9
|
-
super('Border detection mode has already been initialized.')
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export const config = {
|
|
14
|
-
compat: false,
|
|
15
|
-
|
|
16
|
-
get borderDetectionMode() {
|
|
17
|
-
return borderDetectionMode
|
|
18
|
-
},
|
|
19
|
-
set borderDetectionMode(x) {
|
|
20
|
-
if (borderDetectionModeInitialized) {
|
|
21
|
-
throw new InitializedError;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
borderDetectionMode = x;
|
|
25
|
-
borderDetectionModeInitialized = true;
|
|
26
|
-
}
|
|
1
|
+
let borderDetectionMode: 'strictEdge' | 'experimentalAutoFit' = 'strictEdge';
|
|
2
|
+
|
|
3
|
+
let borderDetectionModeInitialized = false;
|
|
4
|
+
|
|
5
|
+
class InitializedError extends Error {
|
|
6
|
+
name = 'InitializedError';
|
|
7
|
+
|
|
8
|
+
constructor() {
|
|
9
|
+
super('Border detection mode has already been initialized.')
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const config = {
|
|
14
|
+
compat: false,
|
|
15
|
+
|
|
16
|
+
get borderDetectionMode() {
|
|
17
|
+
return borderDetectionMode
|
|
18
|
+
},
|
|
19
|
+
set borderDetectionMode(x) {
|
|
20
|
+
if (borderDetectionModeInitialized) {
|
|
21
|
+
throw new InitializedError;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
borderDetectionMode = x;
|
|
25
|
+
borderDetectionModeInitialized = true;
|
|
26
|
+
}
|
|
27
27
|
}
|