@ax-design/reveal-highlight 0.5.2 → 0.5.3

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 (74) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +75 -75
  3. package/build/BaseConfig.d.ts +5 -1
  4. package/build/BaseConfig.d.ts.map +1 -1
  5. package/build/CanvasConfig.d.ts +7 -1
  6. package/build/CanvasConfig.d.ts.map +1 -1
  7. package/build/ComputedStyleStorage.d.ts.map +1 -1
  8. package/build/CustomElements.d.ts +20 -4
  9. package/build/CustomElements.d.ts.map +1 -1
  10. package/build/RevealBoundryStore.d.ts +4 -0
  11. package/build/RevealBoundryStore.d.ts.map +1 -1
  12. package/build/RevealStateManager.d.ts +5 -1
  13. package/build/RevealStateManager.d.ts.map +1 -1
  14. package/build/main.js +113 -82
  15. package/build/utils/types.d.ts +2 -10
  16. package/build/utils/types.d.ts.map +1 -1
  17. package/es/BaseConfig.d.ts +46 -42
  18. package/es/BaseConfig.d.ts.map +1 -1
  19. package/es/BaseConfig.js +241 -219
  20. package/es/BaseConfig.js.map +1 -1
  21. package/es/CanvasConfig.d.ts +21 -15
  22. package/es/CanvasConfig.d.ts.map +1 -1
  23. package/es/CanvasConfig.js +332 -320
  24. package/es/CanvasConfig.js.map +1 -1
  25. package/es/ComputedStyleStorage.d.ts +8 -8
  26. package/es/ComputedStyleStorage.d.ts.map +1 -1
  27. package/es/ComputedStyleStorage.js +68 -58
  28. package/es/ComputedStyleStorage.js.map +1 -1
  29. package/es/CustomElements.d.ts +75 -59
  30. package/es/CustomElements.d.ts.map +1 -1
  31. package/es/CustomElements.js +296 -233
  32. package/es/CustomElements.js.map +1 -1
  33. package/es/Profiler.d.ts +12 -12
  34. package/es/Profiler.js +31 -31
  35. package/es/RevealBoundryStore.d.ts +80 -76
  36. package/es/RevealBoundryStore.d.ts.map +1 -1
  37. package/es/RevealBoundryStore.js +269 -248
  38. package/es/RevealBoundryStore.js.map +1 -1
  39. package/es/RevealStateManager.d.ts +19 -15
  40. package/es/RevealStateManager.d.ts.map +1 -1
  41. package/es/RevealStateManager.js +99 -73
  42. package/es/RevealStateManager.js.map +1 -1
  43. package/es/SvgConfig.d.ts +16 -16
  44. package/es/SvgConfig.js +345 -345
  45. package/es/config.d.ts +4 -4
  46. package/es/config.js +21 -21
  47. package/es/index.d.ts +5 -5
  48. package/es/index.js +205 -205
  49. package/es/tsconfig.tsbuildinfo +1 -1
  50. package/es/utils/extractRGBValue.d.ts +1 -1
  51. package/es/utils/extractRGBValue.js +47 -47
  52. package/es/utils/isValidateBorderDecorationType.d.ts +2 -2
  53. package/es/utils/isValidateBorderDecorationType.js +9 -9
  54. package/es/utils/types.d.ts +94 -102
  55. package/es/utils/types.d.ts.map +1 -1
  56. package/es/utils/types.js +1 -1
  57. package/es/variables.d.ts +1 -1
  58. package/es/variables.js +1 -1
  59. package/package.json +36 -35
  60. package/src/BaseConfig.ts +332 -310
  61. package/src/CanvasConfig.ts +420 -415
  62. package/src/ComputedStyleStorage.ts +102 -89
  63. package/src/CustomElements.ts +344 -272
  64. package/src/Profiler.ts +44 -44
  65. package/src/RevealBoundryStore.ts +315 -291
  66. package/src/RevealStateManager.ts +109 -86
  67. package/src/SvgConfig.ts +422 -422
  68. package/src/config.ts +26 -26
  69. package/src/cssTypedOM.d.ts +52 -52
  70. package/src/index.ts +219 -219
  71. package/src/utils/extractRGBValue.ts +58 -58
  72. package/src/utils/isValidateBorderDecorationType.ts +8 -8
  73. package/src/utils/types.ts +97 -105
  74. package/src/variables.ts +1 -1
