@fmidev/smartmet-alert-client 4.4.19 → 4.7.0-alpha.0

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/.eslintignore +2 -14
  2. package/.github/workflows/test.yaml +26 -0
  3. package/.nvmrc +1 -0
  4. package/dist/index.html +5 -0
  5. package/dist/index.js +105 -135
  6. package/dist/index.mjs +112 -135
  7. package/dist/locale-en-DCEKDw5G.js +8 -0
  8. package/dist/locale-fi-DPiOM1rB.js +8 -0
  9. package/dist/locale-sv-B0FlbgEF.js +8 -0
  10. package/dist/vendor-Cfkkvdz7.js +21 -0
  11. package/dist/vue/index.mjs +15245 -0
  12. package/dist/vue/style.css +1 -0
  13. package/dist/xml-parser-BiNO9kc-.js +13 -0
  14. package/package.json +60 -24
  15. package/src/AlertClientVue.vue +170 -0
  16. package/src/App.vue +55 -205
  17. package/src/assets/img/ui/arrow-down.svg +4 -11
  18. package/src/assets/img/ui/arrow-up.svg +4 -11
  19. package/src/assets/img/ui/clear.svg +7 -21
  20. package/src/assets/img/ui/close.svg +4 -15
  21. package/src/assets/img/ui/toggle-selected.svg +5 -6
  22. package/src/assets/img/ui/toggle-unselected.svg +5 -6
  23. package/src/assets/img/warning/cold-weather.svg +3 -6
  24. package/src/assets/img/warning/flood-level-3.svg +4 -7
  25. package/src/assets/img/warning/forest-fire-weather.svg +2 -6
  26. package/src/assets/img/warning/grass-fire-weather.svg +2 -6
  27. package/src/assets/img/warning/hot-weather.svg +3 -6
  28. package/src/assets/img/warning/pedestrian-safety.svg +3 -7
  29. package/src/assets/img/warning/rain.svg +2 -7
  30. package/src/assets/img/warning/sea-icing.svg +2 -6
  31. package/src/assets/img/warning/sea-thunder-storm.svg +2 -5
  32. package/src/assets/img/warning/sea-water-height-high-water.svg +3 -8
  33. package/src/assets/img/warning/sea-water-height-shallow-water.svg +3 -7
  34. package/src/assets/img/warning/sea-wave-height.svg +4 -7
  35. package/src/assets/img/warning/sea-wind-legend.svg +2 -5
  36. package/src/assets/img/warning/sea-wind.svg +2 -5
  37. package/src/assets/img/warning/several.svg +2 -5
  38. package/src/assets/img/warning/thunder-storm.svg +2 -5
  39. package/src/assets/img/warning/traffic-weather.svg +2 -6
  40. package/src/assets/img/warning/uv-note.svg +2 -6
  41. package/src/assets/img/warning/wind.svg +2 -5
  42. package/src/components/AlertClient.vue +41 -19
  43. package/src/components/CollapsiblePanel.vue +284 -0
  44. package/src/components/DayLarge.vue +12 -7
  45. package/src/components/DaySmall.vue +16 -6
  46. package/src/components/Days.vue +76 -51
  47. package/src/components/DescriptionWarning.vue +15 -8
  48. package/src/components/GrayScaleToggle.vue +11 -6
  49. package/src/components/Legend.vue +36 -248
  50. package/src/components/MapLarge.vue +41 -42
  51. package/src/components/MapSmall.vue +44 -28
  52. package/src/components/PopupRow.vue +6 -3
  53. package/src/components/Region.vue +30 -15
  54. package/src/components/RegionWarning.vue +6 -5
  55. package/src/components/Regions.vue +50 -19
  56. package/src/components/Warning.vue +18 -10
  57. package/src/components/Warnings.vue +36 -21
  58. package/src/main.js +1 -0
  59. package/src/mixins/alertClientCore.js +210 -0
  60. package/src/mixins/config.js +262 -256
  61. package/src/mixins/utils.js +40 -26
  62. package/src/plugins/index.js +1 -1
  63. package/src/scss/_utilities.scss +193 -0
  64. package/src/scss/constants.scss +2 -1
  65. package/src/scss/warningImages.scss +8 -3
  66. package/src/vue.js +41 -0
  67. package/svgo.config.js +45 -0
  68. package/tests/README.md +430 -0
  69. package/tests/fixtures/mockWarningData.js +135 -0
  70. package/tests/integration/warning-flow.spec.js +452 -0
  71. package/tests/setup.js +41 -0
  72. package/tests/unit/components/AlertClient.spec.js +734 -0
  73. package/tests/unit/components/DayLarge.spec.js +281 -0
  74. package/tests/unit/components/DaySmall.spec.js +278 -0
  75. package/tests/unit/components/Days.spec.js +565 -0
  76. package/tests/unit/components/DescriptionWarning.spec.js +432 -0
  77. package/tests/unit/components/GrayScaleToggle.spec.js +311 -0
  78. package/tests/unit/components/Legend.spec.js +223 -0
  79. package/tests/unit/components/MapLarge.spec.js +276 -0
  80. package/tests/unit/components/MapSmall.spec.js +226 -0
  81. package/tests/unit/components/PopupRow.spec.js +261 -0
  82. package/tests/unit/components/Region.spec.js +430 -0
  83. package/tests/unit/components/RegionWarning.snapshot.spec.js +73 -0
  84. package/tests/unit/components/RegionWarning.spec.js +408 -0
  85. package/tests/unit/components/Regions.spec.js +335 -0
  86. package/tests/unit/components/Warning.snapshot.spec.js +107 -0
  87. package/tests/unit/components/Warning.spec.js +472 -0
  88. package/tests/unit/components/Warnings.spec.js +329 -0
  89. package/tests/unit/components/__snapshots__/RegionWarning.snapshot.spec.js.snap +21 -0
  90. package/tests/unit/components/__snapshots__/Warning.snapshot.spec.js.snap +199 -0
  91. package/tests/unit/mixins/config.spec.js +269 -0
  92. package/tests/unit/mixins/i18n.spec.js +115 -0
  93. package/tests/unit/mixins/keycodes.spec.js +37 -0
  94. package/tests/unit/mixins/utils.spec.js +624 -0
  95. package/vite.config.js +96 -26
  96. package/vitest.config.js +40 -0
  97. package/dist/index.mjs.map +0 -1
  98. package/dist/index.relative.html +0 -19
  99. package/dist/index.start.html +0 -20
  100. package/playwright.config.ts +0 -18
  101. package/public/index.relative.html +0 -19
  102. package/public/index.start.html +0 -20
  103. package/src/mixins/panzoom.js +0 -900
  104. package/test/snapshot.test.ts +0 -126
  105. package/vitest.config.ts +0 -6
