zumly 0.9.7 → 0.9.11

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/README.md CHANGED
@@ -1,54 +1,115 @@
1
- # Zumly
1
+ <p align="center">
2
+ <a href="https://zumly.org">
3
+ <img src="https://raw.githubusercontent.com/zumly/website/gh-pages/images/logo-zumly.png" width="200">
4
+ </a>
5
+ </p>
2
6
 
3
- > Zumly powers user interfaces with beautiful zooming transitions.
7
+ <p align="center">
8
+ Zumly is a Javascript library for building zooming user interfaces. Create zooming experiences using web standards.
9
+ </p>
4
10
 
11
+ <p align="center">
12
+ <a href="https://www.npmjs.com/package/zumly"><img src="https://img.shields.io/npm/v/zumly.svg"></a>
13
+ </p>
14
+
15
+ ## Overview
16
+
17
+ Zumly is a frontend library for creating zoomable user interfaces ([ZUI](https://en.wikipedia.org/wiki/Zooming_user_interface)). Instead of hyperlinks and windows, Zumly uses zooming as a metaphor for browsing through information. This way it offers an infinite virtual canvas in which elements can be zoomed themselves to reveal further details.
18
+
19
+ To be more flexible Zumly is primarily focused on zooming transitions without caring about visual design. Most CSS frameworks or custom designs work with Zumly.
5
20
 
6
21
  ## Installation
7
22
 
8
23
  ### NPM
9
24
  ```sh
10
- npm install @zumly/zumly
25
+ npm install zumly
11
26
 
12
27
  # or
13
28
 
14
- yarn add @zumly/zumly
29
+ yarn add zumly
15
30
  ```
16
31
 
32
+ ### Content delivery networks (CDN)
33
+ Include https://unpkg.com/zumly in your project in a `<script>` tag.
34
+
35
+
17
36
  ### Direct download
18
37
 
19
- ### CDN
38
+ Download Zumly files from [unpkg.com](https://unpkg.com/zumly/). Files are in `dist` folder.
20
39
 
21
40
 
22
41
  ## Setup
23
42
 
24
- ### Browser or CDN
25
43
 
26
- ### ES modules
44
+ ### ES6 modules
45
+
46
+ 1. Add CSS inside `<head>` tag:
47
+ ```html
48
+
49
+ <link rel="stylesheet" href="zumly/dist/zumly.css">
50
+
51
+ <!-- Or "https://unpkg.com/zumly@0.9.11/dist/zumly.css" -->
52
+
53
+ ```
54
+
55
+ 2. Add Zumly as ES6 module:
56
+ ```html
57
+ <script type="module">
58
+ import Zumly from "zumly/dist/zumly.mjs"
59
+
60
+ // Or "https://unpkg.com/zumly@0.9.11/dist/zumly.mjs"
61
+ </script>
62
+ ```
27
63
 
28
64
  ### UMD modules
29
65
 
66
+ 1. Add Zumly CSS Styles inside `<head>` tag:
67
+ ```html
30
68
 
31
- ## Hello World
69
+ <link rel="stylesheet" href="zumly/dist/zumly.css">
32
70
 
33
- ### HTML
71
+ <!-- Or "https://unpkg.com/zumly@0.9.11/dist/zumly.css" -->
72
+
73
+ ```
34
74
 
75
+ 2. Add Zumly as UMD module:
35
76
  ```html
36
77
 
37
- <div class="example zumly-canvas"></div>
78
+ <script src="zumly/dist/zumly.umd.js"></script>
79
+
80
+ // Or "https://unpkg.com/zumly"
38
81
 
39
82
  ```
40
83
 
41
- ### JS
42
- ```js
43
84
 
44
- const hello = `<div class="z-view">Hello
45
- <div class='zoom-me' data-to='world'>Zoom to World</div>
46
- </div>`
85
+ ## Hello World
86
+
87
+ 1. Create a container for your Zumly app with `.zumly-canvas`:
88
+
89
+ ```html
90
+
91
+ <div class="example zumly-canvas"></div>
92
+
93
+ ```
47
94
 
48
- const world = `<div class="z-view">Hello
49
- <div class='zoom-me' data-to='world'>Zoom to World</div>
50
- </div>`
95
+ 2. Inside `script` tag write this code:
51
96
 
97
+ ```js
98
+ // Some views
99
+ const hello = `
100
+ <div class="z-view">
101
+ H E L L O <br>
102
+ W <span class="zoom-me" data-to="world">O</span> R L D!
103
+ </div>
104
+ `;
105
+
106
+ const world = `
107
+ <div class="z-view">
108
+ <img src="https://raw.githubusercontent.com/zumly/website/gh-pages/images/world.png"/>
109
+ </div>
110
+ `;
111
+
112
+ // Zumly instance
52
113
  const app = new Zumly({
53
114
  mount: '.example',
54
115
  initialView: 'hello',
@@ -62,7 +123,11 @@ app.init()
62
123
 
63
124
  ```
64
125
 
65
- ### Options
126
+ - See this example live at [codePen](https://codepen.io/zumly/pen/gOPQovd)
127
+
128
+ ### Zumly options
129
+
130
+ 1. The Zumly instance:
66
131
 
67
132
  ```js
68
133
  const app = new Zumly({
@@ -78,7 +143,7 @@ const app = new Zumly({
78
143
  },
79
144
  // Customize transitions. Object. Optional
80
145
  transitions: {
81
- // Effects for background views. Array. ['blur', 'sepia', 'sature']
146
+ // Effects for background views. Array. ['blur', 'sepia', 'saturate']
82
147
  effects: ['sepia'],
83
148
  // How new injected view is adapted. String. Default 'width'
84
149
  cover: 'height',
@@ -94,13 +159,43 @@ const app = new Zumly({
94
159
  app.init()
95
160
  ```
96
161
 
97
- ## Developer environment requirements
162
+ 2. Options for each zoomable element:
163
+
164
+ - Add `z-view` class in you view container:
165
+
166
+ ```html
167
+
168
+ <div class="z-view"></div>
169
+
170
+ ```
171
+
172
+ - Add `zoom-me` class to an HTML element to make it zoomable and add `data-to` attribute with the name of the target view
173
+
174
+ ```html
175
+
176
+ <div class="zoom-me" data-to="anotherView">Zoom me!</div>
177
+
178
+ ```
179
+
180
+ - Each zooming transition can be customized by adding some `data-` attributes:
181
+
182
+ ```html
183
+
184
+ <div class="zoom-me" data-to="anotherView" data-with-duration="2s" data-with-ease="ease-in">
185
+ Zoom me!
186
+ </div>
187
+
188
+ ```
189
+
190
+ ## Development
191
+
192
+ ### Developer environment requirements
98
193
 
99
194
  To run this project, you will need:
100
195
 
101
- - Node.js >= v10.5.0,[install instructions](https://nodejs.org/)
196
+ - Node.js >= v10.5.0
102
197
 
103
- ## Dev mode
198
+ ### Dev mode
104
199
 
105
200
  When developing you can run:
106
201
 
@@ -114,7 +209,7 @@ yarn dev
114
209
 
115
210
  This will regenerate the build files each time a source file is changed and serve on http://localhost:9090
116
211
 
117
- ## Running tests
212
+ ### Running tests
118
213
 
119
214
  ```sh
120
215
  npm run test
@@ -124,7 +219,7 @@ npm run test
124
219
  yarn test
125
220
  ```
126
221
 
127
- ## Building
222
+ ### Building
128
223
 
129
224
  ```sh
130
225
  npm run build
@@ -138,9 +233,28 @@ yarn build
138
233
 
139
234
  Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.
140
235
 
236
+ ### Status: beta
237
+
238
+ Zumly is on early stages of development.
239
+
240
+ ### Roadmap
241
+
242
+ - Allow different template engines. Currently Zumly only accepts string literal templates.
243
+ - Add lateral navigation for same zoom level elements.
244
+ - Add a navegation widget.
245
+ - Add programmatic navigation.
246
+ - Add preseted navigation.
247
+ - Add router. [#3](https://github.com/zumly/zumly/issues/3)
248
+ - Allow recalculate zoom position on resize events.
249
+
250
+
251
+ ## Stay in touch
252
+
253
+ - [Telegram group](https://t.me/ZumlyCommunity)
254
+
141
255
  ## Original idea
142
256
 
143
- I initially created [Zircle UI](https://github.com/zircleUI/zircleUI) as an experiment, now the things are a bit more serious.
257
+ Zumly is a new approach based on another library I made, [Zircle UI](https://github.com/zircleUI/zircleUI)
144
258
 
145
259
  ## License
146
260
 
package/dist/zumly.css CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
- * @zumly/zumly v0.9.7
3
- * Author [object Object], @license MIT
2
+ * zumly v0.9.11
3
+ * Author Juan Martín Muda, @license MIT
4
4
  * https://zumly.org
5
5
  */
6
6
  .zumly-canvas {
@@ -8,25 +8,18 @@
8
8
  width: 100%;
9
9
  height: 100%;
10
10
  overflow: hidden;
11
- box-sizing: border-box;
12
11
  margin: 0;
13
12
  padding: 0;
14
13
  perspective: 1000px;
15
14
  cursor: zoom-out;
16
15
  }
17
16
 
18
- .zumly-canvas > * {
19
- box-sizing: border-box;
20
- margin: 0;
21
- padding: 0;
22
- }
23
-
24
17
  .zumly-canvas:focus {
25
18
  outline: none;
26
19
  }
27
20
 
28
21
  .z-view {
29
-
22
+ position: absolute;
30
23
  }
31
24
 
32
25
  .z-view.is-current-view {
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @zumly/zumly v0.9.7
3
- * Author [object Object], @license MIT
2
+ * zumly v0.9.11
3
+ * Author Juan Martín Muda, @license MIT
4
4
  * https://zumly.org
5
- */.zumly-canvas{position:absolute;width:100%;height:100%;overflow:hidden;perspective:1000px;cursor:zoom-out}.zumly-canvas,.zumly-canvas>*{box-sizing:border-box;margin:0;padding:0}.zumly-canvas:focus{outline:none}.z-view.is-current-view{cursor:default}.z-view.has-no-events,.z-view.is-last-view,.z-view.is-previous-view{pointer-events:none;user-select:none}.z-view.performance{will-change:transform,opacity,filter}.z-view.hide{opacity:0}.zoom-me{cursor:zoom-in}
5
+ */.zumly-canvas{position:absolute;width:100%;height:100%;overflow:hidden;margin:0;padding:0;perspective:1000px;cursor:zoom-out}.zumly-canvas:focus{outline:none}.z-view{position:absolute}.z-view.is-current-view{cursor:default}.z-view.has-no-events,.z-view.is-last-view,.z-view.is-previous-view{pointer-events:none;user-select:none}.z-view.performance{will-change:transform,opacity,filter}.z-view.hide{opacity:0}.zoom-me{cursor:zoom-in}
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @zumly/zumly v0.9.7
3
- * Author [object Object], @license MIT
2
+ * zumly v0.9.11
3
+ * Author Juan Martín Muda, @license MIT
4
4
  * https://zumly.org
5
5
  */
6
- function t(t){if(void 0!==t&&"none"===t[0].toLowerCase())return!0;if(void 0!==t&&t.length>0){return(t=>[...new Set(t)])(t.map(t=>t.toLowerCase())).every(t=>-1!==["blur","sepia","saturate"].indexOf(t))}}function e(t){var e="",n="";if(void 0!==t)return t.map(t=>{e+=""+("blur"===t.toLowerCase()?"blur(0px) ":"sepia"===t.toLowerCase()?"sepia(0) ":"saturate"===t.toLowerCase()?"saturate(0) ":"none"),n+=""+("blur"===t.toLowerCase()?"blur(0.8px) ":"sepia"===t.toLowerCase()?"sepia(5) ":"saturate"===t.toLowerCase()?"saturate(8) ":"none")}),[e,n]}function n(t,e,n){t[e]=n}function s(t,e,s,i,o={isRequired:!1,defaultValue:0,allowedValues:0,hasValidation:0,hasAssignFunction:0}){var a=`'${e}' property is required when instance is defined`,d=`'${e}' property has problems`,c=void 0!==s,l=void 0!==o.defaultValue,u=void 0!==o.hasValidation,h=void 0!==o.hasAssignFunction;if("string"===i||"object"===i||"boolean"===i)var m=typeof s===i;else"array"===i&&(m=Array.isArray(s));o.isRequired&&(c&&m?n(t,e,s):r(!1,a,"error")),!l||u||h||(c&&m?n(t,e,s):void 0===s?n(t,e,o.defaultValue):r(!1,d,"error")),u&&l&&!h&&(c&&m&&o.hasValidation?n(t,e,s):void 0===s?n(t,e,o.defaultValue):r(!1,d,"error")),u&&l&&h&&(c&&m&&o.hasValidation?n(t,e,o.hasAssignFunction):void 0===s?n(t,e,o.defaultValue):r(!1,d,"error"))}function i(t,e,n){const s=e;[{name:"current-view",stage:s.views[0]},{name:"previous-view",stage:s.views[1]},{name:"last-view",stage:s.views[2]}].map(e=>{"zoomOut"===t&&void 0!==e.stage&&(document.documentElement.style.setProperty(`--${e.name}-transform-start-${n}`,e.stage.forwardState.transform),document.documentElement.style.setProperty(`--${e.name}-transform-end-${n}`,e.stage.backwardState.transform),document.documentElement.style.setProperty(`--${e.name}-transformOrigin-start-${n}`,e.stage.forwardState.origin),document.documentElement.style.setProperty(`--${e.name}-transformOrigin-end-${n}`,e.stage.backwardState.origin),document.documentElement.style.setProperty(`--${e.name}-opacity-start-${n}`,1),document.documentElement.style.setProperty(`--${e.name}-filter-start-${n}`,e.stage.forwardState.filter),document.documentElement.style.setProperty(`--${e.name}-filter-end-${n}`,e.stage.backwardState.filter),"current-view"===e.name?(document.documentElement.style.setProperty("--zoom-duration-"+n,e.stage.backwardState.duration),document.documentElement.style.setProperty("--zoom-ease-"+n,e.stage.backwardState.ease),document.documentElement.style.setProperty(`--${e.name}-opacity-end-${n}`,0),document.documentElement.style.setProperty(`--${e.name}-filter-start-${n}`,"none"),document.documentElement.style.setProperty(`--${e.name}-filter-end-${n}`,"none")):document.documentElement.style.setProperty(`--${e.name}-opacity-end-${n}`,1)),"zoomIn"===t&&void 0!==e.stage&&(document.documentElement.style.setProperty(`--${e.name}-transform-start-${n}`,e.stage.backwardState.transform),document.documentElement.style.setProperty(`--${e.name}-transform-end-${n}`,e.stage.forwardState.transform),document.documentElement.style.setProperty(`--${e.name}-transformOrigin-start-${n}`,e.stage.backwardState.origin),document.documentElement.style.setProperty(`--${e.name}-transformOrigin-end-${n}`,e.stage.forwardState.origin),document.documentElement.style.setProperty(`--${e.name}-filter-start-${n}`,e.stage.backwardState.filter),document.documentElement.style.setProperty(`--${e.name}-filter-end-${n}`,e.stage.forwardState.filter),"current-view"===e.name?(document.documentElement.style.setProperty("--zoom-duration-"+n,e.stage.forwardState.duration),document.documentElement.style.setProperty("--zoom-ease-"+n,e.stage.forwardState.ease),document.documentElement.style.setProperty(`--${e.name}-opacity-start-${n}`,0),document.documentElement.style.setProperty(`--${e.name}-filter-start-${n}`,"none"),document.documentElement.style.setProperty(`--${e.name}-filter-end-${n}`,"none")):document.documentElement.style.setProperty(`--${e.name}-opacity-start-${n}`,1),document.documentElement.style.setProperty(`--${e.name}-opacity-end-${n}`,1))})}async function o(t,e,n,s){return new Promise(i=>{var o=null;o=s?t:t.dataset.to,window.requestIdleCallback(async()=>{var t=document.createElement("template");"object"==typeof n[o]&&void 0!==n[o].render?t.innerHTML=await n[o].render():t.innerHTML=n[o];const r=t.content.querySelector(".z-view");s?r.classList.add("is-current-view"):(r.classList.add("is-new-current-view"),r.classList.add("has-no-events"),r.classList.add("hide"),r.classList.add("performance")),r.style.transformOrigin="0 0",r.dataset.viewName=o;var a=e.append(t.content);"object"==typeof n[o]&&void 0!==n[o].mounted&&"function"==typeof n[o].mounted()&&await n[o].mounted(),i(a)})})}function r(t,e,n){e&&"welcome"===n&&console.info("%c Zumly %c "+e,"background: #424085; color: white; border-radius: 3px;","color: #424085"),e&&t&&("info"===n||void 0===n)&&console.info("%c Zumly %c "+e,"background: #6679A3; color: #304157; border-radius: 3px;","color: #6679A3"),e&&"warn"===n&&console.warn("%c Zumly %c "+e,"background: #DCBF53; color: #424085; border-radius: 3px;","color: #424085"),e&&"error"===n&&console.error("%c Zumly %c "+e,"background: #BE4747; color: white; border-radius: 3px;","color: #424085")}window.requestIdleCallback=window.requestIdleCallback||function(t){var e=Date.now();return setTimeout(()=>{t({didTimeout:!1,timeRemaining:()=>Math.max(0,50-(Date.now()-e))})},1)};class a{constructor(i){var o,d;this.instance=a.counter,this.storedViews=[],this.currentStage=null,this.storedPreviousScale=[1],this.trace=[],this.blockEvents=!1,this.touchstartX=0,this.touchstartY=0,this.touchendX=0,this.touchendY=0,this.touching=!1,d=this,(o=i)&&"object"==typeof o?(n(d,"options",!0),s(d,"mount",o.mount,"string",{isRequired:!0}),s(d,"initialView",o.initialView,"string",{isRequired:!0}),s(d,"views",o.views,"object",{isRequired:!0}),s(d,"debug",o.debug,"boolean",{defaultValue:!1}),o.transitions&&"object"==typeof o.transitions?(s(d,"cover",o.transitions.cover,"string",{defaultValue:"width",hasValidation:()=>{["height","width"].indexOf(o.transitions.cover.toLowerCase())}}),s(d,"duration",o.transitions.duration,"string",{defaultValue:"1s"}),s(d,"ease",o.transitions.ease,"string",{defaultValue:"ease-in-out"}),s(d,"effects",o.transitions.effects,"array",{defaultValue:["none","none"],hasValidation:t(o.transitions.effects),hasAssignFunction:e(o.transitions.effects)})):(n(d,"cover","width"),n(d,"duration","1s"),n(d,"ease","ease-in-out"),n(d,"effects",["none","none"]))):r(!1,"'options' object has to be provided when instance is defined","error"),this.options?(this._onZoom=this.onZoom.bind(this),this._onZoomInHandlerStart=this.onZoomInHandlerStart.bind(this),this._onZoomInHandlerEnd=this.onZoomInHandlerEnd.bind(this),this._onZoomOutHandlerStart=this.onZoomOutHandlerStart.bind(this),this._onZoomOutHandlerEnd=this.onZoomOutHandlerEnd.bind(this),this._onTouchStart=this.onTouchStart.bind(this),this._onTouchEnd=this.onTouchEnd.bind(this),this._onKeyUp=this.onKeyUp.bind(this),this._onWeel=this.onWeel.bind(this),this.canvas=document.querySelector(this.mount),this.canvas.setAttribute("tabindex",0),this.canvas.addEventListener("mouseup",this._onZoom,!1),this.canvas.addEventListener("touchend",this._onZoom,!1),this.canvas.addEventListener("touchstart",this._onTouchStart,{passive:!0}),this.canvas.addEventListener("touchend",this._onTouchEnd,!1),this.canvas.addEventListener("keyup",this._onKeyUp,!1),this.canvas.addEventListener("wheel",this._onWeel,{passive:!0})):this.notify("is unable to start: no {options} have been passed to the Zumly's instance.","error")}storeViews(t){this.tracing("storedViews()"),this.storedViews.push(t)}setPreviousScale(t){this.tracing("setPreviousScale()"),this.storedPreviousScale.push(t)}tracing(t){if("ended"===t){const t=this.trace.map((t,e)=>""+(0===e?`Instance ${this.instance}: ${t}`:""+t)).join(" > ");this.notify(t),this.trace=[]}else this.trace.push(t)}static get counter(){return a._counter=(a._counter||0)+1,a._counter}notify(t,e){return r(this.debug,t,e)}zoomLevel(){return this.storedViews.length}async init(){this.options&&(this.tracing("init()"),function(t){var e=document.createElement("style");let n="";["current-view","previous-view","last-view"].map(e=>{n+=`\n .zoom-${e}-${t} {\n animation-name: zoom-${e}-${t};\n animation-duration: var(--zoom-duration-${t});\n animation-timing-function: var(--zoom-ease-${t});\n }\n @keyframes zoom-${e}-${t} {\n 0% {\n transform-origin: var(--${e}-transformOrigin-start-${t});\n transform: var(--${e}-transform-start-${t});\n opacity: var(--${e}-opacity-start-${t});\n filter: var(--${e}-filter-start-${t})\n }\n 100% {\n transform-origin: var(--${e}-transformOrigin-end-${t});\n transform: var(--${e}-transform-end-${t});\n opacity: var(--${e}-opacity-end-${t});\n filter: var(--${e}-filter-end-${t})\n }\n }\n `}),e.innerHTML=n,document.head.appendChild(e)}(this.instance),await o(this.initialView,this.canvas,this.views,"init"),this.storeViews({zoomLevel:this.storedViews.length,views:[{viewName:this.initialView,backwardState:{origin:"0 0",transform:""}}]}),this.notify(""+(this.instance>1?`instance nº ${this.instance} is active.`:`is running! Instance nº ${this.instance} is active. ${this.debug?"Debug is active, can be deactivate by setting 'debug: false' when you define the instance.":""}\n More tips & docs at https://zumly.org`),"welcome"))}async zoomIn(t){this.tracing("zoomIn()");var e=this.instance;const n=this.canvas,s=n.getBoundingClientRect();var r=s.left,a=s.top;const d=this.storedPreviousScale[this.storedPreviousScale.length-1];this.tracing("renderView()"),await o(t,n,this.views),t.classList.add("zoomed");const c=t.getBoundingClientRect();var l=n.querySelector(".is-new-current-view"),u=n.querySelector(".is-current-view"),h=n.querySelector(".is-previous-view"),m=n.querySelector(".is-last-view");null!==m&&n.removeChild(m);const v=l.getBoundingClientRect(),w=v.width/c.width,g=1/w,f=v.height/c.height,p=1/f;var y=t.dataset.withDuration||this.duration,$=t.dataset.withEease||this.ease,E=this.effects[0],S=this.effects[1],b=this.cover;if("width"===b)var L=w,z=g;else"height"===b&&(L=f,z=p);this.setPreviousScale(L);var k=`translate(${c.x-r+(c.width-v.width*z)/2}px, ${c.y-a+(c.height-v.height*z)/2}px) scale(${z})`;l.style.transform=k,u.classList.add("is-previous-view"),u.classList.remove("is-current-view");const V=u.getBoundingClientRect();var O=u.style.transform;u.style.transformOrigin=`${c.x+c.width/2-V.x}px ${c.y+c.height/2-V.y}px`;const P=s.width/2-c.width/2-c.x+V.x,Z=s.height/2-c.height/2-c.y+V.y,x=`translate(${P}px, ${Z}px) scale(${L})`;u.style.transform=x;var C=t.getBoundingClientRect(),H=`translate(${C.x-r+(C.width-v.width)/2}px, ${C.y-a+(C.height-v.height)/2}px)`;if(null!==h){h.classList.remove("is-previous-view"),h.classList.add("is-last-view");var _=h.style.transform,I=u.getBoundingClientRect();h.style.transform=`translate(${P-r}px, ${Z-a}px) scale(${L*d})`;var T=h.querySelector(".zoomed").getBoundingClientRect();h.style.transform=_,u.style.transform=O;var q=u.getBoundingClientRect(),R=`translate(${s.width/2-c.width/2-c.x+(q.x-T.x)+I.x-r+(I.width-T.width)/2}px, ${s.height/2-c.height/2-c.y+(q.y-T.y)+I.y-a+(I.height-T.height)/2}px) scale(${L*d})`}else u.style.transform=O;var Y={zoomLevel:this.storedViews.length,views:[]};const A=l?{viewName:l.dataset.viewName,backwardState:{origin:l.style.transformOrigin,duration:y,ease:$,transform:k,filter:E},forwardState:{origin:l.style.transformOrigin,duration:y,ease:$,transform:H,filter:S}}:null,B=u?{viewName:u.dataset.viewName,backwardState:{origin:u.style.transformOrigin,duration:y,ease:$,transform:O,filter:window.getComputedStyle(document.documentElement).getPropertyValue("--previous-view-filter-end-"+e)},forwardState:{origin:u.style.transformOrigin,duration:y,ease:$,transform:x,filter:S}}:null,N=h?{viewName:h.dataset.viewName,backwardState:{origin:h.style.transformOrigin,duration:y,ease:$,transform:_,filter:window.getComputedStyle(document.documentElement).getPropertyValue("--previous-view-filter-end-"+e)},forwardState:{origin:h.style.transformOrigin,duration:y,ease:$,transform:R,filter:S}}:null,D=m?{viewName:m}:null;null!==A&&Y.views.push(A),null!==B&&Y.views.push(B),null!==N&&Y.views.push(N),null!==D&&Y.views.push(D),this.storeViews(Y),this.currentStage=this.storedViews[this.storedViews.length-1],this.tracing("setCSSVariables()"),i("zoomIn",this.currentStage,this.instance),u.classList.add("performance"),null!==h&&h.classList.add("performance"),l.classList.remove("hide"),l.addEventListener("animationstart",this._onZoomInHandlerStart),l.addEventListener("animationend",this._onZoomInHandlerEnd),u.addEventListener("animationend",this._onZoomInHandlerEnd),null!==h&&h.addEventListener("animationend",this._onZoomInHandlerEnd),l.classList.add("zoom-current-view-"+e),u.classList.add("zoom-previous-view-"+e),null!==h&&h.classList.add("zoom-last-view-"+e)}zoomOut(){this.tracing("zoomOut()"),this.blockEvents=!0,this.storedPreviousScale.pop();var t=this.instance;const e=this.canvas;this.currentStage=this.storedViews[this.storedViews.length-1];const n=this.currentStage.views[3];var s=e.querySelector(".is-current-view"),o=e.querySelector(".is-previous-view"),r=e.querySelector(".is-last-view");(this.tracing("setCSSVariables()"),i("zoomOut",this.currentStage,this.instance),s.classList.remove("performance"),o.querySelector(".zoomed").classList.remove("zoomed"),o.classList.remove("is-previous-view"),o.classList.add("is-current-view"),o.classList.remove("performance"),null!==r&&(r.classList.add("performance"),r.classList.add("is-previous-view"),r.classList.remove("is-last-view"),r.classList.remove("hide")),void 0!==n)&&(e.prepend(n.viewName),e.querySelector(".z-view:first-child").classList.add("hide"));s.addEventListener("animationstart",this._onZoomOutHandlerStart),s.addEventListener("animationend",this._onZoomOutHandlerEnd),o.addEventListener("animationend",this._onZoomOutHandlerEnd),null!==r&&r.addEventListener("animationend",this._onZoomOutHandlerEnd),s.classList.add("zoom-current-view-"+t),o.classList.add("zoom-previous-view-"+t),null!==r&&r.classList.add("zoom-last-view-"+t),this.storedViews.pop()}onZoom(t){this.storedViews.length>1&&!this.blockEvents&&!t.target.classList.contains("zoom-me")&&null===t.target.closest(".is-current-view")&&!this.touching&&(this.tracing("onZoom()"),t.stopPropagation(),this.zoomOut()),this.blockEvents||!t.target.classList.contains("zoom-me")||this.touching||(this.tracing("onZoom()"),t.stopPropagation(),this.zoomIn(t.target))}onKeyUp(t){this.tracing("onKeyUp()"),"ArrowLeft"!==t.key&&"ArrowDown"!==t.key||(t.preventDefault(),this.storedViews.length>1&&!this.blockEvents?this.zoomOut():this.notify("is on level zero. Can't zoom out. Trigger: "+t.key,"warn")),"ArrowRight"!==t.key&&"ArrowUp"!==t.key||(t.preventDefault(),this.notify(t.key+"has not actions defined"))}onWeel(t){this.blockEvents||(this.tracing("onWeel()"),t.deltaY,t.deltaY>0&&this.storedViews.length>1&&!this.blockEvents&&this.zoomOut())}onTouchStart(t){this.tracing("onTouchStart()"),this.touching=!0,this.touchstartX=t.changedTouches[0].screenX,this.touchstartY=t.changedTouches[0].screenY}onTouchEnd(t){this.blockEvents||(this.tracing("onTouchEnd()"),this.touchendX=t.changedTouches[0].screenX,this.touchendY=t.changedTouches[0].screenY,this.handleGesture(t))}handleGesture(t){t.stopPropagation(),this.tracing("handleGesture()"),this.touchendX<this.touchstartX-30&&(this.storedViews.length>1&&!this.blockEvents?(this.tracing("swipe left"),this.zoomOut()):this.notify("is on level zero. Can't zoom out. Trigger: Swipe left","warn")),this.touchendY<this.touchstartY-10&&(this.storedViews.length>1&&!this.blockEvents?this.tracing("swipe up"):this.notify("is on level zero. Can't zoom out. Trigger: Swipe up","warn")),this.touchendY===this.touchstartY&&!this.blockEvents&&t.target.classList.contains("zoom-me")&&this.touching&&(this.touching=!1,this.tracing("tap"),t.preventDefault(),this.zoomIn(t.target)),this.touchendY===this.touchstartY&&this.storedViews.length>1&&!this.blockEvents&&!t.target.classList.contains("zoom-me")&&null===t.target.closest(".is-current-view")&&this.touching&&(this.touching=!1,this.tracing("tap"),this.zoomOut())}onZoomOutHandlerStart(t){this.tracing("onZoomOutHandlerStart()"),this.blockEvents=!0,t.target.removeEventListener("animationstart",this._onZoomOutHandlerStart)}onZoomOutHandlerEnd(t){this.tracing("onZoomOutHandlerEnd()");const e=t.target;var n=this.currentStage;if(e.removeEventListener("animationend",this._onZoomOutHandlerEnd),e.classList.contains("zoom-current-view-"+this.instance)&&(this.canvas.removeChild(e),this.blockEvents=!1),e.classList.contains("zoom-previous-view-"+this.instance)){var s=n.views[1].backwardState.origin,i=n.views[1].backwardState.transform;e.classList.remove("performance"),e.classList.remove("zoom-previous-view-"+this.instance),e.style.transformOrigin=s,e.style.transform=i,e.style.filter="none",2===n.views.length&&this.tracing("ended")}e.classList.contains("zoom-last-view-"+this.instance)&&(s=n.views[2].backwardState.origin,i=n.views[2].backwardState.transform,e.classList.remove("performance"),e.classList.remove("zoom-last-view-"+this.instance),e.style.transformOrigin=s,e.style.transform=i,n.views.length>2&&this.tracing("ended"))}onZoomInHandlerStart(t){this.tracing("onZoomInHandlerStart()"),this.blockEvents=!0,t.target.removeEventListener("animationstart",this._onZoomInHandlerStart)}onZoomInHandlerEnd(t){this.tracing("onZoomInHandlerEnd()");const e=t.target;var n=this.currentStage;if(t.target.classList.contains("is-new-current-view")){this.blockEvents=!1;var s="current-view",i=n.views[0].forwardState.transform,o=n.views[0].forwardState.origin;e.classList.remove("is-new-current-view"),e.classList.add("is-current-view")}else t.target.classList.contains("is-previous-view")?(s="previous-view",i=n.views[1].forwardState.transform,o=n.views[1].forwardState.origin,2===n.views.length&&this.tracing("ended")):(s="last-view",i=n.views[2].forwardState.transform,o=n.views[2].forwardState.origin,n.views.length>2&&this.tracing("ended"));e.classList.remove("performance"),e.classList.remove(`zoom-${s}-${this.instance}`),e.classList.remove("has-no-events"),e.style.transformOrigin=o,e.style.transform=i,e.style.filter=window.getComputedStyle(document.documentElement).getPropertyValue(`--${s}-filter-end-${this.instance}`),e.removeEventListener("animationend",this._onZoomInHandlerEnd)}}export default a;
6
+ function t(t){if(void 0!==t&&"none"===t[0].toLowerCase())return!0;if(void 0!==t&&t.length>0){return(t=>[...new Set(t)])(t.map(t=>t.toLowerCase())).every(t=>-1!==["blur","sepia","saturate"].indexOf(t))}}function e(t){var e="",n="";if(void 0!==t)return t.map(t=>{e+=""+("blur"===t.toLowerCase()?"blur(0px) ":"sepia"===t.toLowerCase()?"sepia(0) ":"saturate"===t.toLowerCase()?"saturate(0) ":"none"),n+=""+("blur"===t.toLowerCase()?"blur(0.8px) ":"sepia"===t.toLowerCase()?"sepia(5) ":"saturate"===t.toLowerCase()?"saturate(8) ":"none")}),[e,n]}function n(t,e,n){t[e]=n}function s(t,e,s,i,o={isRequired:!1,defaultValue:0,allowedValues:0,hasValidation:0,hasAssignFunction:0}){var a=`'${e}' property is required when instance is defined`,d=`'${e}' property has problems`,c=void 0!==s,l=void 0!==o.defaultValue,u=void 0!==o.hasValidation,h=void 0!==o.hasAssignFunction;if("string"===i||"object"===i||"boolean"===i)var m=typeof s===i;else"array"===i&&(m=Array.isArray(s));o.isRequired&&(c&&m?n(t,e,s):r(!1,a,"error")),!l||u||h||(c&&m?n(t,e,s):void 0===s?n(t,e,o.defaultValue):r(!1,d,"error")),u&&l&&!h&&(c&&m&&o.hasValidation?n(t,e,s):void 0===s?n(t,e,o.defaultValue):r(!1,d,"error")),u&&l&&h&&(c&&m&&o.hasValidation?n(t,e,o.hasAssignFunction):void 0===s?n(t,e,o.defaultValue):r(!1,d,"error"))}function i(t,e,n){const s=e;[{name:"current-view",stage:s.views[0]},{name:"previous-view",stage:s.views[1]},{name:"last-view",stage:s.views[2]}].map(e=>{"zoomOut"===t&&void 0!==e.stage&&(document.documentElement.style.setProperty(`--${e.name}-transform-start-${n}`,e.stage.forwardState.transform),document.documentElement.style.setProperty(`--${e.name}-transform-end-${n}`,e.stage.backwardState.transform),document.documentElement.style.setProperty(`--${e.name}-transformOrigin-start-${n}`,e.stage.forwardState.origin),document.documentElement.style.setProperty(`--${e.name}-transformOrigin-end-${n}`,e.stage.backwardState.origin),document.documentElement.style.setProperty(`--${e.name}-opacity-start-${n}`,1),document.documentElement.style.setProperty(`--${e.name}-filter-start-${n}`,e.stage.forwardState.filter),document.documentElement.style.setProperty(`--${e.name}-filter-end-${n}`,e.stage.backwardState.filter),"current-view"===e.name?(document.documentElement.style.setProperty("--zoom-duration-"+n,e.stage.backwardState.duration),document.documentElement.style.setProperty("--zoom-ease-"+n,e.stage.backwardState.ease),document.documentElement.style.setProperty(`--${e.name}-opacity-end-${n}`,0),document.documentElement.style.setProperty(`--${e.name}-filter-start-${n}`,"none"),document.documentElement.style.setProperty(`--${e.name}-filter-end-${n}`,"none")):document.documentElement.style.setProperty(`--${e.name}-opacity-end-${n}`,1)),"zoomIn"===t&&void 0!==e.stage&&(document.documentElement.style.setProperty(`--${e.name}-transform-start-${n}`,e.stage.backwardState.transform),document.documentElement.style.setProperty(`--${e.name}-transform-end-${n}`,e.stage.forwardState.transform),document.documentElement.style.setProperty(`--${e.name}-transformOrigin-start-${n}`,e.stage.backwardState.origin),document.documentElement.style.setProperty(`--${e.name}-transformOrigin-end-${n}`,e.stage.forwardState.origin),document.documentElement.style.setProperty(`--${e.name}-filter-start-${n}`,e.stage.backwardState.filter),document.documentElement.style.setProperty(`--${e.name}-filter-end-${n}`,e.stage.forwardState.filter),"current-view"===e.name?(document.documentElement.style.setProperty("--zoom-duration-"+n,e.stage.forwardState.duration),document.documentElement.style.setProperty("--zoom-ease-"+n,e.stage.forwardState.ease),document.documentElement.style.setProperty(`--${e.name}-opacity-start-${n}`,0),document.documentElement.style.setProperty(`--${e.name}-filter-start-${n}`,"none"),document.documentElement.style.setProperty(`--${e.name}-filter-end-${n}`,"none")):document.documentElement.style.setProperty(`--${e.name}-opacity-start-${n}`,1),document.documentElement.style.setProperty(`--${e.name}-opacity-end-${n}`,1))})}async function o(t,e,n,s,i){var o=null;o=s?t:t.dataset.to;var r=document.createElement("template");if("object"==typeof n[o]&&void 0!==n[o].render)r.innerHTML=await n[o].render();else if("function"==typeof n[o]){var a=document.createElement("div");new n[o]({target:a,context:i,props:t.dataset});a.classList.add("z-view"),r.content.appendChild(a)}else r.innerHTML=n[o];let d=r.content.querySelector(".z-view");s?d.classList.add("is-current-view"):(d.classList.add("is-new-current-view"),d.classList.add("has-no-events"),d.classList.add("hide"),d.classList.add("performance")),d.style.transformOrigin="0 0",d.dataset.viewName=o;await e.append(r.content);"object"==typeof n[o]&&void 0!==n[o].mounted&&"function"==typeof n[o].mounted()&&await n[o].mounted()}function r(t,e,n){e&&"welcome"===n&&console.info("%c Zumly %c "+e,"background: #424085; color: white; border-radius: 3px;","color: #424085"),e&&t&&("info"===n||void 0===n)&&console.info("%c Zumly %c "+e,"background: #6679A3; color: #304157; border-radius: 3px;","color: #6679A3"),e&&"warn"===n&&console.warn("%c Zumly %c "+e,"background: #DCBF53; color: #424085; border-radius: 3px;","color: #424085"),e&&"error"===n&&console.error("%c Zumly %c "+e,"background: #BE4747; color: white; border-radius: 3px;","color: #424085")}window.requestIdleCallback=window.requestIdleCallback||function(t){var e=Date.now();return setTimeout(()=>{t({didTimeout:!1,timeRemaining:()=>Math.max(0,50-(Date.now()-e))})},1)};class a{constructor(i){var o,d;this.instance=a.counter,this.storedViews=[],this.currentStage=null,this.storedPreviousScale=[1],this.trace=[],this.blockEvents=!1,this.touchstartX=0,this.touchstartY=0,this.touchendX=0,this.touchendY=0,this.touching=!1,d=this,(o=i)&&"object"==typeof o?(n(d,"options",!0),s(d,"mount",o.mount,"string",{isRequired:!0}),s(d,"initialView",o.initialView,"string",{isRequired:!0}),s(d,"views",o.views,"object",{isRequired:!0}),s(d,"debug",o.debug,"boolean",{defaultValue:!1}),s(d,"componentContext",o.componentContext,"object",{isRequired:!1,defaultValue:new Map}),o.transitions&&"object"==typeof o.transitions?(s(d,"cover",o.transitions.cover,"string",{defaultValue:"width",hasValidation:()=>{["height","width"].indexOf(o.transitions.cover.toLowerCase())}}),s(d,"duration",o.transitions.duration,"string",{defaultValue:"1s"}),s(d,"ease",o.transitions.ease,"string",{defaultValue:"ease-in-out"}),s(d,"effects",o.transitions.effects,"array",{defaultValue:["none","none"],hasValidation:t(o.transitions.effects),hasAssignFunction:e(o.transitions.effects)})):(n(d,"cover","width"),n(d,"duration","1s"),n(d,"ease","ease-in-out"),n(d,"effects",["none","none"]))):r(!1,"'options' object has to be provided when instance is defined","error"),this.options?(this._onZoom=this.onZoom.bind(this),this._onZoomInHandlerStart=this.onZoomInHandlerStart.bind(this),this._onZoomInHandlerEnd=this.onZoomInHandlerEnd.bind(this),this._onZoomOutHandlerStart=this.onZoomOutHandlerStart.bind(this),this._onZoomOutHandlerEnd=this.onZoomOutHandlerEnd.bind(this),this._onTouchStart=this.onTouchStart.bind(this),this._onTouchEnd=this.onTouchEnd.bind(this),this._onKeyUp=this.onKeyUp.bind(this),this._onWeel=this.onWeel.bind(this),this.canvas=document.querySelector(this.mount),this.canvas.setAttribute("tabindex",0),this.canvas.addEventListener("mouseup",this._onZoom,!1),this.canvas.addEventListener("touchend",this._onZoom,!1),this.canvas.addEventListener("touchstart",this._onTouchStart,{passive:!0}),this.canvas.addEventListener("touchend",this._onTouchEnd,!1),this.canvas.addEventListener("keyup",this._onKeyUp,!1),this.canvas.addEventListener("wheel",this._onWeel,{passive:!0})):this.notify("is unable to start: no {options} have been passed to the Zumly's instance.","error")}storeViews(t){this.tracing("storedViews()"),this.storedViews.push(t)}setPreviousScale(t){this.tracing("setPreviousScale()"),this.storedPreviousScale.push(t)}tracing(t){if("ended"===t){const t=this.trace.map((t,e)=>""+(0===e?`Instance ${this.instance}: ${t}`:""+t)).join(" > ");this.notify(t),this.trace=[]}else this.trace.push(t)}static get counter(){return a._counter=(a._counter||0)+1,a._counter}notify(t,e){return r(this.debug,t,e)}zoomLevel(){return this.storedViews.length}async init(){this.options&&(this.tracing("init()"),function(t){var e=document.createElement("style");let n="";["current-view","previous-view","last-view"].map(e=>{n+=`\n .zoom-${e}-${t} {\n animation-name: zoom-${e}-${t};\n animation-duration: var(--zoom-duration-${t});\n animation-timing-function: var(--zoom-ease-${t});\n }\n @keyframes zoom-${e}-${t} {\n 0% {\n transform-origin: var(--${e}-transformOrigin-start-${t});\n transform: var(--${e}-transform-start-${t});\n opacity: var(--${e}-opacity-start-${t});\n filter: var(--${e}-filter-start-${t})\n }\n 100% {\n transform-origin: var(--${e}-transformOrigin-end-${t});\n transform: var(--${e}-transform-end-${t});\n opacity: var(--${e}-opacity-end-${t});\n filter: var(--${e}-filter-end-${t})\n }\n }\n `}),e.innerHTML=n,document.head.appendChild(e)}(this.instance),await o(this.initialView,this.canvas,this.views,"init",this.componentContext),this.storeViews({zoomLevel:this.storedViews.length,views:[{viewName:this.initialView,backwardState:{origin:"0 0",transform:""}}]}),this.notify(""+(this.instance>1?`instance nº ${this.instance} is active.`:`is running! Instance nº ${this.instance} is active. ${this.debug?"Debug is active, can be deactivate by setting 'debug: false' when you define the instance.":""}\n More tips & docs at https://zumly.org`),"welcome"))}async zoomIn(t){this.tracing("zoomIn()");var e=this.instance;const n=this.canvas,s=n.getBoundingClientRect();var r=s.left,a=s.top;const d=this.storedPreviousScale[this.storedPreviousScale.length-1];this.tracing("renderView()"),await o(t,n,this.views,!1,this.componentContext),t.classList.add("zoomed");const c=t.getBoundingClientRect();var l=n.querySelector(".is-new-current-view"),u=n.querySelector(".is-current-view"),h=n.querySelector(".is-previous-view"),m=n.querySelector(".is-last-view");null!==m&&n.removeChild(m);const v=l.getBoundingClientRect(),w=v.width/c.width,g=1/w,f=v.height/c.height,p=1/f;var y=t.dataset.withDuration||this.duration,$=t.dataset.withEease||this.ease,E=this.effects[0],S=this.effects[1],b=this.cover;if("width"===b)var L=w,z=g;else"height"===b&&(L=f,z=p);this.setPreviousScale(L);var V=`translate(${c.x-r+(c.width-v.width*z)/2}px, ${c.y-a+(c.height-v.height*z)/2}px) scale(${z})`;l.style.transform=V,u.classList.add("is-previous-view"),u.classList.remove("is-current-view");const k=u.getBoundingClientRect();var O=u.style.transform;u.style.transformOrigin=`${c.x+c.width/2-k.x}px ${c.y+c.height/2-k.y}px`;const P=s.width/2-c.width/2-c.x+k.x,Z=s.height/2-c.height/2-c.y+k.y,x=`translate(${P}px, ${Z}px) scale(${L})`;u.style.transform=x;var C=t.getBoundingClientRect(),H=`translate(${C.x-r+(C.width-v.width)/2}px, ${C.y-a+(C.height-v.height)/2}px)`;if(null!==h){h.classList.remove("is-previous-view"),h.classList.add("is-last-view");var _=h.style.transform,I=u.getBoundingClientRect();h.style.transform=`translate(${P-r}px, ${Z-a}px) scale(${L*d})`;var T=h.querySelector(".zoomed").getBoundingClientRect();h.style.transform=_,u.style.transform=O;var q=u.getBoundingClientRect(),R=`translate(${s.width/2-c.width/2-c.x+(q.x-T.x)+I.x-r+(I.width-T.width)/2}px, ${s.height/2-c.height/2-c.y+(q.y-T.y)+I.y-a+(I.height-T.height)/2}px) scale(${L*d})`}else u.style.transform=O;var Y={zoomLevel:this.storedViews.length,views:[]};const A=l?{viewName:l.dataset.viewName,backwardState:{origin:l.style.transformOrigin,duration:y,ease:$,transform:V,filter:E},forwardState:{origin:l.style.transformOrigin,duration:y,ease:$,transform:H,filter:S}}:null,B=u?{viewName:u.dataset.viewName,backwardState:{origin:u.style.transformOrigin,duration:y,ease:$,transform:O,filter:window.getComputedStyle(document.documentElement).getPropertyValue("--previous-view-filter-end-"+e)},forwardState:{origin:u.style.transformOrigin,duration:y,ease:$,transform:x,filter:S}}:null,N=h?{viewName:h.dataset.viewName,backwardState:{origin:h.style.transformOrigin,duration:y,ease:$,transform:_,filter:window.getComputedStyle(document.documentElement).getPropertyValue("--previous-view-filter-end-"+e)},forwardState:{origin:h.style.transformOrigin,duration:y,ease:$,transform:R,filter:S}}:null,j=m?{viewName:m}:null;null!==A&&Y.views.push(A),null!==B&&Y.views.push(B),null!==N&&Y.views.push(N),null!==j&&Y.views.push(j),this.storeViews(Y),this.currentStage=this.storedViews[this.storedViews.length-1],this.tracing("setCSSVariables()"),i("zoomIn",this.currentStage,this.instance),u.classList.add("performance"),null!==h&&h.classList.add("performance"),l.classList.remove("hide"),l.addEventListener("animationstart",this._onZoomInHandlerStart),l.addEventListener("animationend",this._onZoomInHandlerEnd),u.addEventListener("animationend",this._onZoomInHandlerEnd),null!==h&&h.addEventListener("animationend",this._onZoomInHandlerEnd),l.classList.add("zoom-current-view-"+e),u.classList.add("zoom-previous-view-"+e),null!==h&&h.classList.add("zoom-last-view-"+e)}zoomOut(){this.tracing("zoomOut()"),this.blockEvents=!0,this.storedPreviousScale.pop();var t=this.instance;const e=this.canvas;this.currentStage=this.storedViews[this.storedViews.length-1];const n=this.currentStage.views[3];var s=e.querySelector(".is-current-view"),o=e.querySelector(".is-previous-view"),r=e.querySelector(".is-last-view");(this.tracing("setCSSVariables()"),i("zoomOut",this.currentStage,this.instance),s.classList.remove("performance"),o.querySelector(".zoomed").classList.remove("zoomed"),o.classList.remove("is-previous-view"),o.classList.add("is-current-view"),o.classList.remove("performance"),null!==r&&(r.classList.add("performance"),r.classList.add("is-previous-view"),r.classList.remove("is-last-view"),r.classList.remove("hide")),void 0!==n)&&(e.prepend(n.viewName),e.querySelector(".z-view:first-child").classList.add("hide"));s.addEventListener("animationstart",this._onZoomOutHandlerStart),s.addEventListener("animationend",this._onZoomOutHandlerEnd),o.addEventListener("animationend",this._onZoomOutHandlerEnd),null!==r&&r.addEventListener("animationend",this._onZoomOutHandlerEnd),s.classList.add("zoom-current-view-"+t),o.classList.add("zoom-previous-view-"+t),null!==r&&r.classList.add("zoom-last-view-"+t),this.storedViews.pop()}onZoom(t){this.storedViews.length>1&&!this.blockEvents&&!t.target.classList.contains("zoom-me")&&null===t.target.closest(".is-current-view")&&!this.touching&&(this.tracing("onZoom()"),t.stopPropagation(),this.zoomOut()),this.blockEvents||!t.target.classList.contains("zoom-me")||this.touching||(this.tracing("onZoom()"),t.stopPropagation(),this.zoomIn(t.target))}onKeyUp(t){this.tracing("onKeyUp()"),"ArrowLeft"!==t.key&&"ArrowDown"!==t.key||(t.preventDefault(),this.storedViews.length>1&&!this.blockEvents?this.zoomOut():this.notify("is on level zero. Can't zoom out. Trigger: "+t.key,"warn")),"ArrowRight"!==t.key&&"ArrowUp"!==t.key||(t.preventDefault(),this.notify(t.key+"has not actions defined"))}onWeel(t){this.blockEvents||(this.tracing("onWeel()"),t.deltaY,t.deltaY>0&&this.storedViews.length>1&&!this.blockEvents&&this.zoomOut())}onTouchStart(t){this.tracing("onTouchStart()"),this.touching=!0,this.touchstartX=t.changedTouches[0].screenX,this.touchstartY=t.changedTouches[0].screenY}onTouchEnd(t){this.blockEvents||(this.tracing("onTouchEnd()"),this.touchendX=t.changedTouches[0].screenX,this.touchendY=t.changedTouches[0].screenY,this.handleGesture(t))}handleGesture(t){t.stopPropagation(),this.tracing("handleGesture()"),this.touchendX<this.touchstartX-30&&(this.storedViews.length>1&&!this.blockEvents?(this.tracing("swipe left"),this.zoomOut()):this.notify("is on level zero. Can't zoom out. Trigger: Swipe left","warn")),this.touchendY<this.touchstartY-10&&(this.storedViews.length>1&&!this.blockEvents?this.tracing("swipe up"):this.notify("is on level zero. Can't zoom out. Trigger: Swipe up","warn")),this.touchendY===this.touchstartY&&!this.blockEvents&&t.target.classList.contains("zoom-me")&&this.touching&&(this.touching=!1,this.tracing("tap"),t.preventDefault(),this.zoomIn(t.target)),this.touchendY===this.touchstartY&&this.storedViews.length>1&&!this.blockEvents&&!t.target.classList.contains("zoom-me")&&null===t.target.closest(".is-current-view")&&this.touching&&(this.touching=!1,this.tracing("tap"),this.zoomOut())}onZoomOutHandlerStart(t){this.tracing("onZoomOutHandlerStart()"),this.blockEvents=!0,t.target.removeEventListener("animationstart",this._onZoomOutHandlerStart)}onZoomOutHandlerEnd(t){this.tracing("onZoomOutHandlerEnd()");const e=t.target;var n=this.currentStage;if(e.removeEventListener("animationend",this._onZoomOutHandlerEnd),e.classList.contains("zoom-current-view-"+this.instance)){try{this.canvas.removeChild(e)}catch(t){console.debug("Error when trying to remove element after zoom out. Trying to remove its parent instead...");try{this.canvas.removeChild(e.parentElement)}catch(t){console.debug("Error when trying to remove elemont after zoom out:",t),console.debug("Element to remove was:",e)}}this.blockEvents=!1}if(e.classList.contains("zoom-previous-view-"+this.instance)){var s=n.views[1].backwardState.origin,i=n.views[1].backwardState.transform;e.classList.remove("performance"),e.classList.remove("zoom-previous-view-"+this.instance),e.style.transformOrigin=s,e.style.transform=i,e.style.filter="none",2===n.views.length&&this.tracing("ended")}e.classList.contains("zoom-last-view-"+this.instance)&&(s=n.views[2].backwardState.origin,i=n.views[2].backwardState.transform,e.classList.remove("performance"),e.classList.remove("zoom-last-view-"+this.instance),e.style.transformOrigin=s,e.style.transform=i,n.views.length>2&&this.tracing("ended"))}onZoomInHandlerStart(t){this.tracing("onZoomInHandlerStart()"),this.blockEvents=!0,t.target.removeEventListener("animationstart",this._onZoomInHandlerStart)}onZoomInHandlerEnd(t){this.tracing("onZoomInHandlerEnd()");const e=t.target;var n=this.currentStage;if(t.target.classList.contains("is-new-current-view")){this.blockEvents=!1;var s="current-view",i=n.views[0].forwardState.transform,o=n.views[0].forwardState.origin;e.classList.remove("is-new-current-view"),e.classList.add("is-current-view")}else t.target.classList.contains("is-previous-view")?(s="previous-view",i=n.views[1].forwardState.transform,o=n.views[1].forwardState.origin,2===n.views.length&&this.tracing("ended")):(s="last-view",i=n.views[2].forwardState.transform,o=n.views[2].forwardState.origin,n.views.length>2&&this.tracing("ended"));e.classList.remove("performance"),e.classList.remove(`zoom-${s}-${this.instance}`),e.classList.remove("has-no-events"),e.style.transformOrigin=o,e.style.transform=i,e.style.filter=window.getComputedStyle(document.documentElement).getPropertyValue(`--${s}-filter-end-${this.instance}`),e.removeEventListener("animationend",this._onZoomInHandlerEnd)}}export default a;
package/dist/zumly.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @zumly/zumly v0.9.7
3
- * Author [object Object], @license MIT
2
+ * zumly v0.9.11
3
+ * Author Juan Martín Muda, @license MIT
4
4
  * https://zumly.org
5
5
  */
6
6
  function checkArray (array) {
@@ -142,34 +142,45 @@ function setCSSVariables (transition, currentStage, instance) {
142
142
  });
143
143
  }
144
144
 
145
- async function renderView (el, canvas, views, init) {
146
- return new Promise((resolve) => {
145
+ async function renderView (el, canvas, views, init, componentContext) {
147
146
  var viewName = null;
148
147
  init ? viewName = el : viewName = el.dataset.to;
149
- window.requestIdleCallback(async () => {
150
- var newView = document.createElement('template');
148
+ var newView = document.createElement('template');
149
+
150
+ if(typeof views[viewName] === 'object' && views[viewName].render !== undefined) {
151
151
  // makes optional de 'render' function
152
- typeof views[viewName] === 'object' && views[viewName].render !== undefined
153
- ? newView.innerHTML = await views[viewName].render()
154
- : newView.innerHTML = views[viewName];
155
-
156
- const vv = newView.content.querySelector('.z-view');
157
- if (!init) {
158
- vv.classList.add('is-new-current-view');
159
- vv.classList.add('has-no-events');
160
- vv.classList.add('hide');
161
- vv.classList.add('performance');
162
- } else {
163
- vv.classList.add('is-current-view');
164
- }
165
- vv.style.transformOrigin = '0 0';
166
- vv.dataset.viewName = viewName;
167
- var appendedView = canvas.append(newView.content);
168
- // makes optional de 'mounted' hook
169
- if (typeof views[viewName] === 'object' && views[viewName].mounted !== undefined && typeof views[viewName].mounted() === 'function') await views[viewName].mounted();
170
- resolve(appendedView);
171
- });
172
- })
152
+ newView.innerHTML = await views[viewName].render();
153
+ } else if(typeof views[viewName] === 'function') {
154
+ // view is a component constructor
155
+ var newViewInner = document.createElement('div');
156
+ let comp = new views[viewName]({
157
+ target: newViewInner,
158
+ context: componentContext,
159
+ props: el.dataset
160
+ });
161
+ newViewInner.classList.add('z-view');
162
+ newView.content.appendChild(newViewInner);
163
+ } else {
164
+ // view is plain HTML
165
+ newView.innerHTML = views[viewName];
166
+ }
167
+
168
+ let vv = newView.content.querySelector('.z-view');
169
+
170
+ if (!init) {
171
+ vv.classList.add('is-new-current-view');
172
+ vv.classList.add('has-no-events');
173
+ vv.classList.add('hide');
174
+ vv.classList.add('performance');
175
+ } else {
176
+ vv.classList.add('is-current-view');
177
+ }
178
+ vv.style.transformOrigin = '0 0';
179
+ vv.dataset.viewName = viewName;
180
+
181
+ var appendedView = await canvas.append(newView.content);
182
+ // makes optional de 'mounted' hook
183
+ if (typeof views[viewName] === 'object' && views[viewName].mounted !== undefined && typeof views[viewName].mounted() === 'function') await views[viewName].mounted();
173
184
  }
174
185
 
175
186
  function notification (debug, msg, type) {
@@ -200,6 +211,8 @@ function checkParameters (parameters, instance) {
200
211
  validate(instance, 'views', parameters.views, 'object', { isRequired: true });
201
212
  // debug property. Boolean. Optional. Default false
202
213
  validate(instance, 'debug', parameters.debug, 'boolean', { defaultValue: false });
214
+ // Svelte component context
215
+ validate(instance, 'componentContext', parameters.componentContext, 'object', { isRequired: false, defaultValue: new Map() });
203
216
  // Check transtions
204
217
  if (parameters.transitions && typeof parameters.transitions === 'object') {
205
218
  // value exist; type, allowed, deafult
@@ -339,7 +352,7 @@ class Zumly {
339
352
  // add instance style
340
353
  this.tracing('init()');
341
354
  prepareCSS(this.instance);
342
- await renderView(this.initialView, this.canvas, this.views, 'init');
355
+ await renderView(this.initialView, this.canvas, this.views, 'init', this.componentContext);
343
356
  // add to storage. OPTIMIZAR
344
357
  this.storeViews({
345
358
  zoomLevel: this.storedViews.length,
@@ -374,7 +387,7 @@ class Zumly {
374
387
  // generated new view from activated .zoom-me element
375
388
  // generateNewView(el)
376
389
  this.tracing('renderView()');
377
- await renderView(el, canvas, this.views);
390
+ await renderView(el, canvas, this.views, false, this.componentContext);
378
391
  el.classList.add('zoomed');
379
392
  const coordenadasEl = el.getBoundingClientRect();
380
393
  // create new view in a template tag
@@ -681,7 +694,19 @@ class Zumly {
681
694
  element.removeEventListener('animationend', this._onZoomOutHandlerEnd);
682
695
  // current
683
696
  if (element.classList.contains(`zoom-current-view-${this.instance}`)) {
684
- this.canvas.removeChild(element);
697
+ try {
698
+ this.canvas.removeChild(element);
699
+ } catch(e) {
700
+ console.debug("Error when trying to remove element after zoom out. Trying to remove its parent instead...");
701
+ try {
702
+ this.canvas.removeChild(element.parentElement);
703
+ } catch(e) {
704
+ console.debug("Error when trying to remove elemont after zoom out:", e);
705
+ console.debug("Element to remove was:", element);
706
+ }
707
+
708
+ }
709
+
685
710
  this.blockEvents = false;
686
711
  }
687
712
  if (element.classList.contains(`zoom-previous-view-${this.instance}`)) {
package/dist/zumly.umd.js CHANGED
@@ -1,12 +1,12 @@
1
1
  /**
2
- * @zumly/zumly v0.9.7
3
- * Author [object Object], @license MIT
2
+ * zumly v0.9.11
3
+ * Author Juan Martín Muda, @license MIT
4
4
  * https://zumly.org
5
5
  */
6
6
  (function (global, factory) {
7
7
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
8
8
  typeof define === 'function' && define.amd ? define(factory) :
9
- (global = global || self, global['@zumly/zumly'] = factory());
9
+ (global = global || self, global.zumly = factory());
10
10
  }(this, (function () { 'use strict';
11
11
 
12
12
  function styleInject(css, ref) {
@@ -36,7 +36,7 @@
36
36
  }
37
37
  }
38
38
 
39
- var css_248z = "\n.zumly-canvas {\n position: absolute;\n width: 100%;\n height: 100%;\n overflow: hidden;\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n perspective: 1000px;\n cursor: zoom-out;\n}\n\n.zumly-canvas > * {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n}\n\n.zumly-canvas:focus {\n outline: none;\n}\n\n.z-view {\n\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";
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
40
  styleInject(css_248z);
41
41
 
42
42
  function checkArray (array) {
@@ -178,34 +178,45 @@
178
178
  });
179
179
  }
180
180
 
181
- async function renderView (el, canvas, views, init) {
182
- return new Promise((resolve) => {
181
+ async function renderView (el, canvas, views, init, componentContext) {
183
182
  var viewName = null;
184
183
  init ? viewName = el : viewName = el.dataset.to;
185
- window.requestIdleCallback(async () => {
186
- var newView = document.createElement('template');
184
+ var newView = document.createElement('template');
185
+
186
+ if(typeof views[viewName] === 'object' && views[viewName].render !== undefined) {
187
187
  // makes optional de 'render' function
188
- typeof views[viewName] === 'object' && views[viewName].render !== undefined
189
- ? newView.innerHTML = await views[viewName].render()
190
- : newView.innerHTML = views[viewName];
191
-
192
- const vv = newView.content.querySelector('.z-view');
193
- if (!init) {
194
- vv.classList.add('is-new-current-view');
195
- vv.classList.add('has-no-events');
196
- vv.classList.add('hide');
197
- vv.classList.add('performance');
198
- } else {
199
- vv.classList.add('is-current-view');
200
- }
201
- vv.style.transformOrigin = '0 0';
202
- vv.dataset.viewName = viewName;
203
- var appendedView = canvas.append(newView.content);
204
- // makes optional de 'mounted' hook
205
- if (typeof views[viewName] === 'object' && views[viewName].mounted !== undefined && typeof views[viewName].mounted() === 'function') await views[viewName].mounted();
206
- resolve(appendedView);
207
- });
208
- })
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();
209
220
  }
210
221
 
211
222
  function notification (debug, msg, type) {
@@ -236,6 +247,8 @@
236
247
  validate(instance, 'views', parameters.views, 'object', { isRequired: true });
237
248
  // debug property. Boolean. Optional. Default false
238
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() });
239
252
  // Check transtions
240
253
  if (parameters.transitions && typeof parameters.transitions === 'object') {
241
254
  // value exist; type, allowed, deafult
@@ -375,7 +388,7 @@
375
388
  // add instance style
376
389
  this.tracing('init()');
377
390
  prepareCSS(this.instance);
378
- await renderView(this.initialView, this.canvas, this.views, 'init');
391
+ await renderView(this.initialView, this.canvas, this.views, 'init', this.componentContext);
379
392
  // add to storage. OPTIMIZAR
380
393
  this.storeViews({
381
394
  zoomLevel: this.storedViews.length,
@@ -410,7 +423,7 @@
410
423
  // generated new view from activated .zoom-me element
411
424
  // generateNewView(el)
412
425
  this.tracing('renderView()');
413
- await renderView(el, canvas, this.views);
426
+ await renderView(el, canvas, this.views, false, this.componentContext);
414
427
  el.classList.add('zoomed');
415
428
  const coordenadasEl = el.getBoundingClientRect();
416
429
  // create new view in a template tag
@@ -717,7 +730,19 @@
717
730
  element.removeEventListener('animationend', this._onZoomOutHandlerEnd);
718
731
  // current
719
732
  if (element.classList.contains(`zoom-current-view-${this.instance}`)) {
720
- this.canvas.removeChild(element);
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
+
721
746
  this.blockEvents = false;
722
747
  }
723
748
  if (element.classList.contains(`zoom-previous-view-${this.instance}`)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zumly",
3
- "version": "0.9.7",
3
+ "version": "0.9.11",
4
4
  "description": "Javascript library for building zooming user interfaces",
5
5
  "author": {
6
6
  "name": "Juan Martín Muda",
@@ -43,6 +43,7 @@
43
43
  "postcss": "^7.0.27",
44
44
  "postcss-banner": "^3.0.2",
45
45
  "rollup": "^2.2.1",
46
+ "rollup-plugin-copy": "^3.3.0",
46
47
  "rollup-plugin-live-server": "^1.0.3",
47
48
  "rollup-plugin-postcss": "^3.1.2",
48
49
  "rollup-plugin-terser": "^6.1.0",
package/CHANGELOG.md DELETED
@@ -1,230 +0,0 @@
1
- # Changelog
2
-
3
- All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
-
5
- ### [0.9.7](https://github.com/zumly/zumly/compare/v0.9.6...v0.9.7) (2020-07-17)
6
-
7
-
8
- ### Bug Fixes
9
-
10
- * 🐛 disable transform string to loweCase ([df92e42](https://github.com/zumly/zumly/commit/df92e42e9a9d8819bc8140fbc02de7b72c04bda7))
11
-
12
- ### [0.9.6](https://github.com///compare/v0.9.5...v0.9.6) (2020-07-14)
13
-
14
-
15
- ### Bug Fixes
16
-
17
- * 🐛 validate() ([308ea9a](https://github.com///commit/308ea9a0489a6e99886dc94e1d7289a728bf9d99))
18
-
19
- ## [0.9.5](https://github.com/zumly/zumly/compare/v0.9.4...v0.9.5) (2020-07-13)
20
-
21
- ## [0.9.4](https://github.com/zumly/zumly/compare/v0.9.3...v0.9.4) (2020-07-13)
22
-
23
-
24
-
25
- ## [0.9.3](https://github.com/zumly/zumly/compare/v0.9.2...v0.9.3) (2020-07-13)
26
-
27
-
28
-
29
- ## [0.9.2](https://github.com/zumly/zumly/compare/v0.9.1...v0.9.2) (2020-07-11)
30
-
31
-
32
- ### Bug Fixes
33
-
34
- * 🐛 gestures, render function, validator. Add new demo also ([88b308f](https://github.com/zumly/zumly/commit/88b308f))
35
-
36
-
37
-
38
- ## [0.9.1](https://github.com/zumly/zumly/compare/v0.9.0...v0.9.1) (2020-06-27)
39
-
40
-
41
- ### Bug Fixes
42
-
43
- * 🐛 touchs events on mobile ([8b8da5b](https://github.com/zumly/zumly/commit/8b8da5b))
44
-
45
-
46
-
47
- # [0.9.0](https://github.com/zumly/zumly/compare/v0.8.0...v0.9.0) (2020-06-27)
48
-
49
-
50
- ### Features
51
-
52
- * 🎸 add user parameters validation and setting ([f7ebee1](https://github.com/zumly/zumly/commit/f7ebee1))
53
-
54
-
55
-
56
- # [0.8.0](https://github.com/zumly/zumly/compare/v0.7.1...v0.8.0) (2020-06-25)
57
-
58
-
59
- ### Features
60
-
61
- * 🎸 Add notifications & tracing events ([35d074d](https://github.com/zumly/zumly/commit/35d074d))
62
-
63
-
64
-
65
- ## [0.7.1](https://github.com/zumly/zumly/compare/v0.7.0...v0.7.1) (2020-06-24)
66
-
67
-
68
-
69
- # [0.7.0](https://github.com/zumly/zumly/compare/v0.6.0...v0.7.0) (2020-06-23)
70
-
71
-
72
- ### Features
73
-
74
- * 🎸 Major update ([6f5c81b](https://github.com/zumly/zumly/commit/6f5c81b))
75
-
76
-
77
-
78
- # [0.6.0](https://github.com/zumly/zumly/compare/v0.5.0...v0.6.0) (2020-04-22)
79
-
80
-
81
- ### Features
82
-
83
- * 🎸 add method to decide how tocope with different shapes ([03e12cb](https://github.com/zumly/zumly/commit/03e12cb))
84
-
85
-
86
-
87
- # [0.5.0](https://github.com/zumly/zumly/compare/v0.4.0...v0.5.0) (2020-04-14)
88
-
89
-
90
- ### Bug Fixes
91
-
92
- * 🐛 Fix instance id ([c600871](https://github.com/zumly/zumly/commit/c600871))
93
-
94
-
95
- ### Features
96
-
97
- * 🎸 Allows custom parametres for duration, ease and filters ([a8a538d](https://github.com/zumly/zumly/commit/a8a538d))
98
-
99
-
100
-
101
- # [0.4.0](https://github.com/zumly/zumly/compare/v0.3.6...v0.4.0) (2020-04-13)
102
-
103
-
104
- ### Features
105
-
106
- * 🎸 zoom now accepts irregular shapes ([7bd3f24](https://github.com/zumly/zumly/commit/7bd3f24))
107
-
108
-
109
-
110
- ## [0.3.6](https://github.com/zumly/zumly/compare/v0.3.5...v0.3.6) (2020-04-06)
111
-
112
-
113
-
114
- ## [0.3.5](https://github.com/zumly/zumly/compare/v0.3.4...v0.3.5) (2020-04-02)
115
-
116
-
117
- ### Bug Fixes
118
-
119
- * 🐛 Fixes a bug related to previous view scales ([777f1b8](https://github.com/zumly/zumly/commit/777f1b8))
120
-
121
-
122
-
123
- ## [0.3.4](https://github.com/zumly/zumly/compare/v0.3.3...v0.3.4) (2020-04-01)
124
-
125
-
126
- ### Bug Fixes
127
-
128
- * 🐛 Allows mutiple Zumly's instances ([4f4bb55](https://github.com/zumly/zumly/commit/4f4bb55))
129
- * 🐛 Zumly's multiple instances almost ready! ([d72d8c6](https://github.com/zumly/zumly/commit/d72d8c6))
130
-
131
-
132
-
133
- ## [0.3.3](https://github.com/zumly/zumly/compare/v0.3.2...v0.3.3) (2020-03-30)
134
-
135
-
136
- ### Bug Fixes
137
-
138
- * 🐛 Fix scale, different zoomable size & last view issues ([efca9d9](https://github.com/zumly/zumly/commit/efca9d9))
139
-
140
-
141
-
142
- ## [0.3.2](https://github.com/zumly/zumly/compare/v0.3.1...v0.3.2) (2020-03-30)
143
-
144
-
145
- ### Performance Improvements
146
-
147
- * ⚡️ Big speed and smoothness improvments! ([fa24ebc](https://github.com/zumly/zumly/commit/fa24ebc))
148
-
149
-
150
-
151
- ## [0.3.1](https://github.com/zumly/zumly/compare/v0.3.0...v0.3.1) (2020-03-29)
152
-
153
-
154
- ### Performance Improvements
155
-
156
- * ⚡️ Improves zoom out animations in all major browsers ([3f6b48e](https://github.com/zumly/zumly/commit/3f6b48e))
157
-
158
-
159
-
160
- # [0.3.0](https://github.com/zumly/zumly/compare/v0.2.6...v0.3.0) (2020-03-28)
161
-
162
-
163
- ### Bug Fixes
164
-
165
- * 🐛 Change a bit the index.html demo code ([db06353](https://github.com/zumly/zumly/commit/db06353))
166
- * 🐛 Reorder layers ([f68115d](https://github.com/zumly/zumly/commit/f68115d))
167
-
168
-
169
- ### Features
170
-
171
- * 🎸 Add fade in out animations & delete obsolete styles ([f11368d](https://github.com/zumly/zumly/commit/f11368d))
172
-
173
-
174
-
175
- ## [0.2.6](https://github.com/zumly/zumly/compare/v0.2.5...v0.2.6) (2020-03-16)
176
-
177
-
178
- ### Bug Fixes
179
-
180
- * 🐛 Remove previous zoomable active to prevent inconsistence ([5a937ba](https://github.com/zumly/zumly/commit/5a937ba))
181
-
182
-
183
-
184
- ## [0.2.5](https://github.com/zumly/zumly/compare/v0.2.4...v0.2.5) (2020-03-16)
185
-
186
-
187
- ### Performance Improvements
188
-
189
- * ⚡️ add meta viewport ([a95b4ac](https://github.com/zumly/zumly/commit/a95b4ac))
190
-
191
-
192
-
193
- ## [0.2.4](https://github.com/zumly/zumly/compare/v0.2.3...v0.2.4) (2020-03-16)
194
-
195
-
196
-
197
- ## [0.2.3](https://github.com/zumly/zumly/compare/v0.2.2...v0.2.3) (2020-03-15)
198
-
199
- ### [0.2.2](https://github.com/zumly/zumly/compare/v0.2.1...v0.2.2) (2020-03-12)
200
-
201
-
202
- ### Bug Fixes
203
-
204
- * zoomOut method done!! ([a398079](https://github.com/zumly/zumly/commit/a3980794379567bdee2e06100ccc1ed2f93fc116))
205
-
206
- ## [0.2.1](https://github.com/zumly/zumly/compare/v0.2.0...v0.2.1) (2020-03-12)
207
-
208
-
209
- ### Bug Fixes
210
-
211
- * 🐛 mejora snapshoot de estados de vistas, avanza en zoomOut ([29a933c](https://github.com/zumly/zumly/commit/29a933c))
212
-
213
-
214
-
215
- # [0.2.0](https://github.com/zumly/zumly/compare/v0.1.0...v0.2.0) (2020-03-11)
216
-
217
-
218
- ### Features
219
-
220
- * 🎸 add events for zoomOut method ([32c9419](https://github.com/zumly/zumly/commit/32c9419))
221
- * 🎸 Add method to zoom back that is working ([92e45de](https://github.com/zumly/zumly/commit/92e45de))
222
-
223
-
224
-
225
- # 0.1.0 (2020-03-11)
226
-
227
-
228
- ### Features
229
-
230
- * 🎸 primer paso para registrar los estados de zoom level ([28a2223](https://github.com/zumly/zumly/commit/28a2223))