@@ -1,321 +1,333 @@
1
- import { BaseConfig } from './BaseConfig.js';
2
- const createEmptyCanvas = () => document.createElement('canvas');
3
- export class CanvasConfig extends BaseConfig {
4
- constructor(store, $canvas, $container) {
5
- super(store, $canvas, $container);
6
- this.updateCachedReveal = () => {
7
- if (!this.fillDirty)
8
- return;
9
- const c = this.cachedStyle;
10
- const radius = c.trueFillRadius[1] * this.pxRatio;
11
- const size = radius * 2;
12
- const lastStyle = this.cachedImg.cachedReveal;
13
- const { borderReveal, fillReveal } = this.cachedImg.cachedCanvas;
14
- const { borderReveal: borderRevealCtx, fillReveal: fillRevealCtx } = this.cachedImg.cachedCtx;
15
- this._store.updateMaxRadius(c.trueFillRadius[1] * c.borderFillRadius);
16
- for (let i = 0; i < 2; i++) {
17
- // 0 means border, 1 means hover light.
18
- //-----------------------------------------
19
- // Last rendered style.
20
- const ls = i === 0 ? lastStyle.borderReveal : lastStyle.fillReveal;
21
- const color = i === 0 ? c.borderColor : c.hoverLightColor;
22
- const fillRadiusFactor = i === 0 ? c.borderFillRadius : c.hoverLightFillRadius;
23
- const doNotNeedUpdateReveal = color === ls.color && c.opacity === ls.opacity && fillRadiusFactor === ls.radiusFactor;
24
- if (doNotNeedUpdateReveal)
25
- continue;
26
- const reveal = i === 0 ? borderReveal : fillReveal;
27
- const ctx = i === 0 ? borderRevealCtx : fillRevealCtx;
28
- this.syncSizeToRevealRadius(reveal, fillRadiusFactor);
29
- if (!ctx)
30
- continue;
31
- ctx.clearRect(0, 0, reveal.width, reveal.height);
32
- const fillAlpha = i === 0 ? c.opacity : c.opacity * 0.5;
33
- const trueRadius = radius * fillRadiusFactor;
34
- const grd = ctx.createRadialGradient(trueRadius, trueRadius, 0, trueRadius, trueRadius, trueRadius);
35
- grd.addColorStop(0, `rgba(${color}, ${fillAlpha})`);
36
- grd.addColorStop(1, `rgba(${color}, 0.0)`);
37
- const trueSize = size * fillRadiusFactor;
38
- ctx.fillStyle = grd;
39
- ctx.clearRect(0, 0, trueSize, trueSize);
40
- ctx.fillRect(0, 0, trueSize, trueSize);
41
- ls.radius = trueRadius;
42
- ls.radiusFactor = fillRadiusFactor;
43
- ls.color = color;
44
- ls.opacity = c.opacity;
45
- if (!this.ctx)
46
- continue;
47
- ls.pattern = this.ctx.createPattern(reveal, 'no-repeat');
48
- }
49
- this.fillDirty = false;
50
- };
51
- this.updateCachedBitmap = () => {
52
- if (!this.ctx)
53
- return;
54
- this.updateCachedReveal();
55
- };
56
- this.updateAnimateGrd = (frame, grd) => {
57
- const { pressAnimationColor, opacity } = this.cachedStyle;
58
- const _innerAlpha = opacity * (0.2 - frame);
59
- const _outerAlpha = opacity * (0.1 - frame * 0.07);
60
- const _outerBorder = 0.1 + frame * 0.8;
61
- const innerAlpha = _innerAlpha < 0 ? 0 : _innerAlpha;
62
- const outerAlpha = _outerAlpha < 0 ? 0 : _outerAlpha;
63
- let outerBorder = 0;
64
- outerBorder = _outerBorder > 1 ? 1 : _outerBorder;
65
- outerBorder = _outerBorder < 0 ? 0 : _outerBorder;
66
- grd.addColorStop(0, `rgba(${pressAnimationColor},${innerAlpha})`);
67
- grd.addColorStop(outerBorder * 0.55, `rgba(${pressAnimationColor},${outerAlpha})`);
68
- grd.addColorStop(outerBorder, `rgba(${pressAnimationColor}, 0)`);
69
- };
70
- this.drawShape = (hollow) => {
71
- if (!this.ctx)
72
- return;
73
- const b = this.cachedBoundingRect;
74
- const w = b.width * this.pxRatio;
75
- const h = b.height * this.pxRatio;
76
- const c = this.cachedStyle;
77
- const bw = c.borderWidth * this.pxRatio;
78
- const tl = c.topLeftBorderDecorationRadius * this.pxRatio;
79
- const tr = c.topRightBorderDecorationRadius * this.pxRatio;
80
- const bl = c.bottomLeftBorderDecorationRadius * this.pxRatio;
81
- const br = c.bottomRightBorderDecorationRadius * this.pxRatio;
82
- const wlf = c.withLeftBorderFactor;
83
- const wrf = c.withRightBorderFactor;
84
- const wtf = c.withTopBorderFactor;
85
- const wbf = c.withBottomBorderFactor;
86
- const tl2 = bw < tl ? tl - bw : 0;
87
- const tr2 = bw < tr ? tr - bw : 0;
88
- const bl2 = bw < bl ? bl - bw : 0;
89
- const br2 = bw < br ? br - bw : 0;
90
- this.ctx.beginPath();
91
- switch (c.borderDecorationType) {
92
- // Oh... Fuck... It's painful...
93
- case 'round':
94
- // outer
95
- this.ctx.moveTo(tl, 0);
96
- this.ctx.arcTo(w, 0, w, h, tr);
97
- this.ctx.lineTo(w, h - br);
98
- this.ctx.arcTo(w, h, br, h, br);
99
- this.ctx.lineTo(bl, h);
100
- this.ctx.arcTo(0, h, 0, br, bl);
101
- this.ctx.lineTo(0, tl);
102
- this.ctx.arcTo(0, 0, tl, 0, tl);
103
- if (hollow) {
104
- /* prettier-ignore-start */
105
- // inner
106
- /**
107
- +-①----⑧-+
108
- ② ⑦
109
- | |
110
- ③ ⑥
111
- +-④----⑤-+
112
- */
113
- // x y r p
114
- this.ctx.moveTo(tl2, bw * wtf); // ①
115
- this.ctx.arcTo(bw * wlf, bw * wtf, bw * wlf, tl2 + bw * wtf, tl2); // ②
116
- this.ctx.lineTo(bw * wlf, h - bw * wbf - bl2); // ③
117
- this.ctx.arcTo(bw * wlf, h - bw * wbf, bw * wlf + bl2, h - bw * wbf, bl2); // ④
118
- this.ctx.lineTo(w - bw * wrf - br2, h - bw * wbf); // ⑤
119
- this.ctx.arcTo(w - bw * wrf, h - bw * wbf, w - bw * wrf, h - bw * wbf - br2, br2); // ⑥
120
- this.ctx.lineTo(w - bw * wrf, bw * wtf + tr2); // ⑦
121
- this.ctx.arcTo(w - bw * wrf, bw * wtf, w - bw * wrf - tr2, bw * wtf, tr2); // ⑧
122
- this.ctx.lineTo(tl2, bw * wtf); // ①
123
- /* prettier-ignore-end */
124
- }
125
- break;
126
- case 'bevel':
127
- // outer
128
- this.ctx.moveTo(tl, 0);
129
- this.ctx.lineTo(w - tr, 0);
130
- this.ctx.lineTo(w, tr);
131
- this.ctx.lineTo(w, h - br);
132
- this.ctx.lineTo(w - br, h);
133
- this.ctx.lineTo(bl, h);
134
- this.ctx.lineTo(0, h - bl);
135
- this.ctx.lineTo(0, tl);
136
- this.ctx.lineTo(tl, 0);
137
- this.ctx.lineTo(w - tr, 0);
138
- if (hollow) {
139
- // inner
140
- /**
141
- +-①----⑧-+
142
- ② ⑦
143
- | |
144
- ③ ⑥
145
- +-④----⑤-+
146
- */
147
- // x y p
148
- this.ctx.moveTo(tl2 + bw * wlf, bw * wtf); // ①
149
- this.ctx.lineTo(bw * wlf, tl2 + bw * wtf); // ②
150
- this.ctx.lineTo(bw * wlf, h - bl2 - bw * wbf); // ③
151
- this.ctx.lineTo(bw * wlf + bl2, h - bw * wbf); // ④
152
- this.ctx.lineTo(w - br2 - bw * wrf, h - bw * wbf); // ⑤
153
- this.ctx.lineTo(w - bw * wrf, h - br2 - bw * wbf); // ⑥
154
- this.ctx.lineTo(w - bw * wrf, tr2 + bw * wtf); // ⑦
155
- this.ctx.lineTo(w - tr2 - bw * wrf, bw * wtf); // ⑧
156
- this.ctx.lineTo(tl2 + bw * wrf, bw * wtf); // ①
157
- }
158
- break;
159
- case 'miter':
160
- // outer
161
- this.ctx.moveTo(0, 0);
162
- this.ctx.lineTo(w, 0);
163
- this.ctx.lineTo(w, h);
164
- this.ctx.lineTo(0, h);
165
- this.ctx.lineTo(0, 0);
166
- if (hollow) {
167
- // inner
168
- /**
169
- ①--------④
170
- | |
171
- | |
172
- | |
173
- ②--------③
174
- */
175
- // x y p
176
- this.ctx.moveTo(bw * wlf, bw * wtf); // ①
177
- this.ctx.lineTo(bw * wlf, h - bw * wbf); // ②
178
- this.ctx.lineTo(w - bw * wrf, h - bw * wbf); // ③
179
- this.ctx.lineTo(w - bw * wrf, bw * wtf); // ④
180
- this.ctx.lineTo(bw * wlf, bw * wtf); // ①
181
- }
182
- break;
183
- default:
184
- }
185
- this.ctx.closePath();
186
- };
187
- this.syncSizeToElement = (x) => {
188
- const b = this.cachedBoundingRect;
189
- if (x.width !== b.width || x.height !== b.height) {
190
- x.width = b.width * this.pxRatio;
191
- x.height = b.height * this.pxRatio;
192
- x.style.width = `${b.width}px`;
193
- x.style.height = `${b.height}px`;
194
- }
195
- };
196
- this.clear = () => {
197
- if (!this.ctx)
198
- return false;
199
- if (!this.dirty)
200
- return false;
201
- const { width, height } = this.cachedBoundingRect;
202
- this.ctx.setTransform(1, 0, 0, 1, 0, 0);
203
- this.ctx.clearRect(0, 0, width * window.devicePixelRatio, height * window.devicePixelRatio);
204
- this.dirty = false;
205
- return true;
206
- };
207
- this.paint = (skipSamePointerPositionCheck) => {
208
- const store = this._store;
209
- const animationPlaying = store.animationQueue.includes(this);
210
- const samePosition = store.clientX === store.paintedClientX && store.clientY === store.paintedClientY;
211
- if (samePosition && !skipSamePointerPositionCheck && !animationPlaying) {
212
- return false;
213
- }
214
- if (!this.ctx)
215
- return false;
216
- this.dirty = true;
217
- this.ctx.setTransform(1, 0, 0, 1, 0, 0);
218
- this.ctx.clearRect(0, 0, this.paintedWidth, this.paintedHeight);
219
- if (!store.mouseInBoundary && !animationPlaying) {
220
- return false;
221
- }
222
- if (!this.cachedImg.cachedReveal) {
223
- return false;
224
- }
225
- this.syncSizeToElement(this.element);
226
- this.cacheBoundingRect();
227
- const b = this.cachedBoundingRect;
228
- const relativeX = store.clientX - b.left;
229
- const relativeY = store.clientY - b.top;
230
- if (Number.isNaN(relativeX) || Number.isNaN(relativeY)) {
231
- return false;
232
- }
233
- const c = this.cachedStyle;
234
- this.getTrueFillRadius(c.trueFillRadius);
235
- this.paintedWidth = b.width * this.pxRatio;
236
- this.paintedHeight = b.height * this.pxRatio;
237
- const maxRadius = c.trueFillRadius[1];
238
- const inLeftBound = relativeX + maxRadius > 0;
239
- const inRightBound = relativeX - maxRadius < b.width;
240
- const inTopBound = relativeY + maxRadius > 0;
241
- const inBottomBound = relativeY - maxRadius < b.height;
242
- const mouseInRenderArea = inLeftBound && inRightBound && inTopBound && inBottomBound;
243
- if (!mouseInRenderArea && !animationPlaying) {
244
- return false;
245
- }
246
- this.cacheCanvasPaintingStyle();
247
- this.updateCachedBitmap();
248
- if (store.mouseInBoundary) {
249
- const mouseInCanvas = relativeX > 0 && relativeY > 0 && relativeX < b.width && relativeY < b.height;
250
- const fillPattern = this.cachedImg.cachedReveal.fillReveal.pattern;
251
- if (c.hoverLight && mouseInCanvas && fillPattern) {
252
- // draw fill.
253
- const radius = this.cachedImg.cachedReveal.fillReveal.radius;
254
- const putX = Math.floor(relativeX * this.pxRatio - radius);
255
- const putY = Math.floor(relativeY * this.pxRatio - radius);
256
- this.ctx.setTransform(1, 0, 0, 1, 0, 0);
257
- this.drawShape(false);
258
- this.ctx.translate(putX, putY);
259
- this.ctx.fillStyle = fillPattern;
260
- this.ctx.fill();
261
- }
262
- const diffuse = (c.diffuse && mouseInRenderArea) || mouseInCanvas;
263
- const borderPattern = this.cachedImg.cachedReveal.borderReveal.pattern;
264
- if (c.borderWidth !== 0 && borderPattern && diffuse) {
265
- // Draw border.
266
- const radius = this.cachedImg.cachedReveal.borderReveal.radius;
267
- const putX = Math.floor(relativeX * this.pxRatio - radius);
268
- const putY = Math.floor(relativeY * this.pxRatio - radius);
269
- this.ctx.setTransform(1, 0, 0, 1, 0, 0);
270
- this.drawShape(true);
271
- this.ctx.translate(putX, putY);
272
- this.ctx.fillStyle = borderPattern;
273
- this.ctx.fill();
274
- }
275
- }
276
- if (c.pressAnimation && this.mousePressed && this.mouseDownAnimateLogicFrame) {
277
- this.ctx.setTransform(1, 0, 0, 1, 0, 0);
278
- const grdRadius = c.pressAnimationFillMode === 'constrained' ? c.trueFillRadius[1] : Math.max(b.width, b.height);
279
- // prettier-ignore
280
- const animateGrd = this.mouseReleased && this.mouseUpClientX && this.mouseUpClientY
281
- ? this.ctx.createRadialGradient((this.mouseUpClientX - b.left) * this.pxRatio, (this.mouseUpClientY - b.top) * this.pxRatio, 0, (this.mouseUpClientX - b.left) * this.pxRatio, (this.mouseUpClientY - b.top) * this.pxRatio, grdRadius * this.pxRatio)
282
- : this.ctx.createRadialGradient(relativeX * this.pxRatio, relativeY * this.pxRatio, 0, relativeX * this.pxRatio, relativeY * this.pxRatio, grdRadius * this.pxRatio);
283
- this.updateAnimateGrd(this.mouseDownAnimateLogicFrame, animateGrd);
284
- this.drawShape(false);
285
- this.ctx.fillStyle = animateGrd;
286
- this.ctx.fill();
287
- }
288
- return true;
289
- };
290
- this.ctx = $canvas.getContext('2d');
291
- const cachedCanvas = {
292
- borderReveal: createEmptyCanvas(),
293
- fillReveal: createEmptyCanvas(),
294
- };
295
- const cachedCtx = {
296
- borderReveal: cachedCanvas.borderReveal.getContext('2d'),
297
- fillReveal: cachedCanvas.fillReveal.getContext('2d'),
298
- };
299
- this.cachedImg = {
300
- cachedReveal: {
301
- borderReveal: {
302
- radiusFactor: -1,
303
- radius: -1,
304
- color: 'INVALID',
305
- opacity: 0,
306
- pattern: null,
307
- },
308
- fillReveal: {
309
- radiusFactor: -1,
310
- radius: -1,
311
- color: 'INVALID',
312
- opacity: 0,
313
- pattern: null,
314
- },
315
- },
316
- cachedCanvas,
317
- cachedCtx,
318
- };
319
- }
320
- }
1
+ import { BaseConfig } from './BaseConfig.js';
2
+ export class CanvasConfig extends BaseConfig {
3
+ constructor(store, $canvas, $container) {
4
+ super(store, $canvas, $container);
5
+ this.updateCachedReveal = () => {
6
+ if (!this.fillDirty)
7
+ return;
8
+ if (!this.ctx)
9
+ return;
10
+ const c = this.cachedStyle;
11
+ const radius = c.trueFillRadius[1] * this.pxRatio;
12
+ const lastStyle = this.cachedImg.cachedReveal;
13
+ this._store.updateMaxRadius(c.trueFillRadius[1] * c.borderFillRadius);
14
+ for (let i = 0; i < 2; i++) {
15
+ // 0 means border, 1 means hover light.
16
+ //-----------------------------------------
17
+ // Last rendered style.
18
+ const ls = i === 0 ? lastStyle.borderReveal : lastStyle.fillReveal;
19
+ const color = i === 0 ? c.borderColor : c.hoverLightColor;
20
+ const fillRadiusFactor = i === 0 ? c.borderFillRadius : c.hoverLightFillRadius;
21
+ const trueRadius = radius * fillRadiusFactor;
22
+ const doNotNeedUpdateReveal = color === ls.color &&
23
+ c.opacity === ls.opacity &&
24
+ fillRadiusFactor === ls.radiusFactor &&
25
+ trueRadius === ls.radius;
26
+ if (doNotNeedUpdateReveal)
27
+ continue;
28
+ // The gradient is centered at (trueRadius, trueRadius), painting
29
+ // translates it to the pointer. A gradient is used instead of a
30
+ // pre-rendered bitmap, which takes `(4 * radius) ^ 2` pixels per
31
+ // element and is enough to exhaust the memory of mobile browsers.
32
+ const fillAlpha = i === 0 ? c.opacity : c.opacity * 0.5;
33
+ const grd = this.ctx.createRadialGradient(trueRadius, trueRadius, 0, trueRadius, trueRadius, trueRadius);
34
+ grd.addColorStop(0, `rgba(${color}, ${fillAlpha})`);
35
+ grd.addColorStop(1, `rgba(${color}, 0.0)`);
36
+ ls.radius = trueRadius;
37
+ ls.radiusFactor = fillRadiusFactor;
38
+ ls.color = color;
39
+ ls.opacity = c.opacity;
40
+ ls.pattern = grd;
41
+ }
42
+ this.fillDirty = false;
43
+ };
44
+ this.updateCachedBitmap = () => {
45
+ if (!this.ctx)
46
+ return;
47
+ this.updateCachedReveal();
48
+ };
49
+ this.updateAnimateGrd = (frame, grd) => {
50
+ const { pressAnimationColor, opacity } = this.cachedStyle;
51
+ const _innerAlpha = opacity * (0.2 - frame);
52
+ const _outerAlpha = opacity * (0.1 - frame * 0.07);
53
+ const _outerBorder = 0.1 + frame * 0.8;
54
+ const innerAlpha = _innerAlpha < 0 ? 0 : _innerAlpha;
55
+ const outerAlpha = _outerAlpha < 0 ? 0 : _outerAlpha;
56
+ let outerBorder = 0;
57
+ outerBorder = _outerBorder > 1 ? 1 : _outerBorder;
58
+ outerBorder = _outerBorder < 0 ? 0 : _outerBorder;
59
+ grd.addColorStop(0, `rgba(${pressAnimationColor},${innerAlpha})`);
60
+ grd.addColorStop(outerBorder * 0.55, `rgba(${pressAnimationColor},${outerAlpha})`);
61
+ grd.addColorStop(outerBorder, `rgba(${pressAnimationColor}, 0)`);
62
+ };
63
+ this.drawShape = (hollow) => {
64
+ if (!this.ctx)
65
+ return;
66
+ const b = this.cachedBoundingRect;
67
+ const w = b.width * this.pxRatio;
68
+ const h = b.height * this.pxRatio;
69
+ const c = this.cachedStyle;
70
+ const bw = c.borderWidth * this.pxRatio;
71
+ const tl = c.topLeftBorderDecorationRadius * this.pxRatio;
72
+ const tr = c.topRightBorderDecorationRadius * this.pxRatio;
73
+ const bl = c.bottomLeftBorderDecorationRadius * this.pxRatio;
74
+ const br = c.bottomRightBorderDecorationRadius * this.pxRatio;
75
+ const wlf = c.withLeftBorderFactor;
76
+ const wrf = c.withRightBorderFactor;
77
+ const wtf = c.withTopBorderFactor;
78
+ const wbf = c.withBottomBorderFactor;
79
+ const tl2 = bw < tl ? tl - bw : 0;
80
+ const tr2 = bw < tr ? tr - bw : 0;
81
+ const bl2 = bw < bl ? bl - bw : 0;
82
+ const br2 = bw < br ? br - bw : 0;
83
+ this.ctx.beginPath();
84
+ switch (c.borderDecorationType) {
85
+ // Oh... Fuck... It's painful...
86
+ case 'round':
87
+ // outer
88
+ this.ctx.moveTo(tl, 0);
89
+ this.ctx.arcTo(w, 0, w, h, tr);
90
+ this.ctx.lineTo(w, h - br);
91
+ this.ctx.arcTo(w, h, br, h, br);
92
+ this.ctx.lineTo(bl, h);
93
+ this.ctx.arcTo(0, h, 0, br, bl);
94
+ this.ctx.lineTo(0, tl);
95
+ this.ctx.arcTo(0, 0, tl, 0, tl);
96
+ if (hollow) {
97
+ /* prettier-ignore-start */
98
+ // inner
99
+ /**
100
+ +-①----⑧-+
101
+ ② ⑦
102
+ | |
103
+ ③ ⑥
104
+ +-④----⑤-+
105
+ */
106
+ // x y r p
107
+ this.ctx.moveTo(tl2, bw * wtf); // ①
108
+ this.ctx.arcTo(bw * wlf, bw * wtf, bw * wlf, tl2 + bw * wtf, tl2); // ②
109
+ this.ctx.lineTo(bw * wlf, h - bw * wbf - bl2); // ③
110
+ this.ctx.arcTo(bw * wlf, h - bw * wbf, bw * wlf + bl2, h - bw * wbf, bl2); // ④
111
+ this.ctx.lineTo(w - bw * wrf - br2, h - bw * wbf); // ⑤
112
+ this.ctx.arcTo(w - bw * wrf, h - bw * wbf, w - bw * wrf, h - bw * wbf - br2, br2); // ⑥
113
+ this.ctx.lineTo(w - bw * wrf, bw * wtf + tr2); // ⑦
114
+ this.ctx.arcTo(w - bw * wrf, bw * wtf, w - bw * wrf - tr2, bw * wtf, tr2); // ⑧
115
+ this.ctx.lineTo(tl2, bw * wtf); // ①
116
+ /* prettier-ignore-end */
117
+ }
118
+ break;
119
+ case 'bevel':
120
+ // outer
121
+ this.ctx.moveTo(tl, 0);
122
+ this.ctx.lineTo(w - tr, 0);
123
+ this.ctx.lineTo(w, tr);
124
+ this.ctx.lineTo(w, h - br);
125
+ this.ctx.lineTo(w - br, h);
126
+ this.ctx.lineTo(bl, h);
127
+ this.ctx.lineTo(0, h - bl);
128
+ this.ctx.lineTo(0, tl);
129
+ this.ctx.lineTo(tl, 0);
130
+ this.ctx.lineTo(w - tr, 0);
131
+ if (hollow) {
132
+ // inner
133
+ /**
134
+ +-①----⑧-+
135
+ ② ⑦
136
+ | |
137
+ ③ ⑥
138
+ +-④----⑤-+
139
+ */
140
+ // x y p
141
+ this.ctx.moveTo(tl2 + bw * wlf, bw * wtf); // ①
142
+ this.ctx.lineTo(bw * wlf, tl2 + bw * wtf); // ②
143
+ this.ctx.lineTo(bw * wlf, h - bl2 - bw * wbf); // ③
144
+ this.ctx.lineTo(bw * wlf + bl2, h - bw * wbf); // ④
145
+ this.ctx.lineTo(w - br2 - bw * wrf, h - bw * wbf); // ⑤
146
+ this.ctx.lineTo(w - bw * wrf, h - br2 - bw * wbf); // ⑥
147
+ this.ctx.lineTo(w - bw * wrf, tr2 + bw * wtf); // ⑦
148
+ this.ctx.lineTo(w - tr2 - bw * wrf, bw * wtf); // ⑧
149
+ this.ctx.lineTo(tl2 + bw * wrf, bw * wtf); // ①
150
+ }
151
+ break;
152
+ case 'miter':
153
+ // outer
154
+ this.ctx.moveTo(0, 0);
155
+ this.ctx.lineTo(w, 0);
156
+ this.ctx.lineTo(w, h);
157
+ this.ctx.lineTo(0, h);
158
+ this.ctx.lineTo(0, 0);
159
+ if (hollow) {
160
+ // inner
161
+ /**
162
+ ①--------④
163
+ | |
164
+ | |
165
+ | |
166
+ ②--------③
167
+ */
168
+ // x y p
169
+ this.ctx.moveTo(bw * wlf, bw * wtf); // ①
170
+ this.ctx.lineTo(bw * wlf, h - bw * wbf); // ②
171
+ this.ctx.lineTo(w - bw * wrf, h - bw * wbf); // ③
172
+ this.ctx.lineTo(w - bw * wrf, bw * wtf); // ④
173
+ this.ctx.lineTo(bw * wlf, bw * wtf); // ①
174
+ }
175
+ break;
176
+ default:
177
+ }
178
+ this.ctx.closePath();
179
+ };
180
+ this.syncSizeToElement = (x) => {
181
+ const b = this.cachedBoundingRect;
182
+ // Compare against the backing store size; assigning `width` or
183
+ // `height` resets the bitmap even when the value is unchanged.
184
+ const width = Math.floor(b.width * this.pxRatio);
185
+ const height = Math.floor(b.height * this.pxRatio);
186
+ if (x.width !== width || x.height !== height) {
187
+ x.width = width;
188
+ x.height = height;
189
+ x.style.width = `${b.width}px`;
190
+ x.style.height = `${b.height}px`;
191
+ }
192
+ };
193
+ // Inputs of the last painted frame, a frame with identical inputs is
194
+ // skipped and the canvas keeps its content.
195
+ this.paintedRelativeX = NaN;
196
+ this.paintedRelativeY = NaN;
197
+ this.paintedRectWidth = -1;
198
+ this.paintedRectHeight = -1;
199
+ this.paintedStyleVersion = -1;
200
+ this.paintedAnimation = false;
201
+ this.clear = () => {
202
+ if (!this.ctx)
203
+ return false;
204
+ if (!this.dirty)
205
+ return false;
206
+ const { width, height } = this.cachedBoundingRect;
207
+ this.ctx.setTransform(1, 0, 0, 1, 0, 0);
208
+ this.ctx.clearRect(0, 0, width * window.devicePixelRatio, height * window.devicePixelRatio);
209
+ this.dirty = false;
210
+ return true;
211
+ };
212
+ this.paint = (_skipSamePointerPositionCheck) => {
213
+ const store = this._store;
214
+ if (!this.ctx)
215
+ return false;
216
+ const animationPlaying = store.animationQueue.includes(this);
217
+ if (!store.mouseInBoundary && !animationPlaying) {
218
+ this.clear();
219
+ return false;
220
+ }
221
+ if (!this.cachedImg.cachedReveal) {
222
+ return false;
223
+ }
224
+ // Read layout before any write to the canvas, so the read never
225
+ // forces a synchronous layout.
226
+ this.cacheBoundingRect();
227
+ const b = this.cachedBoundingRect;
228
+ const relativeX = store.clientX - b.left;
229
+ const relativeY = store.clientY - b.top;
230
+ if (Number.isNaN(relativeX) || Number.isNaN(relativeY)) {
231
+ return false;
232
+ }
233
+ const c = this.cachedStyle;
234
+ this.getTrueFillRadius(c.trueFillRadius);
235
+ const maxRadius = c.trueFillRadius[1];
236
+ const inLeftBound = relativeX + maxRadius > 0;
237
+ const inRightBound = relativeX - maxRadius < b.width;
238
+ const inTopBound = relativeY + maxRadius > 0;
239
+ const inBottomBound = relativeY - maxRadius < b.height;
240
+ const mouseInRenderArea = inLeftBound && inRightBound && inTopBound && inBottomBound;
241
+ if (!mouseInRenderArea && !animationPlaying) {
242
+ this.clear();
243
+ return false;
244
+ }
245
+ this.cacheCanvasPaintingStyle();
246
+ const unchanged = this.dirty &&
247
+ !animationPlaying &&
248
+ !this.paintedAnimation &&
249
+ relativeX === this.paintedRelativeX &&
250
+ relativeY === this.paintedRelativeY &&
251
+ b.width === this.paintedRectWidth &&
252
+ b.height === this.paintedRectHeight &&
253
+ this.styleVersion === this.paintedStyleVersion;
254
+ if (unchanged) {
255
+ return false;
256
+ }
257
+ this.syncSizeToElement(this.element);
258
+ this.updateCachedBitmap();
259
+ this.dirty = true;
260
+ this.ctx.setTransform(1, 0, 0, 1, 0, 0);
261
+ this.ctx.clearRect(0, 0, this.paintedWidth, this.paintedHeight);
262
+ this.paintedWidth = b.width * this.pxRatio;
263
+ this.paintedHeight = b.height * this.pxRatio;
264
+ this.paintedRelativeX = relativeX;
265
+ this.paintedRelativeY = relativeY;
266
+ this.paintedRectWidth = b.width;
267
+ this.paintedRectHeight = b.height;
268
+ this.paintedStyleVersion = this.styleVersion;
269
+ this.paintedAnimation = animationPlaying;
270
+ if (store.mouseInBoundary) {
271
+ const mouseInCanvas = relativeX > 0 && relativeY > 0 && relativeX < b.width && relativeY < b.height;
272
+ const fillPattern = this.cachedImg.cachedReveal.fillReveal.pattern;
273
+ if (c.hoverLight && mouseInCanvas && fillPattern) {
274
+ // draw fill.
275
+ const radius = this.cachedImg.cachedReveal.fillReveal.radius;
276
+ const putX = Math.floor(relativeX * this.pxRatio - radius);
277
+ const putY = Math.floor(relativeY * this.pxRatio - radius);
278
+ this.ctx.setTransform(1, 0, 0, 1, 0, 0);
279
+ this.drawShape(false);
280
+ this.ctx.translate(putX, putY);
281
+ this.ctx.fillStyle = fillPattern;
282
+ this.ctx.fill();
283
+ }
284
+ const diffuse = (c.diffuse && mouseInRenderArea) || mouseInCanvas;
285
+ const borderPattern = this.cachedImg.cachedReveal.borderReveal.pattern;
286
+ if (c.borderWidth !== 0 && borderPattern && diffuse) {
287
+ // Draw border.
288
+ const radius = this.cachedImg.cachedReveal.borderReveal.radius;
289
+ const putX = Math.floor(relativeX * this.pxRatio - radius);
290
+ const putY = Math.floor(relativeY * this.pxRatio - radius);
291
+ this.ctx.setTransform(1, 0, 0, 1, 0, 0);
292
+ this.drawShape(true);
293
+ this.ctx.translate(putX, putY);
294
+ this.ctx.fillStyle = borderPattern;
295
+ this.ctx.fill();
296
+ }
297
+ }
298
+ if (c.pressAnimation && this.mousePressed && this.mouseDownAnimateLogicFrame) {
299
+ this.ctx.setTransform(1, 0, 0, 1, 0, 0);
300
+ const grdRadius = c.pressAnimationFillMode === 'constrained' ? c.trueFillRadius[1] : Math.max(b.width, b.height);
301
+ // prettier-ignore
302
+ const animateGrd = this.mouseReleased && this.mouseUpClientX && this.mouseUpClientY
303
+ ? this.ctx.createRadialGradient((this.mouseUpClientX - b.left) * this.pxRatio, (this.mouseUpClientY - b.top) * this.pxRatio, 0, (this.mouseUpClientX - b.left) * this.pxRatio, (this.mouseUpClientY - b.top) * this.pxRatio, grdRadius * this.pxRatio)
304
+ : this.ctx.createRadialGradient(relativeX * this.pxRatio, relativeY * this.pxRatio, 0, relativeX * this.pxRatio, relativeY * this.pxRatio, grdRadius * this.pxRatio);
305
+ this.updateAnimateGrd(this.mouseDownAnimateLogicFrame, animateGrd);
306
+ this.drawShape(false);
307
+ this.ctx.fillStyle = animateGrd;
308
+ this.ctx.fill();
309
+ }
310
+ return true;
311
+ };
312
+ this.ctx = $canvas.getContext('2d');
313
+ this.cachedImg = {
314
+ cachedReveal: {
315
+ borderReveal: {
316
+ radiusFactor: -1,
317
+ radius: -1,
318
+ color: 'INVALID',
319
+ opacity: 0,
320
+ pattern: null,
321
+ },
322
+ fillReveal: {
323
+ radiusFactor: -1,
324
+ radius: -1,
325
+ color: 'INVALID',
326
+ opacity: 0,
327
+ pattern: null,
328
+ },
329
+ },
330
+ };
331
+ }
332
+ }
321
333
  //# sourceMappingURL=CanvasConfig.js.map