@@ -1,900 +0,0 @@
1
- /**
2
- * Panzoom 4.5.1 for panning and zooming elements using CSS transforms
3
- * Copyright Timmy Willison and other contributors
4
- * https://github.com/timmywil/panzoom/blob/main/MIT-License.txt
5
- */
6
- /******************************************************************************
7
- Copyright (c) Microsoft Corporation.
8
-
9
- Permission to use, copy, modify, and/or distribute this software for any
10
- purpose with or without fee is hereby granted.
11
-
12
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
13
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
14
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
15
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
16
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
17
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
18
- PERFORMANCE OF THIS SOFTWARE.
19
- ***************************************************************************** */
20
-
21
- let __assign = function () {
22
- __assign =
23
- Object.assign ||
24
- function __assign(t) {
25
- for (var s, i = 1, n = arguments.length; i < n; i++) {
26
- s = arguments[i]
27
- for (const p in s)
28
- if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]
29
- }
30
- return t
31
- }
32
- return __assign.apply(this, arguments)
33
- }
34
-
35
- /* eslint-disable no-var */
36
- if (typeof window !== 'undefined') {
37
- // Support: IE11 only
38
- if (window.NodeList && !NodeList.prototype.forEach) {
39
- NodeList.prototype.forEach = Array.prototype.forEach
40
- }
41
- // Support: IE11 only
42
- // CustomEvent is an object instead of a constructor
43
- if (typeof window.CustomEvent !== 'function') {
44
- window.CustomEvent = function CustomEvent(event, params) {
45
- params = params || { bubbles: false, cancelable: false, detail: null }
46
- var evt = document.createEvent('CustomEvent')
47
- evt.initCustomEvent(
48
- event,
49
- params.bubbles,
50
- params.cancelable,
51
- params.detail
52
- )
53
- return evt
54
- }
55
- }
56
- }
57
-
58
- /**
59
- * Utilites for working with multiple pointer events
60
- */
61
- function findEventIndex(pointers, event) {
62
- var i = pointers.length
63
- while (i--) {
64
- if (pointers[i].pointerId === event.pointerId) {
65
- return i
66
- }
67
- }
68
- return -1
69
- }
70
- function addPointer(pointers, event) {
71
- var i
72
- // Add touches if applicable
73
- if (event.touches) {
74
- i = 0
75
- for (var _i = 0, _a = event.touches; _i < _a.length; _i++) {
76
- var touch = _a[_i]
77
- touch.pointerId = i++
78
- addPointer(pointers, touch)
79
- }
80
- return
81
- }
82
- i = findEventIndex(pointers, event)
83
- // Update if already present
84
- if (i > -1) {
85
- pointers.splice(i, 1)
86
- }
87
- pointers.push(event)
88
- }
89
- function removePointer(pointers, event) {
90
- // Add touches if applicable
91
- if (event.touches) {
92
- // Remove all touches
93
- while (pointers.length) {
94
- pointers.pop()
95
- }
96
- return
97
- }
98
- var i = findEventIndex(pointers, event)
99
- if (i > -1) {
100
- pointers.splice(i, 1)
101
- }
102
- }
103
- /**
104
- * Calculates a center point between
105
- * the given pointer events, for panning
106
- * with multiple pointers.
107
- */
108
- function getMiddle(pointers) {
109
- // Copy to avoid changing by reference
110
- pointers = pointers.slice(0)
111
- var event1 = pointers.pop()
112
- var event2
113
- while ((event2 = pointers.pop())) {
114
- event1 = {
115
- clientX: (event2.clientX - event1.clientX) / 2 + event1.clientX,
116
- clientY: (event2.clientY - event1.clientY) / 2 + event1.clientY,
117
- }
118
- }
119
- return event1
120
- }
121
- /**
122
- * Calculates the distance between two points
123
- * for pinch zooming.
124
- * Limits to the first 2
125
- */
126
- function getDistance(pointers) {
127
- if (pointers.length < 2) {
128
- return 0
129
- }
130
- var event1 = pointers[0]
131
- var event2 = pointers[1]
132
- return Math.sqrt(
133
- Math.pow(Math.abs(event2.clientX - event1.clientX), 2) +
134
- Math.pow(Math.abs(event2.clientY - event1.clientY), 2)
135
- )
136
- }
137
-
138
- var events = {
139
- down: 'mousedown',
140
- move: 'mousemove',
141
- up: 'mouseup mouseleave',
142
- }
143
- if (typeof window !== 'undefined') {
144
- if (typeof window.PointerEvent === 'function') {
145
- events = {
146
- down: 'pointerdown',
147
- move: 'pointermove',
148
- up: 'pointerup pointerleave pointercancel',
149
- }
150
- } else if (typeof window.TouchEvent === 'function') {
151
- events = {
152
- down: 'touchstart',
153
- move: 'touchmove',
154
- up: 'touchend touchcancel',
155
- }
156
- }
157
- }
158
- function onPointer(event, elem, handler, eventOpts) {
159
- events[event].split(' ').forEach(function (name) {
160
- elem.addEventListener(name, handler, eventOpts)
161
- })
162
- }
163
- function destroyPointer(event, elem, handler) {
164
- events[event].split(' ').forEach(function (name) {
165
- elem.removeEventListener(name, handler)
166
- })
167
- }
168
-
169
- var isIE = typeof document !== 'undefined' && !!document.documentMode
170
- /**
171
- * Lazy creation of a CSS style declaration
172
- */
173
- var divStyle
174
- function createStyle() {
175
- if (divStyle) {
176
- return divStyle
177
- }
178
- return (divStyle = document.createElement('div').style)
179
- }
180
- /**
181
- * Proper prefixing for cross-browser compatibility
182
- */
183
- var prefixes = ['webkit', 'moz', 'ms']
184
- var prefixCache = {}
185
- function getPrefixedName(name) {
186
- if (prefixCache[name]) {
187
- return prefixCache[name]
188
- }
189
- var divStyle = createStyle()
190
- if (name in divStyle) {
191
- return (prefixCache[name] = name)
192
- }
193
- var capName = name[0].toUpperCase() + name.slice(1)
194
- var i = prefixes.length
195
- while (i--) {
196
- var prefixedName = ''.concat(prefixes[i]).concat(capName)
197
- if (prefixedName in divStyle) {
198
- return (prefixCache[name] = prefixedName)
199
- }
200
- }
201
- }
202
- /**
203
- * Gets a style value expected to be a number
204
- */
205
- function getCSSNum(name, style) {
206
- return parseFloat(style[getPrefixedName(name)]) || 0
207
- }
208
- function getBoxStyle(elem, name, style) {
209
- if (style === void 0) {
210
- style = window.getComputedStyle(elem)
211
- }
212
- // Support: FF 68+
213
- // Firefox requires specificity for border
214
- var suffix = name === 'border' ? 'Width' : ''
215
- return {
216
- left: getCSSNum(''.concat(name, 'Left').concat(suffix), style),
217
- right: getCSSNum(''.concat(name, 'Right').concat(suffix), style),
218
- top: getCSSNum(''.concat(name, 'Top').concat(suffix), style),
219
- bottom: getCSSNum(''.concat(name, 'Bottom').concat(suffix), style),
220
- }
221
- }
222
- /**
223
- * Set a style using the properly prefixed name
224
- */
225
- function setStyle(elem, name, value) {
226
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
227
- elem.style[getPrefixedName(name)] = value
228
- }
229
- /**
230
- * Constructs the transition from panzoom options
231
- * and takes care of prefixing the transition and transform
232
- */
233
- function setTransition(elem, options) {
234
- var transform = getPrefixedName('transform')
235
- setStyle(
236
- elem,
237
- 'transition',
238
- ''
239
- .concat(transform, ' ')
240
- .concat(options.duration, 'ms ')
241
- .concat(options.easing)
242
- )
243
- }
244
- /**
245
- * Set the transform using the proper prefix
246
- *
247
- * Override the transform setter.
248
- * This is exposed mostly so the user could
249
- * set other parts of a transform
250
- * aside from scale and translate.
251
- * Default is defined in src/css.ts.
252
- *
253
- * ```js
254
- * // This example always sets a rotation
255
- * // when setting the scale and translation
256
- * const panzoom = Panzoom(elem, {
257
- * setTransform: (elem, { scale, x, y }) => {
258
- * panzoom.setStyle('transform', `rotate(0.5turn) scale(${scale}) translate(${x}px, ${y}px)`)
259
- * }
260
- * })
261
- * ```
262
- */
263
- function setTransform(elem, _a, _options) {
264
- var x = _a.x
265
- var y = _a.y
266
- var scale = _a.scale
267
- var isSVG = _a.isSVG
268
- setStyle(
269
- elem,
270
- 'transform',
271
- 'scale('.concat(scale, ') translate(').concat(x, 'px, ').concat(y, 'px)')
272
- )
273
- if (isSVG && isIE) {
274
- var matrixValue = window
275
- .getComputedStyle(elem)
276
- .getPropertyValue('transform')
277
- elem.setAttribute('transform', matrixValue)
278
- }
279
- }
280
- /**
281
- * Dimensions used in containment and focal point zooming
282
- */
283
- function getDimensions(elem) {
284
- var parent = elem.parentNode
285
- var style = window.getComputedStyle(elem)
286
- var parentStyle = window.getComputedStyle(parent)
287
- var rectElem = elem.getBoundingClientRect()
288
- var rectParent = parent.getBoundingClientRect()
289
- return {
290
- elem: {
291
- style,
292
- width: rectElem.width,
293
- height: rectElem.height,
294
- top: rectElem.top,
295
- bottom: rectElem.bottom,
296
- left: rectElem.left,
297
- right: rectElem.right,
298
- margin: getBoxStyle(elem, 'margin', style),
299
- border: getBoxStyle(elem, 'border', style),
300
- },
301
- parent: {
302
- style: parentStyle,
303
- width: rectParent.width,
304
- height: rectParent.height,
305
- top: rectParent.top,
306
- bottom: rectParent.bottom,
307
- left: rectParent.left,
308
- right: rectParent.right,
309
- padding: getBoxStyle(parent, 'padding', parentStyle),
310
- border: getBoxStyle(parent, 'border', parentStyle),
311
- },
312
- }
313
- }
314
-
315
- /**
316
- * Determine if an element is attached to the DOM
317
- * Panzoom requires this so events work properly
318
- */
319
- function isAttached(node) {
320
- var currentNode = node
321
- while (currentNode && currentNode.parentNode) {
322
- if (currentNode.parentNode === document) return true
323
- currentNode =
324
- currentNode.parentNode instanceof ShadowRoot
325
- ? currentNode.parentNode.host
326
- : currentNode.parentNode
327
- }
328
- return false
329
- }
330
-
331
- function getClass(elem) {
332
- return (elem.getAttribute('class') || '').trim()
333
- }
334
- function hasClass(elem, className) {
335
- return (
336
- elem.nodeType === 1 &&
337
- ' '.concat(getClass(elem), ' ').indexOf(' '.concat(className, ' ')) > -1
338
- )
339
- }
340
- function isExcluded(elem, options) {
341
- for (var cur = elem; cur != null; cur = cur.parentNode) {
342
- if (
343
- hasClass(cur, options.excludeClass) ||
344
- options.exclude.indexOf(cur) > -1
345
- ) {
346
- return true
347
- }
348
- }
349
- return false
350
- }
351
-
352
- /**
353
- * Determine if an element is SVG by checking the namespace
354
- * Exception: the <svg> element itself should be treated like HTML
355
- */
356
- var rsvg = /^http:[\w\.\/]+svg$/
357
- function isSVGElement(elem) {
358
- return rsvg.test(elem.namespaceURI) && elem.nodeName.toLowerCase() !== 'svg'
359
- }
360
-
361
- function shallowClone(obj) {
362
- var clone = {}
363
- for (var key in obj) {
364
- if (obj.hasOwnProperty(key)) {
365
- clone[key] = obj[key]
366
- }
367
- }
368
- return clone
369
- }
370
-
371
- var defaultOptions = {
372
- animate: false,
373
- canvas: false,
374
- cursor: 'move',
375
- disablePan: false,
376
- disableZoom: false,
377
- disableXAxis: false,
378
- disableYAxis: false,
379
- duration: 200,
380
- easing: 'ease-in-out',
381
- exclude: [],
382
- excludeClass: 'panzoom-exclude',
383
- handleStartEvent: function (e) {
384
- e.preventDefault()
385
- e.stopPropagation()
386
- },
387
- maxScale: 4,
388
- minScale: 0.125,
389
- overflow: 'hidden',
390
- panOnlyWhenZoomed: false,
391
- pinchAndPan: false,
392
- relative: false,
393
- setTransform,
394
- startX: 0,
395
- startY: 0,
396
- startScale: 1,
397
- step: 0.3,
398
- touchAction: 'none',
399
- }
400
- function Panzoom(elem, options) {
401
- if (!elem) {
402
- throw new Error('Panzoom requires an element as an argument')
403
- }
404
- if (elem.nodeType !== 1) {
405
- throw new Error('Panzoom requires an element with a nodeType of 1')
406
- }
407
- if (!isAttached(elem)) {
408
- throw new Error(
409
- 'Panzoom should be called on elements that have been attached to the DOM'
410
- )
411
- }
412
- options = __assign(__assign({}, defaultOptions), options)
413
- var isSVG = isSVGElement(elem)
414
- var parent = elem.parentNode
415
- // Set parent styles
416
- parent.style.overflow = options.overflow
417
- parent.style.userSelect = 'none'
418
- // This is important for mobile to
419
- // prevent scrolling while panning
420
- parent.style.touchAction = options.touchAction
421
- ;(options.canvas ? parent : elem).style.cursor = options.cursor
422
- // Set element styles
423
- elem.style.userSelect = 'none'
424
- elem.style.touchAction = options.touchAction
425
- // The default for HTML is '50% 50%'
426
- // The default for SVG is '0 0'
427
- // SVG can't be changed in IE
428
- setStyle(
429
- elem,
430
- 'transformOrigin',
431
- typeof options.origin === 'string'
432
- ? options.origin
433
- : isSVG
434
- ? '0 0'
435
- : '50% 50%'
436
- )
437
- function resetStyle() {
438
- parent.style.overflow = ''
439
- parent.style.userSelect = ''
440
- parent.style.touchAction = ''
441
- parent.style.cursor = ''
442
- elem.style.cursor = ''
443
- elem.style.userSelect = ''
444
- elem.style.touchAction = ''
445
- setStyle(elem, 'transformOrigin', '')
446
- }
447
- function setOptions(opts) {
448
- if (opts === void 0) {
449
- opts = {}
450
- }
451
- for (var key in opts) {
452
- if (opts.hasOwnProperty(key)) {
453
- options[key] = opts[key]
454
- }
455
- }
456
- // Handle option side-effects
457
- if (opts.hasOwnProperty('cursor') || opts.hasOwnProperty('canvas')) {
458
- parent.style.cursor = elem.style.cursor = ''
459
- ;(options.canvas ? parent : elem).style.cursor = options.cursor
460
- }
461
- if (opts.hasOwnProperty('overflow')) {
462
- parent.style.overflow = opts.overflow
463
- }
464
- if (opts.hasOwnProperty('touchAction')) {
465
- parent.style.touchAction = opts.touchAction
466
- elem.style.touchAction = opts.touchAction
467
- }
468
- }
469
- var x = 0
470
- var y = 0
471
- var scale = 1
472
- var isPanning = false
473
- zoom(options.startScale, { animate: false, force: true })
474
- // Wait for scale to update
475
- // for accurate dimensions
476
- // to constrain initial values
477
- setTimeout(function () {
478
- pan(options.startX, options.startY, { animate: false, force: true })
479
- })
480
- function trigger(eventName, detail, opts) {
481
- if (opts.silent) {
482
- return
483
- }
484
- var event = new CustomEvent(eventName, { detail })
485
- elem.dispatchEvent(event)
486
- }
487
- function setTransformWithEvent(eventName, opts, originalEvent) {
488
- var value = {
489
- x,
490
- y,
491
- scale,
492
- isSVG,
493
- originalEvent,
494
- }
495
- requestAnimationFrame(function () {
496
- if (typeof opts.animate === 'boolean') {
497
- if (opts.animate) {
498
- setTransition(elem, opts)
499
- } else {
500
- setStyle(elem, 'transition', 'none')
501
- }
502
- }
503
- opts.setTransform(elem, value, opts)
504
- trigger(eventName, value, opts)
505
- trigger('panzoomchange', value, opts)
506
- })
507
- return value
508
- }
509
- function constrainXY(toX, toY, toScale, panOptions) {
510
- var opts = __assign(__assign({}, options), panOptions)
511
- var result = { x, y, opts }
512
- if (
513
- !opts.force &&
514
- (opts.disablePan || (opts.panOnlyWhenZoomed && scale === opts.startScale))
515
- ) {
516
- return result
517
- }
518
- toX = parseFloat(toX)
519
- toY = parseFloat(toY)
520
- if (!opts.disableXAxis) {
521
- result.x = (opts.relative ? x : 0) + toX
522
- }
523
- if (!opts.disableYAxis) {
524
- result.y = (opts.relative ? y : 0) + toY
525
- }
526
- if (opts.contain) {
527
- var dims = getDimensions(elem)
528
- var realWidth = dims.elem.width / scale
529
- var realHeight = dims.elem.height / scale
530
- var scaledWidth = realWidth * toScale
531
- var scaledHeight = realHeight * toScale
532
- var diffHorizontal = (scaledWidth - realWidth) / 2
533
- var diffVertical = (scaledHeight - realHeight) / 2
534
- if (opts.contain === 'inside') {
535
- var minX =
536
- (-dims.elem.margin.left - dims.parent.padding.left + diffHorizontal) /
537
- toScale
538
- var maxX =
539
- (dims.parent.width -
540
- scaledWidth -
541
- dims.parent.padding.left -
542
- dims.elem.margin.left -
543
- dims.parent.border.left -
544
- dims.parent.border.right +
545
- diffHorizontal) /
546
- toScale
547
- result.x = Math.max(Math.min(result.x, maxX), minX)
548
- var minY =
549
- (-dims.elem.margin.top - dims.parent.padding.top + diffVertical) /
550
- toScale
551
- var maxY =
552
- (dims.parent.height -
553
- scaledHeight -
554
- dims.parent.padding.top -
555
- dims.elem.margin.top -
556
- dims.parent.border.top -
557
- dims.parent.border.bottom +
558
- diffVertical) /
559
- toScale
560
- result.y = Math.max(Math.min(result.y, maxY), minY)
561
- } else if (opts.contain === 'outside') {
562
- var minX =
563
- (-(scaledWidth - dims.parent.width) -
564
- dims.parent.padding.left -
565
- dims.parent.border.left -
566
- dims.parent.border.right +
567
- diffHorizontal) /
568
- toScale
569
- var maxX = (diffHorizontal - dims.parent.padding.left) / toScale
570
- result.x = Math.max(Math.min(result.x, maxX), minX)
571
- var minY =
572
- (-(scaledHeight - dims.parent.height) -
573
- dims.parent.padding.top -
574
- dims.parent.border.top -
575
- dims.parent.border.bottom +
576
- diffVertical) /
577
- toScale
578
- var maxY = (diffVertical - dims.parent.padding.top) / toScale
579
- result.y = Math.max(Math.min(result.y, maxY), minY)
580
- }
581
- }
582
- if (opts.roundPixels) {
583
- result.x = Math.round(result.x)
584
- result.y = Math.round(result.y)
585
- }
586
- return result
587
- }
588
- function constrainScale(toScale, zoomOptions) {
589
- var opts = __assign(__assign({}, options), zoomOptions)
590
- var result = { scale, opts }
591
- if (!opts.force && opts.disableZoom) {
592
- return result
593
- }
594
- var minScale = options.minScale
595
- var maxScale = options.maxScale
596
- if (opts.contain) {
597
- var dims = getDimensions(elem)
598
- var elemWidth = dims.elem.width / scale
599
- var elemHeight = dims.elem.height / scale
600
- if (elemWidth > 1 && elemHeight > 1) {
601
- var parentWidth =
602
- dims.parent.width - dims.parent.border.left - dims.parent.border.right
603
- var parentHeight =
604
- dims.parent.height -
605
- dims.parent.border.top -
606
- dims.parent.border.bottom
607
- var elemScaledWidth = parentWidth / elemWidth
608
- var elemScaledHeight = parentHeight / elemHeight
609
- if (options.contain === 'inside') {
610
- maxScale = Math.min(maxScale, elemScaledWidth, elemScaledHeight)
611
- } else if (options.contain === 'outside') {
612
- minScale = Math.max(minScale, elemScaledWidth, elemScaledHeight)
613
- }
614
- }
615
- }
616
- result.scale = Math.min(Math.max(toScale, minScale), maxScale)
617
- return result
618
- }
619
- function pan(toX, toY, panOptions, originalEvent) {
620
- var result = constrainXY(toX, toY, scale, panOptions)
621
- // Only try to set if the result is somehow different
622
- if (x !== result.x || y !== result.y) {
623
- x = result.x
624
- y = result.y
625
- return setTransformWithEvent('panzoompan', result.opts, originalEvent)
626
- }
627
- return {
628
- x,
629
- y,
630
- scale,
631
- isSVG,
632
- originalEvent,
633
- }
634
- }
635
- function zoom(toScale, zoomOptions, originalEvent) {
636
- var result = constrainScale(toScale, zoomOptions)
637
- var opts = result.opts
638
- if (!opts.force && opts.disableZoom) {
639
- return
640
- }
641
- toScale = result.scale
642
- var toX = x
643
- var toY = y
644
- if (opts.focal) {
645
- // The difference between the point after the scale and the point before the scale
646
- // plus the current translation after the scale
647
- // neutralized to no scale (as the transform scale will apply to the translation)
648
- var focal = opts.focal
649
- toX = (focal.x / toScale - focal.x / scale + x * toScale) / toScale
650
- toY = (focal.y / toScale - focal.y / scale + y * toScale) / toScale
651
- }
652
- var panResult = constrainXY(toX, toY, toScale, {
653
- relative: false,
654
- force: true,
655
- })
656
- x = panResult.x
657
- y = panResult.y
658
- scale = toScale
659
- return setTransformWithEvent('panzoomzoom', opts, originalEvent)
660
- }
661
- function zoomInOut(isIn, zoomOptions) {
662
- var opts = __assign(
663
- __assign(__assign({}, options), { animate: true }),
664
- zoomOptions
665
- )
666
- return zoom(scale * Math.exp((isIn ? 1 : -1) * opts.step), opts)
667
- }
668
- function zoomIn(zoomOptions) {
669
- return zoomInOut(true, zoomOptions)
670
- }
671
- function zoomOut(zoomOptions) {
672
- return zoomInOut(false, zoomOptions)
673
- }
674
- function zoomToPoint(toScale, point, zoomOptions, originalEvent) {
675
- var dims = getDimensions(elem)
676
- // Instead of thinking of operating on the panzoom element,
677
- // think of operating on the area inside the panzoom
678
- // element's parent
679
- // Subtract padding and border
680
- var effectiveArea = {
681
- width:
682
- dims.parent.width -
683
- dims.parent.padding.left -
684
- dims.parent.padding.right -
685
- dims.parent.border.left -
686
- dims.parent.border.right,
687
- height:
688
- dims.parent.height -
689
- dims.parent.padding.top -
690
- dims.parent.padding.bottom -
691
- dims.parent.border.top -
692
- dims.parent.border.bottom,
693
- }
694
- // Adjust the clientX/clientY to ignore the area
695
- // outside the effective area
696
- var clientX =
697
- point.clientX -
698
- dims.parent.left -
699
- dims.parent.padding.left -
700
- dims.parent.border.left -
701
- dims.elem.margin.left
702
- var clientY =
703
- point.clientY -
704
- dims.parent.top -
705
- dims.parent.padding.top -
706
- dims.parent.border.top -
707
- dims.elem.margin.top
708
- // Adjust the clientX/clientY for HTML elements,
709
- // because they have a transform-origin of 50% 50%
710
- if (!isSVG) {
711
- clientX -= dims.elem.width / scale / 2
712
- clientY -= dims.elem.height / scale / 2
713
- }
714
- // Convert the mouse point from it's position over the
715
- // effective area before the scale to the position
716
- // over the effective area after the scale.
717
- var focal = {
718
- x: (clientX / effectiveArea.width) * (effectiveArea.width * toScale),
719
- y: (clientY / effectiveArea.height) * (effectiveArea.height * toScale),
720
- }
721
- return zoom(
722
- toScale,
723
- __assign(__assign({}, zoomOptions), { animate: false, focal }),
724
- originalEvent
725
- )
726
- }
727
- function zoomWithWheel(event, zoomOptions) {
728
- // Need to prevent the default here
729
- // or it conflicts with regular page scroll
730
- event.preventDefault()
731
- var opts = __assign(__assign(__assign({}, options), zoomOptions), {
732
- animate: false,
733
- })
734
- // Normalize to deltaX in case shift modifier is used on Mac
735
- var delta = event.deltaY === 0 && event.deltaX ? event.deltaX : event.deltaY
736
- var wheel = delta < 0 ? 1 : -1
737
- var toScale = constrainScale(
738
- scale * Math.exp((wheel * opts.step) / 3),
739
- opts
740
- ).scale
741
- return zoomToPoint(toScale, event, opts, event)
742
- }
743
- function reset(resetOptions) {
744
- var opts = __assign(
745
- __assign(__assign({}, options), { animate: true, force: true }),
746
- resetOptions
747
- )
748
- scale = constrainScale(opts.startScale, opts).scale
749
- var panResult = constrainXY(opts.startX, opts.startY, scale, opts)
750
- x = panResult.x
751
- y = panResult.y
752
- return setTransformWithEvent('panzoomreset', opts)
753
- }
754
- var origX
755
- var origY
756
- var startClientX
757
- var startClientY
758
- var startScale
759
- var startDistance
760
- var pointers = []
761
- function handleDown(event) {
762
- // Don't handle this event if the target is excluded
763
- if (isExcluded(event.target, options)) {
764
- return
765
- }
766
- addPointer(pointers, event)
767
- isPanning = true
768
- options.handleStartEvent(event)
769
- origX = x
770
- origY = y
771
- trigger(
772
- 'panzoomstart',
773
- { x, y, scale, isSVG, originalEvent: event },
774
- options
775
- )
776
- // This works whether there are multiple
777
- // pointers or not
778
- var point = getMiddle(pointers)
779
- startClientX = point.clientX
780
- startClientY = point.clientY
781
- startScale = scale
782
- startDistance = getDistance(pointers)
783
- }
784
- function handleMove(event) {
785
- if (
786
- !isPanning ||
787
- origX === undefined ||
788
- origY === undefined ||
789
- startClientX === undefined ||
790
- startClientY === undefined
791
- ) {
792
- return
793
- }
794
- addPointer(pointers, event)
795
- var current = getMiddle(pointers)
796
- var hasMultiple = pointers.length > 1
797
- var toScale = scale
798
- if (hasMultiple) {
799
- // A startDistance of 0 means
800
- // that there weren't 2 pointers
801
- // handled on start
802
- if (startDistance === 0) {
803
- startDistance = getDistance(pointers)
804
- }
805
- // Use the distance between the first 2 pointers
806
- // to determine the current scale
807
- var diff = getDistance(pointers) - startDistance
808
- toScale = constrainScale((diff * options.step) / 80 + startScale).scale
809
- zoomToPoint(toScale, current, { animate: false }, event)
810
- }
811
- // Pan during pinch if pinchAndPan is true.
812
- // Note: some calculations may be off because the zoom
813
- // above has not yet rendered. However, the behavior
814
- // was removed before the new scale was used in the following
815
- // pan calculation.
816
- // See https://github.com/timmywil/panzoom/issues/512
817
- // and https://github.com/timmywil/panzoom/issues/606
818
- if (!hasMultiple || options.pinchAndPan) {
819
- pan(
820
- origX + (current.clientX - startClientX) / toScale,
821
- origY + (current.clientY - startClientY) / toScale,
822
- {
823
- animate: false,
824
- },
825
- event
826
- )
827
- }
828
- }
829
- function handleUp(event) {
830
- // Don't call panzoomend when panning with 2 touches
831
- // until both touches end
832
- if (pointers.length === 1) {
833
- trigger(
834
- 'panzoomend',
835
- { x, y, scale, isSVG, originalEvent: event },
836
- options
837
- )
838
- }
839
- // Note: don't remove all pointers
840
- // Can restart without having to reinitiate all of them
841
- // Remove the pointer regardless of the isPanning state
842
- removePointer(pointers, event)
843
- if (!isPanning) {
844
- return
845
- }
846
- isPanning = false
847
- origX = origY = startClientX = startClientY = undefined
848
- }
849
- var bound = false
850
- function bind() {
851
- if (bound) {
852
- return
853
- }
854
- bound = true
855
- onPointer('down', options.canvas ? parent : elem, handleDown)
856
- onPointer('move', document, handleMove, { passive: true })
857
- onPointer('up', document, handleUp, { passive: true })
858
- }
859
- function destroy() {
860
- bound = false
861
- destroyPointer('down', options.canvas ? parent : elem, handleDown)
862
- destroyPointer('move', document, handleMove)
863
- destroyPointer('up', document, handleUp)
864
- }
865
- if (!options.noBind) {
866
- bind()
867
- }
868
- return {
869
- bind,
870
- destroy,
871
- eventNames: events,
872
- getPan: function () {
873
- return { x, y }
874
- },
875
- getScale: function () {
876
- return scale
877
- },
878
- getOptions: function () {
879
- return shallowClone(options)
880
- },
881
- handleDown,
882
- handleMove,
883
- handleUp,
884
- pan,
885
- reset,
886
- resetStyle,
887
- setOptions,
888
- setStyle: function (name, value) {
889
- return setStyle(elem, name, value)
890
- },
891
- zoom,
892
- zoomIn,
893
- zoomOut,
894
- zoomToPoint,
895
- zoomWithWheel,
896
- }
897
- }
898
- Panzoom.defaultOptions = defaultOptions
899
-
900
- export { Panzoom as default }