renusify 2.2.6 → 2.3.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 (105) hide show
  1. package/components/app/style.scss +6 -4
  2. package/components/app/toast/style.scss +4 -3
  3. package/components/avatar/style.scss +2 -2
  4. package/components/bar/bottomNavigationCircle.vue +8 -5
  5. package/components/bar/scss/bottomNav.scss +15 -12
  6. package/components/bar/scss/toolbar.scss +32 -30
  7. package/components/bar/toolbar/index.vue +5 -5
  8. package/components/bar/toolbar/laptop.vue +1 -1
  9. package/components/bar/toolbar/mobile.vue +1 -1
  10. package/components/breadcrumb/bredcrumbItem.vue +2 -2
  11. package/components/breadcrumb/style.scss +6 -6
  12. package/components/button/index.vue +1 -1
  13. package/components/button/style.scss +41 -36
  14. package/components/calendar/index.vue +4 -3
  15. package/components/card/index.vue +1 -1
  16. package/components/card/style.scss +14 -11
  17. package/components/chart/chart.vue +3 -3
  18. package/components/chart/worldMap.vue +2 -2
  19. package/components/chat/MessageList.vue +122 -119
  20. package/components/chat/chatInput.vue +3 -3
  21. package/components/chat/chatMsg.vue +23 -21
  22. package/components/chat/index.vue +2 -2
  23. package/components/chip/style.scss +21 -16
  24. package/components/codeEditor/highlightCss.vue +1 -1
  25. package/components/codeEditor/highlightHtml.vue +1 -1
  26. package/components/codeEditor/highlightJs.vue +1 -1
  27. package/components/codeEditor/index.vue +6 -6
  28. package/components/container/style.scss +12 -10
  29. package/components/content/index.vue +17 -14
  30. package/components/cropper/index.vue +2 -2
  31. package/components/float/index.vue +456 -454
  32. package/components/form/camInput/index.vue +2 -2
  33. package/components/form/checkInput/index.vue +2 -2
  34. package/components/form/checkboxInput/index.vue +5 -4
  35. package/components/form/colorInput/Alpha.vue +1 -1
  36. package/components/form/colorInput/Preview.vue +1 -1
  37. package/components/form/colorInput/Saturation.vue +1 -1
  38. package/components/form/colorInput/index.vue +2 -2
  39. package/components/form/colorInput/picker.vue +10 -8
  40. package/components/form/dateInput/index.vue +2 -2
  41. package/components/form/fileInput/index.vue +0 -3
  42. package/components/form/fileInput/single.vue +3 -3
  43. package/components/form/groupInput/index.vue +5 -4
  44. package/components/form/input/index.vue +31 -29
  45. package/components/form/jsonInput/JsonView.vue +5 -4
  46. package/components/form/jsonInput/index.vue +36 -34
  47. package/components/form/numberInput/index.vue +11 -8
  48. package/components/form/radioInput/index.vue +6 -4
  49. package/components/form/rangeInput/index.vue +11 -10
  50. package/components/form/ratingInput/index.vue +5 -5
  51. package/components/form/selectInput/index.vue +8 -6
  52. package/components/form/switchInput/index.vue +9 -7
  53. package/components/form/telInput/index.vue +2 -2
  54. package/components/form/text-editor/style.scss +10 -7
  55. package/components/form/textArea/index.vue +2 -2
  56. package/components/form/timeInput/timepicker.vue +4 -3
  57. package/components/form/unitInput/index.vue +8 -6
  58. package/components/icon/style.scss +5 -4
  59. package/components/img/index.vue +2 -2
  60. package/components/index.js +0 -2
  61. package/components/list/index.vue +1 -1
  62. package/components/list/style.scss +6 -5
  63. package/components/map/index.vue +3 -3
  64. package/components/map/route.vue +2 -2
  65. package/components/menu/index.vue +4 -3
  66. package/components/modal/style.scss +19 -15
  67. package/components/nestable/index.vue +4 -4
  68. package/components/notify/index.vue +55 -53
  69. package/components/notify/notification.vue +5 -3
  70. package/components/progress/style.scss +8 -5
  71. package/components/searchBox/index.vue +15 -12
  72. package/components/skeleton/index.vue +5 -3
  73. package/components/slider/index.vue +18 -15
  74. package/components/swiper/index.vue +2 -2
  75. package/components/table/crud/index.vue +2 -2
  76. package/components/table/style.scss +87 -82
  77. package/components/tabs/index.vue +2 -2
  78. package/components/timeline/index.vue +64 -61
  79. package/components/tree/index.vue +4 -4
  80. package/components/tree/tree-element.vue +2 -2
  81. package/directive/animate/style.scss +72 -41
  82. package/directive/drag/index.js +1 -1
  83. package/directive/ripple/style.scss +6 -4
  84. package/directive/skeleton/style.scss +7 -7
  85. package/directive/sortable/index.js +1 -1
  86. package/directive/sortable/style.scss +7 -3
  87. package/directive/title/style.scss +4 -2
  88. package/index.js +10 -10
  89. package/package.json +1 -1
  90. package/style/app.scss +70 -58
  91. package/style/colors.scss +26 -22
  92. package/style/functions/index.scss +8 -8
  93. package/style/mixins/container.scss +25 -19
  94. package/style/mixins/index.scss +19 -15
  95. package/style/mixins/utilities.scss +26 -21
  96. package/style/style.scss +5 -6
  97. package/style/transitions.scss +14 -13
  98. package/style/variables/base.scss +26 -24
  99. package/style/variables/utilities.scss +35 -34
  100. package/components/html2pdf/index.js +0 -4
  101. package/components/html2pdf/index.vue +0 -280
  102. package/components/html2pdf/pageBreak.js +0 -1
  103. package/components/html2pdf/pageBreak.vue +0 -12
  104. package/style/_include.scss +0 -3
  105. package/style/variables/index.scss +0 -3
