zumly 0.9.11 → 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,809 +0,0 @@
1
- /**
2
- * zumly v0.9.11
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, componentContext) {
182
- var viewName = null;
183
- init ? viewName = el : viewName = el.dataset.to;
184
- var newView = document.createElement('template');
185
-
186
- if(typeof views[viewName] === 'object' && views[viewName].render !== undefined) {
187
- // makes optional de 'render' function
188
- newView.innerHTML = await views[viewName].render();
189
- } else if(typeof views[viewName] === 'function') {
190
- // view is a component constructor
191
- var newViewInner = document.createElement('div');
192
- let comp = new views[viewName]({
193
- target: newViewInner,
194
- context: componentContext,
195
- props: el.dataset
196
- });
197
- newViewInner.classList.add('z-view');
198
- newView.content.appendChild(newViewInner);
199
- } else {
200
- // view is plain HTML
201
- newView.innerHTML = views[viewName];
202
- }
203
-
204
- let vv = newView.content.querySelector('.z-view');
205
-
206
- if (!init) {
207
- vv.classList.add('is-new-current-view');
208
- vv.classList.add('has-no-events');
209
- vv.classList.add('hide');
210
- vv.classList.add('performance');
211
- } else {
212
- vv.classList.add('is-current-view');
213
- }
214
- vv.style.transformOrigin = '0 0';
215
- vv.dataset.viewName = viewName;
216
-
217
- var appendedView = await canvas.append(newView.content);
218
- // makes optional de 'mounted' hook
219
- if (typeof views[viewName] === 'object' && views[viewName].mounted !== undefined && typeof views[viewName].mounted() === 'function') await views[viewName].mounted();
220
- }
221
-
222
- function notification (debug, msg, type) {
223
- if (msg && type === 'welcome') {
224
- console.info(`%c Zumly %c ${msg}`, 'background: #424085; color: white; border-radius: 3px;', 'color: #424085'); // eslint-disable-line no-console
225
- }
226
- if (msg && debug && (type === 'info' || type === undefined)) {
227
- console.info(`%c Zumly %c ${msg}`, 'background: #6679A3; color: #304157; border-radius: 3px;', 'color: #6679A3'); // eslint-disable-line no-console
228
- }
229
- if (msg && type === 'warn') {
230
- console.warn(`%c Zumly %c ${msg}`, 'background: #DCBF53; color: #424085; border-radius: 3px;', 'color: #424085'); // eslint-disable-line no-console
231
- }
232
- if (msg && type === 'error') {
233
- console.error(`%c Zumly %c ${msg}`, 'background: #BE4747; color: white; border-radius: 3px;', 'color: #424085'); // eslint-disable-line no-console
234
- }
235
- }
236
-
237
- function checkParameters (parameters, instance) {
238
- // First check if options are provided
239
- if (parameters && typeof parameters === 'object') {
240
- assignProperty(instance, 'options', true);
241
- // Then check its properties
242
- // mount property. String DOM element. Required
243
- validate(instance, 'mount', parameters.mount, 'string', { isRequired: true });
244
- // initialView property. Strng view name. Required
245
- validate(instance, 'initialView', parameters.initialView, 'string', { isRequired: true });
246
- // views property. Object with views. Required
247
- validate(instance, 'views', parameters.views, 'object', { isRequired: true });
248
- // debug property. Boolean. Optional. Default false
249
- validate(instance, 'debug', parameters.debug, 'boolean', { defaultValue: false });
250
- // Svelte component context
251
- validate(instance, 'componentContext', parameters.componentContext, 'object', { isRequired: false, defaultValue: new Map() });
252
- // Check transtions
253
- if (parameters.transitions && typeof parameters.transitions === 'object') {
254
- // value exist; type, allowed, deafult
255
- validate(instance, 'cover', parameters.transitions.cover, 'string', { defaultValue: 'width', hasValidation: () => { ['height', 'width'].indexOf(parameters.transitions.cover.toLowerCase()) !== -1; } }); // eslint-disable-line
256
- // value, type, , default
257
- validate(instance, 'duration', parameters.transitions.duration, 'string', { defaultValue: '1s' });
258
- // value, type, ,default
259
- validate(instance, 'ease', parameters.transitions.ease, 'string', { defaultValue: 'ease-in-out' });
260
- // value, type, custom validation, custom asignament, default
261
- validate(instance, 'effects', parameters.transitions.effects, 'array', { defaultValue: ['none', 'none'], hasValidation: checkArray(parameters.transitions.effects), hasAssignFunction: setFx(parameters.transitions.effects) });
262
- } else {
263
- // assign deafult values
264
- assignProperty(instance, 'cover', 'width');
265
- assignProperty(instance, 'duration', '1s');
266
- assignProperty(instance, 'ease', 'ease-in-out');
267
- assignProperty(instance, 'effects', ['none', 'none']);
268
- }
269
- } else {
270
- notification(false, '\'options\' object has to be provided when instance is defined', 'error');
271
- }
272
- }
273
-
274
- window.requestIdleCallback = window.requestIdleCallback || shimIdleCallBack;
275
-
276
- /**
277
- * Zumly
278
- * Powers your apps with a zoomable user interface (ZUI) taste.
279
- * @class
280
- */
281
- class Zumly {
282
- /**
283
- * Creates a Zumly instance
284
- * @constructor
285
- * @params {Objet} options
286
- * @example
287
- * new Zumly({
288
- * mount: '.mount',
289
- * initialView: 'home',
290
- * views: {
291
- * home,
292
- * contact,
293
- * ...
294
- * }
295
- *
296
- */
297
- constructor (options) {
298
- // Internal state:
299
- // Register global instances of Zumly
300
- this.instance = Zumly.counter;
301
- // Store snapshots of each zoom transition
302
- this.storedViews = [];
303
- // Show current zoom level properties
304
- this.currentStage = null;
305
- // Store the scale of previous zoom transition
306
- this.storedPreviousScale = [1];
307
- // Array of events useful for debugging
308
- this.trace = [];
309
- // Deactive events during transtions
310
- this.blockEvents = false;
311
- // Initial values for gesture events
312
- this.touchstartX = 0;
313
- this.touchstartY = 0;
314
- this.touchendX = 0;
315
- this.touchendY = 0;
316
- this.touching = false;
317
- // Check if user options exist
318
- checkParameters(options, this);
319
- if (this.options) {
320
- // Event bindings:
321
- this._onZoom = this.onZoom.bind(this);
322
- this._onZoomInHandlerStart = this.onZoomInHandlerStart.bind(this);
323
- this._onZoomInHandlerEnd = this.onZoomInHandlerEnd.bind(this);
324
- this._onZoomOutHandlerStart = this.onZoomOutHandlerStart.bind(this);
325
- this._onZoomOutHandlerEnd = this.onZoomOutHandlerEnd.bind(this);
326
- this._onTouchStart = this.onTouchStart.bind(this);
327
- this._onTouchEnd = this.onTouchEnd.bind(this);
328
- this._onKeyUp = this.onKeyUp.bind(this);
329
- this._onWeel = this.onWeel.bind(this);
330
- // Prepare the instance:
331
- this.canvas = document.querySelector(this.mount);
332
- this.canvas.setAttribute('tabindex', 0);
333
- this.canvas.addEventListener('mouseup', this._onZoom, false);
334
- this.canvas.addEventListener('touchend', this._onZoom, false);
335
- this.canvas.addEventListener('touchstart', this._onTouchStart, { passive: true });
336
- this.canvas.addEventListener('touchend', this._onTouchEnd, false);
337
- this.canvas.addEventListener('keyup', this._onKeyUp, false);
338
- this.canvas.addEventListener('wheel', this._onWeel, { passive: true });
339
- } else {
340
- this.notify('is unable to start: no {options} have been passed to the Zumly\'s instance.', 'error');
341
- }
342
- }
343
-
344
- /**
345
- * Helpers
346
- */
347
- storeViews (data) {
348
- this.tracing('storedViews()');
349
- this.storedViews.push(data);
350
- }
351
-
352
- setPreviousScale (scale) {
353
- this.tracing('setPreviousScale()');
354
- this.storedPreviousScale.push(scale);
355
- }
356
-
357
- tracing (data) {
358
- if (data === 'ended') {
359
- const parse = this.trace.map((task, index) => `${index === 0 ? `Instance ${this.instance}: ${task}` : `${task}`}`).join(' > ');
360
- this.notify(parse);
361
- this.trace = [];
362
- } else {
363
- this.trace.push(data);
364
- }
365
- }
366
-
367
- /**
368
- * Private methods
369
- */
370
- static get counter () {
371
- Zumly._counter = (Zumly._counter || 0) + 1;
372
- return Zumly._counter
373
- }
374
-
375
- notify (msg, type) {
376
- return notification(this.debug, msg, type)
377
- }
378
-
379
- /**
380
- * Public methods
381
- */
382
- zoomLevel () {
383
- return this.storedViews.length
384
- }
385
-
386
- async init () {
387
- if (this.options) {
388
- // add instance style
389
- this.tracing('init()');
390
- prepareCSS(this.instance);
391
- await renderView(this.initialView, this.canvas, this.views, 'init', this.componentContext);
392
- // add to storage. OPTIMIZAR
393
- this.storeViews({
394
- zoomLevel: this.storedViews.length,
395
- views: [{
396
- viewName: this.initialView,
397
- backwardState: {
398
- origin: '0 0',
399
- transform: ''
400
- }
401
- }]
402
- });
403
- //
404
- this.notify(`${this.instance > 1
405
- ? `instance nº ${this.instance} is active.`
406
- : `is running! Instance nº ${this.instance} is active. ${this.debug
407
- ? 'Debug is active, can be deactivate by setting \'debug: false\' when you define the instance.' : ''}
408
- More tips & docs at https://zumly.org`}`, 'welcome');
409
- }
410
- }
411
-
412
- /**
413
- * Main methods
414
- */
415
- async zoomIn (el) {
416
- this.tracing('zoomIn()');
417
- var instance = this.instance;
418
- const canvas = this.canvas;
419
- const coordenadasCanvas = canvas.getBoundingClientRect();
420
- var offsetX = coordenadasCanvas.left;
421
- var offsetY = coordenadasCanvas.top;
422
- const preScale = this.storedPreviousScale[this.storedPreviousScale.length - 1];
423
- // generated new view from activated .zoom-me element
424
- // generateNewView(el)
425
- this.tracing('renderView()');
426
- await renderView(el, canvas, this.views, false, this.componentContext);
427
- el.classList.add('zoomed');
428
- const coordenadasEl = el.getBoundingClientRect();
429
- // create new view in a template tag
430
- // select VIEWS from DOM
431
- var currentView = canvas.querySelector('.is-new-current-view');
432
- var previousView = canvas.querySelector('.is-current-view');
433
- var lastView = canvas.querySelector('.is-previous-view');
434
- var removeView = canvas.querySelector('.is-last-view');
435
- if (removeView !== null) canvas.removeChild(removeView);
436
- // do changes
437
- const cc = currentView.getBoundingClientRect();
438
- const scale = cc.width / coordenadasEl.width;
439
- const scaleInv = 1 / scale;
440
- const scaleh = cc.height / coordenadasEl.height;
441
- const scaleInvh = 1 / scaleh;
442
- // muy interesante featura... usar el zoom de acuardo a la h o w mayor y agra
443
- var duration = el.dataset.withDuration || this.duration;
444
- var ease = el.dataset.withEease || this.ease;
445
- var filterIn = this.effects[0];
446
- var filterOut = this.effects[1];
447
- var cover = this.cover;
448
-
449
- if (cover === 'width') {
450
- var laScala = scale;
451
- var laScalaInv = scaleInv;
452
- } else if (cover === 'height') {
453
- laScala = scaleh;
454
- laScalaInv = scaleInvh;
455
- }
456
-
457
- this.setPreviousScale(laScala);
458
- 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})`;
459
- currentView.style.transform = transformCurrentView0;
460
- //
461
- previousView.classList.add('is-previous-view');
462
- previousView.classList.remove('is-current-view');
463
- const coordenadasPreviousView = previousView.getBoundingClientRect();
464
- // PREVIOUS VIEW EXACTAMENTE ONDE ESTANA ANTES COMO CURRENT
465
- var transformPreviousView0 = previousView.style.transform;
466
- previousView.style.transformOrigin = `${coordenadasEl.x + coordenadasEl.width / 2 - coordenadasPreviousView.x}px ${coordenadasEl.y + coordenadasEl.height / 2 - coordenadasPreviousView.y}px`;
467
-
468
- const x = coordenadasCanvas.width / 2 - coordenadasEl.width / 2 - coordenadasEl.x + coordenadasPreviousView.x;
469
- const y = coordenadasCanvas.height / 2 - coordenadasEl.height / 2 - coordenadasEl.y + coordenadasPreviousView.y;
470
-
471
- const transformPreviousView1 = `translate(${x}px, ${y}px) scale(${laScala})`;
472
- // PREVIOUS VIEW FINAL STAGE
473
- previousView.style.transform = transformPreviousView1;
474
- // ACA CAMBIA LA COSA, LEVANTO LAS COORDENADAS DEL ELEMENTO CLICLEADO QUE ESTBA DNRO DE PREVIOUS VIEW
475
- var newcoordenadasEl = el.getBoundingClientRect();
476
- // LO QUE DETERMINA LA POSICINES FONAL DEL CURRENT VIEW
477
- var transformCurrentView1 = `translate(${newcoordenadasEl.x - offsetX + (newcoordenadasEl.width - cc.width) / 2}px, ${newcoordenadasEl.y - offsetY + (newcoordenadasEl.height - cc.height) / 2}px)`;
478
-
479
- if (lastView !== null) {
480
- lastView.classList.remove('is-previous-view');
481
- lastView.classList.add('is-last-view');
482
- var transformLastView0 = lastView.style.transform;
483
- var newcoordenadasPV = previousView.getBoundingClientRect();
484
- lastView.style.transform = `translate(${x - offsetX}px, ${y - offsetY}px) scale(${laScala * preScale})`;
485
- const last = lastView.querySelector('.zoomed');
486
- var coorLast = last.getBoundingClientRect();
487
- lastView.style.transform = transformLastView0;
488
- previousView.style.transform = transformPreviousView0;
489
- var coorPrev = previousView.getBoundingClientRect();
490
- 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 +
491
- (newcoordenadasPV.height - coorLast.height) / 2}px) scale(${laScala * preScale})`;
492
- } else {
493
- previousView.style.transform = transformPreviousView0;
494
- }
495
- // arrays
496
- var snapShoot = {
497
- zoomLevel: this.storedViews.length,
498
- views: []
499
- };
500
- const currentv = currentView ? {
501
- viewName: currentView.dataset.viewName,
502
- backwardState: {
503
- origin: currentView.style.transformOrigin,
504
- duration: duration,
505
- ease: ease,
506
- transform: transformCurrentView0,
507
- filter: filterIn
508
- },
509
- forwardState: {
510
- origin: currentView.style.transformOrigin,
511
- duration: duration,
512
- ease: ease,
513
- transform: transformCurrentView1,
514
- filter: filterOut
515
- }
516
- } : null;
517
- const previousv = previousView ? {
518
- viewName: previousView.dataset.viewName,
519
- backwardState: {
520
- origin: previousView.style.transformOrigin,
521
- duration: duration,
522
- ease: ease,
523
- transform: transformPreviousView0,
524
- filter: window.getComputedStyle(document.documentElement).getPropertyValue(`--previous-view-filter-end-${instance}`)
525
- },
526
- forwardState: {
527
- origin: previousView.style.transformOrigin,
528
- duration: duration,
529
- ease: ease,
530
- transform: transformPreviousView1,
531
- filter: filterOut
532
- }
533
- } : null;
534
- const lastv = lastView ? {
535
- viewName: lastView.dataset.viewName,
536
- backwardState: {
537
- origin: lastView.style.transformOrigin,
538
- duration: duration,
539
- ease: ease,
540
- transform: transformLastView0,
541
- filter: window.getComputedStyle(document.documentElement).getPropertyValue(`--previous-view-filter-end-${instance}`)
542
- },
543
- forwardState: {
544
- origin: lastView.style.transformOrigin,
545
- duration: duration,
546
- ease: ease,
547
- transform: transformLastView1,
548
- filter: filterOut
549
- }
550
- } : null;
551
- const gonev = removeView ? { // ACA VA LA VISTA ENTERA FALTA REALIZAR UN ZOOM IGUAL ANTES DE SACARLA DE JUEGO
552
- viewName: removeView
553
- } : null;
554
- if (currentv !== null) snapShoot.views.push(currentv);
555
- if (previousv !== null) snapShoot.views.push(previousv);
556
- if (lastv !== null) snapShoot.views.push(lastv);
557
- if (gonev !== null) snapShoot.views.push(gonev);
558
- this.storeViews(snapShoot);
559
- this.currentStage = this.storedViews[this.storedViews.length - 1];
560
- // animation
561
- this.tracing('setCSSVariables()');
562
- setCSSVariables('zoomIn', this.currentStage, this.instance);
563
- previousView.classList.add('performance');
564
- if (lastView !== null) lastView.classList.add('performance');
565
- //
566
- currentView.classList.remove('hide');
567
- currentView.addEventListener('animationstart', this._onZoomInHandlerStart);
568
- currentView.addEventListener('animationend', this._onZoomInHandlerEnd);
569
- previousView.addEventListener('animationend', this._onZoomInHandlerEnd);
570
- if (lastView !== null) lastView.addEventListener('animationend', this._onZoomInHandlerEnd);
571
- //
572
- currentView.classList.add(`zoom-current-view-${instance}`);
573
- previousView.classList.add(`zoom-previous-view-${instance}`);
574
- if (lastView !== null) lastView.classList.add(`zoom-last-view-${instance}`);
575
- }
576
-
577
- zoomOut () {
578
- this.tracing('zoomOut()');
579
- this.blockEvents = true;
580
- this.storedPreviousScale.pop();
581
- var instance = this.instance;
582
- const canvas = this.canvas;
583
- this.currentStage = this.storedViews[this.storedViews.length - 1];
584
- const reAttachView = this.currentStage.views[3];
585
- var currentView = canvas.querySelector('.is-current-view');
586
- var previousView = canvas.querySelector('.is-previous-view');
587
- var lastView = canvas.querySelector('.is-last-view');
588
- //
589
- this.tracing('setCSSVariables()');
590
- setCSSVariables('zoomOut', this.currentStage, this.instance);
591
- //
592
- //
593
- currentView.classList.remove('performance');
594
- //
595
- previousView.querySelector('.zoomed').classList.remove('zoomed');
596
- previousView.classList.remove('is-previous-view');
597
- previousView.classList.add('is-current-view');
598
- previousView.classList.remove('performance');
599
- //
600
- if (lastView !== null) {
601
- lastView.classList.add('performance');
602
- lastView.classList.add('is-previous-view');
603
- lastView.classList.remove('is-last-view');
604
- lastView.classList.remove('hide');
605
- }
606
- //
607
- if (reAttachView !== undefined) {
608
- canvas.prepend(reAttachView.viewName);
609
- var newlastView = canvas.querySelector('.z-view:first-child');
610
- newlastView.classList.add('hide');
611
- }
612
- //
613
- currentView.addEventListener('animationstart', this._onZoomOutHandlerStart);
614
- currentView.addEventListener('animationend', this._onZoomOutHandlerEnd);
615
- previousView.addEventListener('animationend', this._onZoomOutHandlerEnd);
616
- if (lastView !== null) lastView.addEventListener('animationend', this._onZoomOutHandlerEnd);
617
- //
618
- currentView.classList.add(`zoom-current-view-${instance}`);
619
- previousView.classList.add(`zoom-previous-view-${instance}`);
620
- if (lastView !== null) lastView.classList.add(`zoom-last-view-${instance}`);
621
- this.storedViews.pop();
622
- }
623
-
624
- /**
625
- * Event hangling
626
- */
627
- onZoom (event) {
628
- if (this.storedViews.length > 1 && !this.blockEvents && !event.target.classList.contains('zoom-me') && event.target.closest('.is-current-view') === null && !this.touching) {
629
- this.tracing('onZoom()');
630
- event.stopPropagation();
631
- this.zoomOut();
632
- }
633
- if (!this.blockEvents && event.target.classList.contains('zoom-me') && !this.touching) {
634
- this.tracing('onZoom()');
635
- event.stopPropagation();
636
- this.zoomIn(event.target);
637
- }
638
- }
639
-
640
- onKeyUp (event) {
641
- this.tracing('onKeyUp()');
642
- // Possible conflict with usar inputs
643
- if (event.key === 'ArrowLeft' || event.key === 'ArrowDown') {
644
- event.preventDefault();
645
- if (this.storedViews.length > 1 && !this.blockEvents) {
646
- this.zoomOut();
647
- } else {
648
- this.notify(`is on level zero. Can't zoom out. Trigger: ${event.key}`, 'warn');
649
- }
650
- }
651
- if (event.key === 'ArrowRight' || event.key === 'ArrowUp') {
652
- event.preventDefault();
653
- this.notify(event.key + 'has not actions defined');
654
- }
655
- }
656
-
657
- onWeel (event) {
658
- // inertia need to be fixed
659
- if (!this.blockEvents) {
660
- this.tracing('onWeel()');
661
- if (event.deltaY < 0) ;
662
- if (event.deltaY > 0) {
663
- if (this.storedViews.length > 1 && !this.blockEvents) {
664
- this.zoomOut();
665
- }
666
- }
667
- }
668
- }
669
-
670
- onTouchStart (event) {
671
- this.tracing('onTouchStart()');
672
- this.touching = true;
673
- this.touchstartX = event.changedTouches[0].screenX;
674
- this.touchstartY = event.changedTouches[0].screenY;
675
- }
676
-
677
- onTouchEnd (event) {
678
- if (!this.blockEvents) {
679
- this.tracing('onTouchEnd()');
680
- this.touchendX = event.changedTouches[0].screenX;
681
- this.touchendY = event.changedTouches[0].screenY;
682
- this.handleGesture(event);
683
- // event.preventDefault()
684
- }
685
- }
686
-
687
- handleGesture (event) {
688
- event.stopPropagation();
689
- this.tracing('handleGesture()');
690
- if (this.touchendX < this.touchstartX - 30) {
691
- if (this.storedViews.length > 1 && !this.blockEvents) {
692
- this.tracing('swipe left');
693
- this.zoomOut();
694
- } else {
695
- this.notify("is on level zero. Can't zoom out. Trigger: Swipe left", 'warn');
696
- }
697
- }
698
- if (this.touchendY < this.touchstartY - 10) {
699
- if (this.storedViews.length > 1 && !this.blockEvents) {
700
- this.tracing('swipe up');
701
- // Disabled. In near future enable if Zumly is full screen
702
- // this.zoomOut()
703
- } else {
704
- this.notify("is on level zero. Can't zoom out. Trigger: Swipe up", 'warn');
705
- }
706
- }
707
- if (this.touchendY === this.touchstartY && !this.blockEvents && event.target.classList.contains('zoom-me') && this.touching) {
708
- this.touching = false;
709
- this.tracing('tap');
710
- event.preventDefault();
711
- this.zoomIn(event.target);
712
- }
713
- 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) {
714
- this.touching = false;
715
- this.tracing('tap');
716
- this.zoomOut();
717
- }
718
- }
719
-
720
- onZoomOutHandlerStart (event) {
721
- this.tracing('onZoomOutHandlerStart()');
722
- this.blockEvents = true;
723
- event.target.removeEventListener('animationstart', this._onZoomOutHandlerStart);
724
- }
725
-
726
- onZoomOutHandlerEnd (event) {
727
- this.tracing('onZoomOutHandlerEnd()');
728
- const element = event.target;
729
- var currentZoomLevel = this.currentStage;
730
- element.removeEventListener('animationend', this._onZoomOutHandlerEnd);
731
- // current
732
- if (element.classList.contains(`zoom-current-view-${this.instance}`)) {
733
- try {
734
- this.canvas.removeChild(element);
735
- } catch(e) {
736
- console.debug("Error when trying to remove element after zoom out. Trying to remove its parent instead...");
737
- try {
738
- this.canvas.removeChild(element.parentElement);
739
- } catch(e) {
740
- console.debug("Error when trying to remove elemont after zoom out:", e);
741
- console.debug("Element to remove was:", element);
742
- }
743
-
744
- }
745
-
746
- this.blockEvents = false;
747
- }
748
- if (element.classList.contains(`zoom-previous-view-${this.instance}`)) {
749
- var origin = currentZoomLevel.views[1].backwardState.origin;
750
- var transform = currentZoomLevel.views[1].backwardState.transform;
751
- element.classList.remove('performance');
752
- element.classList.remove(`zoom-previous-view-${this.instance}`);
753
- element.style.transformOrigin = origin;
754
- element.style.transform = transform;
755
- element.style.filter = 'none';
756
- if (currentZoomLevel.views.length === 2) this.tracing('ended');
757
- }
758
- if (element.classList.contains(`zoom-last-view-${this.instance}`)) {
759
- origin = currentZoomLevel.views[2].backwardState.origin;
760
- transform = currentZoomLevel.views[2].backwardState.transform;
761
- element.classList.remove('performance');
762
- element.classList.remove(`zoom-last-view-${this.instance}`);
763
- element.style.transformOrigin = origin;
764
- element.style.transform = transform;
765
- if (currentZoomLevel.views.length > 2) this.tracing('ended');
766
- }
767
- }
768
-
769
- onZoomInHandlerStart (event) {
770
- this.tracing('onZoomInHandlerStart()');
771
- this.blockEvents = true;
772
- event.target.removeEventListener('animationstart', this._onZoomInHandlerStart);
773
- }
774
-
775
- onZoomInHandlerEnd (event) {
776
- this.tracing('onZoomInHandlerEnd()');
777
- const element = event.target;
778
- var currentZoomLevel = this.currentStage;
779
- if (event.target.classList.contains('is-new-current-view')) {
780
- this.blockEvents = false;
781
- var viewName = 'current-view';
782
- var transform = currentZoomLevel.views[0].forwardState.transform;
783
- var origin = currentZoomLevel.views[0].forwardState.origin;
784
- element.classList.remove('is-new-current-view');
785
- element.classList.add('is-current-view');
786
- } else if (event.target.classList.contains('is-previous-view')) {
787
- viewName = 'previous-view';
788
- transform = currentZoomLevel.views[1].forwardState.transform;
789
- origin = currentZoomLevel.views[1].forwardState.origin;
790
- if (currentZoomLevel.views.length === 2) this.tracing('ended');
791
- } else {
792
- viewName = 'last-view';
793
- transform = currentZoomLevel.views[2].forwardState.transform;
794
- origin = currentZoomLevel.views[2].forwardState.origin;
795
- if (currentZoomLevel.views.length > 2) this.tracing('ended');
796
- }
797
- element.classList.remove('performance');
798
- element.classList.remove(`zoom-${viewName}-${this.instance}`);
799
- element.classList.remove('has-no-events');
800
- element.style.transformOrigin = origin;
801
- element.style.transform = transform;
802
- element.style.filter = window.getComputedStyle(document.documentElement).getPropertyValue(`--${viewName}-filter-end-${this.instance}`);
803
- element.removeEventListener('animationend', this._onZoomInHandlerEnd);
804
- }
805
- }
806
-
807
- return Zumly;
808
-
809
- })));