zumly 0.9.10 → 0.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/zumly.umd.js DELETED
@@ -1,779 +0,0 @@
1
- /**
2
- * zumly v0.9.9
3
- * Author Juan Martín Muda, @license MIT
4
- * https://zumly.org
5
- */
6
- (function (global, factory) {
7
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
8
- typeof define === 'function' && define.amd ? define(factory) :
9
- (global = global || self, global.zumly = factory());
10
- }(this, (function () { 'use strict';
11
-
12
- function styleInject(css, ref) {
13
- if ( ref === void 0 ) ref = {};
14
- var insertAt = ref.insertAt;
15
-
16
- if (!css || typeof document === 'undefined') { return; }
17
-
18
- var head = document.head || document.getElementsByTagName('head')[0];
19
- var style = document.createElement('style');
20
- style.type = 'text/css';
21
-
22
- if (insertAt === 'top') {
23
- if (head.firstChild) {
24
- head.insertBefore(style, head.firstChild);
25
- } else {
26
- head.appendChild(style);
27
- }
28
- } else {
29
- head.appendChild(style);
30
- }
31
-
32
- if (style.styleSheet) {
33
- style.styleSheet.cssText = css;
34
- } else {
35
- style.appendChild(document.createTextNode(css));
36
- }
37
- }
38
-
39
- var css_248z = "\n.zumly-canvas {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n margin: 0;\n padding: 0;\n perspective: 1000px;\n cursor: zoom-out;\n}\n\n.zumly-canvas:focus {\n outline: none;\n}\n\n.z-view {\n position: absolute;\n}\n\n.z-view.is-current-view {\n cursor: default;\n}\n\n.z-view.is-new-current-view {\n\n}\n\n.z-view.is-previous-view, .z-view.is-last-view, .z-view.has-no-events {\n pointer-events: none;\n user-select: none;\n}\n\n.z-view.performance {\n will-change: transform, opacity, filter\n}\n\n.z-view.hide {\n opacity: 0\n}\n\n.zoom-me {\n cursor: zoom-in;\n}\n\n.zoom-me > .zoomed {}\n";
40
- styleInject(css_248z);
41
-
42
- function checkArray (array) {
43
- // remove duplicates and map
44
- if (array !== undefined && array[0].toLowerCase() === 'none') {
45
- return true
46
- }
47
- if (array !== undefined && array.length > 0) {
48
- const unique = array => [...new Set(array)];
49
- const lowerArray = array.map(e => e.toLowerCase());
50
- return unique(lowerArray).every(value => ['blur', 'sepia', 'saturate'].indexOf(value) !== -1)
51
- }
52
- }
53
-
54
- function setFx (values) {
55
- var start = '';
56
- var end = '';
57
- if (values !== undefined) {
58
- values.map(effect => {
59
- start += `${effect.toLowerCase() === 'blur' ? 'blur(0px) ' : effect.toLowerCase() === 'sepia' ? 'sepia(0) ' : effect.toLowerCase() === 'saturate' ? 'saturate(0) ' : 'none'}`;
60
- end += `${effect.toLowerCase() === 'blur' ? 'blur(0.8px) ' : effect.toLowerCase() === 'sepia' ? 'sepia(5) ' : effect.toLowerCase() === 'saturate' ? 'saturate(8) ' : 'none'}`;
61
- });
62
- return [start, end]
63
- }
64
- }
65
- function assignProperty (instance, propertiesToAdd, value) {
66
- instance[propertiesToAdd] = value;
67
- }
68
-
69
- function validate (instance, name, value, type, options = { isRequired: false, defaultValue: 0, allowedValues: 0, hasValidation: 0, hasAssignFunction: 0 }) {
70
- var msg = `'${name}' property is required when instance is defined`;
71
- var msg1 = `'${name}' property has problems`;
72
- var checkValue = value !== undefined;
73
- var checkDefault = options.defaultValue !== undefined;
74
- var checkCustomValidation = options.hasValidation !== undefined;
75
- var checkCustomAssign = options.hasAssignFunction !== undefined;
76
- if (type === 'string' || type === 'object' || type === 'boolean') {
77
- var checkTypeof = typeof value === type; // eslint-disable-line
78
- // value = checkTypeof && type === 'string' ? value.toLowerCase() : value
79
- } else if (type === 'array') {
80
- checkTypeof = Array.isArray(value);
81
- }
82
- if (options.isRequired) {
83
- checkValue && checkTypeof ? assignProperty(instance, name, value) : notification(false, msg, 'error');
84
- }
85
- if (checkDefault && !checkCustomValidation && !checkCustomAssign) {
86
- checkValue && checkTypeof ? assignProperty(instance, name, value) : value === undefined ? assignProperty(instance, name, options.defaultValue) : notification(false, msg1, 'error');
87
- }
88
- if (checkCustomValidation && checkDefault && !checkCustomAssign) {
89
- checkValue && checkTypeof && options.hasValidation ? assignProperty(instance, name, value) : value === undefined ? assignProperty(instance, name, options.defaultValue) : notification(false, msg1, 'error');
90
- }
91
- // console.log(name, checkCustomValidation, checkDefault, checkCustomAssign)
92
- if (checkCustomValidation && checkDefault && checkCustomAssign) {
93
- checkValue && checkTypeof && options.hasValidation ? assignProperty(instance, name, options.hasAssignFunction) : value === undefined ? assignProperty(instance, name, options.defaultValue) : notification(false, msg1, 'error');
94
- }
95
- }
96
-
97
- function shimIdleCallBack (cb) {
98
- var start = Date.now();
99
- return setTimeout(() => {
100
- cb({ didTimeout: false, timeRemaining () { return Math.max(0, 50 - (Date.now() - start)) } }); // eslint-disable-line
101
- }, 1)
102
- }
103
-
104
- function prepareCSS (instance) {
105
- var instanceStyle = document.createElement('style');
106
- const views = ['current-view', 'previous-view', 'last-view'];
107
- let result = '';
108
- views.map(view => {
109
- result += `
110
- .zoom-${view}-${instance} {
111
- animation-name: zoom-${view}-${instance};
112
- animation-duration: var(--zoom-duration-${instance});
113
- animation-timing-function: var(--zoom-ease-${instance});
114
- }
115
- @keyframes zoom-${view}-${instance} {
116
- 0% {
117
- transform-origin: var(--${view}-transformOrigin-start-${instance});
118
- transform: var(--${view}-transform-start-${instance});
119
- opacity: var(--${view}-opacity-start-${instance});
120
- filter: var(--${view}-filter-start-${instance})
121
- }
122
- 100% {
123
- transform-origin: var(--${view}-transformOrigin-end-${instance});
124
- transform: var(--${view}-transform-end-${instance});
125
- opacity: var(--${view}-opacity-end-${instance});
126
- filter: var(--${view}-filter-end-${instance})
127
- }
128
- }
129
- `;
130
- });
131
- instanceStyle.innerHTML = result;
132
- document.head.appendChild(instanceStyle);
133
- }
134
-
135
- function setCSSVariables (transition, currentStage, instance) {
136
- const viewStage = currentStage;
137
- const current = viewStage.views[0];
138
- const previous = viewStage.views[1];
139
- const last = viewStage.views[2];
140
- const views = [{ name: 'current-view', stage: current }, { name: 'previous-view', stage: previous }, { name: 'last-view', stage: last }];
141
- views.map(view => {
142
- if (transition === 'zoomOut' && view.stage !== undefined) {
143
- document.documentElement.style.setProperty(`--${view.name}-transform-start-${instance}`, view.stage.forwardState.transform);
144
- document.documentElement.style.setProperty(`--${view.name}-transform-end-${instance}`, view.stage.backwardState.transform);
145
- document.documentElement.style.setProperty(`--${view.name}-transformOrigin-start-${instance}`, view.stage.forwardState.origin);
146
- document.documentElement.style.setProperty(`--${view.name}-transformOrigin-end-${instance}`, view.stage.backwardState.origin);
147
- document.documentElement.style.setProperty(`--${view.name}-opacity-start-${instance}`, 1);
148
- document.documentElement.style.setProperty(`--${view.name}-filter-start-${instance}`, view.stage.forwardState.filter);
149
- document.documentElement.style.setProperty(`--${view.name}-filter-end-${instance}`, view.stage.backwardState.filter);
150
- if (view.name === 'current-view') {
151
- document.documentElement.style.setProperty(`--zoom-duration-${instance}`, view.stage.backwardState.duration);
152
- document.documentElement.style.setProperty(`--zoom-ease-${instance}`, view.stage.backwardState.ease);
153
- document.documentElement.style.setProperty(`--${view.name}-opacity-end-${instance}`, 0);
154
- document.documentElement.style.setProperty(`--${view.name}-filter-start-${instance}`, 'none');
155
- document.documentElement.style.setProperty(`--${view.name}-filter-end-${instance}`, 'none');
156
- } else {
157
- document.documentElement.style.setProperty(`--${view.name}-opacity-end-${instance}`, 1);
158
- }
159
- }
160
- if (transition === 'zoomIn' && view.stage !== undefined) {
161
- document.documentElement.style.setProperty(`--${view.name}-transform-start-${instance}`, view.stage.backwardState.transform);
162
- document.documentElement.style.setProperty(`--${view.name}-transform-end-${instance}`, view.stage.forwardState.transform);
163
- document.documentElement.style.setProperty(`--${view.name}-transformOrigin-start-${instance}`, view.stage.backwardState.origin);
164
- document.documentElement.style.setProperty(`--${view.name}-transformOrigin-end-${instance}`, view.stage.forwardState.origin);
165
- document.documentElement.style.setProperty(`--${view.name}-filter-start-${instance}`, view.stage.backwardState.filter);
166
- document.documentElement.style.setProperty(`--${view.name}-filter-end-${instance}`, view.stage.forwardState.filter);
167
- if (view.name === 'current-view') {
168
- document.documentElement.style.setProperty(`--zoom-duration-${instance}`, view.stage.forwardState.duration);
169
- document.documentElement.style.setProperty(`--zoom-ease-${instance}`, view.stage.forwardState.ease);
170
- document.documentElement.style.setProperty(`--${view.name}-opacity-start-${instance}`, 0);
171
- document.documentElement.style.setProperty(`--${view.name}-filter-start-${instance}`, 'none');
172
- document.documentElement.style.setProperty(`--${view.name}-filter-end-${instance}`, 'none');
173
- } else {
174
- document.documentElement.style.setProperty(`--${view.name}-opacity-start-${instance}`, 1);
175
- }
176
- document.documentElement.style.setProperty(`--${view.name}-opacity-end-${instance}`, 1);
177
- }
178
- });
179
- }
180
-
181
- async function renderView (el, canvas, views, init) {
182
- var viewName = null;
183
- init ? viewName = el : viewName = el.dataset.to;
184
- var newView = document.createElement('template');
185
- // makes optional de 'render' function
186
- typeof views[viewName] === 'object' && views[viewName].render !== undefined
187
- ? newView.innerHTML = await views[viewName].render()
188
- : newView.innerHTML = views[viewName];
189
-
190
- const vv = newView.content.querySelector('.z-view');
191
- if (!init) {
192
- vv.classList.add('is-new-current-view');
193
- vv.classList.add('has-no-events');
194
- vv.classList.add('hide');
195
- vv.classList.add('performance');
196
- } else {
197
- vv.classList.add('is-current-view');
198
- }
199
- vv.style.transformOrigin = '0 0';
200
- vv.dataset.viewName = viewName;
201
- var appendedView = await canvas.append(newView.content);
202
- // makes optional de 'mounted' hook
203
- if (typeof views[viewName] === 'object' && views[viewName].mounted !== undefined && typeof views[viewName].mounted() === 'function') await views[viewName].mounted();
204
- }
205
-
206
- function notification (debug, msg, type) {
207
- if (msg && type === 'welcome') {
208
- console.info(`%c Zumly %c ${msg}`, 'background: #424085; color: white; border-radius: 3px;', 'color: #424085'); // eslint-disable-line no-console
209
- }
210
- if (msg && debug && (type === 'info' || type === undefined)) {
211
- console.info(`%c Zumly %c ${msg}`, 'background: #6679A3; color: #304157; border-radius: 3px;', 'color: #6679A3'); // eslint-disable-line no-console
212
- }
213
- if (msg && type === 'warn') {
214
- console.warn(`%c Zumly %c ${msg}`, 'background: #DCBF53; color: #424085; border-radius: 3px;', 'color: #424085'); // eslint-disable-line no-console
215
- }
216
- if (msg && type === 'error') {
217
- console.error(`%c Zumly %c ${msg}`, 'background: #BE4747; color: white; border-radius: 3px;', 'color: #424085'); // eslint-disable-line no-console
218
- }
219
- }
220
-
221
- function checkParameters (parameters, instance) {
222
- // First check if options are provided
223
- if (parameters && typeof parameters === 'object') {
224
- assignProperty(instance, 'options', true);
225
- // Then check its properties
226
- // mount property. String DOM element. Required
227
- validate(instance, 'mount', parameters.mount, 'string', { isRequired: true });
228
- // initialView property. Strng view name. Required
229
- validate(instance, 'initialView', parameters.initialView, 'string', { isRequired: true });
230
- // views property. Object with views. Required
231
- validate(instance, 'views', parameters.views, 'object', { isRequired: true });
232
- // debug property. Boolean. Optional. Default false
233
- validate(instance, 'debug', parameters.debug, 'boolean', { defaultValue: false });
234
- // Check transtions
235
- if (parameters.transitions && typeof parameters.transitions === 'object') {
236
- // value exist; type, allowed, deafult
237
- validate(instance, 'cover', parameters.transitions.cover, 'string', { defaultValue: 'width', hasValidation: () => { ['height', 'width'].indexOf(parameters.transitions.cover.toLowerCase()) !== -1; } }); // eslint-disable-line
238
- // value, type, , default
239
- validate(instance, 'duration', parameters.transitions.duration, 'string', { defaultValue: '1s' });
240
- // value, type, ,default
241
- validate(instance, 'ease', parameters.transitions.ease, 'string', { defaultValue: 'ease-in-out' });
242
- // value, type, custom validation, custom asignament, default
243
- validate(instance, 'effects', parameters.transitions.effects, 'array', { defaultValue: ['none', 'none'], hasValidation: checkArray(parameters.transitions.effects), hasAssignFunction: setFx(parameters.transitions.effects) });
244
- } else {
245
- // assign deafult values
246
- assignProperty(instance, 'cover', 'width');
247
- assignProperty(instance, 'duration', '1s');
248
- assignProperty(instance, 'ease', 'ease-in-out');
249
- assignProperty(instance, 'effects', ['none', 'none']);
250
- }
251
- } else {
252
- notification(false, '\'options\' object has to be provided when instance is defined', 'error');
253
- }
254
- }
255
-
256
- window.requestIdleCallback = window.requestIdleCallback || shimIdleCallBack;
257
-
258
- /**
259
- * Zumly
260
- * Powers your apps with a zoomable user interface (ZUI) taste.
261
- * @class
262
- */
263
- class Zumly {
264
- /**
265
- * Creates a Zumly instance
266
- * @constructor
267
- * @params {Objet} options
268
- * @example
269
- * new Zumly({
270
- * mount: '.mount',
271
- * initialView: 'home',
272
- * views: {
273
- * home,
274
- * contact,
275
- * ...
276
- * }
277
- *
278
- */
279
- constructor (options) {
280
- // Internal state:
281
- // Register global instances of Zumly
282
- this.instance = Zumly.counter;
283
- // Store snapshots of each zoom transition
284
- this.storedViews = [];
285
- // Show current zoom level properties
286
- this.currentStage = null;
287
- // Store the scale of previous zoom transition
288
- this.storedPreviousScale = [1];
289
- // Array of events useful for debugging
290
- this.trace = [];
291
- // Deactive events during transtions
292
- this.blockEvents = false;
293
- // Initial values for gesture events
294
- this.touchstartX = 0;
295
- this.touchstartY = 0;
296
- this.touchendX = 0;
297
- this.touchendY = 0;
298
- this.touching = false;
299
- // Check if user options exist
300
- checkParameters(options, this);
301
- if (this.options) {
302
- // Event bindings:
303
- this._onZoom = this.onZoom.bind(this);
304
- this._onZoomInHandlerStart = this.onZoomInHandlerStart.bind(this);
305
- this._onZoomInHandlerEnd = this.onZoomInHandlerEnd.bind(this);
306
- this._onZoomOutHandlerStart = this.onZoomOutHandlerStart.bind(this);
307
- this._onZoomOutHandlerEnd = this.onZoomOutHandlerEnd.bind(this);
308
- this._onTouchStart = this.onTouchStart.bind(this);
309
- this._onTouchEnd = this.onTouchEnd.bind(this);
310
- this._onKeyUp = this.onKeyUp.bind(this);
311
- this._onWeel = this.onWeel.bind(this);
312
- // Prepare the instance:
313
- this.canvas = document.querySelector(this.mount);
314
- this.canvas.setAttribute('tabindex', 0);
315
- this.canvas.addEventListener('mouseup', this._onZoom, false);
316
- this.canvas.addEventListener('touchend', this._onZoom, false);
317
- this.canvas.addEventListener('touchstart', this._onTouchStart, { passive: true });
318
- this.canvas.addEventListener('touchend', this._onTouchEnd, false);
319
- this.canvas.addEventListener('keyup', this._onKeyUp, false);
320
- this.canvas.addEventListener('wheel', this._onWeel, { passive: true });
321
- } else {
322
- this.notify('is unable to start: no {options} have been passed to the Zumly\'s instance.', 'error');
323
- }
324
- }
325
-
326
- /**
327
- * Helpers
328
- */
329
- storeViews (data) {
330
- this.tracing('storedViews()');
331
- this.storedViews.push(data);
332
- }
333
-
334
- setPreviousScale (scale) {
335
- this.tracing('setPreviousScale()');
336
- this.storedPreviousScale.push(scale);
337
- }
338
-
339
- tracing (data) {
340
- if (data === 'ended') {
341
- const parse = this.trace.map((task, index) => `${index === 0 ? `Instance ${this.instance}: ${task}` : `${task}`}`).join(' > ');
342
- this.notify(parse);
343
- this.trace = [];
344
- } else {
345
- this.trace.push(data);
346
- }
347
- }
348
-
349
- /**
350
- * Private methods
351
- */
352
- static get counter () {
353
- Zumly._counter = (Zumly._counter || 0) + 1;
354
- return Zumly._counter
355
- }
356
-
357
- notify (msg, type) {
358
- return notification(this.debug, msg, type)
359
- }
360
-
361
- /**
362
- * Public methods
363
- */
364
- zoomLevel () {
365
- return this.storedViews.length
366
- }
367
-
368
- async init () {
369
- if (this.options) {
370
- // add instance style
371
- this.tracing('init()');
372
- prepareCSS(this.instance);
373
- await renderView(this.initialView, this.canvas, this.views, 'init');
374
- // add to storage. OPTIMIZAR
375
- this.storeViews({
376
- zoomLevel: this.storedViews.length,
377
- views: [{
378
- viewName: this.initialView,
379
- backwardState: {
380
- origin: '0 0',
381
- transform: ''
382
- }
383
- }]
384
- });
385
- //
386
- this.notify(`${this.instance > 1
387
- ? `instance nº ${this.instance} is active.`
388
- : `is running! Instance nº ${this.instance} is active. ${this.debug
389
- ? 'Debug is active, can be deactivate by setting \'debug: false\' when you define the instance.' : ''}
390
- More tips & docs at https://zumly.org`}`, 'welcome');
391
- }
392
- }
393
-
394
- /**
395
- * Main methods
396
- */
397
- async zoomIn (el) {
398
- this.tracing('zoomIn()');
399
- var instance = this.instance;
400
- const canvas = this.canvas;
401
- const coordenadasCanvas = canvas.getBoundingClientRect();
402
- var offsetX = coordenadasCanvas.left;
403
- var offsetY = coordenadasCanvas.top;
404
- const preScale = this.storedPreviousScale[this.storedPreviousScale.length - 1];
405
- // generated new view from activated .zoom-me element
406
- // generateNewView(el)
407
- this.tracing('renderView()');
408
- await renderView(el, canvas, this.views);
409
- el.classList.add('zoomed');
410
- const coordenadasEl = el.getBoundingClientRect();
411
- // create new view in a template tag
412
- // select VIEWS from DOM
413
- var currentView = canvas.querySelector('.is-new-current-view');
414
- var previousView = canvas.querySelector('.is-current-view');
415
- var lastView = canvas.querySelector('.is-previous-view');
416
- var removeView = canvas.querySelector('.is-last-view');
417
- if (removeView !== null) canvas.removeChild(removeView);
418
- // do changes
419
- const cc = currentView.getBoundingClientRect();
420
- const scale = cc.width / coordenadasEl.width;
421
- const scaleInv = 1 / scale;
422
- const scaleh = cc.height / coordenadasEl.height;
423
- const scaleInvh = 1 / scaleh;
424
- // muy interesante featura... usar el zoom de acuardo a la h o w mayor y agra
425
- var duration = el.dataset.withDuration || this.duration;
426
- var ease = el.dataset.withEease || this.ease;
427
- var filterIn = this.effects[0];
428
- var filterOut = this.effects[1];
429
- var cover = this.cover;
430
-
431
- if (cover === 'width') {
432
- var laScala = scale;
433
- var laScalaInv = scaleInv;
434
- } else if (cover === 'height') {
435
- laScala = scaleh;
436
- laScalaInv = scaleInvh;
437
- }
438
-
439
- this.setPreviousScale(laScala);
440
- var transformCurrentView0 = `translate(${coordenadasEl.x - offsetX + (coordenadasEl.width - cc.width * laScalaInv) / 2}px, ${coordenadasEl.y - offsetY + (coordenadasEl.height - cc.height * laScalaInv) / 2}px) scale(${laScalaInv})`;
441
- currentView.style.transform = transformCurrentView0;
442
- //
443
- previousView.classList.add('is-previous-view');
444
- previousView.classList.remove('is-current-view');
445
- const coordenadasPreviousView = previousView.getBoundingClientRect();
446
- // PREVIOUS VIEW EXACTAMENTE ONDE ESTANA ANTES COMO CURRENT
447
- var transformPreviousView0 = previousView.style.transform;
448
- previousView.style.transformOrigin = `${coordenadasEl.x + coordenadasEl.width / 2 - coordenadasPreviousView.x}px ${coordenadasEl.y + coordenadasEl.height / 2 - coordenadasPreviousView.y}px`;
449
-
450
- const x = coordenadasCanvas.width / 2 - coordenadasEl.width / 2 - coordenadasEl.x + coordenadasPreviousView.x;
451
- const y = coordenadasCanvas.height / 2 - coordenadasEl.height / 2 - coordenadasEl.y + coordenadasPreviousView.y;
452
-
453
- const transformPreviousView1 = `translate(${x}px, ${y}px) scale(${laScala})`;
454
- // PREVIOUS VIEW FINAL STAGE
455
- previousView.style.transform = transformPreviousView1;
456
- // ACA CAMBIA LA COSA, LEVANTO LAS COORDENADAS DEL ELEMENTO CLICLEADO QUE ESTBA DNRO DE PREVIOUS VIEW
457
- var newcoordenadasEl = el.getBoundingClientRect();
458
- // LO QUE DETERMINA LA POSICINES FONAL DEL CURRENT VIEW
459
- var transformCurrentView1 = `translate(${newcoordenadasEl.x - offsetX + (newcoordenadasEl.width - cc.width) / 2}px, ${newcoordenadasEl.y - offsetY + (newcoordenadasEl.height - cc.height) / 2}px)`;
460
-
461
- if (lastView !== null) {
462
- lastView.classList.remove('is-previous-view');
463
- lastView.classList.add('is-last-view');
464
- var transformLastView0 = lastView.style.transform;
465
- var newcoordenadasPV = previousView.getBoundingClientRect();
466
- lastView.style.transform = `translate(${x - offsetX}px, ${y - offsetY}px) scale(${laScala * preScale})`;
467
- const last = lastView.querySelector('.zoomed');
468
- var coorLast = last.getBoundingClientRect();
469
- lastView.style.transform = transformLastView0;
470
- previousView.style.transform = transformPreviousView0;
471
- var coorPrev = previousView.getBoundingClientRect();
472
- var transformLastView1 = `translate(${coordenadasCanvas.width / 2 - coordenadasEl.width / 2 - coordenadasEl.x + (coorPrev.x - coorLast.x) + newcoordenadasPV.x - offsetX + (newcoordenadasPV.width - coorLast.width) / 2}px, ${coordenadasCanvas.height / 2 - coordenadasEl.height / 2 - coordenadasEl.y + (coorPrev.y - coorLast.y) + newcoordenadasPV.y - offsetY +
473
- (newcoordenadasPV.height - coorLast.height) / 2}px) scale(${laScala * preScale})`;
474
- } else {
475
- previousView.style.transform = transformPreviousView0;
476
- }
477
- // arrays
478
- var snapShoot = {
479
- zoomLevel: this.storedViews.length,
480
- views: []
481
- };
482
- const currentv = currentView ? {
483
- viewName: currentView.dataset.viewName,
484
- backwardState: {
485
- origin: currentView.style.transformOrigin,
486
- duration: duration,
487
- ease: ease,
488
- transform: transformCurrentView0,
489
- filter: filterIn
490
- },
491
- forwardState: {
492
- origin: currentView.style.transformOrigin,
493
- duration: duration,
494
- ease: ease,
495
- transform: transformCurrentView1,
496
- filter: filterOut
497
- }
498
- } : null;
499
- const previousv = previousView ? {
500
- viewName: previousView.dataset.viewName,
501
- backwardState: {
502
- origin: previousView.style.transformOrigin,
503
- duration: duration,
504
- ease: ease,
505
- transform: transformPreviousView0,
506
- filter: window.getComputedStyle(document.documentElement).getPropertyValue(`--previous-view-filter-end-${instance}`)
507
- },
508
- forwardState: {
509
- origin: previousView.style.transformOrigin,
510
- duration: duration,
511
- ease: ease,
512
- transform: transformPreviousView1,
513
- filter: filterOut
514
- }
515
- } : null;
516
- const lastv = lastView ? {
517
- viewName: lastView.dataset.viewName,
518
- backwardState: {
519
- origin: lastView.style.transformOrigin,
520
- duration: duration,
521
- ease: ease,
522
- transform: transformLastView0,
523
- filter: window.getComputedStyle(document.documentElement).getPropertyValue(`--previous-view-filter-end-${instance}`)
524
- },
525
- forwardState: {
526
- origin: lastView.style.transformOrigin,
527
- duration: duration,
528
- ease: ease,
529
- transform: transformLastView1,
530
- filter: filterOut
531
- }
532
- } : null;
533
- const gonev = removeView ? { // ACA VA LA VISTA ENTERA FALTA REALIZAR UN ZOOM IGUAL ANTES DE SACARLA DE JUEGO
534
- viewName: removeView
535
- } : null;
536
- if (currentv !== null) snapShoot.views.push(currentv);
537
- if (previousv !== null) snapShoot.views.push(previousv);
538
- if (lastv !== null) snapShoot.views.push(lastv);
539
- if (gonev !== null) snapShoot.views.push(gonev);
540
- this.storeViews(snapShoot);
541
- this.currentStage = this.storedViews[this.storedViews.length - 1];
542
- // animation
543
- this.tracing('setCSSVariables()');
544
- setCSSVariables('zoomIn', this.currentStage, this.instance);
545
- previousView.classList.add('performance');
546
- if (lastView !== null) lastView.classList.add('performance');
547
- //
548
- currentView.classList.remove('hide');
549
- currentView.addEventListener('animationstart', this._onZoomInHandlerStart);
550
- currentView.addEventListener('animationend', this._onZoomInHandlerEnd);
551
- previousView.addEventListener('animationend', this._onZoomInHandlerEnd);
552
- if (lastView !== null) lastView.addEventListener('animationend', this._onZoomInHandlerEnd);
553
- //
554
- currentView.classList.add(`zoom-current-view-${instance}`);
555
- previousView.classList.add(`zoom-previous-view-${instance}`);
556
- if (lastView !== null) lastView.classList.add(`zoom-last-view-${instance}`);
557
- }
558
-
559
- zoomOut () {
560
- this.tracing('zoomOut()');
561
- this.blockEvents = true;
562
- this.storedPreviousScale.pop();
563
- var instance = this.instance;
564
- const canvas = this.canvas;
565
- this.currentStage = this.storedViews[this.storedViews.length - 1];
566
- const reAttachView = this.currentStage.views[3];
567
- var currentView = canvas.querySelector('.is-current-view');
568
- var previousView = canvas.querySelector('.is-previous-view');
569
- var lastView = canvas.querySelector('.is-last-view');
570
- //
571
- this.tracing('setCSSVariables()');
572
- setCSSVariables('zoomOut', this.currentStage, this.instance);
573
- //
574
- //
575
- currentView.classList.remove('performance');
576
- //
577
- previousView.querySelector('.zoomed').classList.remove('zoomed');
578
- previousView.classList.remove('is-previous-view');
579
- previousView.classList.add('is-current-view');
580
- previousView.classList.remove('performance');
581
- //
582
- if (lastView !== null) {
583
- lastView.classList.add('performance');
584
- lastView.classList.add('is-previous-view');
585
- lastView.classList.remove('is-last-view');
586
- lastView.classList.remove('hide');
587
- }
588
- //
589
- if (reAttachView !== undefined) {
590
- canvas.prepend(reAttachView.viewName);
591
- var newlastView = canvas.querySelector('.z-view:first-child');
592
- newlastView.classList.add('hide');
593
- }
594
- //
595
- currentView.addEventListener('animationstart', this._onZoomOutHandlerStart);
596
- currentView.addEventListener('animationend', this._onZoomOutHandlerEnd);
597
- previousView.addEventListener('animationend', this._onZoomOutHandlerEnd);
598
- if (lastView !== null) lastView.addEventListener('animationend', this._onZoomOutHandlerEnd);
599
- //
600
- currentView.classList.add(`zoom-current-view-${instance}`);
601
- previousView.classList.add(`zoom-previous-view-${instance}`);
602
- if (lastView !== null) lastView.classList.add(`zoom-last-view-${instance}`);
603
- this.storedViews.pop();
604
- }
605
-
606
- /**
607
- * Event hangling
608
- */
609
- onZoom (event) {
610
- if (this.storedViews.length > 1 && !this.blockEvents && !event.target.classList.contains('zoom-me') && event.target.closest('.is-current-view') === null && !this.touching) {
611
- this.tracing('onZoom()');
612
- event.stopPropagation();
613
- this.zoomOut();
614
- }
615
- if (!this.blockEvents && event.target.classList.contains('zoom-me') && !this.touching) {
616
- this.tracing('onZoom()');
617
- event.stopPropagation();
618
- this.zoomIn(event.target);
619
- }
620
- }
621
-
622
- onKeyUp (event) {
623
- this.tracing('onKeyUp()');
624
- // Possible conflict with usar inputs
625
- if (event.key === 'ArrowLeft' || event.key === 'ArrowDown') {
626
- event.preventDefault();
627
- if (this.storedViews.length > 1 && !this.blockEvents) {
628
- this.zoomOut();
629
- } else {
630
- this.notify(`is on level zero. Can't zoom out. Trigger: ${event.key}`, 'warn');
631
- }
632
- }
633
- if (event.key === 'ArrowRight' || event.key === 'ArrowUp') {
634
- event.preventDefault();
635
- this.notify(event.key + 'has not actions defined');
636
- }
637
- }
638
-
639
- onWeel (event) {
640
- // inertia need to be fixed
641
- if (!this.blockEvents) {
642
- this.tracing('onWeel()');
643
- if (event.deltaY < 0) ;
644
- if (event.deltaY > 0) {
645
- if (this.storedViews.length > 1 && !this.blockEvents) {
646
- this.zoomOut();
647
- }
648
- }
649
- }
650
- }
651
-
652
- onTouchStart (event) {
653
- this.tracing('onTouchStart()');
654
- this.touching = true;
655
- this.touchstartX = event.changedTouches[0].screenX;
656
- this.touchstartY = event.changedTouches[0].screenY;
657
- }
658
-
659
- onTouchEnd (event) {
660
- if (!this.blockEvents) {
661
- this.tracing('onTouchEnd()');
662
- this.touchendX = event.changedTouches[0].screenX;
663
- this.touchendY = event.changedTouches[0].screenY;
664
- this.handleGesture(event);
665
- // event.preventDefault()
666
- }
667
- }
668
-
669
- handleGesture (event) {
670
- event.stopPropagation();
671
- this.tracing('handleGesture()');
672
- if (this.touchendX < this.touchstartX - 30) {
673
- if (this.storedViews.length > 1 && !this.blockEvents) {
674
- this.tracing('swipe left');
675
- this.zoomOut();
676
- } else {
677
- this.notify("is on level zero. Can't zoom out. Trigger: Swipe left", 'warn');
678
- }
679
- }
680
- if (this.touchendY < this.touchstartY - 10) {
681
- if (this.storedViews.length > 1 && !this.blockEvents) {
682
- this.tracing('swipe up');
683
- // Disabled. In near future enable if Zumly is full screen
684
- // this.zoomOut()
685
- } else {
686
- this.notify("is on level zero. Can't zoom out. Trigger: Swipe up", 'warn');
687
- }
688
- }
689
- if (this.touchendY === this.touchstartY && !this.blockEvents && event.target.classList.contains('zoom-me') && this.touching) {
690
- this.touching = false;
691
- this.tracing('tap');
692
- event.preventDefault();
693
- this.zoomIn(event.target);
694
- }
695
- if (this.touchendY === this.touchstartY && this.storedViews.length > 1 && !this.blockEvents && !event.target.classList.contains('zoom-me') && event.target.closest('.is-current-view') === null && this.touching) {
696
- this.touching = false;
697
- this.tracing('tap');
698
- this.zoomOut();
699
- }
700
- }
701
-
702
- onZoomOutHandlerStart (event) {
703
- this.tracing('onZoomOutHandlerStart()');
704
- this.blockEvents = true;
705
- event.target.removeEventListener('animationstart', this._onZoomOutHandlerStart);
706
- }
707
-
708
- onZoomOutHandlerEnd (event) {
709
- this.tracing('onZoomOutHandlerEnd()');
710
- const element = event.target;
711
- var currentZoomLevel = this.currentStage;
712
- element.removeEventListener('animationend', this._onZoomOutHandlerEnd);
713
- // current
714
- if (element.classList.contains(`zoom-current-view-${this.instance}`)) {
715
- this.canvas.removeChild(element);
716
- this.blockEvents = false;
717
- }
718
- if (element.classList.contains(`zoom-previous-view-${this.instance}`)) {
719
- var origin = currentZoomLevel.views[1].backwardState.origin;
720
- var transform = currentZoomLevel.views[1].backwardState.transform;
721
- element.classList.remove('performance');
722
- element.classList.remove(`zoom-previous-view-${this.instance}`);
723
- element.style.transformOrigin = origin;
724
- element.style.transform = transform;
725
- element.style.filter = 'none';
726
- if (currentZoomLevel.views.length === 2) this.tracing('ended');
727
- }
728
- if (element.classList.contains(`zoom-last-view-${this.instance}`)) {
729
- origin = currentZoomLevel.views[2].backwardState.origin;
730
- transform = currentZoomLevel.views[2].backwardState.transform;
731
- element.classList.remove('performance');
732
- element.classList.remove(`zoom-last-view-${this.instance}`);
733
- element.style.transformOrigin = origin;
734
- element.style.transform = transform;
735
- if (currentZoomLevel.views.length > 2) this.tracing('ended');
736
- }
737
- }
738
-
739
- onZoomInHandlerStart (event) {
740
- this.tracing('onZoomInHandlerStart()');
741
- this.blockEvents = true;
742
- event.target.removeEventListener('animationstart', this._onZoomInHandlerStart);
743
- }
744
-
745
- onZoomInHandlerEnd (event) {
746
- this.tracing('onZoomInHandlerEnd()');
747
- const element = event.target;
748
- var currentZoomLevel = this.currentStage;
749
- if (event.target.classList.contains('is-new-current-view')) {
750
- this.blockEvents = false;
751
- var viewName = 'current-view';
752
- var transform = currentZoomLevel.views[0].forwardState.transform;
753
- var origin = currentZoomLevel.views[0].forwardState.origin;
754
- element.classList.remove('is-new-current-view');
755
- element.classList.add('is-current-view');
756
- } else if (event.target.classList.contains('is-previous-view')) {
757
- viewName = 'previous-view';
758
- transform = currentZoomLevel.views[1].forwardState.transform;
759
- origin = currentZoomLevel.views[1].forwardState.origin;
760
- if (currentZoomLevel.views.length === 2) this.tracing('ended');
761
- } else {
762
- viewName = 'last-view';
763
- transform = currentZoomLevel.views[2].forwardState.transform;
764
- origin = currentZoomLevel.views[2].forwardState.origin;
765
- if (currentZoomLevel.views.length > 2) this.tracing('ended');
766
- }
767
- element.classList.remove('performance');
768
- element.classList.remove(`zoom-${viewName}-${this.instance}`);
769
- element.classList.remove('has-no-events');
770
- element.style.transformOrigin = origin;
771
- element.style.transform = transform;
772
- element.style.filter = window.getComputedStyle(document.documentElement).getPropertyValue(`--${viewName}-filter-end-${this.instance}`);
773
- element.removeEventListener('animationend', this._onZoomInHandlerEnd);
774
- }
775
- }
776
-
777
- return Zumly;
778
-
779
- })));