@@ -1,465 +1,467 @@
1
1
  <template>
2
- <div :class="classes">
3
- <div class="float-container" :class="{'in-zoom':inZoom}" ref="float">
4
- <slot :resume="resume" :pause="pause" :move="moveTo" :transform="transform" :zoom="zoomAbs"
5
- :ease="ease"></slot>
6
- </div>
2
+ <div :class="classes">
3
+ <div ref="float" :class="{'in-zoom':inZoom}" class="float-container">
4
+ <slot :ease="ease" :move="moveTo" :pause="pause" :resume="resume" :transform="transform"
5
+ :zoom="zoomAbs"></slot>
7
6
  </div>
7
+ </div>
8
8
  </template>
9
9
  <script>
10
- export default {
11
- name: 'r-float',
12
- props: {
13
- bordered: Boolean,
14
- disableZoom: Boolean,
15
- disableMove: Boolean,
16
- trnsfrmOrigin: Object,
17
- zoom: {type: Number, default: 1},
18
- maxZoom: {
19
- type: Number,
20
- default: 10
21
- },
22
- minZoom: {
23
- type: Number,
24
- default: .1
25
- }
26
- },
27
- emits:['move','zoom'],
28
- data() {
29
- return {
30
- started: Date.now(),
31
- transform: {
32
- x: 0,
33
- y: 0,
34
- scale: this.zoom
35
- },
36
- inZoom: false,
37
- paused: false,
38
- storedCTMResult: {x: 0, y: 0},
39
- isDirty: false,
40
- lastTouchEndTime: 0,
41
- lastSingleFingerOffset: null,
42
- touchInProgress: false,
43
- multiTouch: false,
44
- mouseX: 0,
45
- mouseY: 0,
46
- pinchZoomLength: 0,
47
- frameAnimation: null
48
- }
49
- },
50
- mounted() {
51
- this.builder()
52
- },
53
- computed: {
54
- classes() {
55
- let a = {
56
- 'float-bordered': this.bordered
57
- }
58
- a[`${this.$r.prefix}float`]=true
59
- return a
60
- },
61
- domElement() {
62
- return this.$refs.float
63
- },
64
- owner() {
65
- return this.domElement.parentElement;
66
- },
67
- transformOrigin() {
68
- if (!this.trnsfrmOrigin || !this.isNumber(this.trnsfrmOrigin.x) || !this.isNumber(this.trnsfrmOrigin.y)) return;
69
-
70
- return this.trnsfrmOrigin;
71
- },
72
- getTransformOriginOffset() {
73
- let ownerRect = this.owner.getBoundingClientRect();
74
- return {
75
- x: ownerRect.width * this.transformOrigin.x,
76
- y: ownerRect.height * this.transformOrigin.y
77
- };
78
- },
79
- midPoint() {
80
- let ownerRect = this.owner.getBoundingClientRect();
81
- return {
82
- x: ownerRect.width / 2,
83
- y: ownerRect.height / 2
84
- };
85
- },
86
- getBBox() {
87
- return {
88
- left: 0,
89
- top: 0,
90
- width: this.domElement.clientWidth,
91
- height: this.domElement.clientHeight
92
- };
93
- }
94
- },
95
- methods: {
96
- builder() {
97
- this.domElement.scrollTop = 0;
98
- this.owner.setAttribute('tabindex', 0);
99
- this.listenForEvents();
100
- this.zoomAbs(this.transform.x, this.transform.y, this.transform.scale);
101
- },
102
- applyTransform() {
103
- this.isDirty = false;
104
- this.domElement.style.transformOrigin = '0 0 0';
105
- this.domElement.style.transform = 'matrix(' +
106
- this.transform.scale + ', 0, 0, ' +
107
- this.transform.scale + ', ' +
108
- this.transform.x + ', ' + this.transform.y + ')';
109
- this.frameAnimation = 0;
110
- },
111
- pause() {
112
- this.releaseEvents();
113
- this.paused = true;
114
- },
115
- resume() {
116
- if (this.paused) {
117
- this.listenForEvents();
118
- this.paused = false;
119
- }
120
- },
121
- listenForEvents() {
122
- this.owner.addEventListener('mousedown', this.onMouseDown, {passive: false});
123
- this.owner.addEventListener('dblclick', this.onDoubleClick, {passive: false});
124
- this.owner.addEventListener('touchstart', this.onTouch, {passive: false});
125
- this.owner.addEventListener('keydown', this.onKeyDown, {passive: false});
126
- this.owner.addEventListener('wheel', this.onMouseWheel, {passive: false});
127
- this.makeDirty();
128
- },
129
- transformToScreen(x, y) {
130
- this.storedCTMResult.x = x;
131
- this.storedCTMResult.y = y;
132
- return this.storedCTMResult;
133
- },
134
- moveTo(dx, dy) {
135
- if (this.disableMove) return;
136
- this.transform.x += dx;
137
- this.transform.y += dy;
138
- this.$emit('move', [dx, dy])
139
- this.makeDirty();
140
- },
141
- makeDirty() {
142
- this.isDirty = true;
143
- this.frameAnimation = window.requestAnimationFrame(this.frame);
144
- },
145
- ease() {
146
- this.inZoom = true
147
- setTimeout(() => {
148
- this.inZoom = false
149
- }, 500)
150
- },
151
- zoomByRatio(clientX, clientY, ratio, ease = false) {
152
- if (this.disableZoom) return;
153
- if (ease) this.ease();
154
- if (this.isNaN(clientX) || this.isNaN(clientY) || this.isNaN(ratio)) {
155
- throw new Error('zoom requires valid numbers');
156
- }
157
-
158
- let newScale = this.transform.scale * ratio;
159
-
160
- if (newScale < this.minZoom) {
161
- if (this.transform.scale === this.minZoom) return;
162
-
163
- ratio = this.minZoom / this.transform.scale;
164
- }
165
- if (newScale > this.maxZoom) {
166
- if (this.transform.scale === this.maxZoom) return;
167
-
168
- ratio = this.maxZoom / this.transform.scale;
169
- }
170
-
171
- let size = this.transformToScreen(clientX, clientY);
172
-
173
- this.transform.x = size.x - ratio * (size.x - this.transform.x);
174
- this.transform.y = size.y - ratio * (size.y - this.transform.y);
175
-
176
- this.transform.scale *= ratio;
177
-
178
- this.$emit('zoom', [clientX, clientY, ratio]);
179
-
180
- this.makeDirty();
181
- },
182
- zoomAbs(clientX, clientY, zoomLevel) {
183
- let ratio = zoomLevel / this.transform.scale;
184
- this.zoomByRatio(clientX, clientY, ratio);
185
- },
186
- frame() {
187
- if (this.isDirty) this.applyTransform();
188
- },
189
- onKeyDown(e) {
190
- let x = 0,
191
- y = 0,
192
- z = 0;
193
- if (e.keyCode === 38) {
194
- y = -1; // up
195
- } else if (e.keyCode === 40) {
196
- y = 1; // down
197
- } else if (e.keyCode === 37) {
198
- x = -1; // left
199
- } else if (e.keyCode === 39) {
200
- x = 1; // right
201
- } else if (e.keyCode === 189 || e.keyCode === 109) {
202
- // DASH or SUBTRACT
203
- z = 1; // `-` - zoom out
204
- } else if (e.keyCode === 187 || e.keyCode === 107) {
205
- // EQUAL SIGN or ADD
206
- z = -1; // `=` - zoom in (equal sign on US layout is under `+`)
207
- }
208
-
209
- if (x || y) {
210
- e.preventDefault();
211
- e.stopPropagation();
212
-
213
- let clientRect = this.owner.getBoundingClientRect();
214
-
215
- let offset = Math.min(clientRect.width, clientRect.height);
216
- let moveSpeedRatio = 0.05;
217
- let dx = offset * moveSpeedRatio * x;
218
- let dy = offset * moveSpeedRatio * y;
219
-
220
- this.moveTo(dx, dy);
221
- }
222
-
223
- if (z) {
224
- let scaleMultiplier = this.getScaleMultiplier(z * 100);
225
- let offset = this.transformOrigin ? this.getTransformOriginOffset : this.midPoint;
226
- this.zoomByRatio(offset.x, offset.y, scaleMultiplier);
227
- }
228
- },
229
- onTouch(e) {
230
- if (e.touches.length === 1) {
231
- return this.handleSingleFingerTouch(e, e.touches[0]);
232
- } else if (e.touches.length === 2) {
233
- // handleTouchMove() will care about pinch zoom.
234
- this.pinchZoomLength = this.getPinchZoomLength(e.touches[0], e.touches[1]);
235
- this.multiTouch = true;
236
- this.startTouchListenerIfNeeded();
237
- }
238
- },
239
- handleSingleFingerTouch(e) {
240
- let touch = e.touches[0];
241
- let offset = this.getOffsetXY(touch);
242
- this.lastSingleFingerOffset = offset;
243
- let point = this.transformToScreen(offset.x, offset.y);
244
- this.mouseX = point.x;
245
- this.mouseY = point.y;
246
-
247
- this.startTouchListenerIfNeeded();
248
- },
249
- startTouchListenerIfNeeded() {
250
- if (this.touchInProgress) {
251
- return;
252
- }
253
-
254
- this.touchInProgress = true;
255
- document.addEventListener('touchmove', this.handleTouchMove, {passive: false});
256
- document.addEventListener('touchend', this.handleTouchEnd);
257
- document.addEventListener('touchcancel', this.handleTouchEnd);
258
- },
259
- handleTouchMove(e) {
260
- e.stopPropagation();
261
- e.preventDefault();
262
- if (e.touches.length === 1) {
263
- let touch = e.touches[0];
264
-
265
- let offset = this.getOffsetXY(touch);
266
- let point = this.transformToScreen(offset.x, offset.y);
267
-
268
- let dx = point.x - this.mouseX;
269
- let dy = point.y - this.mouseY;
270
-
271
- this.mouseX = point.x;
272
- this.mouseY = point.y;
273
- this.moveTo(dx, dy);
274
- } else if (e.touches.length === 2) {
275
- // it's a zoom, let's find direction
276
- this.multiTouch = true;
277
- let t1 = e.touches[0];
278
- let t2 = e.touches[1];
279
- let currentPinchLength = this.getPinchZoomLength(t1, t2);
280
-
281
- let scaleMultiplier =
282
- 1 + (currentPinchLength / this.pinchZoomLength - 1);
283
-
284
- let firstTouchPoint = this.getOffsetXY(t1);
285
- let secondTouchPoint = this.getOffsetXY(t2);
286
- this.mouseX = (firstTouchPoint.x + secondTouchPoint.x) / 2;
287
- this.mouseY = (firstTouchPoint.y + secondTouchPoint.y) / 2;
288
- if (this.transformOrigin) {
289
- let offset = this.getTransformOriginOffset;
290
- this.mouseX = offset.x;
291
- this.mouseY = offset.y;
292
- }
293
-
294
- this.zoomByRatio(this.mouseX, this.mouseY, scaleMultiplier);
295
-
296
- this.pinchZoomLength = currentPinchLength;
297
- }
298
- },
299
- handleTouchEnd(e) {
300
- if (e.touches.length > 0) {
301
- let offset = this.getOffsetXY(e.touches[0]);
302
- let point = this.transformToScreen(offset.x, offset.y);
303
- this.mouseX = point.x;
304
- this.mouseY = point.y;
305
- } else {
306
- let now = new Date();
307
- if (now - this.lastTouchEndTime < 300) {
308
- if (this.transformOrigin) {
309
- let offset = this.getTransformOriginOffset;
310
- this.zoomByRatio(offset.x, offset.y, this.transform.scale);
311
- } else {
312
- // We want untransformed x/y here.
313
- this.zoomByRatio(this.lastSingleFingerOffset.x, this.lastSingleFingerOffset.y, this.transform.scale);
314
- }
315
- }
316
-
317
- this.lastTouchEndTime = now;
318
- this.releaseTouches();
319
- }
320
- },
321
- getPinchZoomLength(finger1, finger2) {
322
- let dx = finger1.clientX - finger2.clientX;
323
- let dy = finger1.clientY - finger2.clientY;
324
- return Math.sqrt(dx * dx + dy * dy);
325
- },
326
- onDoubleClick(e) {
327
- e.preventDefault()
328
- e.stopPropagation()
329
- let offset = this.getOffsetXY(e);
330
- if (this.transformOrigin) {
331
- offset = this.getTransformOriginOffset;
332
- }
333
- let scaleMultiplier = this.getScaleMultiplier(-1000);
334
- this.zoomByRatio(offset.x, offset.y, scaleMultiplier, true);
335
- },
336
- onMouseDown(e) {
337
- if (this.touchInProgress) {
338
- e.stopPropagation();
339
- return false;
340
- }
341
- let isLeftButton =
342
- (e.button === 1 && window.event !== null) || e.button === 0;
343
- if (!isLeftButton) return;
344
-
345
- let offset = this.getOffsetXY(e);
346
- let point = this.transformToScreen(offset.x, offset.y);
347
- this.mouseX = point.x;
348
- this.mouseY = point.y;
349
-
350
- document.addEventListener('mousemove', this.onMouseMove);
351
- document.addEventListener('mouseup', this.onMouseUp);
352
-
353
- return false;
354
- },
355
- onMouseMove(e) {
356
- if (this.touchInProgress) return;
357
-
358
- let offset = this.getOffsetXY(e);
359
- let point = this.transformToScreen(offset.x, offset.y);
360
- let dx = point.x - this.mouseX;
361
- let dy = point.y - this.mouseY;
362
-
363
- this.mouseX = point.x;
364
- this.mouseY = point.y;
365
- this.moveTo(dx, dy);
366
- },
367
- onMouseUp() {
368
- this.releaseDocumentMouse();
369
- },
370
- onMouseWheel(e) {
371
- let delta = e.deltaY;
372
- if (e.deltaMode > 0) delta *= 100;
373
-
374
- let scaleMultiplier = this.getScaleMultiplier(delta);
375
-
376
- if (scaleMultiplier !== 1) {
377
- let offset = this.transformOrigin
378
- ? this.getTransformOriginOffset
379
- : this.getOffsetXY(e);
380
- this.zoomByRatio(offset.x, offset.y, scaleMultiplier);
381
- e.preventDefault();
382
- }
383
- },
384
- getOffsetXY(e) {
385
- let offsetX, offsetY;
386
- let ownerRect = this.owner.getBoundingClientRect();
387
- offsetX = e.clientX - ownerRect.left;
388
- offsetY = e.clientY - ownerRect.top;
389
-
390
- return {x: offsetX, y: offsetY};
391
- },
392
- getScaleMultiplier(delta) {
393
- let sign = Math.sign(delta);
394
- let deltaAdjustedSpeed = Math.min(0.25, Math.abs(delta / 128));
395
- return 1 - sign * deltaAdjustedSpeed;
396
- },
397
- isNumber(x) {
398
- return Number.isFinite(x);
399
- },
400
- isNaN(value) {
401
- if (Number.isNaN) {
402
- return Number.isNaN(value);
403
- }
404
-
405
- return value !== value;
406
- },
407
- releaseEvents() {
408
- this.owner.removeEventListener('wheel', this.onMouseWheel);
409
- this.owner.removeEventListener('mousedown', this.onMouseDown);
410
- this.owner.removeEventListener('keydown', this.onKeyDown);
411
- this.owner.removeEventListener('dblclick', this.onDoubleClick);
412
- this.owner.removeEventListener('touchstart', this.onTouch);
413
-
414
- if (this.frameAnimation) {
415
- window.cancelAnimationFrame(this.frameAnimation);
416
- this.frameAnimation = 0;
417
- }
418
-
419
-
420
- this.releaseDocumentMouse();
421
- this.releaseTouches();
422
- },
423
- releaseDocumentMouse() {
424
- document.removeEventListener('mousemove', this.onMouseMove);
425
- document.removeEventListener('mouseup', this.onMouseUp);
426
- },
427
- releaseTouches() {
428
- document.removeEventListener('touchmove', this.handleTouchMove);
429
- document.removeEventListener('touchend', this.handleTouchEnd);
430
- document.removeEventListener('touchcancel', this.handleTouchEnd);
431
- this.multiTouch = false;
432
- this.touchInProgress = false;
433
- },
434
- },
435
- beforeUnmount() {
436
- this.releaseEvents();
437
- }
10
+ export default {
11
+ name: 'r-float',
12
+ props: {
13
+ bordered: Boolean,
14
+ disableZoom: Boolean,
15
+ disableMove: Boolean,
16
+ trnsfrmOrigin: Object,
17
+ zoom: {type: Number, default: 1},
18
+ maxZoom: {
19
+ type: Number,
20
+ default: 10
21
+ },
22
+ minZoom: {
23
+ type: Number,
24
+ default: .1
438
25
  }
439
- </script>
440
- <style lang="scss">
441
- @import "../../style/_include.scss";
442
-
443
- .#{$prefix}float {
444
- width: 100%;
445
- max-width: 100%;
446
- max-height: 100vh;
447
- height: 100%;
448
- overflow: hidden;
449
- outline: none;
450
- border-radius: map-get($borders, 'sm');
451
-
452
- &.float-bordered {
453
- border: 1px solid #3a3e3a;
26
+ },
27
+ emits: ['move', 'zoom'],
28
+ data() {
29
+ return {
30
+ started: Date.now(),
31
+ transform: {
32
+ x: 0,
33
+ y: 0,
34
+ scale: this.zoom
35
+ },
36
+ inZoom: false,
37
+ paused: false,
38
+ storedCTMResult: {x: 0, y: 0},
39
+ isDirty: false,
40
+ lastTouchEndTime: 0,
41
+ lastSingleFingerOffset: null,
42
+ touchInProgress: false,
43
+ multiTouch: false,
44
+ mouseX: 0,
45
+ mouseY: 0,
46
+ pinchZoomLength: 0,
47
+ frameAnimation: null
48
+ }
49
+ },
50
+ mounted() {
51
+ this.builder()
52
+ },
53
+ computed: {
54
+ classes() {
55
+ let a = {
56
+ 'float-bordered': this.bordered
57
+ }
58
+ a[`${this.$r.prefix}float`] = true
59
+ return a
60
+ },
61
+ domElement() {
62
+ return this.$refs.float
63
+ },
64
+ owner() {
65
+ return this.domElement.parentElement;
66
+ },
67
+ transformOrigin() {
68
+ if (!this.trnsfrmOrigin || !this.isNumber(this.trnsfrmOrigin.x) || !this.isNumber(this.trnsfrmOrigin.y)) return;
69
+
70
+ return this.trnsfrmOrigin;
71
+ },
72
+ getTransformOriginOffset() {
73
+ let ownerRect = this.owner.getBoundingClientRect();
74
+ return {
75
+ x: ownerRect.width * this.transformOrigin.x,
76
+ y: ownerRect.height * this.transformOrigin.y
77
+ };
78
+ },
79
+ midPoint() {
80
+ let ownerRect = this.owner.getBoundingClientRect();
81
+ return {
82
+ x: ownerRect.width / 2,
83
+ y: ownerRect.height / 2
84
+ };
85
+ },
86
+ getBBox() {
87
+ return {
88
+ left: 0,
89
+ top: 0,
90
+ width: this.domElement.clientWidth,
91
+ height: this.domElement.clientHeight
92
+ };
93
+ }
94
+ },
95
+ methods: {
96
+ builder() {
97
+ this.domElement.scrollTop = 0;
98
+ this.owner.setAttribute('tabindex', 0);
99
+ this.listenForEvents();
100
+ this.zoomAbs(this.transform.x, this.transform.y, this.transform.scale);
101
+ },
102
+ applyTransform() {
103
+ this.isDirty = false;
104
+ this.domElement.style.transformOrigin = '0 0 0';
105
+ this.domElement.style.transform = 'matrix(' +
106
+ this.transform.scale + ', 0, 0, ' +
107
+ this.transform.scale + ', ' +
108
+ this.transform.x + ', ' + this.transform.y + ')';
109
+ this.frameAnimation = 0;
110
+ },
111
+ pause() {
112
+ this.releaseEvents();
113
+ this.paused = true;
114
+ },
115
+ resume() {
116
+ if (this.paused) {
117
+ this.listenForEvents();
118
+ this.paused = false;
119
+ }
120
+ },
121
+ listenForEvents() {
122
+ this.owner.addEventListener('mousedown', this.onMouseDown, {passive: false});
123
+ this.owner.addEventListener('dblclick', this.onDoubleClick, {passive: false});
124
+ this.owner.addEventListener('touchstart', this.onTouch, {passive: false});
125
+ this.owner.addEventListener('keydown', this.onKeyDown, {passive: false});
126
+ this.owner.addEventListener('wheel', this.onMouseWheel, {passive: false});
127
+ this.makeDirty();
128
+ },
129
+ transformToScreen(x, y) {
130
+ this.storedCTMResult.x = x;
131
+ this.storedCTMResult.y = y;
132
+ return this.storedCTMResult;
133
+ },
134
+ moveTo(dx, dy) {
135
+ if (this.disableMove) return;
136
+ this.transform.x += dx;
137
+ this.transform.y += dy;
138
+ this.$emit('move', [dx, dy])
139
+ this.makeDirty();
140
+ },
141
+ makeDirty() {
142
+ this.isDirty = true;
143
+ this.frameAnimation = window.requestAnimationFrame(this.frame);
144
+ },
145
+ ease() {
146
+ this.inZoom = true
147
+ setTimeout(() => {
148
+ this.inZoom = false
149
+ }, 500)
150
+ },
151
+ zoomByRatio(clientX, clientY, ratio, ease = false) {
152
+ if (this.disableZoom) return;
153
+ if (ease) this.ease();
154
+ if (this.isNaN(clientX) || this.isNaN(clientY) || this.isNaN(ratio)) {
155
+ throw new Error('zoom requires valid numbers');
156
+ }
157
+
158
+ let newScale = this.transform.scale * ratio;
159
+
160
+ if (newScale < this.minZoom) {
161
+ if (this.transform.scale === this.minZoom) return;
162
+
163
+ ratio = this.minZoom / this.transform.scale;
164
+ }
165
+ if (newScale > this.maxZoom) {
166
+ if (this.transform.scale === this.maxZoom) return;
167
+
168
+ ratio = this.maxZoom / this.transform.scale;
169
+ }
170
+
171
+ let size = this.transformToScreen(clientX, clientY);
172
+
173
+ this.transform.x = size.x - ratio * (size.x - this.transform.x);
174
+ this.transform.y = size.y - ratio * (size.y - this.transform.y);
175
+
176
+ this.transform.scale *= ratio;
177
+
178
+ this.$emit('zoom', [clientX, clientY, ratio]);
179
+
180
+ this.makeDirty();
181
+ },
182
+ zoomAbs(clientX, clientY, zoomLevel) {
183
+ let ratio = zoomLevel / this.transform.scale;
184
+ this.zoomByRatio(clientX, clientY, ratio);
185
+ },
186
+ frame() {
187
+ if (this.isDirty) this.applyTransform();
188
+ },
189
+ onKeyDown(e) {
190
+ let x = 0,
191
+ y = 0,
192
+ z = 0;
193
+ if (e.keyCode === 38) {
194
+ y = -1; // up
195
+ } else if (e.keyCode === 40) {
196
+ y = 1; // down
197
+ } else if (e.keyCode === 37) {
198
+ x = -1; // left
199
+ } else if (e.keyCode === 39) {
200
+ x = 1; // right
201
+ } else if (e.keyCode === 189 || e.keyCode === 109) {
202
+ // DASH or SUBTRACT
203
+ z = 1; // `-` - zoom out
204
+ } else if (e.keyCode === 187 || e.keyCode === 107) {
205
+ // EQUAL SIGN or ADD
206
+ z = -1; // `=` - zoom in (equal sign on US layout is under `+`)
207
+ }
208
+
209
+ if (x || y) {
210
+ e.preventDefault();
211
+ e.stopPropagation();
212
+
213
+ let clientRect = this.owner.getBoundingClientRect();
214
+
215
+ let offset = Math.min(clientRect.width, clientRect.height);
216
+ let moveSpeedRatio = 0.05;
217
+ let dx = offset * moveSpeedRatio * x;
218
+ let dy = offset * moveSpeedRatio * y;
219
+
220
+ this.moveTo(dx, dy);
221
+ }
222
+
223
+ if (z) {
224
+ let scaleMultiplier = this.getScaleMultiplier(z * 100);
225
+ let offset = this.transformOrigin ? this.getTransformOriginOffset : this.midPoint;
226
+ this.zoomByRatio(offset.x, offset.y, scaleMultiplier);
454
227
  }
228
+ },
229
+ onTouch(e) {
230
+ if (e.touches.length === 1) {
231
+ return this.handleSingleFingerTouch(e, e.touches[0]);
232
+ } else if (e.touches.length === 2) {
233
+ // handleTouchMove() will care about pinch zoom.
234
+ this.pinchZoomLength = this.getPinchZoomLength(e.touches[0], e.touches[1]);
235
+ this.multiTouch = true;
236
+ this.startTouchListenerIfNeeded();
237
+ }
238
+ },
239
+ handleSingleFingerTouch(e) {
240
+ let touch = e.touches[0];
241
+ let offset = this.getOffsetXY(touch);
242
+ this.lastSingleFingerOffset = offset;
243
+ let point = this.transformToScreen(offset.x, offset.y);
244
+ this.mouseX = point.x;
245
+ this.mouseY = point.y;
246
+
247
+ this.startTouchListenerIfNeeded();
248
+ },
249
+ startTouchListenerIfNeeded() {
250
+ if (this.touchInProgress) {
251
+ return;
252
+ }
253
+
254
+ this.touchInProgress = true;
255
+ document.addEventListener('touchmove', this.handleTouchMove, {passive: false});
256
+ document.addEventListener('touchend', this.handleTouchEnd);
257
+ document.addEventListener('touchcancel', this.handleTouchEnd);
258
+ },
259
+ handleTouchMove(e) {
260
+ e.stopPropagation();
261
+ e.preventDefault();
262
+ if (e.touches.length === 1) {
263
+ let touch = e.touches[0];
264
+
265
+ let offset = this.getOffsetXY(touch);
266
+ let point = this.transformToScreen(offset.x, offset.y);
267
+
268
+ let dx = point.x - this.mouseX;
269
+ let dy = point.y - this.mouseY;
270
+
271
+ this.mouseX = point.x;
272
+ this.mouseY = point.y;
273
+ this.moveTo(dx, dy);
274
+ } else if (e.touches.length === 2) {
275
+ // it's a zoom, let's find direction
276
+ this.multiTouch = true;
277
+ let t1 = e.touches[0];
278
+ let t2 = e.touches[1];
279
+ let currentPinchLength = this.getPinchZoomLength(t1, t2);
280
+
281
+ let scaleMultiplier =
282
+ 1 + (currentPinchLength / this.pinchZoomLength - 1);
283
+
284
+ let firstTouchPoint = this.getOffsetXY(t1);
285
+ let secondTouchPoint = this.getOffsetXY(t2);
286
+ this.mouseX = (firstTouchPoint.x + secondTouchPoint.x) / 2;
287
+ this.mouseY = (firstTouchPoint.y + secondTouchPoint.y) / 2;
288
+ if (this.transformOrigin) {
289
+ let offset = this.getTransformOriginOffset;
290
+ this.mouseX = offset.x;
291
+ this.mouseY = offset.y;
292
+ }
455
293
 
456
- .float-container {
457
- width: 100%;
458
- height: 100%;
294
+ this.zoomByRatio(this.mouseX, this.mouseY, scaleMultiplier);
459
295
 
460
- &.in-zoom {
461
- transition: all 0.5s ease-in-out;
462
- }
296
+ this.pinchZoomLength = currentPinchLength;
297
+ }
298
+ },
299
+ handleTouchEnd(e) {
300
+ if (e.touches.length > 0) {
301
+ let offset = this.getOffsetXY(e.touches[0]);
302
+ let point = this.transformToScreen(offset.x, offset.y);
303
+ this.mouseX = point.x;
304
+ this.mouseY = point.y;
305
+ } else {
306
+ let now = new Date();
307
+ if (now - this.lastTouchEndTime < 300) {
308
+ if (this.transformOrigin) {
309
+ let offset = this.getTransformOriginOffset;
310
+ this.zoomByRatio(offset.x, offset.y, this.transform.scale);
311
+ } else {
312
+ // We want untransformed x/y here.
313
+ this.zoomByRatio(this.lastSingleFingerOffset.x, this.lastSingleFingerOffset.y, this.transform.scale);
314
+ }
463
315
  }
316
+
317
+ this.lastTouchEndTime = now;
318
+ this.releaseTouches();
319
+ }
320
+ },
321
+ getPinchZoomLength(finger1, finger2) {
322
+ let dx = finger1.clientX - finger2.clientX;
323
+ let dy = finger1.clientY - finger2.clientY;
324
+ return Math.sqrt(dx * dx + dy * dy);
325
+ },
326
+ onDoubleClick(e) {
327
+ e.preventDefault()
328
+ e.stopPropagation()
329
+ let offset = this.getOffsetXY(e);
330
+ if (this.transformOrigin) {
331
+ offset = this.getTransformOriginOffset;
332
+ }
333
+ let scaleMultiplier = this.getScaleMultiplier(-1000);
334
+ this.zoomByRatio(offset.x, offset.y, scaleMultiplier, true);
335
+ },
336
+ onMouseDown(e) {
337
+ if (this.touchInProgress) {
338
+ e.stopPropagation();
339
+ return false;
340
+ }
341
+ let isLeftButton =
342
+ (e.button === 1 && window.event !== null) || e.button === 0;
343
+ if (!isLeftButton) return;
344
+
345
+ let offset = this.getOffsetXY(e);
346
+ let point = this.transformToScreen(offset.x, offset.y);
347
+ this.mouseX = point.x;
348
+ this.mouseY = point.y;
349
+
350
+ document.addEventListener('mousemove', this.onMouseMove);
351
+ document.addEventListener('mouseup', this.onMouseUp);
352
+
353
+ return false;
354
+ },
355
+ onMouseMove(e) {
356
+ if (this.touchInProgress) return;
357
+
358
+ let offset = this.getOffsetXY(e);
359
+ let point = this.transformToScreen(offset.x, offset.y);
360
+ let dx = point.x - this.mouseX;
361
+ let dy = point.y - this.mouseY;
362
+
363
+ this.mouseX = point.x;
364
+ this.mouseY = point.y;
365
+ this.moveTo(dx, dy);
366
+ },
367
+ onMouseUp() {
368
+ this.releaseDocumentMouse();
369
+ },
370
+ onMouseWheel(e) {
371
+ let delta = e.deltaY;
372
+ if (e.deltaMode > 0) delta *= 100;
373
+
374
+ let scaleMultiplier = this.getScaleMultiplier(delta);
375
+
376
+ if (scaleMultiplier !== 1) {
377
+ let offset = this.transformOrigin
378
+ ? this.getTransformOriginOffset
379
+ : this.getOffsetXY(e);
380
+ this.zoomByRatio(offset.x, offset.y, scaleMultiplier);
381
+ e.preventDefault();
382
+ }
383
+ },
384
+ getOffsetXY(e) {
385
+ let offsetX, offsetY;
386
+ let ownerRect = this.owner.getBoundingClientRect();
387
+ offsetX = e.clientX - ownerRect.left;
388
+ offsetY = e.clientY - ownerRect.top;
389
+
390
+ return {x: offsetX, y: offsetY};
391
+ },
392
+ getScaleMultiplier(delta) {
393
+ let sign = Math.sign(delta);
394
+ let deltaAdjustedSpeed = Math.min(0.25, Math.abs(delta / 128));
395
+ return 1 - sign * deltaAdjustedSpeed;
396
+ },
397
+ isNumber(x) {
398
+ return Number.isFinite(x);
399
+ },
400
+ isNaN(value) {
401
+ if (Number.isNaN) {
402
+ return Number.isNaN(value);
403
+ }
404
+
405
+ return value !== value;
406
+ },
407
+ releaseEvents() {
408
+ this.owner.removeEventListener('wheel', this.onMouseWheel);
409
+ this.owner.removeEventListener('mousedown', this.onMouseDown);
410
+ this.owner.removeEventListener('keydown', this.onKeyDown);
411
+ this.owner.removeEventListener('dblclick', this.onDoubleClick);
412
+ this.owner.removeEventListener('touchstart', this.onTouch);
413
+
414
+ if (this.frameAnimation) {
415
+ window.cancelAnimationFrame(this.frameAnimation);
416
+ this.frameAnimation = 0;
417
+ }
418
+
419
+
420
+ this.releaseDocumentMouse();
421
+ this.releaseTouches();
422
+ },
423
+ releaseDocumentMouse() {
424
+ document.removeEventListener('mousemove', this.onMouseMove);
425
+ document.removeEventListener('mouseup', this.onMouseUp);
426
+ },
427
+ releaseTouches() {
428
+ document.removeEventListener('touchmove', this.handleTouchMove);
429
+ document.removeEventListener('touchend', this.handleTouchEnd);
430
+ document.removeEventListener('touchcancel', this.handleTouchEnd);
431
+ this.multiTouch = false;
432
+ this.touchInProgress = false;
433
+ },
434
+ },
435
+ beforeUnmount() {
436
+ this.releaseEvents();
437
+ }
438
+ }
439
+ </script>
440
+ <style lang="scss">
441
+ @use "sass:map";
442
+ @use "../../style/variables/base";
443
+
444
+
445
+ .#{base.$prefix}float {
446
+ width: 100%;
447
+ max-width: 100%;
448
+ max-height: 100vh;
449
+ height: 100%;
450
+ overflow: hidden;
451
+ outline: none;
452
+ border-radius: map.get(base.$borders, 'sm');
453
+
454
+ &.float-bordered {
455
+ border: 1px solid #3a3e3a;
456
+ }
457
+
458
+ .float-container {
459
+ width: 100%;
460
+ height: 100%;
461
+
462
+ &.in-zoom {
463
+ transition: all 0.5s ease-in-out;
464
464
  }
465
+ }
466
+ }
465
467
  </style>