├── .gitignore ├── README.md ├── configurator_featured.jpg ├── css └── base.css ├── favicon.ico ├── img ├── 1.jpg ├── 1_large.jpg ├── 2.jpg ├── 2_large.jpg ├── 3.jpg ├── 3_large.jpg ├── 4.jpg ├── 4_large.jpg ├── 5.jpg ├── 5_large.jpg ├── 6.jpg └── 6_large.jpg ├── index.html ├── index2.html ├── index3.html ├── index4.html ├── index5.html ├── index6.html └── js ├── CSSPlugin.min.js ├── Configurator.js ├── EasePack.min.js ├── GridToFullscreenEffect.js ├── TweenLite.min.js ├── basicDemo.js ├── dat-gui.min.js ├── imagesloaded.pkgd.min.js └── three.min.js /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Configurator for Creating Custom WebGL Distortion Effects 2 | 3 | A configurator for creating unique fullscreen image animations with WebGL distortion effects powered by Three.js. By Daniel Velasquez. 4 | 5 | ![Fullscreen image animation configurator](./configurator_featured.jpg) 6 | 7 | [Article on Codrops](https://tympanus.net/codrops/?p=40753) 8 | 9 | [Demo](https://tympanus.net/Development/WebGLDistortionConfigurator/?default=true) 10 | 11 | ## Options 12 | 13 | Options used to modify the effect and create variations: 14 | 15 | ```javascript 16 | const options = { 17 | // Timing of the effect and vertice timing calculation 18 | duration: 1, // Seconds of the animation 19 | easings: { 20 | toFullscreen: Power0.easeNone, // gsap EasePack easing 21 | toGrid: Power0.easeNone // gsap EasePack easing 22 | }, 23 | timing: { 24 | // How to calculate the timing of a vertice 25 | type: "sameEnd", // "sameEnd" | "sections" 26 | props: {} // Type specific props 27 | }, 28 | // Plane transformations 29 | transformation: { 30 | type: "none", // "flipX" | "sin" | "simplex" etc... 31 | props: {} // Type specific props 32 | }, 33 | // The plane activation used with timing 34 | activation: { 35 | type: "sides", // "sides" | "corners" | "radial" | etc... 36 | props: {} // Type specific props 37 | }, 38 | // General seed for some effects 39 | seed: 0, // Number 40 | randomizeSeed: null, // "itemUnique" | "InOutUnique" | "tweenUnique" 41 | // Easings for the effects tweens 42 | debug: { 43 | activation: false // Display the activation as color 44 | } 45 | }; 46 | ``` 47 | 48 | ## Credits 49 | 50 | - [three.js](https://threejs.org/) by Ricardo Cabello 51 | - [GSAP](https://greensock.com/) by Jack Doyle 52 | - [imagesLoaded](https://imagesloaded.desandro.com/) by Dave DeSandro 53 | - Images from [Unsplash.com](https://unsplash.com/) 54 | 55 | ## License 56 | 57 | This resource can be used freely if integrated or build upon in personal or commercial projects such as websites, web apps and web templates intended for sale. It is not allowed to take the resource "as-is" and sell it, redistribute, re-publish it, or sell "pluginized" versions of it. Free plugins built using this resource should have a visible mention and link to the original work. Always consider the licenses of all included libraries, scripts and images used. 58 | 59 | ## Misc 60 | 61 | Follow Daniel: [Twitter](https://twitter.com/Anemolito), [Codepen](https://codepen.io/Anemolo/), [CodeSandbox](https://codesandbox.io/u/Anemolo), [GitHub](https://github.com/Anemolo) 62 | 63 | Follow Codrops: [Twitter](http://www.twitter.com/codrops), [Facebook](http://www.facebook.com/codrops), [Google+](https://plus.google.com/101095823814290637419), [GitHub](https://github.com/codrops), [Pinterest](http://www.pinterest.com/codrops/), [Instagram](https://www.instagram.com/codropsss/) 64 | 65 | [© Codrops 2019](http://www.codrops.com) 66 | -------------------------------------------------------------------------------- /configurator_featured.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anemolo/WebGLDistortionConfigurator/c27a14182850a1f441eee0ceb41418c58b7c006e/configurator_featured.jpg -------------------------------------------------------------------------------- /css/base.css: -------------------------------------------------------------------------------- 1 | #cdawrap .carbon-text { 2 | --cda-text-color: #aba1a6; 3 | padding: 0.25rem 0 0.75rem; 4 | display: block; 5 | line-height: 1.4; 6 | font-weight: 700; 7 | font-weight: var(--cda-text-weight); 8 | text-decoration: none; 9 | text-transform: none; 10 | letter-spacing: 0px; 11 | border: 0; 12 | } 13 | 14 | body #cdawrap { 15 | --cda-left: 2rem; 16 | --cda-right: auto; 17 | --cda-top: auto; 18 | --cda-bottom: 6rem; 19 | z-index: 1; 20 | } 21 | 22 | *, 23 | *::after, 24 | *::before { 25 | box-sizing: border-box; 26 | } 27 | 28 | :root { 29 | font-size: 15px; 30 | } 31 | 32 | body { 33 | margin: 0; 34 | --color-text: #615d5d; 35 | --color-bg: #121217; 36 | --color-link: #aba1a6; 37 | --color-link-hover: #fff; 38 | --color-info: #f58a4e; 39 | color: var(--color-text); 40 | background-color: var(--color-bg); 41 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif; 42 | font-weight: 600; 43 | -webkit-font-smoothing: antialiased; 44 | -moz-osx-font-smoothing: grayscale; 45 | overflow: hidden; 46 | } 47 | 48 | .dg .title { 49 | transition: background-color 300ms ease-out; 50 | } 51 | 52 | .shine { 53 | transition: background-color 100ms ease-out !important; 54 | background-color: #fff !important; 55 | } 56 | 57 | #app { 58 | top: 0; 59 | left: 0; 60 | position: fixed; 61 | width: 100vw; 62 | height: 100vh; 63 | overflow: hidden; 64 | } 65 | 66 | #app:hover { 67 | cursor: pointer; 68 | } 69 | 70 | .dg.ac { 71 | z-index: 99999 !important; 72 | } 73 | 74 | /* Page Loader */ 75 | .js .loading::before { 76 | content: ''; 77 | position: fixed; 78 | z-index: 100000; 79 | top: 0; 80 | left: 0; 81 | width: 100%; 82 | height: 100%; 83 | background: var(--color-bg); 84 | } 85 | 86 | .js .loading::after { 87 | content: ''; 88 | position: fixed; 89 | z-index: 100000; 90 | top: 50%; 91 | left: 50%; 92 | width: 60px; 93 | height: 60px; 94 | margin: -30px 0 0 -30px; 95 | pointer-events: none; 96 | border-radius: 50%; 97 | opacity: 0.4; 98 | background: var(--color-link); 99 | animation: loaderAnim 0.7s linear infinite alternate forwards; 100 | } 101 | 102 | @keyframes loaderAnim { 103 | to { 104 | opacity: 1; 105 | transform: scale3d(0.5,0.5,1); 106 | } 107 | } 108 | 109 | a { 110 | text-decoration: none; 111 | color: var(--color-link); 112 | outline: none; 113 | } 114 | 115 | a:hover, 116 | a:focus { 117 | color: var(--color-link-hover); 118 | outline: none; 119 | } 120 | 121 | .frame { 122 | padding: 3rem 5vw; 123 | text-align: center; 124 | position: relative; 125 | z-index: 1000; 126 | } 127 | 128 | .frame__title { 129 | font-size: 1rem; 130 | margin: 0 0 1rem; 131 | } 132 | 133 | .frame__tagline { 134 | color: var(--color-info); 135 | } 136 | 137 | .frame__links { 138 | display: inline; 139 | } 140 | 141 | .frame a { 142 | text-transform: lowercase; 143 | } 144 | 145 | .frame__links a:not(:last-child), 146 | .frame__demos a:not(:last-child) { 147 | margin-right: 1rem; 148 | } 149 | 150 | .frame__demos { 151 | margin: 1rem 0; 152 | } 153 | 154 | .frame__demo--current, 155 | .frame__demo--current:hover { 156 | color: var(--color-text); 157 | } 158 | 159 | .content { 160 | display: flex; 161 | flex-direction: column; 162 | width: 100vw; 163 | height: calc(100vh - 13rem); 164 | position: relative; 165 | justify-content: flex-start; 166 | align-items: center; 167 | } 168 | 169 | .content__img { 170 | width: 500px; 171 | max-width: 100%; 172 | display: block; 173 | cursor: pointer; 174 | } 175 | 176 | .content__img--large { 177 | pointer-events: none; 178 | position: fixed; 179 | opacity: 0; 180 | } 181 | 182 | @media screen and (min-width: 53em) { 183 | .frame { 184 | position: fixed; 185 | text-align: left; 186 | z-index: 10000; 187 | top: 0; 188 | left: 0; 189 | display: grid; 190 | align-content: space-between; 191 | width: 100%; 192 | max-width: none; 193 | height: 100vh; 194 | padding: 3rem; 195 | pointer-events: none; 196 | grid-template-columns: 50% 50%; 197 | grid-template-rows: auto auto auto; 198 | grid-template-areas: 'title ...' 199 | '... ...' 200 | 'links demos'; 201 | } 202 | .frame__title-wrap { 203 | grid-area: title; 204 | display: flex; 205 | } 206 | .frame__title { 207 | margin: 0; 208 | } 209 | .frame__tagline { 210 | position: relative; 211 | margin: 0 0 0 1rem; 212 | padding: 0 0 0 1rem; 213 | opacity: 0.5; 214 | } 215 | .frame__demos { 216 | margin: 0; 217 | grid-area: demos; 218 | justify-self: end; 219 | } 220 | .frame__links { 221 | grid-area: links; 222 | padding: 0; 223 | justify-self: start; 224 | } 225 | .frame a { 226 | pointer-events: auto; 227 | } 228 | .content { 229 | height: 100vh; 230 | justify-content: center; 231 | } 232 | } 233 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anemolo/WebGLDistortionConfigurator/c27a14182850a1f441eee0ceb41418c58b7c006e/favicon.ico -------------------------------------------------------------------------------- /img/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anemolo/WebGLDistortionConfigurator/c27a14182850a1f441eee0ceb41418c58b7c006e/img/1.jpg -------------------------------------------------------------------------------- /img/1_large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anemolo/WebGLDistortionConfigurator/c27a14182850a1f441eee0ceb41418c58b7c006e/img/1_large.jpg -------------------------------------------------------------------------------- /img/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anemolo/WebGLDistortionConfigurator/c27a14182850a1f441eee0ceb41418c58b7c006e/img/2.jpg -------------------------------------------------------------------------------- /img/2_large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anemolo/WebGLDistortionConfigurator/c27a14182850a1f441eee0ceb41418c58b7c006e/img/2_large.jpg -------------------------------------------------------------------------------- /img/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anemolo/WebGLDistortionConfigurator/c27a14182850a1f441eee0ceb41418c58b7c006e/img/3.jpg -------------------------------------------------------------------------------- /img/3_large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anemolo/WebGLDistortionConfigurator/c27a14182850a1f441eee0ceb41418c58b7c006e/img/3_large.jpg -------------------------------------------------------------------------------- /img/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anemolo/WebGLDistortionConfigurator/c27a14182850a1f441eee0ceb41418c58b7c006e/img/4.jpg -------------------------------------------------------------------------------- /img/4_large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anemolo/WebGLDistortionConfigurator/c27a14182850a1f441eee0ceb41418c58b7c006e/img/4_large.jpg -------------------------------------------------------------------------------- /img/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anemolo/WebGLDistortionConfigurator/c27a14182850a1f441eee0ceb41418c58b7c006e/img/5.jpg -------------------------------------------------------------------------------- /img/5_large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anemolo/WebGLDistortionConfigurator/c27a14182850a1f441eee0ceb41418c58b7c006e/img/5_large.jpg -------------------------------------------------------------------------------- /img/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anemolo/WebGLDistortionConfigurator/c27a14182850a1f441eee0ceb41418c58b7c006e/img/6.jpg -------------------------------------------------------------------------------- /img/6_large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anemolo/WebGLDistortionConfigurator/c27a14182850a1f441eee0ceb41418c58b7c006e/img/6_large.jpg -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Configurator for Creating Custom WebGL Distortion Effects | Preset 1 | Codrops 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |
18 |

Configurator for Creating Custom WebGL Distortion Effects

19 |

Click the image

20 |
21 | 26 |
27 | preset 1 28 | preset 2 29 | preset 3 30 | preset 4 31 | preset 5 32 | preset 6 33 |
34 |
35 |
36 |
37 |
38 | An image 39 | An image 40 |
41 |
42 |
43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /index2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Configurator for Creating Custom WebGL Distortion Effects | Preset 2 | Codrops 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |
18 |

Configurator for Creating Custom WebGL Distortion Effects

19 |

Click the image

20 |
21 | 26 |
27 | preset 1 28 | preset 2 29 | preset 3 30 | preset 4 31 | preset 5 32 | preset 6 33 |
34 |
35 |
36 |
37 |
38 | An image 39 | An image 40 |
41 |
42 |
43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /index3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Configurator for Creating Custom WebGL Distortion Effects | Preset 3 | Codrops 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |
18 |

Configurator for Creating Custom WebGL Distortion Effects

19 |

Click the image

20 |
21 | 26 |
27 | preset 1 28 | preset 2 29 | preset 3 30 | preset 4 31 | preset 5 32 | preset 6 33 |
34 |
35 |
36 |
37 |
38 | An image 39 | An image 40 |
41 |
42 |
43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /index4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Configurator for Creating Custom WebGL Distortion Effects | Preset 4 | Codrops 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |
18 |

Configurator for Creating Custom WebGL Distortion Effects

19 |

Click the image

20 |
21 | 26 |
27 | preset 1 28 | preset 2 29 | preset 3 30 | preset 4 31 | preset 5 32 | preset 6 33 |
34 |
35 |
36 |
37 |
38 | An image 39 | An image 40 |
41 |
42 |
43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /index5.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Configurator for Creating Custom WebGL Distortion Effects | Preset 5 | Codrops 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |
18 |

Configurator for Creating Custom WebGL Distortion Effects

19 |

Click the image

20 |
21 | 26 |
27 | preset 1 28 | preset 2 29 | preset 3 30 | preset 4 31 | preset 5 32 | preset 6 33 |
34 |
35 |
36 |
37 |
38 | An image 39 | An image 40 |
41 |
42 |
43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /index6.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Configurator for Creating Custom WebGL Distortion Effects | Preset 6 | Codrops 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |
18 |

Configurator for Creating Custom WebGL Distortion Effects

19 |

Click the image

20 |
21 | 26 |
27 | preset 1 28 | preset 2 29 | preset 3 30 | preset 4 31 | preset 5 32 | preset 6 33 |
34 |
35 |
36 |
37 |
38 | An image 39 | An image 40 |
41 |
42 |
43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /js/CSSPlugin.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * VERSION: 2.1.3 3 | * DATE: 2019-05-17 4 | * UPDATES AND DOCS AT: http://greensock.com 5 | * 6 | * @license Copyright (c) 2008-2019, GreenSock. All rights reserved. 7 | * This work is subject to the terms at http://greensock.com/standard-license or for 8 | * Club GreenSock members, the software agreement that was issued with your membership. 9 | * 10 | * @author: Jack Doyle, jack@greensock.com 11 | */ 12 | var _gsScope="undefined"!=typeof module&&module.exports&&"undefined"!=typeof global?global:this||window;(_gsScope._gsQueue||(_gsScope._gsQueue=[])).push(function(){"use strict";_gsScope._gsDefine("plugins.CSSPlugin",["plugins.TweenPlugin","TweenLite"],function(a,b){var c,d,e,f,g=function(){a.call(this,"css"),this._overwriteProps.length=0,this.setRatio=g.prototype.setRatio},h=_gsScope._gsDefine.globals,i={},j=g.prototype=new a("css");j.constructor=g,g.version="2.1.3",g.API=2,g.defaultTransformPerspective=0,g.defaultSkewType="compensated",g.defaultSmoothOrigin=!0,j="px",g.suffixMap={top:j,right:j,bottom:j,left:j,width:j,height:j,fontSize:j,padding:j,margin:j,perspective:j,lineHeight:""};var k,l,m,n,o,p,q,r,s=/(?:\-|\.|\b)(\d|\.|e\-)+/g,t=/(?:\d|\-\d|\.\d|\-\.\d|\+=\d|\-=\d|\+=.\d|\-=\.\d)+/g,u=/(?:\+=|\-=|\-|\b)[\d\-\.]+[a-zA-Z0-9]*(?:%|\b)/gi,v=/(?:\+=|\-=|\-|\b)[\d\-\.]+[a-zA-Z0-9]*(?:%|\b),?/gi,w=/(?![+-]?\d*\.?\d+|[+-]|e[+-]\d+)[^0-9]/g,x=/(?:\d|\-|\+|=|#|\.)*/g,y=/opacity *= *([^)]*)/i,z=/opacity:([^;]*)/i,A=/alpha\(opacity *=.+?\)/i,B=/^(rgb|hsl)/,C=/([A-Z])/g,D=/-([a-z])/gi,E=/(^(?:url\(\"|url\())|(?:(\"\))$|\)$)/gi,F=function(a,b){return b.toUpperCase()},G=/(?:Left|Right|Width)/i,H=/(M11|M12|M21|M22)=[\d\-\.e]+/gi,I=/progid\:DXImageTransform\.Microsoft\.Matrix\(.+?\)/i,J=/,(?=[^\)]*(?:\(|$))/gi,K=/[\s,\(]/i,L=Math.PI/180,M=180/Math.PI,N={},O={style:{}},P=_gsScope.document||{createElement:function(){return O}},Q=function(a,b){var c=P.createElementNS?P.createElementNS(b||"http://www.w3.org/1999/xhtml",a):P.createElement(a);return c.style?c:P.createElement(a)},R=Q("div"),S=Q("img"),T=g._internals={_specialProps:i},U=(_gsScope.navigator||{}).userAgent||"",V=function(){var a=U.indexOf("Android"),b=Q("a");return m=-1!==U.indexOf("Safari")&&-1===U.indexOf("Chrome")&&(-1===a||parseFloat(U.substr(a+8,2))>3),o=m&&parseFloat(U.substr(U.indexOf("Version/")+8,2))<6,n=-1!==U.indexOf("Firefox"),(/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(U)||/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(U))&&(p=parseFloat(RegExp.$1)),b?(b.style.cssText="top:1px;opacity:.55;",/^0.55/.test(b.style.opacity)):!1}(),W=function(a){return y.test("string"==typeof a?a:(a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100:1},X=function(a){_gsScope.console&&console.log(a)},Y="",Z="",$=function(a,b){b=b||R;var c,d,e=b.style;if(void 0!==e[a])return a;for(a=a.charAt(0).toUpperCase()+a.substr(1),c=["O","Moz","ms","Ms","Webkit"],d=5;--d>-1&&void 0===e[c[d]+a];);return d>=0?(Z=3===d?"ms":c[d],Y="-"+Z.toLowerCase()+"-",Z+a):null},_="undefined"!=typeof window?window:P.defaultView||{getComputedStyle:function(){}},aa=function(a){return _.getComputedStyle(a)},ba=g.getStyle=function(a,b,c,d,e){var f;return V||"opacity"!==b?(!d&&a.style[b]?f=a.style[b]:(c=c||aa(a))?f=c[b]||c.getPropertyValue(b)||c.getPropertyValue(b.replace(C,"-$1").toLowerCase()):a.currentStyle&&(f=a.currentStyle[b]),null==e||f&&"none"!==f&&"auto"!==f&&"auto auto"!==f?f:e):W(a)},ca=T.convertToPixels=function(a,c,d,e,f){if("px"===e||!e&&"lineHeight"!==c)return d;if("auto"===e||!d)return 0;var h,i,j,k=G.test(c),l=a,m=R.style,n=0>d,o=1===d;if(n&&(d=-d),o&&(d*=100),"lineHeight"!==c||e)if("%"===e&&-1!==c.indexOf("border"))h=d/100*(k?a.clientWidth:a.clientHeight);else{if(m.cssText="border:0 solid red;position:"+ba(a,"position")+";line-height:0;","%"!==e&&l.appendChild&&"v"!==e.charAt(0)&&"rem"!==e)m[k?"borderLeftWidth":"borderTopWidth"]=d+e;else{if(l=a.parentNode||P.body,-1!==ba(l,"display").indexOf("flex")&&(m.position="absolute"),i=l._gsCache,j=b.ticker.frame,i&&k&&i.time===j)return i.width*d/100;m[k?"width":"height"]=d+e}l.appendChild(R),h=parseFloat(R[k?"offsetWidth":"offsetHeight"]),l.removeChild(R),k&&"%"===e&&g.cacheWidths!==!1&&(i=l._gsCache=l._gsCache||{},i.time=j,i.width=h/d*100),0!==h||f||(h=ca(a,c,d,e,!0))}else i=aa(a).lineHeight,a.style.lineHeight=d,h=parseFloat(aa(a).lineHeight),a.style.lineHeight=i;return o&&(h/=100),n?-h:h},da=T.calculateOffset=function(a,b,c){if("absolute"!==ba(a,"position",c))return 0;var d="left"===b?"Left":"Top",e=ba(a,"margin"+d,c);return a["offset"+d]-(ca(a,b,parseFloat(e),e.replace(x,""))||0)},ea=function(a,b){var c,d,e,f={};if(b=b||aa(a,null))if(c=b.length)for(;--c>-1;)e=b[c],(-1===e.indexOf("-transform")||Fa===e)&&(f[e.replace(D,F)]=b.getPropertyValue(e));else for(c in b)(-1===c.indexOf("Transform")||Ea===c)&&(f[c]=b[c]);else if(b=a.currentStyle||a.style)for(c in b)"string"==typeof c&&void 0===f[c]&&(f[c.replace(D,F)]=b[c]);return V||(f.opacity=W(a)),d=Ta(a,b,!1),f.rotation=d.rotation,f.skewX=d.skewX,f.scaleX=d.scaleX,f.scaleY=d.scaleY,f.x=d.x,f.y=d.y,Ha&&(f.z=d.z,f.rotationX=d.rotationX,f.rotationY=d.rotationY,f.scaleZ=d.scaleZ),f.filters&&delete f.filters,f},fa=function(a,b,c,d,e){var f,g,h,i={},j=a.style;for(g in c)"cssText"!==g&&"length"!==g&&isNaN(g)&&(b[g]!==(f=c[g])||e&&e[g])&&-1===g.indexOf("Origin")&&("number"==typeof f||"string"==typeof f)&&(i[g]="auto"!==f||"left"!==g&&"top"!==g?""!==f&&"auto"!==f&&"none"!==f||"string"!=typeof b[g]||""===b[g].replace(w,"")?f:0:da(a,g),void 0!==j[g]&&(h=new ua(j,g,j[g],h)));if(d)for(g in d)"className"!==g&&(i[g]=d[g]);return{difs:i,firstMPT:h}},ga={width:["Left","Right"],height:["Top","Bottom"]},ha=["marginLeft","marginRight","marginTop","marginBottom"],ia=function(a,b,c){if("svg"===(a.nodeName+"").toLowerCase())return(c||aa(a))[b]||0;if(a.getCTM&&Qa(a))return a.getBBox()[b]||0;var d=parseFloat("width"===b?a.offsetWidth:a.offsetHeight),e=ga[b],f=e.length;for(c=c||aa(a,null);--f>-1;)d-=parseFloat(ba(a,"padding"+e[f],c,!0))||0,d-=parseFloat(ba(a,"border"+e[f]+"Width",c,!0))||0;return d},ja=function(a,b){if("contain"===a||"auto"===a||"auto auto"===a)return a+" ";(null==a||""===a)&&(a="0 0");var c,d=a.split(" "),e=-1!==a.indexOf("left")?"0%":-1!==a.indexOf("right")?"100%":d[0],f=-1!==a.indexOf("top")?"0%":-1!==a.indexOf("bottom")?"100%":d[1];if(d.length>3&&!b){for(d=a.split(", ").join(",").split(","),a=[],c=0;c2?" "+d[2]:""),b&&(b.oxp=-1!==e.indexOf("%"),b.oyp=-1!==f.indexOf("%"),b.oxr="="===e.charAt(1),b.oyr="="===f.charAt(1),b.ox=parseFloat(e.replace(w,"")),b.oy=parseFloat(f.replace(w,"")),b.v=a),b||a},ka=function(a,b){return"function"==typeof a&&(a=a(r,q)),"string"==typeof a&&"="===a.charAt(1)?parseInt(a.charAt(0)+"1",10)*parseFloat(a.substr(2)):parseFloat(a)-parseFloat(b)||0},la=function(a,b){"function"==typeof a&&(a=a(r,q));var c="string"==typeof a&&"="===a.charAt(1);return"string"==typeof a&&"v"===a.charAt(a.length-2)&&(a=(c?a.substr(0,2):0)+window["inner"+("vh"===a.substr(-2)?"Height":"Width")]*(parseFloat(c?a.substr(2):a)/100)),null==a?b:c?parseInt(a.charAt(0)+"1",10)*parseFloat(a.substr(2))+b:parseFloat(a)||0},ma=function(a,b,c,d){var e,f,g,h,i,j=1e-6;return"function"==typeof a&&(a=a(r,q)),null==a?h=b:"number"==typeof a?h=a:(e=360,f=a.split("_"),i="="===a.charAt(1),g=(i?parseInt(a.charAt(0)+"1",10)*parseFloat(f[0].substr(2)):parseFloat(f[0]))*(-1===a.indexOf("rad")?1:M)-(i?0:b),f.length&&(d&&(d[c]=b+g),-1!==a.indexOf("short")&&(g%=e,g!==g%(e/2)&&(g=0>g?g+e:g-e)),-1!==a.indexOf("_cw")&&0>g?g=(g+9999999999*e)%e-(g/e|0)*e:-1!==a.indexOf("ccw")&&g>0&&(g=(g-9999999999*e)%e-(g/e|0)*e)),h=b+g),j>h&&h>-j&&(h=0),h},na={aqua:[0,255,255],lime:[0,255,0],silver:[192,192,192],black:[0,0,0],maroon:[128,0,0],teal:[0,128,128],blue:[0,0,255],navy:[0,0,128],white:[255,255,255],fuchsia:[255,0,255],olive:[128,128,0],yellow:[255,255,0],orange:[255,165,0],gray:[128,128,128],purple:[128,0,128],green:[0,128,0],red:[255,0,0],pink:[255,192,203],cyan:[0,255,255],transparent:[255,255,255,0]},oa=function(a,b,c){return a=0>a?a+1:a>1?a-1:a,255*(1>6*a?b+(c-b)*a*6:.5>a?c:2>3*a?b+(c-b)*(2/3-a)*6:b)+.5|0},pa=g.parseColor=function(a,b){var c,d,e,f,g,h,i,j,k,l,m;if(a)if("number"==typeof a)c=[a>>16,a>>8&255,255&a];else{if(","===a.charAt(a.length-1)&&(a=a.substr(0,a.length-1)),na[a])c=na[a];else if("#"===a.charAt(0))4===a.length&&(d=a.charAt(1),e=a.charAt(2),f=a.charAt(3),a="#"+d+d+e+e+f+f),a=parseInt(a.substr(1),16),c=[a>>16,a>>8&255,255&a];else if("hsl"===a.substr(0,3))if(c=m=a.match(s),b){if(-1!==a.indexOf("="))return a.match(t)}else g=Number(c[0])%360/360,h=Number(c[1])/100,i=Number(c[2])/100,e=.5>=i?i*(h+1):i+h-i*h,d=2*i-e,c.length>3&&(c[3]=Number(c[3])),c[0]=oa(g+1/3,d,e),c[1]=oa(g,d,e),c[2]=oa(g-1/3,d,e);else c=a.match(s)||na.transparent;c[0]=Number(c[0]),c[1]=Number(c[1]),c[2]=Number(c[2]),c.length>3&&(c[3]=Number(c[3]))}else c=na.black;return b&&!m&&(d=c[0]/255,e=c[1]/255,f=c[2]/255,j=Math.max(d,e,f),k=Math.min(d,e,f),i=(j+k)/2,j===k?g=h=0:(l=j-k,h=i>.5?l/(2-j-k):l/(j+k),g=j===d?(e-f)/l+(f>e?6:0):j===e?(f-d)/l+2:(d-e)/l+4,g*=60),c[0]=g+.5|0,c[1]=100*h+.5|0,c[2]=100*i+.5|0),c},qa=function(a,b){var c,d,e,f=a.match(ra)||[],g=0,h="";if(!f.length)return a;for(c=0;c0?g[0].replace(s,""):"";return k?e=b?function(a){var b,m,n,o;if("number"==typeof a)a+=l;else if(d&&J.test(a)){for(o=a.replace(J,"|").split("|"),n=0;nn--)for(;++nm--)for(;++mi;i++)h[a[i]]=j[i]=j[i]||j[(i-1)/2>>0];return e.parse(b,h,f,g)}},ua=(T._setPluginRatio=function(a){this.plugin.setRatio(a);for(var b,c,d,e,f,g=this.data,h=g.proxy,i=g.firstMPT,j=1e-6;i;)b=h[i.v],i.r?b=i.r(b):j>b&&b>-j&&(b=0),i.t[i.p]=b,i=i._next;if(g.autoRotate&&(g.autoRotate.rotation=g.mod?g.mod.call(this._tween,h.rotation,this.t,this._tween):h.rotation),1===a||0===a)for(i=g.firstMPT,f=1===a?"e":"b";i;){if(c=i.t,c.type){if(1===c.type){for(e=c.xs0+c.s+c.xs1,d=1;d0;)i="xn"+g,h=d.p+"_"+i,n[h]=d.data[i],m[h]=d[i],f||(j=new ua(d,i,h,j,d.rxp[i]));d=d._next}return{proxy:m,end:n,firstMPT:j,pt:k}},T.CSSPropTween=function(a,b,d,e,g,h,i,j,k,l,m){this.t=a,this.p=b,this.s=d,this.c=e,this.n=i||b,a instanceof va||f.push(this.n),this.r=j?"function"==typeof j?j:Math.round:j,this.type=h||0,k&&(this.pr=k,c=!0),this.b=void 0===l?d:l,this.e=void 0===m?d+e:m,g&&(this._next=g,g._prev=this)}),wa=function(a,b,c,d,e,f){var g=new va(a,b,c,d-c,e,-1,f);return g.b=c,g.e=g.xs0=d,g},xa=g.parseComplex=function(a,b,c,d,e,f,h,i,j,l){c=c||f||"","function"==typeof d&&(d=d(r,q)),h=new va(a,b,0,0,h,l?2:1,null,!1,i,c,d),d+="",e&&ra.test(d+c)&&(d=[c,d],g.colorStringFilter(d),c=d[0],d=d[1]);var m,n,o,p,u,v,w,x,y,z,A,B,C,D=c.split(", ").join(",").split(" "),E=d.split(", ").join(",").split(" "),F=D.length,G=k!==!1;for((-1!==d.indexOf(",")||-1!==c.indexOf(","))&&(-1!==(d+c).indexOf("rgb")||-1!==(d+c).indexOf("hsl")?(D=D.join(" ").replace(J,", ").split(" "),E=E.join(" ").replace(J,", ").split(" ")):(D=D.join(" ").split(",").join(", ").split(" "),E=E.join(" ").split(",").join(", ").split(" ")),F=D.length),F!==E.length&&(D=(f||"").split(" "),F=D.length),h.plugin=j,h.setRatio=l,ra.lastIndex=0,m=0;F>m;m++)if(p=D[m],u=E[m]+"",x=parseFloat(p),x||0===x)h.appendXtra("",x,ka(u,x),u.replace(t,""),G&&-1!==u.indexOf("px")?Math.round:!1,!0);else if(e&&ra.test(p))B=u.indexOf(")")+1,B=")"+(B?u.substr(B):""),C=-1!==u.indexOf("hsl")&&V,z=u,p=pa(p,C),u=pa(u,C),y=p.length+u.length>6,y&&!V&&0===u[3]?(h["xs"+h.l]+=h.l?" transparent":"transparent",h.e=h.e.split(E[m]).join("transparent")):(V||(y=!1),C?h.appendXtra(z.substr(0,z.indexOf("hsl"))+(y?"hsla(":"hsl("),p[0],ka(u[0],p[0]),",",!1,!0).appendXtra("",p[1],ka(u[1],p[1]),"%,",!1).appendXtra("",p[2],ka(u[2],p[2]),y?"%,":"%"+B,!1):h.appendXtra(z.substr(0,z.indexOf("rgb"))+(y?"rgba(":"rgb("),p[0],u[0]-p[0],",",Math.round,!0).appendXtra("",p[1],u[1]-p[1],",",Math.round).appendXtra("",p[2],u[2]-p[2],y?",":B,Math.round),y&&(p=p.length<4?1:p[3],h.appendXtra("",p,(u.length<4?1:u[3])-p,B,!1))),ra.lastIndex=0;else if(v=p.match(s)){if(w=u.match(t),!w||w.length!==v.length)return h;for(o=0,n=0;n0;)j["xn"+ya]=0,j["xs"+ya]="";j.xs0="",j._next=j._prev=j.xfirst=j.data=j.plugin=j.setRatio=j.rxp=null,j.appendXtra=function(a,b,c,d,e,f){var g=this,h=g.l;return g["xs"+h]+=f&&(h||g["xs"+h])?" "+a:a||"",c||0===h||g.plugin?(g.l++,g.type=g.setRatio?2:1,g["xs"+g.l]=d||"",h>0?(g.data["xn"+h]=b+c,g.rxp["xn"+h]=e,g["xn"+h]=b,g.plugin||(g.xfirst=new va(g,"xn"+h,b,c,g.xfirst||g,0,g.n,e,g.pr),g.xfirst.xs0=0),g):(g.data={s:b+c},g.rxp={},g.s=b,g.c=c,g.r=e,g)):(g["xs"+h]+=b+(d||""),g)};var za=function(a,b){b=b||{},this.p=b.prefix?$(a)||a:a,i[a]=i[this.p]=this,this.format=b.formatter||sa(b.defaultValue,b.color,b.collapsible,b.multi),b.parser&&(this.parse=b.parser),this.clrs=b.color,this.multi=b.multi,this.keyword=b.keyword,this.dflt=b.defaultValue,this.allowFunc=b.allowFunc,this.pr=b.priority||0},Aa=T._registerComplexSpecialProp=function(a,b,c){"object"!=typeof b&&(b={parser:c});var d,e,f=a.split(","),g=b.defaultValue;for(c=c||[g],d=0;dh.length?i.length:h.length,g=0;j>g;g++)b=h[g]=h[g]||this.dflt,c=i[g]=i[g]||this.dflt,m&&(k=b.indexOf(m),l=c.indexOf(m),k!==l&&(-1===l?h[g]=h[g].split(m).join(""):-1===k&&(h[g]+=" "+m)));b=h.join(", "),c=i.join(", ")}return xa(a,this.p,b,c,this.clrs,this.dflt,d,this.pr,e,f)},j.parse=function(a,b,c,d,f,g,h){return this.parseComplex(a.style,this.format(ba(a,this.p,e,!1,this.dflt)),this.format(b),f,g)},g.registerSpecialProp=function(a,b,c){Aa(a,{parser:function(a,d,e,f,g,h,i){var j=new va(a,e,0,0,g,2,e,!1,c);return j.plugin=h,j.setRatio=b(a,d,f._tween,e),j},priority:c})},g.useSVGTransformAttr=!0;var Ca,Da="scaleX,scaleY,scaleZ,x,y,z,skewX,skewY,rotation,rotationX,rotationY,perspective,xPercent,yPercent".split(","),Ea=$("transform"),Fa=Y+"transform",Ga=$("transformOrigin"),Ha=null!==$("perspective"),Ia=T.Transform=function(){this.perspective=parseFloat(g.defaultTransformPerspective)||0,this.force3D=g.defaultForce3D!==!1&&Ha?g.defaultForce3D||"auto":!1},Ja=_gsScope.SVGElement,Ka=function(a,b,c){var d,e=P.createElementNS("http://www.w3.org/2000/svg",a),f=/([a-z])([A-Z])/g;for(d in c)e.setAttributeNS(null,d.replace(f,"$1-$2").toLowerCase(),c[d]);return b.appendChild(e),e},La=P.documentElement||{},Ma=function(){var a,b,c,d=p||/Android/i.test(U)&&!_gsScope.chrome;return P.createElementNS&&La.appendChild&&!d&&(a=Ka("svg",La),b=Ka("rect",a,{width:100,height:50,x:100}),c=b.getBoundingClientRect().width,b.style[Ga]="50% 50%",b.style[Ea]="scaleX(0.5)",d=c===b.getBoundingClientRect().width&&!(n&&Ha),La.removeChild(a)),d}(),Na=function(a,b,c,d,e,f){var h,i,j,k,l,m,n,o,p,q,r,s,t,u,v=a._gsTransform,w=Sa(a,!0);v&&(t=v.xOrigin,u=v.yOrigin),(!d||(h=d.split(" ")).length<2)&&(n=a.getBBox(),0===n.x&&0===n.y&&n.width+n.height===0&&(n={x:parseFloat(a.hasAttribute("x")?a.getAttribute("x"):a.hasAttribute("cx")?a.getAttribute("cx"):0)||0,y:parseFloat(a.hasAttribute("y")?a.getAttribute("y"):a.hasAttribute("cy")?a.getAttribute("cy"):0)||0,width:0,height:0}),b=ja(b).split(" "),h=[(-1!==b[0].indexOf("%")?parseFloat(b[0])/100*n.width:parseFloat(b[0]))+n.x,(-1!==b[1].indexOf("%")?parseFloat(b[1])/100*n.height:parseFloat(b[1]))+n.y]),c.xOrigin=k=parseFloat(h[0]),c.yOrigin=l=parseFloat(h[1]),d&&w!==Ra&&(m=w[0],n=w[1],o=w[2],p=w[3],q=w[4],r=w[5],s=m*p-n*o,s&&(i=k*(p/s)+l*(-o/s)+(o*r-p*q)/s,j=k*(-n/s)+l*(m/s)-(m*r-n*q)/s,k=c.xOrigin=h[0]=i,l=c.yOrigin=h[1]=j)),v&&(f&&(c.xOffset=v.xOffset,c.yOffset=v.yOffset,v=c),e||e!==!1&&g.defaultSmoothOrigin!==!1?(i=k-t,j=l-u,v.xOffset+=i*w[0]+j*w[2]-i,v.yOffset+=i*w[1]+j*w[3]-j):v.xOffset=v.yOffset=0),f||a.setAttribute("data-svg-origin",h.join(" "))},Oa=function(a){var b,c=Q("svg",this.ownerSVGElement&&this.ownerSVGElement.getAttribute("xmlns")||"http://www.w3.org/2000/svg"),d=this.parentNode,e=this.nextSibling,f=this.style.cssText;if(La.appendChild(c),c.appendChild(this),this.style.display="block",a)try{b=this.getBBox(),this._originalGetBBox=this.getBBox,this.getBBox=Oa}catch(g){}else this._originalGetBBox&&(b=this._originalGetBBox());return e?d.insertBefore(this,e):d.appendChild(this),La.removeChild(c),this.style.cssText=f,b},Pa=function(a){try{return a.getBBox()}catch(b){return Oa.call(a,!0)}},Qa=function(a){return!(!Ja||!a.getCTM||a.parentNode&&!a.ownerSVGElement||!Pa(a))},Ra=[1,0,0,1,0,0],Sa=function(a,b){var c,d,e,f,g,h,i,j=a._gsTransform||new Ia,k=1e5,l=a.style;if(Ea?d=ba(a,Fa,null,!0):a.currentStyle&&(d=a.currentStyle.filter.match(H),d=d&&4===d.length?[d[0].substr(4),Number(d[2].substr(4)),Number(d[1].substr(4)),d[3].substr(4),j.x||0,j.y||0].join(","):""),c=!d||"none"===d||"matrix(1, 0, 0, 1, 0, 0)"===d,Ea&&c&&!a.offsetParent&&a!==La&&(f=l.display,l.display="block",i=a.parentNode,i&&a.offsetParent||(g=1,h=a.nextSibling,La.appendChild(a)),d=ba(a,Fa,null,!0),c=!d||"none"===d||"matrix(1, 0, 0, 1, 0, 0)"===d,f?l.display=f:Xa(l,"display"),g&&(h?i.insertBefore(a,h):i?i.appendChild(a):La.removeChild(a))),(j.svg||a.getCTM&&Qa(a))&&(c&&-1!==(l[Ea]+"").indexOf("matrix")&&(d=l[Ea],c=0),e=a.getAttribute("transform"),c&&e&&(e=a.transform.baseVal.consolidate().matrix,d="matrix("+e.a+","+e.b+","+e.c+","+e.d+","+e.e+","+e.f+")",c=0)),c)return Ra;for(e=(d||"").match(s)||[],ya=e.length;--ya>-1;)f=Number(e[ya]),e[ya]=(g=f-(f|=0))?(g*k+(0>g?-.5:.5)|0)/k+f:f;return b&&e.length>6?[e[0],e[1],e[4],e[5],e[12],e[13]]:e},Ta=T.getTransform=function(a,c,d,e){if(a._gsTransform&&d&&!e)return a._gsTransform;var f,h,i,j,k,l,m=d?a._gsTransform||new Ia:new Ia,n=m.scaleX<0,o=2e-5,p=1e5,q=Ha?parseFloat(ba(a,Ga,c,!1,"0 0 0").split(" ")[2])||m.zOrigin||0:0,r=parseFloat(g.defaultTransformPerspective)||0;if(m.svg=!(!a.getCTM||!Qa(a)),m.svg&&(Na(a,ba(a,Ga,c,!1,"50% 50%")+"",m,a.getAttribute("data-svg-origin")),Ca=g.useSVGTransformAttr||Ma),f=Sa(a),f!==Ra){if(16===f.length){var s,t,u,v,w,x=f[0],y=f[1],z=f[2],A=f[3],B=f[4],C=f[5],D=f[6],E=f[7],F=f[8],G=f[9],H=f[10],I=f[12],J=f[13],K=f[14],L=f[11],N=Math.atan2(D,H);m.zOrigin&&(K=-m.zOrigin,I=F*K-f[12],J=G*K-f[13],K=H*K+m.zOrigin-f[14]),m.rotationX=N*M,N&&(v=Math.cos(-N),w=Math.sin(-N),s=B*v+F*w,t=C*v+G*w,u=D*v+H*w,F=B*-w+F*v,G=C*-w+G*v,H=D*-w+H*v,L=E*-w+L*v,B=s,C=t,D=u),N=Math.atan2(-z,H),m.rotationY=N*M,N&&(v=Math.cos(-N),w=Math.sin(-N),s=x*v-F*w,t=y*v-G*w,u=z*v-H*w,G=y*w+G*v,H=z*w+H*v,L=A*w+L*v,x=s,y=t,z=u),N=Math.atan2(y,x),m.rotation=N*M,N&&(v=Math.cos(N),w=Math.sin(N),s=x*v+y*w,t=B*v+C*w,u=F*v+G*w,y=y*v-x*w,C=C*v-B*w,G=G*v-F*w,x=s,B=t,F=u),m.rotationX&&Math.abs(m.rotationX)+Math.abs(m.rotation)>359.9&&(m.rotationX=m.rotation=0,m.rotationY=180-m.rotationY),N=Math.atan2(B,C),m.scaleX=(Math.sqrt(x*x+y*y+z*z)*p+.5|0)/p,m.scaleY=(Math.sqrt(C*C+D*D)*p+.5|0)/p,m.scaleZ=(Math.sqrt(F*F+G*G+H*H)*p+.5|0)/p,x/=m.scaleX,B/=m.scaleY,y/=m.scaleX,C/=m.scaleY,Math.abs(N)>o?(m.skewX=N*M,B=0,"simple"!==m.skewType&&(m.scaleY*=1/Math.cos(N))):m.skewX=0,m.perspective=L?1/(0>L?-L:L):0,m.x=I,m.y=J,m.z=K,m.svg&&(m.x-=m.xOrigin-(m.xOrigin*x-m.yOrigin*B),m.y-=m.yOrigin-(m.yOrigin*y-m.xOrigin*C))}else if(!Ha||e||!f.length||m.x!==f[4]||m.y!==f[5]||!m.rotationX&&!m.rotationY){var O=f.length>=6,P=O?f[0]:1,Q=f[1]||0,R=f[2]||0,S=O?f[3]:1;m.x=f[4]||0,m.y=f[5]||0,i=Math.sqrt(P*P+Q*Q),j=Math.sqrt(S*S+R*R),k=P||Q?Math.atan2(Q,P)*M:m.rotation||0,l=R||S?Math.atan2(R,S)*M+k:m.skewX||0,m.scaleX=i,m.scaleY=j,m.rotation=k,m.skewX=l,Ha&&(m.rotationX=m.rotationY=m.z=0,m.perspective=r,m.scaleZ=1),m.svg&&(m.x-=m.xOrigin-(m.xOrigin*P+m.yOrigin*R),m.y-=m.yOrigin-(m.xOrigin*Q+m.yOrigin*S))}Math.abs(m.skewX)>90&&Math.abs(m.skewX)<270&&(n?(m.scaleX*=-1,m.skewX+=m.rotation<=0?180:-180,m.rotation+=m.rotation<=0?180:-180):(m.scaleY*=-1,m.skewX+=m.skewX<=0?180:-180)),m.zOrigin=q;for(h in m)m[h]-o&&(m[h]=0)}return d&&(a._gsTransform=m,m.svg&&(Ca&&a.style[Ea]?b.delayedCall(.001,function(){Xa(a.style,Ea)}):!Ca&&a.getAttribute("transform")&&b.delayedCall(.001,function(){a.removeAttribute("transform")}))),m},Ua=function(a){var b,c,d=this.data,e=-d.rotation*L,f=e+d.skewX*L,g=1e5,h=(Math.cos(e)*d.scaleX*g|0)/g,i=(Math.sin(e)*d.scaleX*g|0)/g,j=(Math.sin(f)*-d.scaleY*g|0)/g,k=(Math.cos(f)*d.scaleY*g|0)/g,l=this.t.style,m=this.t.currentStyle;if(m){c=i,i=-j,j=-c,b=m.filter,l.filter="";var n,o,q=this.t.offsetWidth,r=this.t.offsetHeight,s="absolute"!==m.position,t="progid:DXImageTransform.Microsoft.Matrix(M11="+h+", M12="+i+", M21="+j+", M22="+k,u=d.x+q*d.xPercent/100,v=d.y+r*d.yPercent/100;if(null!=d.ox&&(n=(d.oxp?q*d.ox*.01:d.ox)-q/2,o=(d.oyp?r*d.oy*.01:d.oy)-r/2,u+=n-(n*h+o*i),v+=o-(n*j+o*k)),s?(n=q/2,o=r/2,t+=", Dx="+(n-(n*h+o*i)+u)+", Dy="+(o-(n*j+o*k)+v)+")"):t+=", sizingMethod='auto expand')",-1!==b.indexOf("DXImageTransform.Microsoft.Matrix(")?l.filter=b.replace(I,t):l.filter=t+" "+b,(0===a||1===a)&&1===h&&0===i&&0===j&&1===k&&(s&&-1===t.indexOf("Dx=0, Dy=0")||y.test(b)&&100!==parseFloat(RegExp.$1)||-1===b.indexOf(b.indexOf("Alpha"))&&l.removeAttribute("filter")),!s){var w,z,A,B=8>p?1:-1;for(n=d.ieOffsetX||0,o=d.ieOffsetY||0,d.ieOffsetX=Math.round((q-((0>h?-h:h)*q+(0>i?-i:i)*r))/2+u),d.ieOffsetY=Math.round((r-((0>k?-k:k)*r+(0>j?-j:j)*q))/2+v),ya=0;4>ya;ya++)z=ha[ya],w=m[z],c=-1!==w.indexOf("px")?parseFloat(w):ca(this.t,z,parseFloat(w),w.replace(x,""))||0,A=c!==d[z]?2>ya?-d.ieOffsetX:-d.ieOffsetY:2>ya?n-d.ieOffsetX:o-d.ieOffsetY,l[z]=(d[z]=Math.round(c-A*(0===ya||2===ya?1:B)))+"px"}}},Va=T.set3DTransformRatio=T.setTransformRatio=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,o,p,q,r,s,t,u,v,w,x,y,z=this.data,A=this.t.style,B=z.rotation,C=z.rotationX,D=z.rotationY,E=z.scaleX,F=z.scaleY,G=z.scaleZ,H=z.x,I=z.y,J=z.z,K=z.svg,M=z.perspective,N=z.force3D,O=z.skewY,P=z.skewX;if(O&&(P+=O,B+=O),((1===a||0===a)&&"auto"===N&&(this.tween._totalTime===this.tween._totalDuration||!this.tween._totalTime)||!N)&&!J&&!M&&!D&&!C&&1===G||Ca&&K||!Ha)return void(B||P||K?(B*=L,x=P*L,y=1e5,c=Math.cos(B)*E,f=Math.sin(B)*E,d=Math.sin(B-x)*-F,g=Math.cos(B-x)*F,x&&"simple"===z.skewType&&(b=Math.tan(x-O*L),b=Math.sqrt(1+b*b),d*=b,g*=b,O&&(b=Math.tan(O*L),b=Math.sqrt(1+b*b),c*=b,f*=b)),K&&(H+=z.xOrigin-(z.xOrigin*c+z.yOrigin*d)+z.xOffset,I+=z.yOrigin-(z.xOrigin*f+z.yOrigin*g)+z.yOffset,Ca&&(z.xPercent||z.yPercent)&&(q=this.t.getBBox(),H+=.01*z.xPercent*q.width,I+=.01*z.yPercent*q.height),q=1e-6,q>H&&H>-q&&(H=0),q>I&&I>-q&&(I=0)),u=(c*y|0)/y+","+(f*y|0)/y+","+(d*y|0)/y+","+(g*y|0)/y+","+H+","+I+")",K&&Ca?this.t.setAttribute("transform","matrix("+u):A[Ea]=(z.xPercent||z.yPercent?"translate("+z.xPercent+"%,"+z.yPercent+"%) matrix(":"matrix(")+u):A[Ea]=(z.xPercent||z.yPercent?"translate("+z.xPercent+"%,"+z.yPercent+"%) matrix(":"matrix(")+E+",0,0,"+F+","+H+","+I+")");if(n&&(q=1e-4,q>E&&E>-q&&(E=G=2e-5),q>F&&F>-q&&(F=G=2e-5),!M||z.z||z.rotationX||z.rotationY||(M=0)),B||P)B*=L,r=c=Math.cos(B),s=f=Math.sin(B),P&&(B-=P*L,r=Math.cos(B),s=Math.sin(B),"simple"===z.skewType&&(b=Math.tan((P-O)*L),b=Math.sqrt(1+b*b),r*=b,s*=b,z.skewY&&(b=Math.tan(O*L),b=Math.sqrt(1+b*b),c*=b,f*=b))),d=-s,g=r;else{if(!(D||C||1!==G||M||K))return void(A[Ea]=(z.xPercent||z.yPercent?"translate("+z.xPercent+"%,"+z.yPercent+"%) translate3d(":"translate3d(")+H+"px,"+I+"px,"+J+"px)"+(1!==E||1!==F?" scale("+E+","+F+")":""));c=g=1,d=f=0}k=1,e=h=i=j=l=m=0,o=M?-1/M:0,p=z.zOrigin,q=1e-6,v=",",w="0",B=D*L,B&&(r=Math.cos(B),s=Math.sin(B),i=-s,l=o*-s,e=c*s,h=f*s,k=r,o*=r,c*=r,f*=r),B=C*L,B&&(r=Math.cos(B),s=Math.sin(B),b=d*r+e*s,t=g*r+h*s,j=k*s,m=o*s,e=d*-s+e*r,h=g*-s+h*r,k*=r,o*=r,d=b,g=t),1!==G&&(e*=G,h*=G,k*=G,o*=G),1!==F&&(d*=F,g*=F,j*=F,m*=F),1!==E&&(c*=E,f*=E,i*=E,l*=E),(p||K)&&(p&&(H+=e*-p,I+=h*-p,J+=k*-p+p),K&&(H+=z.xOrigin-(z.xOrigin*c+z.yOrigin*d)+z.xOffset,I+=z.yOrigin-(z.xOrigin*f+z.yOrigin*g)+z.yOffset),q>H&&H>-q&&(H=w),q>I&&I>-q&&(I=w),q>J&&J>-q&&(J=0)),u=z.xPercent||z.yPercent?"translate("+z.xPercent+"%,"+z.yPercent+"%) matrix3d(":"matrix3d(",u+=(q>c&&c>-q?w:c)+v+(q>f&&f>-q?w:f)+v+(q>i&&i>-q?w:i),u+=v+(q>l&&l>-q?w:l)+v+(q>d&&d>-q?w:d)+v+(q>g&&g>-q?w:g),C||D||1!==G?(u+=v+(q>j&&j>-q?w:j)+v+(q>m&&m>-q?w:m)+v+(q>e&&e>-q?w:e),u+=v+(q>h&&h>-q?w:h)+v+(q>k&&k>-q?w:k)+v+(q>o&&o>-q?w:o)+v):u+=",0,0,0,0,1,0,",u+=H+v+I+v+J+v+(M?1+-J/M:1)+")",A[Ea]=u};j=Ia.prototype,j.x=j.y=j.z=j.skewX=j.skewY=j.rotation=j.rotationX=j.rotationY=j.zOrigin=j.xPercent=j.yPercent=j.xOffset=j.yOffset=0,j.scaleX=j.scaleY=j.scaleZ=1,Aa("transform,scale,scaleX,scaleY,scaleZ,x,y,z,rotation,rotationX,rotationY,rotationZ,skewX,skewY,shortRotation,shortRotationX,shortRotationY,shortRotationZ,transformOrigin,svgOrigin,transformPerspective,directionalRotation,parseTransform,force3D,skewType,xPercent,yPercent,smoothOrigin",{parser:function(a,b,c,d,f,h,i){if(d._lastParsedTransform===i)return f;d._lastParsedTransform=i;var j=i.scale&&"function"==typeof i.scale?i.scale:0;j&&(i.scale=j(r,a));var k,l,m,n,o,p,s,t,u,v=a._gsTransform,w=a.style,x=1e-6,y=Da.length,z=i,A={},B="transformOrigin",C=Ta(a,e,!0,z.parseTransform),D=z.transform&&("function"==typeof z.transform?z.transform(r,q):z.transform);if(C.skewType=z.skewType||C.skewType||g.defaultSkewType,d._transform=C,"rotationZ"in z&&(z.rotation=z.rotationZ),D&&"string"==typeof D&&Ea)l=R.style,l[Ea]=D,l.display="block",l.position="absolute",-1!==D.indexOf("%")&&(l.width=ba(a,"width"),l.height=ba(a,"height")),P.body.appendChild(R),k=Ta(R,null,!1),"simple"===C.skewType&&(k.scaleY*=Math.cos(k.skewX*L)),C.svg&&(p=C.xOrigin,s=C.yOrigin,k.x-=C.xOffset,k.y-=C.yOffset,(z.transformOrigin||z.svgOrigin)&&(D={},Na(a,ja(z.transformOrigin),D,z.svgOrigin,z.smoothOrigin,!0),p=D.xOrigin,s=D.yOrigin,k.x-=D.xOffset-C.xOffset,k.y-=D.yOffset-C.yOffset),(p||s)&&(t=Sa(R,!0),k.x-=p-(p*t[0]+s*t[2]),k.y-=s-(p*t[1]+s*t[3]))),P.body.removeChild(R),k.perspective||(k.perspective=C.perspective),null!=z.xPercent&&(k.xPercent=la(z.xPercent,C.xPercent)),null!=z.yPercent&&(k.yPercent=la(z.yPercent,C.yPercent));else if("object"==typeof z){if(k={scaleX:la(null!=z.scaleX?z.scaleX:z.scale,C.scaleX),scaleY:la(null!=z.scaleY?z.scaleY:z.scale,C.scaleY),scaleZ:la(z.scaleZ,C.scaleZ),x:la(z.x,C.x),y:la(z.y,C.y),z:la(z.z,C.z),xPercent:la(z.xPercent,C.xPercent),yPercent:la(z.yPercent,C.yPercent),perspective:la(z.transformPerspective,C.perspective)},o=z.directionalRotation,null!=o)if("object"==typeof o)for(l in o)z[l]=o[l];else z.rotation=o;"string"==typeof z.x&&-1!==z.x.indexOf("%")&&(k.x=0,k.xPercent=la(z.x,C.xPercent)),"string"==typeof z.y&&-1!==z.y.indexOf("%")&&(k.y=0,k.yPercent=la(z.y,C.yPercent)),k.rotation=ma("rotation"in z?z.rotation:"shortRotation"in z?z.shortRotation+"_short":C.rotation,C.rotation,"rotation",A),Ha&&(k.rotationX=ma("rotationX"in z?z.rotationX:"shortRotationX"in z?z.shortRotationX+"_short":C.rotationX||0,C.rotationX,"rotationX",A),k.rotationY=ma("rotationY"in z?z.rotationY:"shortRotationY"in z?z.shortRotationY+"_short":C.rotationY||0,C.rotationY,"rotationY",A)),k.skewX=ma(z.skewX,C.skewX),k.skewY=ma(z.skewY,C.skewY)}for(Ha&&null!=z.force3D&&(C.force3D=z.force3D,n=!0),m=C.force3D||C.z||C.rotationX||C.rotationY||k.z||k.rotationX||k.rotationY||k.perspective,m||null==z.scale||(k.scaleZ=1);--y>-1;)u=Da[y],D=k[u]-C[u],(D>x||-x>D||null!=z[u]||null!=N[u])&&(n=!0,f=new va(C,u,C[u],D,f),u in A&&(f.e=A[u]),f.xs0=0,f.plugin=h,d._overwriteProps.push(f.n));return D="function"==typeof z.transformOrigin?z.transformOrigin(r,q):z.transformOrigin,C.svg&&(D||z.svgOrigin)&&(p=C.xOffset,s=C.yOffset,Na(a,ja(D),k,z.svgOrigin,z.smoothOrigin),f=wa(C,"xOrigin",(v?C:k).xOrigin,k.xOrigin,f,B),f=wa(C,"yOrigin",(v?C:k).yOrigin,k.yOrigin,f,B),(p!==C.xOffset||s!==C.yOffset)&&(f=wa(C,"xOffset",v?p:C.xOffset,C.xOffset,f,B),f=wa(C,"yOffset",v?s:C.yOffset,C.yOffset,f,B)),D="0px 0px"),(D||Ha&&m&&C.zOrigin)&&(Ea?(n=!0,u=Ga,D||(D=(ba(a,u,e,!1,"50% 50%")+"").split(" "),D=D[0]+" "+D[1]+" "+C.zOrigin+"px"),D+="",f=new va(w,u,0,0,f,-1,B),f.b=w[u],f.plugin=h,Ha?(l=C.zOrigin,D=D.split(" "),C.zOrigin=(D.length>2?parseFloat(D[2]):l)||0,f.xs0=f.e=D[0]+" "+(D[1]||"50%")+" 0px",f=new va(C,"zOrigin",0,0,f,-1,f.n),f.b=l,f.xs0=f.e=C.zOrigin):f.xs0=f.e=D):ja(D+"",C)),n&&(d._transformType=C.svg&&Ca||!m&&3!==this._transformType?2:3),j&&(i.scale=j),f},allowFunc:!0,prefix:!0}),Aa("boxShadow",{defaultValue:"0px 0px 0px 0px #999",prefix:!0,color:!0,multi:!0,keyword:"inset"}),Aa("clipPath",{defaultValue:"inset(0%)",prefix:!0,multi:!0,formatter:sa("inset(0% 0% 0% 0%)",!1,!0)}),Aa("borderRadius",{defaultValue:"0px",parser:function(a,b,c,f,g,h){b=this.format(b);var i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y=["borderTopLeftRadius","borderTopRightRadius","borderBottomRightRadius","borderBottomLeftRadius"],z=a.style;for(q=parseFloat(a.offsetWidth),r=parseFloat(a.offsetHeight),i=b.split(" "),j=0;jp?1:0))||""):(p=parseFloat(n),s=n.substr((p+"").length)),""===s&&(s=d[c]||t),s!==t&&(v=ca(a,"borderLeft",o,t),w=ca(a,"borderTop",o,t),"%"===s?(m=v/q*100+"%",l=w/r*100+"%"):"em"===s?(x=ca(a,"borderLeft",1,"em"),m=v/x+"em",l=w/x+"em"):(m=v+"px",l=w+"px"),u&&(n=parseFloat(m)+p+s,k=parseFloat(l)+p+s)),g=xa(z,y[j],m+" "+l,n+" "+k,!1,"0px",g);return g},prefix:!0,formatter:sa("0px 0px 0px 0px",!1,!0)}),Aa("borderBottomLeftRadius,borderBottomRightRadius,borderTopLeftRadius,borderTopRightRadius",{defaultValue:"0px",parser:function(a,b,c,d,f,g){return xa(a.style,c,this.format(ba(a,c,e,!1,"0px 0px")),this.format(b),!1,"0px",f)},prefix:!0,formatter:sa("0px 0px",!1,!0)}),Aa("backgroundPosition",{defaultValue:"0 0",parser:function(a,b,c,d,f,g){ 13 | var h,i,j,k,l,m,n="background-position",o=e||aa(a,null),q=this.format((o?p?o.getPropertyValue(n+"-x")+" "+o.getPropertyValue(n+"-y"):o.getPropertyValue(n):a.currentStyle.backgroundPositionX+" "+a.currentStyle.backgroundPositionY)||"0 0"),r=this.format(b);if(-1!==q.indexOf("%")!=(-1!==r.indexOf("%"))&&r.split(",").length<2&&(m=ba(a,"backgroundImage").replace(E,""),m&&"none"!==m)){for(h=q.split(" "),i=r.split(" "),S.setAttribute("src",m),j=2;--j>-1;)q=h[j],k=-1!==q.indexOf("%"),k!==(-1!==i[j].indexOf("%"))&&(l=0===j?a.offsetWidth-S.width:a.offsetHeight-S.height,h[j]=k?parseFloat(q)/100*l+"px":parseFloat(q)/l*100+"%");q=h.join(" ")}return this.parseComplex(a.style,q,r,f,g)},formatter:ja}),Aa("backgroundSize",{defaultValue:"0 0",formatter:function(a){return a+="","co"===a.substr(0,2)?a:ja(-1===a.indexOf(" ")?a+" "+a:a)}}),Aa("perspective",{defaultValue:"0px",prefix:!0}),Aa("perspectiveOrigin",{defaultValue:"50% 50%",prefix:!0}),Aa("transformStyle",{prefix:!0}),Aa("backfaceVisibility",{prefix:!0}),Aa("userSelect",{prefix:!0}),Aa("margin",{parser:ta("marginTop,marginRight,marginBottom,marginLeft")}),Aa("padding",{parser:ta("paddingTop,paddingRight,paddingBottom,paddingLeft")}),Aa("clip",{defaultValue:"rect(0px,0px,0px,0px)",parser:function(a,b,c,d,f,g){var h,i,j;return 9>p?(i=a.currentStyle,j=8>p?" ":",",h="rect("+i.clipTop+j+i.clipRight+j+i.clipBottom+j+i.clipLeft+")",b=this.format(b).split(",").join(j)):(h=this.format(ba(a,this.p,e,!1,this.dflt)),b=this.format(b)),this.parseComplex(a.style,h,b,f,g)}}),Aa("textShadow",{defaultValue:"0px 0px 0px #999",color:!0,multi:!0}),Aa("autoRound,strictUnits",{parser:function(a,b,c,d,e){return e}}),Aa("border",{defaultValue:"0px solid #000",parser:function(a,b,c,d,f,g){var h=ba(a,"borderTopWidth",e,!1,"0px"),i=this.format(b).split(" "),j=i[0].replace(x,"");return"px"!==j&&(h=parseFloat(h)/ca(a,"borderTopWidth",1,j)+j),this.parseComplex(a.style,this.format(h+" "+ba(a,"borderTopStyle",e,!1,"solid")+" "+ba(a,"borderTopColor",e,!1,"#000")),i.join(" "),f,g)},color:!0,formatter:function(a){var b=a.split(" ");return b[0]+" "+(b[1]||"solid")+" "+(a.match(ra)||["#000"])[0]}}),Aa("borderWidth",{parser:ta("borderTopWidth,borderRightWidth,borderBottomWidth,borderLeftWidth")}),Aa("float,cssFloat,styleFloat",{parser:function(a,b,c,d,e,f){var g=a.style,h="cssFloat"in g?"cssFloat":"styleFloat";return new va(g,h,0,0,e,-1,c,!1,0,g[h],b)}});var Wa=function(a){var b,c=this.t,d=c.filter||ba(this.data,"filter")||"",e=this.s+this.c*a|0;100===e&&(-1===d.indexOf("atrix(")&&-1===d.indexOf("radient(")&&-1===d.indexOf("oader(")?(c.removeAttribute("filter"),b=!ba(this.data,"filter")):(c.filter=d.replace(A,""),b=!0)),b||(this.xn1&&(c.filter=d=d||"alpha(opacity="+e+")"),-1===d.indexOf("pacity")?0===e&&this.xn1||(c.filter=d+" alpha(opacity="+e+")"):c.filter=d.replace(y,"opacity="+e))};Aa("opacity,alpha,autoAlpha",{defaultValue:"1",parser:function(a,b,c,d,f,g){var h=parseFloat(ba(a,"opacity",e,!1,"1")),i=a.style,j="autoAlpha"===c;return"string"==typeof b&&"="===b.charAt(1)&&(b=("-"===b.charAt(0)?-1:1)*parseFloat(b.substr(2))+h),j&&1===h&&"hidden"===ba(a,"visibility",e)&&0!==b&&(h=0),V?f=new va(i,"opacity",h,b-h,f):(f=new va(i,"opacity",100*h,100*(b-h),f),f.xn1=j?1:0,i.zoom=1,f.type=2,f.b="alpha(opacity="+f.s+")",f.e="alpha(opacity="+(f.s+f.c)+")",f.data=a,f.plugin=g,f.setRatio=Wa),j&&(f=new va(i,"visibility",0,0,f,-1,null,!1,0,0!==h?"inherit":"hidden",0===b?"hidden":"inherit"),f.xs0="inherit",d._overwriteProps.push(f.n),d._overwriteProps.push(c)),f}});var Xa=function(a,b){b&&(a.removeProperty?(("ms"===b.substr(0,2)||"webkit"===b.substr(0,6))&&(b="-"+b),a.removeProperty(b.replace(C,"-$1").toLowerCase())):a.removeAttribute(b))},Ya=function(a){if(this.t._gsClassPT=this,1===a||0===a){this.t.setAttribute("class",0===a?this.b:this.e);for(var b=this.data,c=this.t.style;b;)b.v?c[b.p]=b.v:Xa(c,b.p),b=b._next;1===a&&this.t._gsClassPT===this&&(this.t._gsClassPT=null)}else this.t.getAttribute("class")!==this.e&&this.t.setAttribute("class",this.e)};Aa("className",{parser:function(a,b,d,f,g,h,i){var j,k,l,m,n,o=a.getAttribute("class")||"",p=a.style.cssText;if(g=f._classNamePT=new va(a,d,0,0,g,2),g.setRatio=Ya,g.pr=-11,c=!0,g.b=o,k=ea(a,e),l=a._gsClassPT){for(m={},n=l.data;n;)m[n.p]=1,n=n._next;l.setRatio(1)}return a._gsClassPT=g,g.e="="!==b.charAt(1)?b:o.replace(new RegExp("(?:\\s|^)"+b.substr(2)+"(?![\\w-])"),"")+("+"===b.charAt(0)?" "+b.substr(2):""),a.setAttribute("class",g.e),j=fa(a,k,ea(a),i,m),a.setAttribute("class",o),g.data=j.firstMPT,a.style.cssText!==p&&(a.style.cssText=p),g=g.xfirst=f.parse(a,j.difs,g,h)}});var Za=function(a){if((1===a||0===a)&&this.data._totalTime===this.data._totalDuration&&"isFromStart"!==this.data.data){var b,c,d,e,f,g=this.t.style,h=i.transform.parse;if("all"===this.e)g.cssText="",e=!0;else for(b=this.e.split(" ").join("").split(","),d=b.length;--d>-1;)c=b[d],i[c]&&(i[c].parse===h?e=!0:c="transformOrigin"===c?Ga:i[c].p),Xa(g,c);e&&(Xa(g,Ea),f=this.t._gsTransform,f&&(f.svg&&(this.t.removeAttribute("data-svg-origin"),this.t.removeAttribute("transform")),delete this.t._gsTransform))}};for(Aa("clearProps",{parser:function(a,b,d,e,f){return f=new va(a,d,0,0,f,2),f.setRatio=Za,f.e=b,f.pr=-10,f.data=e._tween,c=!0,f}}),j="bezier,throwProps,physicsProps,physics2D".split(","),ya=j.length;ya--;)Ba(j[ya]);j=g.prototype,j._firstPT=j._lastParsedTransform=j._transform=null,j._onInitTween=function(a,b,h,j){if(!a.nodeType)return!1;this._target=q=a,this._tween=h,this._vars=b,r=j,k=b.autoRound,c=!1,d=b.suffixMap||g.suffixMap,e=aa(a,""),f=this._overwriteProps;var n,p,s,t,u,v,w,x,y,A=a.style;if(l&&""===A.zIndex&&(n=ba(a,"zIndex",e),("auto"===n||""===n)&&this._addLazySet(A,"zIndex",0)),"string"==typeof b&&(t=A.cssText,n=ea(a,e),A.cssText=t+";"+b,n=fa(a,n,ea(a)).difs,!V&&z.test(b)&&(n.opacity=parseFloat(RegExp.$1)),b=n,A.cssText=t),b.className?this._firstPT=p=i.className.parse(a,b.className,"className",this,null,null,b):this._firstPT=p=this.parse(a,b,null),this._transformType){for(y=3===this._transformType,Ea?m&&(l=!0,""===A.zIndex&&(w=ba(a,"zIndex",e),("auto"===w||""===w)&&this._addLazySet(A,"zIndex",0)),o&&this._addLazySet(A,"WebkitBackfaceVisibility",this._vars.WebkitBackfaceVisibility||(y?"visible":"hidden"))):A.zoom=1,s=p;s&&s._next;)s=s._next;x=new va(a,"transform",0,0,null,2),this._linkCSSP(x,null,s),x.setRatio=Ea?Va:Ua,x.data=this._transform||Ta(a,e,!0),x.tween=h,x.pr=-1,f.pop()}if(c){for(;p;){for(v=p._next,s=t;s&&s.pr>p.pr;)s=s._next;(p._prev=s?s._prev:u)?p._prev._next=p:t=p,(p._next=s)?s._prev=p:u=p,p=v}this._firstPT=t}return!0},j.parse=function(a,b,c,f){var g,h,j,l,m,n,o,p,s,t,u=a.style;for(g in b){if(n=b[g],h=i[g],"function"!=typeof n||h&&h.allowFunc||(n=n(r,q)),h)c=h.parse(a,n,g,this,c,f,b);else{if("--"===g.substr(0,2)){this._tween._propLookup[g]=this._addTween.call(this._tween,a.style,"setProperty",aa(a).getPropertyValue(g)+"",n+"",g,!1,g);continue}m=ba(a,g,e)+"",s="string"==typeof n,"color"===g||"fill"===g||"stroke"===g||-1!==g.indexOf("Color")||s&&B.test(n)?(s||(n=pa(n),n=(n.length>3?"rgba(":"rgb(")+n.join(",")+")"),c=xa(u,g,m,n,!0,"transparent",c,0,f)):s&&K.test(n)?c=xa(u,g,m,n,!0,null,c,0,f):(j=parseFloat(m),o=j||0===j?m.substr((j+"").length):"",(""===m||"auto"===m)&&("width"===g||"height"===g?(j=ia(a,g,e),o="px"):"left"===g||"top"===g?(j=da(a,g,e),o="px"):(j="opacity"!==g?0:1,o="")),t=s&&"="===n.charAt(1),t?(l=parseInt(n.charAt(0)+"1",10),n=n.substr(2),l*=parseFloat(n),p=n.replace(x,"")):(l=parseFloat(n),p=s?n.replace(x,""):""),""===p&&(p=g in d?d[g]:o),n=l||0===l?(t?l+j:l)+p:b[g],o!==p&&(""!==p||"lineHeight"===g)&&(l||0===l)&&j&&(j=ca(a,g,j,o),"%"===p?(j/=ca(a,g,100,"%")/100,b.strictUnits!==!0&&(m=j+"%")):"em"===p||"rem"===p||"vw"===p||"vh"===p?j/=ca(a,g,1,p):"px"!==p&&(l=ca(a,g,l,p),p="px"),t&&(l||0===l)&&(n=l+j+p)),t&&(l+=j),!j&&0!==j||!l&&0!==l?void 0!==u[g]&&(n||n+""!="NaN"&&null!=n)?(c=new va(u,g,l||j||0,0,c,-1,g,!1,0,m,n),c.xs0="none"!==n||"display"!==g&&-1===g.indexOf("Style")?n:m):X("invalid "+g+" tween value: "+b[g]):(c=new va(u,g,j,l-j,c,0,g,k!==!1&&("px"===p||"zIndex"===g),0,m,n),c.xs0=p))}f&&c&&!c.plugin&&(c.plugin=f)}return c},j.setRatio=function(a){var b,c,d,e=this._firstPT,f=1e-6;if(1!==a||this._tween._time!==this._tween._duration&&0!==this._tween._time)if(a||this._tween._time!==this._tween._duration&&0!==this._tween._time||this._tween._rawPrevTime===-1e-6)for(;e;){if(b=e.c*a+e.s,e.r?b=e.r(b):f>b&&b>-f&&(b=0),e.type)if(1===e.type)if(d=e.l,2===d)e.t[e.p]=e.xs0+b+e.xs1+e.xn1+e.xs2;else if(3===d)e.t[e.p]=e.xs0+b+e.xs1+e.xn1+e.xs2+e.xn2+e.xs3;else if(4===d)e.t[e.p]=e.xs0+b+e.xs1+e.xn1+e.xs2+e.xn2+e.xs3+e.xn3+e.xs4;else if(5===d)e.t[e.p]=e.xs0+b+e.xs1+e.xn1+e.xs2+e.xn2+e.xs3+e.xn3+e.xs4+e.xn4+e.xs5;else{for(c=e.xs0+b+e.xs1,d=1;d-1;)_a(a[e],b,c);else for(d=a.childNodes,e=d.length;--e>-1;)f=d[e],g=f.type,f.style&&(b.push(ea(f)),c&&c.push(f)),1!==g&&9!==g&&11!==g||!f.childNodes.length||_a(f,b,c)};return g.cascadeTo=function(a,c,d){var e,f,g,h,i=b.to(a,c,d),j=[i],k=[],l=[],m=[],n=b._internals.reservedProps;for(a=i._targets||i.target,_a(a,k,m),i.render(c,!0,!0),_a(a,l),i.render(0,!0,!0),i._enabled(!0),e=m.length;--e>-1;)if(f=fa(m[e],k[e],l[e]),f.firstMPT){f=f.difs;for(g in d)n[g]&&(f[g]=d[g]);h={};for(g in f)h[g]=k[e][g];j.push(b.fromTo(m[e],c,h,f))}return j},a.activate([g]),g},!0)}),_gsScope._gsDefine&&_gsScope._gsQueue.pop()(),function(a){"use strict";var b=function(){return(_gsScope.GreenSockGlobals||_gsScope)[a]};"undefined"!=typeof module&&module.exports?(require("../TweenLite.min.js"),module.exports=b()):"function"==typeof define&&define.amd&&define(["TweenLite"],b)}("CSSPlugin"); -------------------------------------------------------------------------------- /js/Configurator.js: -------------------------------------------------------------------------------- 1 | function encode(key, value) { 2 | return encodeURIComponent(key) + "=" + encodeURIComponent(value); 3 | } 4 | 5 | class DynamicFolder { 6 | constructor(name, controllerData, type, data) { 7 | this.name = name; 8 | this.mounted = false; 9 | this.gui = null; 10 | this.controllerData = controllerData; 11 | this.data = {}; 12 | this.controllers = {}; 13 | 14 | this.setData(type, data); 15 | } 16 | setData(type, givenData) { 17 | if (!type) { 18 | type = this.type; 19 | } 20 | let data = this.data[type]; 21 | // If there is given data, don't use saved data. 22 | if (!data || givenData) { 23 | data = {}; 24 | this.controllerData.get(type).forEach((item, key) => { 25 | data[key] = item.initialValue; 26 | }); 27 | } 28 | if (givenData) { 29 | const dataKeys = Object.keys(data); 30 | dataKeys.forEach(key => { 31 | if (givenData[key]) data[key] = givenData[key]; 32 | }); 33 | } 34 | 35 | this.type = type; 36 | this.data[type] = data; 37 | if (this.mounted) this.render(); 38 | } 39 | getData() { 40 | const data = this.data[this.type]; 41 | return data; 42 | } 43 | renderItems(data, controllerData) { 44 | controllerData.forEach((item, key) => { 45 | const controller = this.gui.add.apply( 46 | this.gui, 47 | [data, key].concat(item.onAdd) 48 | ); 49 | this.controllers[key] = controller; 50 | if (item.onController) { 51 | item.onController.forEach((value, key) => { 52 | controller[key](value); 53 | }); 54 | } 55 | }); 56 | } 57 | render() { 58 | if (!this.mounted) return; 59 | this.clean(); 60 | const gui = this.gui; 61 | 62 | this.renderItems(this.data[this.type], this.controllerData.get(this.type)); 63 | const nControllers = gui.__controllers.length; 64 | if (nControllers === 0) { 65 | gui.name = this.name + " (Empty)"; 66 | } else { 67 | gui.name = this.name + " +" + nControllers; 68 | } 69 | this.gui.domElement.children[0].children[0].classList.add("shine"); 70 | setTimeout(() => { 71 | this.gui.domElement.children[0].children[0].classList.remove("shine"); 72 | }, 100); 73 | } 74 | clean() { 75 | if (!this.mounted) return; 76 | while (this.gui.__controllers.length > 0) { 77 | this.gui.remove(this.gui.__controllers[0]); 78 | } 79 | } 80 | mount(parentGUI) { 81 | if (this.mounted) return; 82 | const gui = parentGUI.addFolder(this.name); 83 | this.gui = gui; 84 | this.mounted = true; 85 | if (this.type != null) { 86 | this.render(); 87 | } 88 | } 89 | } 90 | class Configurator { 91 | constructor(container, items, options) { 92 | this.gui = null; 93 | this.storageEffects = { 94 | idList: { 95 | drafts: this.getIds("drafts"), 96 | saved: this.getIds("saved") 97 | }, 98 | retrieved: {} 99 | }; 100 | this.forceDraft = false; 101 | this.onProgressChange = options.onProgressChange; 102 | delete options.onProgressChange; 103 | this.effectID = null; 104 | this.defaultOptions = Object.assign({}, options); 105 | options = this.getQueryOptionsOrLastValidDraft(options); 106 | this.effect = new GridToFullscreenEffect(container, items, options); 107 | this.initialized = false; 108 | this.options = {}; 109 | // Generate a map of easings, with the easing object as a key 110 | // To use later as a lookup table 111 | let keys = Object.keys(window.com.greensock.easing); 112 | const easings = new Map([]); 113 | let easingLookup = new Map([]); 114 | keys.forEach(easeName => { 115 | let easeMeta = { name: easeName, types: [] }; 116 | let ease = window.com.greensock.easing[easeName]; 117 | let validTypes = ["easeIn", "easeOut", "easeInOut", "easeNone"]; 118 | validTypes.forEach(type => { 119 | let easeType = ease[type]; 120 | if (easeType) { 121 | easeMeta.types.push(type); 122 | easingLookup.set(easeType, { name: easeName, type }); 123 | } 124 | }); 125 | if (easeMeta.types.length > 0) { 126 | easings.set(easeName, easeMeta.types); 127 | } 128 | }); 129 | 130 | this.easings = easings; 131 | this.easingLookup = easingLookup; 132 | 133 | this.getCustomOptions = this.getCustomOptions.bind(this); 134 | this.onItemFinishChangeReset = this.onItemFinishChangeReset.bind(this); 135 | this.onEffectIdGUIFinishChange = this.onEffectIdGUIFinishChange.bind(this); 136 | this.onSaveClick = this.onSaveClick.bind(this); 137 | this.guiControllers = {}; 138 | // if (this.forceDraft) 139 | // this.saveEffectToStorage(this.getCustomOptions(), false); 140 | } 141 | saveIds(type, ids) { 142 | const key = type + "Ids"; 143 | 144 | localStorage.setItem(key, JSON.stringify(ids)); 145 | } 146 | getIds(type) { 147 | const key = type + "Ids"; 148 | let ids = JSON.parse(localStorage.getItem(key)); 149 | if (!Array.isArray(ids)) { 150 | ids = []; 151 | localStorage.setItem(key, JSON.stringify(ids)); 152 | } 153 | return ids; 154 | } 155 | updateDynamicItem(name, type, data) { 156 | const folder = this.guiControllers["dynamicFolder-" + name]; 157 | if (!folder) return; 158 | 159 | folder.setData(type, data); 160 | this.effect.options[name].props = folder.getData(); 161 | } 162 | createIDListOptions() { 163 | const withPrefix = prefix => (res, id, i) => { 164 | res[prefix + "-" + i] = id; 165 | return res; 166 | }; 167 | const drafts = this.storageEffects.idList.drafts.reduce( 168 | withPrefix("drafts"), 169 | {} 170 | ); 171 | 172 | const saved = this.storageEffects.idList.saved.reduce( 173 | withPrefix("saved"), 174 | {} 175 | ); 176 | return Object.assign( 177 | { 178 | default: null 179 | }, 180 | drafts, 181 | saved 182 | ); 183 | } 184 | onEffectIdGUIFinishChange(id) { 185 | if (!this.forceDraft && (id == null || id == "null")) { 186 | this.effect.setOptions(this.defaultOptions); 187 | } else { 188 | const effect = this.getStorageEffect(id); 189 | this.effect.setOptions(effect); 190 | } 191 | 192 | const dynamicItems = ["activation", "transformation", "timing"]; 193 | dynamicItems.forEach(name => { 194 | const dynamicTypeGUI = this.guiControllers["dynamicType-" + name]; 195 | const dynamicFolder = this.guiControllers["dynamicFolder-" + name]; 196 | dynamicTypeGUI.object = this.effect.options[name]; 197 | dynamicTypeGUI.updateDisplay(); 198 | dynamicFolder.setData( 199 | this.effect.options[name].type, 200 | this.effect.options[name].props 201 | ); 202 | 203 | this.effect.options[name].props = dynamicFolder.getData(); 204 | }); 205 | const controllers = ["duration", "seed", "randomizeSeed"]; 206 | controllers.forEach(name => { 207 | const controller = this.guiControllers[name]; 208 | controller.updateDisplay(); 209 | }); 210 | const toGridEasingMeta = this.easingLookup.get( 211 | this.effect.options.easings.toGrid 212 | ); 213 | const toFullEasingMeta = this.easingLookup.get( 214 | this.effect.options.easings.toFullscreen 215 | ); 216 | this.toGridEase.name = toGridEasingMeta.name; 217 | this.toGridEase.type = toGridEasingMeta.type; 218 | this.toFullEase.name = toFullEasingMeta.name; 219 | this.toFullEase.type = toFullEasingMeta.type; 220 | [ 221 | "toGridEaseName", 222 | "toGridEaseType", 223 | "toFullEaseName", 224 | "toFullEaseType" 225 | ].forEach(k => { 226 | const controller = this.guiControllers[k]; 227 | controller.updateDisplay(); 228 | }); 229 | 230 | let toGridEaseTypes = this.easings.get(toGridEasingMeta.name); 231 | this.setControllerOptions( 232 | this.guiControllers["toGridEaseType"], 233 | toGridEaseTypes, 234 | true 235 | ); 236 | let toFullEaseTypes = this.easings.get(toFullEasingMeta.name); 237 | this.setControllerOptions( 238 | this.guiControllers["toFullEaseType"], 239 | toFullEaseTypes, 240 | true 241 | ); 242 | 243 | this.saveSettingsToURL(); 244 | } 245 | onIDListUpdate() { 246 | this.effectSelectGUI = this.effectSelectGUI 247 | .options(this.createIDListOptions()) 248 | .onFinishChange(this.onEffectIdGUIFinishChange); 249 | this.effectSelectGUI.updateDisplay(); 250 | } 251 | saveEffectToStorage(data, hardSave) { 252 | if (!data) return; 253 | let initialID = this.effectID; 254 | let id = this.effectID; 255 | // If the effect it's the default save it as a draft or saved 256 | if (id == null || id == "null") { 257 | id = Math.random() 258 | .toString(36) 259 | .substring(7); 260 | if (hardSave) { 261 | id = "saved-" + id; 262 | this.storageEffects.idList.saved.push(id); 263 | this.saveIds("saved", this.storageEffects.idList.saved); 264 | } else { 265 | id = "draft-" + id; 266 | this.storageEffects.idList.drafts.unshift(id); 267 | if (this.storageEffects.idList.drafts.length > 5) { 268 | this.storageEffects.idList.drafts.pop(); 269 | } 270 | this.saveIds("drafts", this.storageEffects.idList.drafts); 271 | } 272 | this.effectID = id; 273 | } 274 | // If this effect is a draft, and you are hard saving. 275 | // Delete the draft and generate new ID 276 | const draftIndex = this.storageEffects.idList.drafts.indexOf(id); 277 | if (hardSave && draftIndex > -1) { 278 | // Delete from local memory and storage 279 | delete this.storageEffects.retrieved[id]; 280 | localStorage.setItem(id, null); 281 | // Remove from index list 282 | this.storageEffects.idList.drafts.splice(draftIndex, 1); 283 | this.saveIds("drafts", this.storageEffects.idList.drafts); 284 | 285 | // Create new savedId 286 | id = 287 | "saved-" + 288 | Math.random() 289 | .toString(36) 290 | .substring(7); 291 | 292 | this.storageEffects.idList.saved.push(id); 293 | this.saveIds("saved", this.storageEffects.idList.saved); 294 | 295 | this.effectID = id; 296 | } 297 | // Same to memory and storage 298 | this.storageEffects.retrieved[id] = data; 299 | localStorage.setItem(id, JSON.stringify(data)); 300 | 301 | if (initialID !== this.effectID) { 302 | this.onIDListUpdate(); 303 | } 304 | 305 | return [id, data]; 306 | } 307 | getStorageEffect(id) { 308 | const effectInMemory = this.storageEffects.retrieved[id]; 309 | if (effectInMemory == null) { 310 | return JSON.parse(localStorage.getItem(id)); 311 | } 312 | return effectInMemory; 313 | } 314 | init() { 315 | this.effect.init(); 316 | this.effect.forceInitializePlane(0); 317 | const gui = new dat.GUI(); 318 | this.gui = gui; 319 | this.initialized = true; 320 | 321 | const effect = this.effect; 322 | const options = effect.options; 323 | 324 | this.effectSelectGUI = gui 325 | .add(this, "effectID", this.createIDListOptions()) 326 | .onFinishChange(this.onEffectIdGUIFinishChange) 327 | .name("Preset"); 328 | const progressGUI = gui 329 | .add(effect.uniforms.uProgress, "value", 0, 1, 0.025) 330 | .name("Progress") 331 | .onChange(progress => { 332 | if (effect.tween) { 333 | effect.tween.kill(); 334 | effect.tween = null; 335 | } 336 | if (this.onProgressChange) 337 | this.onProgressChange({ index: effect.currentImageIndex, progress }); 338 | if (progress > 0) { 339 | effect.itemsWrapper.style.zIndex = 0; 340 | effect.container.style.zIndex = 2; 341 | } else { 342 | effect.itemsWrapper.style.zIndex = 0; 343 | effect.container.style.zIndex = 0; 344 | } 345 | const isFullscreen = progress > 0.5; 346 | effect.isFullscreen = isFullscreen; 347 | effect.isAnimating = false; 348 | effect.render(); 349 | }); 350 | 351 | effect.options.onProgressTween = function(progress) { 352 | progressGUI.updateDisplay(); 353 | }; 354 | this.guiControllers["duration"] = gui 355 | .add(options, "duration", 0.5, 5, 0.25) 356 | .name("Duration") 357 | .onFinishChange(() => { 358 | this.onItemFinishChange(); 359 | }); 360 | 361 | // Easings 362 | 363 | const easingFolder = gui.addFolder("Easings"); 364 | 365 | const easingsList = Array.from(this.easings.keys()).sort((a, b) => { 366 | if (a.name < b.name) return -1; 367 | if (a.name > b.name) return 1; 368 | return 0; 369 | }); 370 | 371 | const toGridEasingMeta = this.easingLookup.get(options.easings.toGrid); 372 | const toFullEasingMeta = this.easingLookup.get( 373 | options.easings.toFullscreen 374 | ); 375 | 376 | this.toGridEase = { 377 | name: toGridEasingMeta.name, 378 | type: toGridEasingMeta.type 379 | }; 380 | this.toFullEase = { 381 | name: toFullEasingMeta.name, 382 | type: toFullEasingMeta.type 383 | }; 384 | 385 | this.guiControllers["toGridEaseName"] = easingFolder 386 | .add(this.toGridEase, "name", easingsList) 387 | .name("To-Grid easing") 388 | .onFinishChange(name => { 389 | let easeTypes = this.easings.get(name); 390 | this.setControllerOptions( 391 | this.guiControllers["toGridEaseType"], 392 | easeTypes 393 | ); 394 | const easingFunction = 395 | window.com.greensock.easing[name][this.toGridEase.type]; 396 | options.easings.toGrid = easingFunction; 397 | this.onItemFinishChange(); 398 | }); 399 | 400 | this.guiControllers["toGridEaseType"] = easingFolder 401 | .add(this.toGridEase, "type", this.easings.get(toGridEasingMeta.name)) 402 | .name("To-Grid type") 403 | .onFinishChange(type => { 404 | const easingFunction = 405 | window.com.greensock.easing[this.toGridEase.name][type]; 406 | options.easings.toGrid = easingFunction; 407 | this.onItemFinishChange(); 408 | }); 409 | 410 | this.guiControllers["toFullEaseName"] = easingFolder 411 | .add(this.toFullEase, "name", easingsList) 412 | .name("To-Full easing") 413 | .onFinishChange(name => { 414 | let easeTypes = this.easings.get(name); 415 | this.setControllerOptions( 416 | this.guiControllers["toFullEaseType"], 417 | easeTypes 418 | ); 419 | 420 | const easingFunction = 421 | window.com.greensock.easing[name][this.toFullEase.type]; 422 | options.easings.toFullscreen = easingFunction; 423 | this.onItemFinishChange(); 424 | }); 425 | 426 | this.guiControllers["toFullEaseType"] = easingFolder 427 | .add(this.toFullEase, "type", this.easings.get(toGridEasingMeta.name)) 428 | .name("To-Full type") 429 | .onFinishChange(type => { 430 | const easingFunction = 431 | window.com.greensock.easing[this.toFullEase.name][type]; 432 | options.easings.toFullscreen = easingFunction; 433 | this.onItemFinishChange(); 434 | }); 435 | 436 | // Timing 437 | // Fill all timings with empty options as default. 438 | const timingTypes = Object.keys(timings); 439 | const timingFolderItems = new Map( 440 | timingTypes 441 | .map(type => [type, new Map([])]) 442 | .concat([ 443 | [ 444 | "sameEnd", 445 | new Map([ 446 | [ 447 | "latestStart", 448 | { 449 | initialValue: 0.5, 450 | onAdd: [0, 1, 0.05], 451 | onController: new Map([ 452 | ["onFinishChange", this.onItemFinishChangeReset] 453 | ]) 454 | } 455 | ], 456 | [ 457 | "reverse", 458 | { 459 | initialValue: false, 460 | onAdd: [], 461 | onController: new Map([ 462 | ["name", "SyncStart"], 463 | ["onFinishChange", this.onItemFinishChangeReset] 464 | ]) 465 | } 466 | ] 467 | ]) 468 | ], 469 | [ 470 | "sections", 471 | new Map([ 472 | [ 473 | "sections", 474 | { 475 | initialValue: 1, 476 | onAdd: [1, 10, 1], 477 | onController: new Map([ 478 | ["onFinishChange", this.onItemFinishChangeReset] 479 | ]) 480 | } 481 | ] 482 | ]) 483 | ] 484 | ]) 485 | ); 486 | this.timingFolderItems = timingFolderItems; 487 | 488 | const timingFolder = this.createDynamicFolder( 489 | "timing", 490 | timingFolderItems, 491 | options.timing 492 | ); 493 | timingFolder.mount(gui); 494 | 495 | const activationTypes = Object.keys(activations); 496 | const activationFolderItems = new Map( 497 | activationTypes 498 | .map(k => [k, new Map([])]) 499 | .concat([ 500 | [ 501 | "snake", 502 | new Map([ 503 | [ 504 | "rows", 505 | { 506 | initialValue: 4, 507 | onAdd: [2, 7, 1], 508 | onController: new Map([ 509 | ["onFinishChange", this.onItemFinishChangeReset] 510 | ]) 511 | } 512 | ] 513 | ]) 514 | ], 515 | [ 516 | "squares", 517 | new Map([ 518 | [ 519 | "size", 520 | { 521 | initialValue: 4, 522 | onAdd: [2, 10, 1], 523 | onController: new Map([ 524 | ["onFinishChange", this.onItemFinishChangeReset] 525 | ]) 526 | } 527 | ] 528 | ]) 529 | ], 530 | [ 531 | "corners", 532 | new Map([ 533 | [ 534 | "topLeft", 535 | { 536 | initialValue: false, 537 | onController: new Map([ 538 | ["onFinishChange", this.onItemFinishChangeReset] 539 | ]) 540 | } 541 | ], 542 | [ 543 | "bottomLeft", 544 | { 545 | initialValue: false, 546 | onController: new Map([ 547 | ["onFinishChange", this.onItemFinishChangeReset] 548 | ]) 549 | } 550 | ], 551 | [ 552 | "topRight", 553 | { 554 | initialValue: false, 555 | onController: new Map([ 556 | ["onFinishChange", this.onItemFinishChangeReset] 557 | ]) 558 | } 559 | ], 560 | [ 561 | "bottomRight", 562 | { 563 | initialValue: false, 564 | onController: new Map([ 565 | ["onFinishChange", this.onItemFinishChangeReset] 566 | ]) 567 | } 568 | ] 569 | ]) 570 | ], 571 | [ 572 | "radial", 573 | new Map([ 574 | [ 575 | "onMouse", 576 | { 577 | initialValue: false, 578 | onController: new Map([ 579 | ["onFinishChange", this.onItemFinishChangeReset] 580 | ]) 581 | } 582 | ], 583 | [ 584 | "x", 585 | { 586 | initialValue: 0.5, 587 | onAdd: [0, 1, 0.05], 588 | onController: new Map([ 589 | ["onFinishChange", this.onItemFinishChangeReset] 590 | ]) 591 | } 592 | ], 593 | [ 594 | "y", 595 | { 596 | initialValue: 0.5, 597 | onAdd: [0, 1, 0.05], 598 | onController: new Map([ 599 | ["onFinishChange", this.onItemFinishChangeReset] 600 | ]) 601 | } 602 | ] 603 | ]) 604 | ], 605 | [ 606 | "side", 607 | new Map([ 608 | [ 609 | "top", 610 | { 611 | initialValue: false, 612 | onController: new Map([ 613 | ["onFinishChange", this.onItemFinishChangeReset] 614 | ]) 615 | } 616 | ], 617 | [ 618 | "left", 619 | { 620 | initialValue: false, 621 | onController: new Map([ 622 | ["onFinishChange", this.onItemFinishChangeReset] 623 | ]) 624 | } 625 | ], 626 | [ 627 | "bottom", 628 | { 629 | initialValue: false, 630 | onController: new Map([ 631 | ["onFinishChange", this.onItemFinishChangeReset] 632 | ]) 633 | } 634 | ], 635 | [ 636 | "right", 637 | { 638 | initialValue: false, 639 | onController: new Map([ 640 | ["onFinishChange", this.onItemFinishChangeReset] 641 | ]) 642 | } 643 | ] 644 | ]) 645 | ], 646 | [ 647 | "sin", 648 | new Map([ 649 | [ 650 | "x", 651 | { 652 | initialValue: false, 653 | onController: new Map([ 654 | ["onFinishChange", this.onItemFinishChangeReset] 655 | ]) 656 | } 657 | ], 658 | [ 659 | "frequencyX", 660 | { 661 | initialValue: 2, 662 | onAdd: [1, 8, 0.2], 663 | onController: new Map([ 664 | ["onFinishChange", this.onItemFinishChangeReset] 665 | ]) 666 | } 667 | ], 668 | [ 669 | "piOffsetX", 670 | { 671 | initialValue: 0.5, 672 | onAdd: [0, 2, 0.25], 673 | onController: new Map([ 674 | ["onFinishChange", this.onItemFinishChangeReset] 675 | ]) 676 | } 677 | ], 678 | [ 679 | "y", 680 | { 681 | initialValue: false, 682 | onController: new Map([ 683 | ["onFinishChange", this.onItemFinishChangeReset] 684 | ]) 685 | } 686 | ], 687 | [ 688 | "frequencyY", 689 | { 690 | initialValue: 2, 691 | onAdd: [1, 8, 0.2], 692 | onController: new Map([ 693 | ["onFinishChange", this.onItemFinishChangeReset] 694 | ]) 695 | } 696 | ], 697 | [ 698 | "piOffsetY", 699 | { 700 | initialValue: 0.5, 701 | onAdd: [0, 2, 0.25], 702 | onController: new Map([ 703 | ["onFinishChange", this.onItemFinishChangeReset] 704 | ]) 705 | } 706 | ], 707 | [ 708 | "joinWith", 709 | { 710 | initialValue: "multiplication", 711 | onAdd: [["sum", "multiplication", "min", "max"]], 712 | onController: new Map([ 713 | ["onFinishChange", this.onItemFinishChangeReset] 714 | ]) 715 | } 716 | ] 717 | ]) 718 | ] 719 | ]) 720 | ); 721 | this.activationFolderItems = activationFolderItems; 722 | 723 | const activationFolder = this.createDynamicFolder( 724 | "activation", 725 | activationFolderItems, 726 | options.activation, 727 | { 728 | onFinishTypeChange: (type, folder) => { 729 | const props = folder.getData(); 730 | 731 | // If its empty set an option to true as default. 732 | // We don't want to set initial value so it's not skiped 733 | switch (type) { 734 | case "side": 735 | if (!props.top && !props.bottom && !props.left && !props.right) { 736 | folder.controllers["top"].setValue(true); 737 | } 738 | break; 739 | case "corners": 740 | if ( 741 | !props.topLeft && 742 | !props.bottomLeft && 743 | !props.bottomLeft && 744 | !props.topRight 745 | ) { 746 | folder.controllers["topLeft"].setValue(true); 747 | } 748 | break; 749 | case "sin": 750 | break; 751 | } 752 | } 753 | } 754 | ); 755 | gui 756 | .add(options.debug, "activation") 757 | .name("Debug Activation") 758 | .onFinishChange(value => { 759 | effect.uniforms.uDebugActivation.value = value; 760 | effect.render(); 761 | this.onItemFinishChange(); 762 | }); 763 | 764 | activationFolder.mount(gui); 765 | 766 | const transformTypes = Object.keys(transformations); 767 | const transformFolderItems = new Map( 768 | transformTypes 769 | .map(k => [k, new Map([])]) 770 | .concat([ 771 | [ 772 | "rotation", 773 | new Map([ 774 | [ 775 | "unify", 776 | { 777 | initialValue: false, 778 | onController: new Map([ 779 | ["onFinishChange", this.onItemFinishChangeReset] 780 | ]) 781 | } 782 | ], 783 | [ 784 | "angle", 785 | { 786 | initialValue: 180, 787 | onAdd: [90, 720, 90], 788 | onController: new Map([ 789 | ["onFinishChange", this.onItemFinishChangeReset] 790 | ]) 791 | } 792 | ] 793 | ]) 794 | ], 795 | [ 796 | "fluid", 797 | new Map([ 798 | [ 799 | "amplitude", 800 | { 801 | initialValue: 0.3, 802 | onAdd: [0, 2, 0.1], 803 | onController: new Map([ 804 | ["onFinishChange", this.onItemFinishChangeReset] 805 | ]) 806 | } 807 | ], 808 | [ 809 | "frequency", 810 | { 811 | initialValue: 1, 812 | onAdd: [0.5, 4, 0.2], 813 | onController: new Map([ 814 | ["onFinishChange", this.onItemFinishChangeReset] 815 | ]) 816 | } 817 | ], 818 | [ 819 | "onMouse", 820 | { 821 | initialValue: false, 822 | onController: new Map([ 823 | ["onFinishChange", this.onItemFinishChangeReset] 824 | ]) 825 | } 826 | ], 827 | [ 828 | "x", 829 | { 830 | initialValue: 0.5, 831 | onAdd: [0, 1, 0.1], 832 | onController: new Map([ 833 | ["onFinishChange", this.onItemFinishChangeReset] 834 | ]) 835 | } 836 | ], 837 | [ 838 | "y", 839 | { 840 | initialValue: 0.5, 841 | onAdd: [0, 1, 0.1], 842 | onController: new Map([ 843 | ["onFinishChange", this.onItemFinishChangeReset] 844 | ]) 845 | } 846 | ], 847 | [ 848 | "progressLimit", 849 | { 850 | initialValue: 0.5, 851 | onAdd: [0, 1, 0.05], 852 | onController: new Map([ 853 | ["onFinishChange", this.onItemFinishChangeReset] 854 | ]) 855 | } 856 | ] 857 | ]) 858 | ], 859 | [ 860 | "wavy", 861 | new Map([ 862 | [ 863 | "amplitude", 864 | { 865 | initialValue: 0.4, 866 | onAdd: [0, 3, 0.2], 867 | onController: new Map([ 868 | ["onFinishChange", this.onItemFinishChangeReset] 869 | ]) 870 | } 871 | ], 872 | [ 873 | "frequency", 874 | { 875 | initialValue: 4, 876 | onAdd: [1, 10, 0.2], 877 | onController: new Map([ 878 | ["onFinishChange", this.onItemFinishChangeReset] 879 | ]) 880 | } 881 | ] 882 | ]) 883 | ], 884 | [ 885 | "simplex", 886 | new Map([ 887 | [ 888 | "amplitudeX", 889 | { 890 | initialValue: 0.2, 891 | onAdd: [0, 3, 0.2], 892 | onController: new Map([ 893 | ["onFinishChange", this.onItemFinishChangeReset] 894 | ]) 895 | } 896 | ], 897 | [ 898 | "amplitudeY", 899 | { 900 | initialValue: 0.2, 901 | onAdd: [0, 3, 0.2], 902 | onController: new Map([ 903 | ["onFinishChange", this.onItemFinishChangeReset] 904 | ]) 905 | } 906 | ], 907 | [ 908 | "frequencyX", 909 | { 910 | initialValue: 0.3, 911 | onAdd: [0, 4, 0.2], 912 | onController: new Map([ 913 | ["onFinishChange", this.onItemFinishChangeReset] 914 | ]) 915 | } 916 | ], 917 | [ 918 | "frequencyY", 919 | { 920 | initialValue: 0.3, 921 | onAdd: [0, 4, 0.2], 922 | onController: new Map([ 923 | ["onFinishChange", this.onItemFinishChangeReset] 924 | ]) 925 | } 926 | ], 927 | [ 928 | "progressLimit", 929 | { 930 | initialValue: 0.5, 931 | onAdd: [0, 1, 0.05], 932 | onController: new Map([ 933 | ["onFinishChange", this.onItemFinishChangeReset] 934 | ]) 935 | } 936 | ] 937 | ]) 938 | ], 939 | [ 940 | "flipX", 941 | new Map([ 942 | [ 943 | "beizerC0x", 944 | { 945 | initialValue: 0.5, 946 | onAdd: [-1, 2, 0.1], 947 | onController: new Map([ 948 | ["onFinishChange", this.onItemFinishChangeReset] 949 | ]) 950 | } 951 | ], 952 | [ 953 | "beizerC0y", 954 | { 955 | initialValue: 0.5, 956 | onAdd: [-1, 2, 0.1], 957 | onController: new Map([ 958 | ["onFinishChange", this.onItemFinishChangeReset] 959 | ]) 960 | } 961 | ], 962 | [ 963 | "beizerC1x", 964 | { 965 | initialValue: 0.5, 966 | onAdd: [-1, 2, 0.1], 967 | onController: new Map([ 968 | ["onFinishChange", this.onItemFinishChangeReset] 969 | ]) 970 | } 971 | ], 972 | [ 973 | "beizerC1y", 974 | { 975 | initialValue: 0.5, 976 | onAdd: [-1, 2, 0.1], 977 | onController: new Map([ 978 | ["onFinishChange", this.onItemFinishChangeReset] 979 | ]) 980 | } 981 | ] 982 | ]) 983 | ] 984 | ]) 985 | ); 986 | this.transformFolderItems = transformFolderItems; 987 | 988 | const transformationFolder = this.createDynamicFolder( 989 | "transformation", 990 | transformFolderItems, 991 | options.transformation 992 | ); 993 | transformationFolder.mount(gui); 994 | 995 | this.guiControllers["seed"] = gui 996 | .add(options, "seed") 997 | .onFinishChange(seed => { 998 | effect.uniforms.uSeed.value = seed; 999 | this.onItemFinishChange(); 1000 | }) 1001 | .name("Seed"); 1002 | this.guiControllers["randomizeSeed"] = gui 1003 | .add(options, "randomizeSeed", { 1004 | nope: null, 1005 | itemUnique: "itemUnique", 1006 | inOutUnique: "inOutUnique", 1007 | tweenUnique: "tweenUnique" 1008 | }) 1009 | .onFinishChange(() => { 1010 | this.onItemFinishChange(); 1011 | }) 1012 | .name("Randomize seed"); 1013 | gui.add(this, "onSaveClick").name("Save as preset"); 1014 | gui.add(this, "copyOptions").name("Copy to clipboard"); 1015 | 1016 | if (this.forceDraft) { 1017 | this.forceDraft = false; 1018 | this.saveEffectToStorage(this.getCustomOptions(), false); 1019 | } 1020 | this.saveSettingsToURL(); 1021 | } 1022 | onSaveClick() { 1023 | const saved = this.saveEffectToStorage(this.getCustomOptions(), true); 1024 | } 1025 | createDynamicFolder(name, dynamicControllerData, item, options) { 1026 | const folder = new DynamicFolder( 1027 | name + " Options", 1028 | dynamicControllerData, 1029 | item.type, 1030 | item.props 1031 | ); 1032 | this.guiControllers["dynamicFolder-" + name] = folder; 1033 | 1034 | this.guiControllers["dynamicType-" + name] = this.gui 1035 | .add(item, "type", Array.from(dynamicControllerData.keys())) 1036 | .name(name) 1037 | .onFinishChange(type => { 1038 | this.updateDynamicItem(name, type, null); 1039 | if (options && options.onFinishTypeChange) { 1040 | options.onFinishTypeChange(type, folder); 1041 | } 1042 | this.onItemFinishChangeReset(); 1043 | }); 1044 | 1045 | this.effect.options[name].props = folder.getData(); 1046 | 1047 | return folder; 1048 | } 1049 | getQueryOptionsOrLastValidDraft(options) { 1050 | // Check if there are URL settings 1051 | let replacementSettings = this.getURLQuerySettings(); 1052 | 1053 | if ( 1054 | replacementSettings != null && 1055 | !( 1056 | Object.keys(replacementSettings).length === 1 && 1057 | replacementSettings.default 1058 | ) 1059 | ) { 1060 | let validOptions = [ 1061 | "activation", 1062 | "timing", 1063 | "transformation", 1064 | 1065 | "duration", 1066 | "easings", 1067 | "seed", 1068 | "randomizeSeed" 1069 | ]; 1070 | const givenOptions = {}; 1071 | validOptions.forEach(key => { 1072 | // We have to delete it in case the given settings have anything there. 1073 | // If there are saved settings, but a given option is not given. Default it. 1074 | delete options[key]; 1075 | options[key] = replacementSettings[key]; 1076 | }); 1077 | 1078 | this.forceDraft = true; 1079 | } 1080 | 1081 | return options; 1082 | } 1083 | onItemFinishChangeReset(a) { 1084 | this.effect.reset(); 1085 | this.onItemFinishChange(); 1086 | } 1087 | onItemFinishChange() { 1088 | this.saveEffectToStorage(this.getCustomOptions(), false); 1089 | 1090 | this.saveSettingsToURL(); 1091 | } 1092 | settingsToURLQuery(settings) { 1093 | if (this.effectID == null || this.effectID == "null") { 1094 | return "default=true"; 1095 | } 1096 | let params = []; 1097 | const rawItems = ["duration", "seed", "randomizeSeed"]; 1098 | 1099 | rawItems.forEach(key => { 1100 | if (settings[key]) { 1101 | let value = settings[key]; 1102 | if (typeof value === "number") { 1103 | value = value.toFixed(2).replace(/^0|(\.[0-9](0)+)$|(0)+$/g, ""); 1104 | } 1105 | params.push(encode(key, settings[key])); 1106 | } 1107 | }); 1108 | 1109 | if (settings.easings) { 1110 | if (settings.easings.toFullscreen) { 1111 | params.push(encode("toFull", settings.easings.toFullscreen)); 1112 | } 1113 | if (settings.easings.toGrid) { 1114 | params.push(encode("toGrid", settings.easings.toGrid)); 1115 | } 1116 | } 1117 | const withTypesAndProps = ["timing", "transformation", "activation"]; 1118 | 1119 | withTypesAndProps.forEach(key => { 1120 | const item = settings[key]; 1121 | if (!item) return; 1122 | let itemParams = [null]; 1123 | 1124 | if (item.type) { 1125 | // params.push(encode(key, item.type)); 1126 | itemParams[0] = encodeURIComponent(item.type); 1127 | } 1128 | if (item.props) { 1129 | const keys = Object.keys(item.props); 1130 | 1131 | const propParams = keys.map(key => { 1132 | let propValue = item.props[key]; 1133 | 1134 | if (typeof propValue === "number") { 1135 | propValue = propValue 1136 | .toFixed(2) 1137 | .replace(/^0|(\.[0-9](0)+)$|(0)+$/g, ""); 1138 | } 1139 | return encodeURIComponent(key) + "," + encodeURIComponent(propValue); 1140 | }); 1141 | itemParams = itemParams.concat(propParams); 1142 | } 1143 | params.push(encode(key, itemParams)); 1144 | }); 1145 | 1146 | return params.join("&"); 1147 | } 1148 | saveSettingsToURL() { 1149 | const URLQuery = this.settingsToURLQuery(this.getCustomOptions()); 1150 | window.history.replaceState({}, document.title, "?" + URLQuery); 1151 | } 1152 | getURLQuerySettings() { 1153 | const queries = window.location.href.split("?")[1]; 1154 | if (!queries) return; 1155 | const queriesArray = queries.split("&").map(queryString => { 1156 | queryString = decodeURIComponent(queryString); 1157 | const equals = queryString.indexOf("="); 1158 | return [ 1159 | queryString.substring(0, equals), 1160 | queryString.substring(equals + 1) 1161 | ]; 1162 | }); 1163 | const settings = queriesArray.reduce((res, param) => { 1164 | const key = param[0]; 1165 | const value = param[1]; 1166 | 1167 | switch (key) { 1168 | case "timing": 1169 | case "transformation": 1170 | case "activation": 1171 | const item = {}; 1172 | // [type, propKey1, propValue1, ... propKeyN, propValueN ] 1173 | const valueArray = value.split(","); 1174 | const type = valueArray[0]; 1175 | if (type.length > 0) { 1176 | item.type = type; 1177 | } 1178 | const propsArray = valueArray.slice(1); 1179 | if (propsArray.length > 0) { 1180 | const props = {}; 1181 | 1182 | for (let i = 0; i < propsArray.length; i += 2) { 1183 | const propKey = propsArray[i]; 1184 | let propValue = propsArray[i + 1]; 1185 | // Convert to number if it's number 1186 | if (propValue.length > 0 && !isNaN(propValue * 1)) 1187 | propValue = propValue * 1; 1188 | else if (propValue === "true" || propValue === "false") 1189 | propValue = propValue === "true"; 1190 | 1191 | props[propKey] = propValue; 1192 | } 1193 | item.props = props; 1194 | } 1195 | 1196 | res[key] = item; 1197 | break; 1198 | case "duration": 1199 | case "seed": 1200 | res[key] = Number(value); 1201 | break; 1202 | case "randomizeSeed": 1203 | res[key] = value; 1204 | break; 1205 | case "toFull": 1206 | case "toGrid": 1207 | if (!res.easings) { 1208 | res.easings = {}; 1209 | } 1210 | if (key === "toFull") { 1211 | res.easings.toFullscreen = value; 1212 | } else { 1213 | res.easings.toGrid = value; 1214 | } 1215 | break; 1216 | case "default": 1217 | res.default = value; 1218 | break; 1219 | default: 1220 | break; 1221 | } 1222 | return res; 1223 | }, {}); 1224 | if (Object.keys(settings).length === 0) { 1225 | return null; 1226 | } 1227 | return settings; 1228 | } 1229 | omitDataWithDefaultValues(data) { 1230 | const newData = {}; 1231 | 1232 | const items = [ 1233 | ["timing", { type: "sameEnd", props: this.timingFolderItems }], 1234 | ["activation", { type: "corners", props: this.activationFolderItems }], 1235 | ["transformation", { type: "none", props: this.transformFolderItems }] 1236 | ]; 1237 | // Copy values if they are not default ones 1238 | items.forEach(arr => { 1239 | const key = arr[0]; 1240 | const item = data[key]; 1241 | const newItem = {}; 1242 | 1243 | if (item.type !== arr[1].type) { 1244 | newItem.type = item.type; 1245 | } 1246 | if (item.props) { 1247 | const defaultProps = arr[1].props.get(item.type); 1248 | const newProps = {}; 1249 | defaultProps.forEach((propInfo, propKey) => { 1250 | const prop = item.props[propKey]; 1251 | if (prop != null && propInfo.initialValue !== item.props[propKey]) { 1252 | newProps[propKey] = item.props[propKey]; 1253 | } 1254 | }); 1255 | 1256 | if (Object.keys(newProps).length > 0) { 1257 | newItem.props = newProps; 1258 | } 1259 | } 1260 | if (Object.keys(newItem).length > 0) { 1261 | newData[key] = newItem; 1262 | } 1263 | }); 1264 | return newData; 1265 | } 1266 | getCustomOptions() { 1267 | // Everything breaks if you delete data from the original object. 1268 | // Instead, do it as an additive process; 1269 | const options = this.effect.options; 1270 | // [key, value] to delete if match 1271 | // ['timing', this.timingFolderItems] 1272 | 1273 | const newOptions = this.omitDataWithDefaultValues(options); 1274 | 1275 | const itemsDefault = [ 1276 | ["duration", 1], 1277 | ["randomizeSeed", null], 1278 | ["seed", 0] 1279 | ]; 1280 | itemsDefault.forEach(item => { 1281 | if (Array.isArray(item)) { 1282 | if (options[item[0]] !== item[1]) { 1283 | newOptions[item[0]] = options[item[0]]; 1284 | } 1285 | } 1286 | }); 1287 | newOptions.easings = {}; 1288 | 1289 | if ( 1290 | this.toFullEase.name !== "Linear" && 1291 | this.toFullEase.name !== "Power0" 1292 | ) { 1293 | newOptions.easings.toFullscreen = `${this.toFullEase.name}.${this.toFullEase.type}`; 1294 | } 1295 | if ( 1296 | this.toGridEase.name !== "Linear" && 1297 | this.toGridEase.name !== "Power0" 1298 | ) { 1299 | newOptions.easings.toGrid = `${this.toGridEase.name}.${this.toGridEase.type}`; 1300 | } 1301 | if (Object.keys(newOptions.easings).length === 0) { 1302 | delete newOptions.easings; 1303 | } 1304 | 1305 | return newOptions; 1306 | } 1307 | copyOptions() { 1308 | const customOptions = this.getCustomOptions(); 1309 | 1310 | copyTextToClipboard(JSON.stringify(customOptions)); 1311 | } 1312 | setControllerOptions(controller, options, force) { 1313 | const select = controller.__select; 1314 | while (select.firstChild) { 1315 | select.removeChild(select.firstChild); 1316 | } 1317 | if (options.length === 0) return; 1318 | 1319 | options.forEach(type => { 1320 | const opt = document.createElement("option"); 1321 | opt.innerHTML = type; 1322 | opt.setAttribute("value", type); 1323 | select.appendChild(opt); 1324 | }); 1325 | let value = controller.getValue(); 1326 | const valueIsAnOption = options.indexOf(value) > -1; 1327 | if (force) { 1328 | if (!valueIsAnOption) { 1329 | controller.object[controller.property] = options[0]; 1330 | } 1331 | controller.updateDisplay(); 1332 | } else { 1333 | if (valueIsAnOption) { 1334 | controller.setValue(value); 1335 | } else { 1336 | controller.setValue(options[0]); 1337 | } 1338 | } 1339 | } 1340 | } 1341 | 1342 | function fallbackCopyTextToClipboard(text) { 1343 | var textArea = document.createElement("textarea"); 1344 | textArea.value = text; 1345 | document.body.appendChild(textArea); 1346 | textArea.focus(); 1347 | textArea.select(); 1348 | 1349 | try { 1350 | var successful = document.execCommand("copy"); 1351 | var msg = successful ? "successful" : "unsuccessful"; 1352 | console.log("Fallback: Copying text command was " + msg); 1353 | } catch (err) { 1354 | console.error("Fallback: Oops, unable to copy", err); 1355 | } 1356 | 1357 | document.body.removeChild(textArea); 1358 | } 1359 | function copyTextToClipboard(text) { 1360 | if (!navigator.clipboard) { 1361 | fallbackCopyTextToClipboard(text); 1362 | return; 1363 | } 1364 | navigator.clipboard.writeText(text).then( 1365 | function() { 1366 | console.log("Async: Copying to clipboard was successful!"); 1367 | }, 1368 | function(err) { 1369 | console.error("Async: Could not copy text: ", err); 1370 | } 1371 | ); 1372 | } 1373 | -------------------------------------------------------------------------------- /js/EasePack.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * VERSION: 1.16.0 3 | * DATE: 2018-02-15 4 | * UPDATES AND DOCS AT: http://greensock.com 5 | * 6 | * @license Copyright (c) 2008-2019, GreenSock. All rights reserved. 7 | * This work is subject to the terms at http://greensock.com/standard-license or for 8 | * Club GreenSock members, the software agreement that was issued with your membership. 9 | * 10 | * @author: Jack Doyle, jack@greensock.com 11 | **/ 12 | var _gsScope="undefined"!=typeof module&&module.exports&&"undefined"!=typeof global?global:this||window;(_gsScope._gsQueue||(_gsScope._gsQueue=[])).push(function(){"use strict";_gsScope._gsDefine("easing.Back",["easing.Ease"],function(a){var b,c,d,e,f=_gsScope.GreenSockGlobals||_gsScope,g=f.com.greensock,h=2*Math.PI,i=Math.PI/2,j=g._class,k=function(b,c){var d=j("easing."+b,function(){},!0),e=d.prototype=new a;return e.constructor=d,e.getRatio=c,d},l=a.register||function(){},m=function(a,b,c,d,e){var f=j("easing."+a,{easeOut:new b,easeIn:new c,easeInOut:new d},!0);return l(f,a),f},n=function(a,b,c){this.t=a,this.v=b,c&&(this.next=c,c.prev=this,this.c=c.v-b,this.gap=c.t-a)},o=function(b,c){var d=j("easing."+b,function(a){this._p1=a||0===a?a:1.70158,this._p2=1.525*this._p1},!0),e=d.prototype=new a;return e.constructor=d,e.getRatio=c,e.config=function(a){return new d(a)},d},p=m("Back",o("BackOut",function(a){return(a-=1)*a*((this._p1+1)*a+this._p1)+1}),o("BackIn",function(a){return a*a*((this._p1+1)*a-this._p1)}),o("BackInOut",function(a){return(a*=2)<1?.5*a*a*((this._p2+1)*a-this._p2):.5*((a-=2)*a*((this._p2+1)*a+this._p2)+2)})),q=j("easing.SlowMo",function(a,b,c){b=b||0===b?b:.7,null==a?a=.7:a>1&&(a=1),this._p=1!==a?b:0,this._p1=(1-a)/2,this._p2=a,this._p3=this._p1+this._p2,this._calcEnd=c===!0},!0),r=q.prototype=new a;return r.constructor=q,r.getRatio=function(a){var b=a+(.5-a)*this._p;return athis._p3?this._calcEnd?1===a?0:1-(a=(a-this._p3)/this._p1)*a:b+(a-b)*(a=(a-this._p3)/this._p1)*a*a*a:this._calcEnd?1:b},q.ease=new q(.7,.7),r.config=q.config=function(a,b,c){return new q(a,b,c)},b=j("easing.SteppedEase",function(a,b){a=a||1,this._p1=1/a,this._p2=a+(b?0:1),this._p3=b?1:0},!0),r=b.prototype=new a,r.constructor=b,r.getRatio=function(a){return 0>a?a=0:a>=1&&(a=.999999999),((this._p2*a|0)+this._p3)*this._p1},r.config=b.config=function(a,c){return new b(a,c)},c=j("easing.ExpoScaleEase",function(a,b,c){this._p1=Math.log(b/a),this._p2=b-a,this._p3=a,this._ease=c},!0),r=c.prototype=new a,r.constructor=c,r.getRatio=function(a){return this._ease&&(a=this._ease.getRatio(a)),(this._p3*Math.exp(this._p1*a)-this._p3)/this._p2},r.config=c.config=function(a,b,d){return new c(a,b,d)},d=j("easing.RoughEase",function(b){b=b||{};for(var c,d,e,f,g,h,i=b.taper||"none",j=[],k=0,l=0|(b.points||20),m=l,o=b.randomize!==!1,p=b.clamp===!0,q=b.template instanceof a?b.template:null,r="number"==typeof b.strength?.4*b.strength:.4;--m>-1;)c=o?Math.random():1/l*m,d=q?q.getRatio(c):c,"none"===i?e=r:"out"===i?(f=1-c,e=f*f*r):"in"===i?e=c*c*r:.5>c?(f=2*c,e=f*f*.5*r):(f=2*(1-c),e=f*f*.5*r),o?d+=Math.random()*e-.5*e:m%2?d+=.5*e:d-=.5*e,p&&(d>1?d=1:0>d&&(d=0)),j[k++]={x:c,y:d};for(j.sort(function(a,b){return a.x-b.x}),h=new n(1,1,null),m=l;--m>-1;)g=j[m],h=new n(g.x,g.y,h);this._prev=new n(0,0,0!==h.t?h:h.next)},!0),r=d.prototype=new a,r.constructor=d,r.getRatio=function(a){var b=this._prev;if(a>b.t){for(;b.next&&a>=b.t;)b=b.next;b=b.prev}else for(;b.prev&&a<=b.t;)b=b.prev;return this._prev=b,b.v+(a-b.t)/b.gap*b.c},r.config=function(a){return new d(a)},d.ease=new d,m("Bounce",k("BounceOut",function(a){return 1/2.75>a?7.5625*a*a:2/2.75>a?7.5625*(a-=1.5/2.75)*a+.75:2.5/2.75>a?7.5625*(a-=2.25/2.75)*a+.9375:7.5625*(a-=2.625/2.75)*a+.984375}),k("BounceIn",function(a){return(a=1-a)<1/2.75?1-7.5625*a*a:2/2.75>a?1-(7.5625*(a-=1.5/2.75)*a+.75):2.5/2.75>a?1-(7.5625*(a-=2.25/2.75)*a+.9375):1-(7.5625*(a-=2.625/2.75)*a+.984375)}),k("BounceInOut",function(a){var b=.5>a;return a=b?1-2*a:2*a-1,a=1/2.75>a?7.5625*a*a:2/2.75>a?7.5625*(a-=1.5/2.75)*a+.75:2.5/2.75>a?7.5625*(a-=2.25/2.75)*a+.9375:7.5625*(a-=2.625/2.75)*a+.984375,b?.5*(1-a):.5*a+.5})),m("Circ",k("CircOut",function(a){return Math.sqrt(1-(a-=1)*a)}),k("CircIn",function(a){return-(Math.sqrt(1-a*a)-1)}),k("CircInOut",function(a){return(a*=2)<1?-.5*(Math.sqrt(1-a*a)-1):.5*(Math.sqrt(1-(a-=2)*a)+1)})),e=function(b,c,d){var e=j("easing."+b,function(a,b){this._p1=a>=1?a:1,this._p2=(b||d)/(1>a?a:1),this._p3=this._p2/h*(Math.asin(1/this._p1)||0),this._p2=h/this._p2},!0),f=e.prototype=new a;return f.constructor=e,f.getRatio=c,f.config=function(a,b){return new e(a,b)},e},m("Elastic",e("ElasticOut",function(a){return this._p1*Math.pow(2,-10*a)*Math.sin((a-this._p3)*this._p2)+1},.3),e("ElasticIn",function(a){return-(this._p1*Math.pow(2,10*(a-=1))*Math.sin((a-this._p3)*this._p2))},.3),e("ElasticInOut",function(a){return(a*=2)<1?-.5*(this._p1*Math.pow(2,10*(a-=1))*Math.sin((a-this._p3)*this._p2)):this._p1*Math.pow(2,-10*(a-=1))*Math.sin((a-this._p3)*this._p2)*.5+1},.45)),m("Expo",k("ExpoOut",function(a){return 1-Math.pow(2,-10*a)}),k("ExpoIn",function(a){return Math.pow(2,10*(a-1))-.001}),k("ExpoInOut",function(a){return(a*=2)<1?.5*Math.pow(2,10*(a-1)):.5*(2-Math.pow(2,-10*(a-1)))})),m("Sine",k("SineOut",function(a){return Math.sin(a*i)}),k("SineIn",function(a){return-Math.cos(a*i)+1}),k("SineInOut",function(a){return-.5*(Math.cos(Math.PI*a)-1)})),j("easing.EaseLookup",{find:function(b){return a.map[b]}},!0),l(f.SlowMo,"SlowMo","ease,"),l(d,"RoughEase","ease,"),l(b,"SteppedEase","ease,"),p},!0)}),_gsScope._gsDefine&&_gsScope._gsQueue.pop()(),function(){"use strict";var a=function(){return _gsScope.GreenSockGlobals||_gsScope};"undefined"!=typeof module&&module.exports?(require("../TweenLite.min.js"),module.exports=a()):"function"==typeof define&&define.amd&&define(["TweenLite"],a)}(); -------------------------------------------------------------------------------- /js/GridToFullscreenEffect.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A grid items to fullscreen transition 3 | * @module GridToFullscreenEffect 4 | * @author Daniel Velasquez 5 | * @version 1.0.0 6 | */ 7 | 8 | class GridToFullscreenEffect { 9 | /** 10 | Initializes instance variables. 11 | @param {HTMLDivElement} container - Container of the webGL canvas. 12 | @param {HTMLDivElement} itemsWrapper - Container of the grid items. 13 | @param {object} options - A configuration object. 14 | */ 15 | constructor(container, itemsWrapper, options = {}) { 16 | this.container = container; 17 | this.itemsWrapper = itemsWrapper; 18 | 19 | this.initialised = false; 20 | this.camera = null; 21 | this.scene = null; 22 | this.renderer = null; 23 | this.raycaster = new THREE.Raycaster(); 24 | 25 | options.scrollContainer = options.scrollContainer || null; 26 | 27 | // Effect options 28 | options.duration = options.duration || 1; 29 | 30 | // Vertex options 31 | options.timing = options.timing || {}; 32 | options.timing.type = options.timing.type || "sameEnd"; 33 | options.timing.props = options.timing.props || {}; 34 | 35 | options.transformation = options.transformation || {}; 36 | options.transformation.type = options.transformation.type || "none"; 37 | options.transformation.props = options.transformation.props || {}; 38 | 39 | options.activation = options.activation || {}; 40 | options.activation.type = options.activation.type || "corners"; 41 | options.activation.props = options.activation.props || { topLeft: true }; 42 | 43 | options.seed = options.seed || 0; 44 | // "itemUnique" | "InOutUnique" | "tweenUnique" 45 | options.randomizeSeed = options.randomizeSeed || null; 46 | 47 | options.easings = options.easings || {}; 48 | options.easings.toFullscreen = 49 | options.easings.toFullscreen || Power0.easeNone; 50 | if (typeof options.easings.toFullscreen == "string") { 51 | options.easings.toFullscreen = getEaseFromString( 52 | options.easings.toFullscreen 53 | ); 54 | } 55 | options.easings.toGrid = options.easings.toGrid || Power0.easeNone; 56 | if (typeof options.easings.toGrid == "string") { 57 | options.easings.toGrid = getEaseFromString(options.easings.toGrid); 58 | } 59 | options.debug = options.debug || {}; 60 | options.debug.activation = options.debug.activation || false; 61 | 62 | this.uniforms = { 63 | uImage: new THREE.Uniform(null), 64 | uImageRes: new THREE.Uniform(new THREE.Vector2(1, 1)), 65 | uImageLarge: new THREE.Uniform(null), 66 | uImageLargeRes: new THREE.Uniform(new THREE.Vector2(1, 1)), 67 | 68 | // Calculated Uniforms 69 | uProgress: new THREE.Uniform(0), 70 | uMeshScale: new THREE.Uniform(new THREE.Vector2(1, 1)), 71 | uPlaneCenter: new THREE.Uniform(new THREE.Vector2(0, 0)), 72 | uViewSize: new THREE.Uniform(new THREE.Vector2(1, 1)), 73 | uScaleToViewSize: new THREE.Uniform(new THREE.Vector2(1, 1)), 74 | uClosestCorner: new THREE.Uniform(0), 75 | uMouse: new THREE.Uniform(new THREE.Vector2(0, 0)), 76 | 77 | // Option Uniforms 78 | uSeed: new THREE.Uniform(0), 79 | 80 | // Debug Uniforms 81 | uDebugActivation: new THREE.Uniform(false) 82 | }; 83 | this.options = null; 84 | this.setOptions(options, true); 85 | 86 | this.textures = []; 87 | 88 | this.currentImageIndex = -1; 89 | this.isFullscreen = false; 90 | this.isAnimating = false; 91 | 92 | this.onResize = this.onResize.bind(this); 93 | this.reset = this.reset.bind(this); 94 | } 95 | setOptions(partialOptions = {}, override) { 96 | let options = this.options; 97 | 98 | if (override) { 99 | options = partialOptions; 100 | this.options = options; 101 | if (this.initialised) { 102 | this.reset(); 103 | } 104 | return; 105 | } 106 | options.scrollContainer = partialOptions.scrollContainer || null; 107 | 108 | // Effect options 109 | options.duration = partialOptions.duration || 1; 110 | 111 | // Vertex options 112 | options.timing = Object.assign({}, partialOptions.timing); 113 | if (partialOptions.timing) { 114 | options.timing.type = partialOptions.timing.type || "sameEnd"; 115 | options.timing.props = Object.assign({}, partialOptions.timing.props); 116 | } else { 117 | options.timing.type = "sameEnd"; 118 | options.timing.props = {}; 119 | } 120 | 121 | options.transformation = Object.assign({}, partialOptions.transformation); 122 | if (partialOptions.transformation) { 123 | options.transformation.type = 124 | partialOptions.transformation.type || "none"; 125 | options.transformation.props = Object.assign( 126 | {}, 127 | partialOptions.transformation.props 128 | ); 129 | } else { 130 | options.transformation.type = "none"; 131 | options.transformation.props = {}; 132 | } 133 | 134 | options.activation = Object.assign({}, partialOptions.activation); 135 | if (partialOptions.activation) { 136 | options.activation.type = partialOptions.activation.type || "corners"; 137 | options.activation.props = Object.assign( 138 | {}, 139 | partialOptions.activation.props 140 | ); 141 | if ( 142 | options.activation.type === "corners" && 143 | Object.keys(options.activation.props).length === 0 144 | ) { 145 | options.activation.props.topLeft = true; 146 | } 147 | } else { 148 | options.activation.type = "corners"; 149 | options.activation.props = { topLeft: true }; 150 | } 151 | options.seed = partialOptions.seed || 0; 152 | // "itemUnique" | "InOutUnique" | "tweenUnique" 153 | options.randomizeSeed = partialOptions.randomizeSeed || null; 154 | 155 | options.easings = {}; 156 | if (partialOptions.easings) { 157 | options.easings.toFullscreen = 158 | partialOptions.easings.toFullscreen || Power0.easeNone; 159 | if (typeof partialOptions.easings.toFullscreen == "string") { 160 | options.easings.toFullscreen = getEaseFromString( 161 | partialOptions.easings.toFullscreen 162 | ); 163 | } 164 | options.easings.toGrid = partialOptions.easings.toGrid || Power0.easeNone; 165 | if (typeof partialOptions.easings.toGrid == "string") { 166 | options.easings.toGrid = getEaseFromString( 167 | partialOptions.easings.toGrid 168 | ); 169 | } 170 | } else { 171 | options.easings.toFullscreen = Power0.easeNone; 172 | options.easings.toGrid = Power0.easeNone; 173 | } 174 | 175 | options.debug = {}; 176 | if (partialOptions.debug) { 177 | options.debug.activation = partialOptions.debug.activation || false; 178 | } else { 179 | options.debug.activation = false; 180 | } 181 | 182 | this.uniforms.uSeed.value = options.seed; 183 | this.uniforms.uDebugActivation.value = options.debug.activation; 184 | 185 | this.options = options; 186 | if (this.initialised) { 187 | this.reset(); 188 | } 189 | } 190 | /** 191 | An image 192 | @typedef {Object} ImageObject 193 | @property {HTMLImageElement} element - Html element of image 194 | @property {Image} image - Image object 195 | 196 | An set of small and large image 197 | @typedef {Object} ImageSet 198 | @property {ImageObject} small - Small image element 199 | @property {ImageObject} small - Large image element 200 | 201 | */ 202 | /** 203 | Creates the textures for the plane and sets them if needed. 204 | @param {imageSet[]} images - Small and large images of grid items. 205 | */ 206 | createTextures(images) { 207 | const textures = []; 208 | for (let i = 0; i < images.length; i++) { 209 | const imageSet = images[i]; 210 | const largeTexture = new THREE.Texture(imageSet.large.image); 211 | 212 | // So It doesnt get resized to the power of 2 213 | largeTexture.generateMipmaps = false; 214 | largeTexture.wrapS = largeTexture.wrapT = THREE.ClampToEdgeWrapping; 215 | largeTexture.minFilter = THREE.LinearFilter; 216 | largeTexture.needsUpdate = true; 217 | const smallTexture = new THREE.Texture(imageSet.small.image); 218 | smallTexture.generateMipmaps = false; 219 | smallTexture.wrapS = smallTexture.wrapT = THREE.ClampToEdgeWrapping; 220 | smallTexture.minFilter = THREE.LinearFilter; 221 | smallTexture.needsUpdate = true; 222 | const textureSet = { 223 | large: { 224 | element: imageSet.large.element, 225 | texture: largeTexture 226 | }, 227 | small: { 228 | element: imageSet.small.element, 229 | texture: smallTexture 230 | } 231 | }; 232 | 233 | textures.push(textureSet); 234 | } 235 | this.textures = textures; 236 | this.setCurrentTextures(); 237 | } 238 | /** 239 | Sets the correct textures to the uniforms. And renders if not in a loop 240 | */ 241 | setCurrentTextures() { 242 | if (this.currentImageIndex === -1) return; 243 | const textureSet = this.textures[this.currentImageIndex]; 244 | if (!textureSet) return; 245 | this.uniforms.uImage.value = textureSet.small.texture; 246 | this.uniforms.uImageRes.value.x = 247 | textureSet.small.texture.image.naturalWidth; 248 | this.uniforms.uImageRes.value.y = 249 | textureSet.small.texture.image.naturalHeight; 250 | this.uniforms.uImageLarge.value = textureSet.large.texture; 251 | this.uniforms.uImageLargeRes.value.x = 252 | textureSet.large.texture.image.naturalWidth; 253 | this.uniforms.uImageLargeRes.value.y = 254 | textureSet.large.texture.image.naturalHeight; 255 | if (!this.isAnimating) { 256 | this.render(); 257 | } 258 | } 259 | /** 260 | Initiates THREEJS objects and adds listeners to the items 261 | */ 262 | init() { 263 | this.renderer = new THREE.WebGLRenderer({ 264 | alpha: true, 265 | antialias: true 266 | }); 267 | this.renderer.setPixelRatio(window.devicePixelRatio); 268 | this.renderer.setSize(window.innerWidth, window.innerHeight); 269 | this.container.appendChild(this.renderer.domElement); 270 | 271 | this.scene = new THREE.Scene(); 272 | this.camera = new THREE.PerspectiveCamera( 273 | 45, 274 | window.innerWidth / window.innerHeight, 275 | 0.1, 276 | 10000 277 | ); 278 | this.camera.position.z = 50; 279 | this.camera.lookAt = this.scene.position; 280 | 281 | const viewSize = this.getViewSize(); 282 | this.uniforms.uViewSize.value = new THREE.Vector2( 283 | viewSize.width, 284 | viewSize.height 285 | ); 286 | 287 | const segments = 128; 288 | var geometry = new THREE.PlaneBufferGeometry(1, 1, segments, segments); 289 | 290 | const shaders = this.getShaders(); 291 | var material = new THREE.ShaderMaterial({ 292 | uniforms: this.uniforms, 293 | vertexShader: shaders.vertex, 294 | fragmentShader: shaders.fragment, 295 | side: THREE.DoubleSide 296 | }); 297 | this.mesh = new THREE.Mesh(geometry, material); 298 | this.scene.add(this.mesh); 299 | 300 | window.addEventListener("resize", this.onResize); 301 | if (this.options.scrollContainer) { 302 | this.options.scrollContainer.addEventListener("scroll", ev => { 303 | this.recalculateUniforms(ev); 304 | this.render(); 305 | }); 306 | } 307 | 308 | for (let i = 0; i < this.itemsWrapper.children.length; i++) { 309 | const image = this.itemsWrapper.children[i].children[0]; 310 | image.addEventListener("mousedown", this.createOnMouseDown(i)); 311 | } 312 | this.initialised = true; 313 | } 314 | reset() { 315 | const shaders = this.getShaders(); 316 | 317 | this.mesh.material.vertexShader = shaders.vertex; 318 | this.mesh.material.fragmentShader = shaders.fragment; 319 | this.mesh.material.needsUpdate = true; 320 | 321 | const uniforms = this.uniforms; 322 | const options = this.options; 323 | 324 | this.render(); 325 | } 326 | getShaders() { 327 | const shaderInfo = { 328 | transform: this.options.transformation, 329 | activation: this.options.activation, 330 | timing: this.options.timing 331 | }; 332 | 333 | const transformOptions = this.options.transformation; 334 | let transformation = ""; 335 | if (isFunction(transformOptions.type)) { 336 | transformation = transformOptions.type(shaderInfo); 337 | } else if (transformOptions.type != null) { 338 | transformation = transformations[transformOptions.type]( 339 | transformOptions.props, 340 | shaderInfo 341 | ); 342 | } 343 | const activationOptions = this.options.activation; 344 | let activation = ""; 345 | if (isFunction(activationOptions.type)) { 346 | activation = activationOptions.type(shaderInfo); 347 | } else if (activationOptions.type != null) { 348 | activation = activations[activationOptions.type]( 349 | activationOptions.props, 350 | shaderInfo 351 | ); 352 | } 353 | 354 | const timingOptions = this.options.timing; 355 | let timing = ""; 356 | if (isFunction(timing.type)) { 357 | timing = timingOptions.type(); 358 | } else if (timingOptions.type != null) { 359 | timing = timings[timingOptions.type](timingOptions.props, shaderInfo); 360 | } 361 | 362 | const vertex = this.createVertexShader({ 363 | activation, 364 | transformation, 365 | timing 366 | }); 367 | const fragment = this.createFragmentShader(); 368 | return { 369 | fragment, 370 | vertex 371 | }; 372 | } 373 | /** 374 | Creates a listener that sends item to fullscreen when activated. 375 | @return {function} Event listener 376 | */ 377 | createOnMouseDown(itemIndex) { 378 | return ev => { 379 | this.currentImageIndex = itemIndex; 380 | if (this.options.randomizeSeed === "itemUnique") { 381 | this.uniforms.uSeed.value = itemIndex * 1000; 382 | } 383 | if (this.options.onItemClick) this.options.onItemClick(itemIndex); 384 | this.recalculateUniforms(ev); 385 | // this.setTextures(); 386 | this.setCurrentTextures(); 387 | this.toFullscreen(); 388 | }; 389 | } 390 | /* 391 | Tweens the plane to grid position if on fullscreen 392 | */ 393 | toGrid() { 394 | if (!this.isFullscreen || this.isAnimating) return; 395 | 396 | this.isAnimating = true; 397 | if (this.options.onToGridStart) 398 | this.options.onToGridStart({ index: this.currentImageIndex }); 399 | 400 | if ( 401 | this.options.randomizeSeed === "InOutUnique" || 402 | this.options.randomizeSeed === "tweenUnique" 403 | ) { 404 | this.uniforms.uSeed.value = Math.floor(Math.random() * 10000); 405 | } 406 | this.tween = TweenLite.to(this.uniforms.uProgress, this.options.duration, { 407 | value: 0, 408 | ease: this.options.easings.toGrid, 409 | onUpdate: () => { 410 | if (this.options.onProgressTween) 411 | this.options.onProgressTween(this.uniforms.uProgress.value); 412 | 413 | this.render(); 414 | }, 415 | onComplete: () => { 416 | this.isAnimating = false; 417 | this.isFullscreen = false; 418 | this.tween = null; 419 | this.itemsWrapper.style.zIndex = 0; 420 | this.container.style.zIndex = 0; 421 | this.render(); 422 | if (this.options.onToGridFinish) 423 | this.options.onToGridFinish({ 424 | index: -1, 425 | lastIndex: this.currentImageIndex 426 | }); 427 | // this.currentImageIndex = -1; 428 | } 429 | }); 430 | } 431 | calculateMouse(ev) { 432 | const rect = this.itemsWrapper.children[ 433 | this.currentImageIndex 434 | ].children[0].getBoundingClientRect(); 435 | const mouseNormalized = { 436 | x: (ev.clientX - rect.left) / rect.width, 437 | // Allways invert Y coord 438 | y: 1 - (ev.clientY - rect.top) / rect.height 439 | }; 440 | 441 | this.uniforms.uMouse.value = new THREE.Vector2( 442 | mouseNormalized.x, 443 | mouseNormalized.y 444 | ); 445 | } 446 | recalculateUniforms(ev) { 447 | if (this.currentImageIndex === -1) return; 448 | 449 | const rect = this.itemsWrapper.children[ 450 | this.currentImageIndex 451 | ].children[0].getBoundingClientRect(); 452 | const mouseNormalized = { 453 | x: (ev.clientX - rect.left) / rect.width, 454 | // Allways invert Y coord 455 | y: 1 - (ev.clientY - rect.top) / rect.height 456 | }; 457 | 458 | const xIndex = rect.left > window.innerWidth - (rect.left + rect.width); 459 | const yIndex = rect.top > window.innerHeight - (rect.top + rect.height); 460 | 461 | const closestCorner = xIndex * 2 + yIndex; 462 | this.uniforms.uClosestCorner.value = closestCorner; 463 | this.uniforms.uMouse.value = new THREE.Vector2( 464 | mouseNormalized.x, 465 | mouseNormalized.y 466 | ); 467 | 468 | const viewSize = this.getViewSize(); 469 | const widthViewUnit = (rect.width * viewSize.width) / window.innerWidth; 470 | const heightViewUnit = (rect.height * viewSize.height) / window.innerHeight; 471 | // x and y are based on top left of screen. While ThreeJs is on the center 472 | const xViewUnit = 473 | (rect.left * viewSize.width) / window.innerWidth - viewSize.width / 2; 474 | const yViewUnit = 475 | (rect.top * viewSize.height) / window.innerHeight - viewSize.height / 2; 476 | 477 | const geometry = this.mesh.geometry; 478 | const mesh = this.mesh; 479 | 480 | // // The plain's size is initially 1. So the scale is the new size 481 | 482 | mesh.scale.x = widthViewUnit; 483 | mesh.scale.y = heightViewUnit; 484 | 485 | // // Move the object by its top left corners, not the center 486 | let x = xViewUnit + widthViewUnit / 2; 487 | let y = -yViewUnit - heightViewUnit / 2; 488 | 489 | // geometry.translate(x, y, 0); 490 | mesh.position.x = x; 491 | mesh.position.y = y; 492 | 493 | // Used to scale the plane from the center 494 | // divided by scale so when later scaled it looks fine 495 | this.uniforms.uPlaneCenter.value.x = x / widthViewUnit; 496 | this.uniforms.uPlaneCenter.value.y = y / heightViewUnit; 497 | 498 | this.uniforms.uMeshScale.value.x = widthViewUnit; 499 | this.uniforms.uMeshScale.value.y = heightViewUnit; 500 | 501 | this.uniforms.uScaleToViewSize.value.x = viewSize.width / widthViewUnit - 1; 502 | this.uniforms.uScaleToViewSize.value.y = 503 | viewSize.height / heightViewUnit - 1; 504 | } 505 | forceInitializePlane(index = 0) { 506 | this.currentImageIndex = index; 507 | this.recalculateUniforms({ 508 | clientX: window.innerWidth / 2, 509 | clientY: window.innerHeight 510 | }); 511 | this.setCurrentTextures(); 512 | } 513 | toFullscreen() { 514 | if (this.isFullscreen || this.isAnimating) return; 515 | 516 | this.isAnimating = true; 517 | 518 | this.itemsWrapper.style.zIndex = 0; 519 | this.container.style.zIndex = 2; 520 | 521 | if (this.options.onToFullscreenStart) 522 | this.options.onToFullscreenStart({ index: this.currentImageIndex }); 523 | 524 | if (this.options.randomizeSeed === "tweenUnique") { 525 | this.uniforms.uSeed.value = Math.floor(Math.random() * 10000); 526 | } 527 | this.tween = TweenLite.to(this.uniforms.uProgress, this.options.duration, { 528 | value: 1, 529 | ease: this.options.easings.toFullscreen, 530 | onUpdate: () => { 531 | if (this.options.onProgressTween) 532 | this.options.onProgressTween(this.uniforms.uProgress.value); 533 | this.render(); 534 | }, 535 | onComplete: () => { 536 | this.isAnimating = false; 537 | this.isFullscreen = true; 538 | this.tween = null; 539 | if (this.options.onToFullscreenFinish) 540 | this.options.onToFullscreenFinish({ 541 | index: this.currentImageIndex 542 | }); 543 | } 544 | }); 545 | } 546 | /** 547 | Gives the width and height of the current camera's view. 548 | @typedef {Object} Size 549 | @property {number} width 550 | @property {number} height 551 | 552 | @return {Size} The size of the camera's view 553 | 554 | */ 555 | getViewSize() { 556 | const fovInRadians = (this.camera.fov * Math.PI) / 180; 557 | const height = Math.abs( 558 | this.camera.position.z * Math.tan(fovInRadians / 2) * 2 559 | ); 560 | 561 | return { width: height * this.camera.aspect, height }; 562 | } 563 | /** 564 | Renders ThreeJS to the canvas. 565 | */ 566 | render() { 567 | this.renderer.render(this.scene, this.camera); 568 | } 569 | /** 570 | Resize Event Listener. 571 | Updates anything that uses the window's size. 572 | @param {Event} ev resize event 573 | */ 574 | onResize(ev) { 575 | this.camera.aspect = window.innerWidth / window.innerHeight; 576 | this.camera.updateProjectionMatrix(); 577 | this.renderer.setSize(window.innerWidth, window.innerHeight); 578 | 579 | if (this.currentImageIndex > -1) { 580 | this.recalculateUniforms(ev); 581 | this.render(); 582 | } 583 | } 584 | createVertexShader({ activation, transformation, timing }) { 585 | return ` 586 | ${vertexUniforms} 587 | ${cubicBeizer} 588 | ${simplex} 589 | 590 | ${quadraticBezier} 591 | 592 | 593 | ${activation} 594 | float linearStep(float edge0, float edge1, float val) { 595 | float x = clamp( (val - edge0) / (edge1 - edge0),0.,1.); 596 | return x; 597 | } 598 | 599 | mat2 rotate2d(float _angle){ 600 | return mat2(cos(_angle),-sin(_angle), 601 | sin(_angle),cos(_angle)); 602 | } 603 | void main(){ 604 | 605 | vec3 pos = position.xyz; 606 | vec2 newUV = uv; 607 | 608 | float activation = getActivation(uv); 609 | 610 | float vertexProgress = uProgress; 611 | 612 | ${timing} 613 | 614 | vec3 transformedPos = pos; 615 | vec2 transformedUV = uv; 616 | ${transformation} 617 | pos = transformedPos; 618 | newUV = transformedUV; 619 | 620 | // Scale 621 | // uScaleToViewSize 622 | scale = vec2( 623 | 1. + uScaleToViewSize * vertexProgress 624 | ); 625 | // Since we are moving the mesh not the geometry the geometry is in the center 626 | 627 | 628 | 629 | 630 | pos.xy *= scale; 631 | 632 | 633 | // Move to center 634 | // Mesh moves it into position. Shader moves it to the center 635 | pos.y += -uPlaneCenter.y * vertexProgress; 636 | pos.x += -uPlaneCenter.x * vertexProgress; 637 | 638 | // Move slightly to the front 639 | pos.z += vertexProgress; 640 | 641 | gl_Position = projectionMatrix * modelViewMatrix * vec4(pos,1.); 642 | vProgress = vertexProgress; 643 | vActivation = activation; 644 | vUv = newUV; 645 | } 646 | `; 647 | } 648 | createFragmentShader() { 649 | return ` 650 | uniform float uProgress; 651 | uniform sampler2D uImage; 652 | uniform vec2 uImageRes; 653 | uniform sampler2D uImageLarge; 654 | uniform vec2 uImageLargeRes; 655 | uniform vec2 uMeshScale; 656 | uniform bool uDebugActivation; 657 | 658 | varying vec2 vUv; 659 | varying float vProgress; 660 | varying vec2 scale; 661 | varying float vActivation; 662 | 663 | vec2 preserveAspectRatioSlice(vec2 uv, vec2 planeSize, vec2 imageSize ){ 664 | 665 | vec2 ratio = vec2( 666 | min((planeSize.x / planeSize.y) / (imageSize.x / imageSize.y), 1.0), 667 | min((planeSize.y / planeSize.x) / (imageSize.y / imageSize.x), 1.0) 668 | ); 669 | 670 | 671 | vec2 sliceUvs = vec2( 672 | uv.x * ratio.x + (1.0 - ratio.x) * 0.5, 673 | uv.y * ratio.y + (1.0 - ratio.y) * 0.5 674 | ); 675 | 676 | return sliceUvs; 677 | } 678 | 679 | void main(){ 680 | 681 | vec2 uv = vUv; 682 | 683 | vec2 scaledPlane = uMeshScale * scale; 684 | 685 | 686 | vec2 smallImageUV = preserveAspectRatioSlice(uv, scaledPlane, uImageRes); 687 | 688 | vec3 color = texture2D(uImage,smallImageUV).xyz; 689 | 690 | if(vProgress > 0.){ 691 | vec2 largeImageUV = preserveAspectRatioSlice(uv, scaledPlane, uImageLargeRes); 692 | color = mix(color,texture2D(uImageLarge,largeImageUV).xyz, vProgress ); 693 | } 694 | if(uDebugActivation){ 695 | color = vec3(vActivation); 696 | } 697 | 698 | gl_FragColor = vec4(color,1.); 699 | } 700 | `; 701 | } 702 | } 703 | function getEaseFromString(easeString) { 704 | const dotIndex = easeString.indexOf("."); 705 | const name = easeString.substring(0, dotIndex); 706 | const type = easeString.substring(dotIndex + 1); 707 | const easingTypes = window.com.greensock.easing[name]; 708 | if (!easingTypes) return Power0.easeNone; 709 | const ease = easingTypes[type]; 710 | if (!ease) return easingTypes["easeIn"]; 711 | return ease; 712 | } 713 | function isFunction(functionToCheck) { 714 | return ( 715 | functionToCheck && {}.toString.call(functionToCheck) === "[object Function]" 716 | ); 717 | } 718 | const timings = { 719 | none: options => { 720 | return ``; 721 | }, 722 | sameEnd: options => { 723 | const latestStart = ensureFloat(options.latestStart || 0.5); 724 | const syncStart = options.reverse; 725 | let sync = "vertexProgress = smoothstep(startAt,1.,uProgress)"; 726 | if (syncStart) { 727 | sync = "vertexProgress = smoothstep(0., 1.- startAt, uProgress)"; 728 | } 729 | return ` 730 | float startAt = activation * ${latestStart}; 731 | ${sync}; 732 | `; 733 | }, 734 | sections: options => { 735 | const sections = ensureFloat(options.sections || 1); 736 | 737 | return ` 738 | // Vertex end by parts 739 | float activationPart = 1./${sections}; 740 | float activationPartDuration = 1./(${sections}+1.); 741 | 742 | float progressStart = (activation / activationPart) * activationPartDuration; 743 | float progressEnd = min(progressStart + activationPartDuration,1.); 744 | vertexProgress = linearStep(progressStart,progressEnd,uProgress); 745 | `; 746 | } 747 | }; 748 | var activations = { 749 | none: () => "float getActivation(vec2 uv){return 0.;}", 750 | side: options => { 751 | let res = []; 752 | let x = []; 753 | let y = []; 754 | if (options.top) y.push("(1.-uv.y)"); 755 | if (options.bottom) y.push("uv.y"); 756 | if (options.left) x.push("uv.x"); 757 | if (options.right) x.push("(1.-uv.x)"); 758 | 759 | let xFormula = x.join("*2.*"); 760 | if (x.length > 1) { 761 | xFormula += "*2."; 762 | } 763 | if (xFormula.length > 0) res = res.concat(`(${xFormula})`); 764 | 765 | let yFormula = y.join("*2.*"); 766 | if (y.length > 1) { 767 | yFormula += "*2."; 768 | } 769 | if (yFormula.length > 0) res = res.concat(`(${yFormula})`); 770 | 771 | if (res.length === 0) { 772 | res.push("0."); 773 | } 774 | 775 | return ` 776 | float getActivation(vec2 uv){ 777 | return ${res.join("*")}; 778 | } 779 | `; 780 | }, 781 | corners: options => { 782 | let res = []; 783 | let uphill = []; 784 | let downhill = []; 785 | if (options.topLeft) downhill.push("(uv.x + 1.- uv.y)"); 786 | if (options.bottomRight) downhill.push("(1.-uv.x + uv.y)"); 787 | if (options.bottomLeft) uphill.push("(uv.x + uv.y)"); 788 | if (options.topRight) uphill.push("(1.-uv.x + 1.- uv.y)"); 789 | 790 | if (uphill.length > 0) { 791 | let formula = uphill[0] + "/2."; 792 | if (uphill.length > 1) { 793 | formula = uphill.join("*"); 794 | } 795 | res.push(formula); 796 | } 797 | if (downhill.length > 0) { 798 | let formula = downhill[0] + "/2."; 799 | if (downhill.length > 1) { 800 | formula = downhill.join("*"); 801 | } 802 | res.push(formula); 803 | } 804 | 805 | if (res.length === 0) { 806 | res.push("0."); 807 | } 808 | 809 | return ` 810 | float getActivation(vec2 uv){ 811 | return ${res.join("*")}; 812 | } 813 | `; 814 | 815 | return ` 816 | float getActivation(vec2 uv){ 817 | float top = (1.-uv.y); 818 | float right = uv.x; 819 | float bottom = uv.y; 820 | float left = 1.- uv.x; 821 | 822 | return top *0.333333 + (right * 0.333333 + (right * bottom)*0.666666 ); 823 | } 824 | `; 825 | }, 826 | radial: options => { 827 | let x = ensureFloat(options.x || 0.5); 828 | let y = ensureFloat(options.y || 0.5); 829 | if (options.onMouse) { 830 | x = "uMouse.x"; 831 | y = "uMouse.y"; 832 | } 833 | return ` 834 | float getActivation(vec2 uv){ 835 | vec2 point = vec2(${x},${y}); 836 | float maxDistance = distance(point, 1.-floor(point+0.5)); 837 | float dist = smoothstep(0.,maxDistance,distance(point,uv)); 838 | return dist; 839 | } 840 | `; 841 | }, 842 | closestCorner: () => ` 843 | float getActivation(vec2 uv){ 844 | 845 | float y = mod(uClosestCorner,2.) *2. -1.; 846 | float x = (floor(uClosestCorner /2.)*2.-1.)*-1.; 847 | 848 | float xAct = abs(min(0.,x)) + uv.x * x; 849 | float yAct = abs(min(0.,y)) + uv.y * y; 850 | 851 | return (xAct+yAct)/2.; 852 | } 853 | `, 854 | closestSide: () => ` 855 | float getActivation(vec2 uv){ 856 | 857 | float y = mod(uClosestCorner,2.) *2. -1.; 858 | float x = (floor(uClosestCorner /2.)*2.-1.)*-1.; 859 | 860 | float xAct = abs(min(0.,x)) + uv.x * x; 861 | float yAct = abs(min(0.,y)) + uv.y * y; 862 | 863 | return (xAct+yAct)/2.; 864 | } 865 | `, 866 | snake: options => { 867 | const size = options.rows || 10; 868 | const sectionSize = ensureFloat(1 / size); 869 | 870 | return ` 871 | float getActivation(vec2 uv){ 872 | float index = min(floor(uv.y / ${sectionSize}), ${ensureFloat( 873 | size - 1 874 | )}); 875 | // 0 right or 1 left 876 | float direction = mod(index, 2.); 877 | // -1 left and 1 right 878 | float sign = -(direction * 2. -1.); 879 | 880 | // alternate 1. - uv.x and uv.x 881 | float xDirection = (direction + uv.x * sign); 882 | 883 | float y = mod(uv.y, ${sectionSize}) / ${sectionSize}; 884 | y = (direction + y * sign) ; 885 | float yDirection = (xDirection + y); 886 | 887 | // float yDirection = (y * 0.5 + xDirection * 0.5); 888 | return ( xDirection * ${sectionSize} + index *${sectionSize}); 889 | } 890 | `; 891 | }, 892 | squares: options => { 893 | const size = options.size || 4; 894 | const indexSection = ensureFloat(1 / size); 895 | 896 | // There are more colors than rows/columns. 897 | const nColors = ensureFloat((size - 1) * 2); 898 | const colorSection = ensureFloat(1 / nColors); 899 | return ` 900 | float getActivation(vec2 uv){ 901 | 902 | float xIndex = floor(uv.x / ${indexSection}); 903 | float yIndex = floor(uv.y / ${indexSection}); 904 | 905 | return xIndex * ${colorSection} + ${colorSection} * yIndex; 906 | } 907 | `; 908 | }, 909 | sin: options => { 910 | let formulas = []; 911 | if (options.x) { 912 | let freqX = ensureFloat(options.frequencyX || 2); 913 | let piOffsetX = ensureFloat(options.piOffsetX || 0.5); 914 | formulas.push( 915 | `(sin(uv.x * 3.14 * ${freqX} + 3.14 * ${piOffsetX}) * 0.5 + 0.5)` 916 | ); 917 | } 918 | if (options.y) { 919 | let freqY = ensureFloat(options.frequencyY || 2); 920 | let piOffsetY = ensureFloat(options.piOffsetY || 0.5); 921 | formulas.push( 922 | `(sin(uv.y * 3.14 * ${freqY} + 3.14 * ${piOffsetY}) * 0.5 + 0.5)` 923 | ); 924 | } 925 | const joinWith = options.joinWith || "multiplication"; 926 | let final = formulas[0]; 927 | if (formulas.length === 0) { 928 | final = "0"; 929 | } 930 | if (formulas.length > 1) { 931 | switch (joinWith) { 932 | case "sum": 933 | final = `(${final}+ ${formulas[1]})/2.`; 934 | break; 935 | case "multiplication": 936 | final = final + "*" + formulas[1]; 937 | break; 938 | case "max": 939 | final = `max(${final}, ${formulas[1]})`; 940 | break; 941 | case "min": 942 | final = `min(${final}, ${formulas[1]})`; 943 | break; 944 | default: 945 | final = final + "*" + formulas[1]; 946 | break; 947 | } 948 | } 949 | return ` 950 | float getActivation(vec2 uv){ 951 | return ${final}; 952 | } 953 | `; 954 | } 955 | }; 956 | function ensureFloat(num) { 957 | let stringed = num.toString(); 958 | const dotIndex = stringed.indexOf("."); 959 | if (dotIndex === -1) { 960 | stringed += "."; 961 | } 962 | return stringed; 963 | } 964 | const transformations = { 965 | none: () => "", 966 | flipX: (options, shaderInfo) => { 967 | let c0x = ensureFloat(options.beizerC0x || 0.5); 968 | let c0y = ensureFloat(options.beizerC0y || 0.5); 969 | 970 | let c1x = ensureFloat(options.beizerC1x || 0.5); 971 | let c1y = ensureFloat(options.beizerC1y || 0.5); 972 | 973 | let textureFlip = ""; 974 | if (shaderInfo.timing.type === "sameEnd") { 975 | const latestStart = ensureFloat( 976 | shaderInfo.timing.props.latestStart || 0.5 977 | ); 978 | textureFlip = ` 979 | // Flip texture on flipped sections 980 | 981 | // Flip the controls because who knows why 982 | // But it works exactly 983 | 984 | // Multiply by aspect ratio to account for mesh scaling 985 | float aspectRatio = (uMeshScale.x / uMeshScale.y); 986 | float stepFormula = 0.5 - (${latestStart} * ${latestStart} * ${latestStart}) * aspectRatio; 987 | 988 | transformedUV.x = mix(transformedUV.x,1.-transformedUV.x, 989 | step(stepFormula,beizerProgress)); 990 | `; 991 | } 992 | 993 | // Only works with sync ending 994 | return ` 995 | 996 | float beizerProgress = cubicBezier(vertexProgress, 997 | ${c0x},${c0y}, 998 | ${c1x},${c1y}); 999 | 1000 | float flippedX = -transformedPos.x; 1001 | transformedPos.x = mix (transformedPos.x, flippedX,beizerProgress ); 1002 | 1003 | ${textureFlip} 1004 | `; 1005 | }, 1006 | simplex: props => { 1007 | let seed = ensureFloat(props.seed || 0); 1008 | let amplitudeX = ensureFloat(props.amplitudeX || 0.2); 1009 | let amplitudeY = ensureFloat(props.amplitudeY || 0.2); 1010 | let frequencyX = ensureFloat(props.frequencyX || 0.3); 1011 | let frequencyY = ensureFloat(props.frequencyY || 0.3); 1012 | let progressLimit = ensureFloat(props.progressLimit || 0.5); 1013 | return ` 1014 | float simplexProgress = min(clamp((vertexProgress) / ${progressLimit},0.,1.),clamp((1.-vertexProgress) / (1.-${progressLimit}),0.,1.)); 1015 | simplexProgress = smoothstep(0.,1.,simplexProgress); 1016 | float noiseX = snoise(vec2(transformedPos.x +uSeed, transformedPos.y + uSeed + simplexProgress * 1.) * ${frequencyX} ) ; 1017 | float noiseY = snoise(vec2(transformedPos.y +uSeed, transformedPos.x + uSeed + simplexProgress * 1.) * ${frequencyY}) ; 1018 | transformedPos.x += ${amplitudeX} * noiseX * simplexProgress; 1019 | transformedPos.y += ${amplitudeY} * noiseY * simplexProgress; 1020 | `; 1021 | }, 1022 | fluid: props => { 1023 | const frequency = ensureFloat(props.frequency || 1); 1024 | const amplitude = ensureFloat(props.amplitude || 0.3); 1025 | let x = ensureFloat((props.x || 0.5) - 0.5); 1026 | let y = ensureFloat((props.y || 0.5) - 0.5); 1027 | if (props.onMouse) { 1028 | x = "uMouse.x - 0.5"; 1029 | y = "uMouse.y - 0.5"; 1030 | } 1031 | const progressLimit = ensureFloat(props.progressLimit || 0.5); 1032 | return ` 1033 | float velvetProgress = min(clamp((vertexProgress) / ${progressLimit},0.,1.),clamp((1.-vertexProgress) / (1.-${progressLimit}),0.,1.)); 1034 | velvetProgress = sin(velvetProgress * (3.14 / 2.) * ${frequency}); 1035 | vec2 velvetPoint = vec2(${x},${y}); 1036 | vec2 velvetToPoint = transformedPos.xy; 1037 | transformedPos.xy = mix(transformedPos.xy, velvetPoint + velvetToPoint*${amplitude}, velvetProgress); 1038 | 1039 | `; 1040 | }, 1041 | wavy: props => { 1042 | const seed = ensureFloat(props.seed || 0); 1043 | const amplitude = ensureFloat(props.amplitude || 0.4); 1044 | const frequency = ensureFloat(props.frequency || 4); 1045 | return ` 1046 | float limit = 0.5; 1047 | float wavyProgress = min(clamp((vertexProgress) / limit,0.,1.),clamp((1.-vertexProgress) / (1.-limit),0.,1.)); 1048 | 1049 | float dist = length(transformedPos.xy); 1050 | 1051 | float angle = atan(transformedPos.x,transformedPos.y); 1052 | 1053 | float nextDist = dist * (${amplitude} * (sin(angle * ${frequency} + ${seed}) /2.+0.5)+ 1.); 1054 | 1055 | transformedPos.x = mix(transformedPos.x,sin(angle) * nextDist , wavyProgress); 1056 | transformedPos.y = mix(transformedPos.y,cos(angle) * nextDist, wavyProgress); 1057 | `; 1058 | }, 1059 | circle: props => { 1060 | return ` 1061 | float limit = 0.5; 1062 | float circleProgress = min(clamp((vertexProgress) / limit,0.,1.),clamp((1.-vertexProgress) / (1.-limit),0.,1.)); 1063 | 1064 | float maxDistance = 0.5; 1065 | float dist = length(transformedPos.xy); 1066 | 1067 | float nextDist = min(maxDistance,dist); 1068 | float overload = step(maxDistance,dist); 1069 | float angle = atan(transformedPos.x,transformedPos.y); 1070 | 1071 | transformedPos.x = mix(transformedPos.x,sin(angle) * nextDist , circleProgress ); 1072 | transformedPos.y = mix(transformedPos.y,cos(angle) * nextDist, circleProgress); 1073 | transformedPos.z += -0.5 * overload * circleProgress; 1074 | 1075 | `; 1076 | }, 1077 | rotation: props => { 1078 | const angle = props.angle || 360; 1079 | const PIslice = ensureFloat(angle / 360); 1080 | 1081 | let progress = "vertexProgress"; 1082 | if (props.unify) { 1083 | progress = "uProgress"; 1084 | } 1085 | return ` 1086 | mat2 rotation = rotate2d(${progress}*(3.14*2.)*${PIslice}); 1087 | transformedUV.xy -= 0.5; 1088 | transformedUV.xy = rotation * transformedUV.xy; 1089 | transformedUV.xy += 0.5; 1090 | 1091 | transformedPos.xy = rotation * transformedPos.xy; 1092 | `; 1093 | } 1094 | }; 1095 | var vertexUniforms = ` 1096 | uniform float uProgress; 1097 | uniform vec2 uScaleToViewSize; 1098 | uniform vec2 uPlaneCenter; 1099 | uniform vec2 uMeshScale; 1100 | uniform vec2 uMouse; 1101 | uniform vec2 uViewSize; 1102 | 1103 | uniform float uClosestCorner; 1104 | 1105 | // Option Uniforms 1106 | uniform float uSeed; 1107 | varying vec2 vUv; 1108 | varying vec2 scale; 1109 | varying float vProgress; 1110 | varying float vActivation; 1111 | 1112 | `; 1113 | 1114 | var cubicBeizer = ` 1115 | // Helper functions: 1116 | float slopeFromT (float t, float A, float B, float C){ 1117 | float dtdx = 1.0/(3.0*A*t*t + 2.0*B*t + C); 1118 | return dtdx; 1119 | } 1120 | 1121 | float xFromT (float t, float A, float B, float C, float D){ 1122 | float x = A*(t*t*t) + B*(t*t) + C*t + D; 1123 | return x; 1124 | } 1125 | 1126 | float yFromT (float t, float E, float F, float G, float H){ 1127 | float y = E*(t*t*t) + F*(t*t) + G*t + H; 1128 | return y; 1129 | } 1130 | float cubicBezier (float x, float a, float b, float c, float d){ 1131 | 1132 | float y0a = 0.00; // initial y 1133 | float x0a = 0.00; // initial x 1134 | float y1a = b; // 1st influence y 1135 | float x1a = a; // 1st influence x 1136 | float y2a = d; // 2nd influence y 1137 | float x2a = c; // 2nd influence x 1138 | float y3a = 1.00; // final y 1139 | float x3a = 1.00; // final x 1140 | 1141 | float A = x3a - 3.*x2a + 3.*x1a - x0a; 1142 | float B = 3.*x2a - 6.*x1a + 3.*x0a; 1143 | float C = 3.*x1a - 3.*x0a; 1144 | float D = x0a; 1145 | 1146 | float E = y3a - 3.*y2a + 3.*y1a - y0a; 1147 | float F = 3.*y2a - 6.*y1a + 3.*y0a; 1148 | float G = 3.*y1a - 3.*y0a; 1149 | float H = y0a; 1150 | 1151 | // Solve for t given x (using Newton-Raphelson), then solve for y given t. 1152 | // Assume for the first guess that t = x. 1153 | float currentt = x; 1154 | const int nRefinementIterations = 5; 1155 | for (int i=0; i < nRefinementIterations; i++){ 1156 | float currentx = xFromT (currentt, A,B,C,D); 1157 | float currentslope = slopeFromT (currentt, A,B,C); 1158 | currentt -= (currentx - x)*(currentslope); 1159 | currentt = clamp(currentt, 0.,1.); 1160 | } 1161 | 1162 | float y = yFromT (currentt, E,F,G,H); 1163 | return y; 1164 | } 1165 | `; 1166 | var simplex = ` 1167 | vec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); } 1168 | 1169 | float snoise(vec2 v){ 1170 | const vec4 C = vec4(0.211324865405187, 0.366025403784439, 1171 | -0.577350269189626, 0.024390243902439); 1172 | vec2 i = floor(v + dot(v, C.yy) ); 1173 | vec2 x0 = v - i + dot(i, C.xx); 1174 | vec2 i1; 1175 | i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); 1176 | vec4 x12 = x0.xyxy + C.xxzz; 1177 | x12.xy -= i1; 1178 | i = mod(i, 289.0); 1179 | vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) 1180 | + i.x + vec3(0.0, i1.x, 1.0 )); 1181 | vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), 1182 | dot(x12.zw,x12.zw)), 0.0); 1183 | m = m*m ; 1184 | m = m*m ; 1185 | vec3 x = 2.0 * fract(p * C.www) - 1.0; 1186 | vec3 h = abs(x) - 0.5; 1187 | vec3 ox = floor(x + 0.5); 1188 | vec3 a0 = x - ox; 1189 | m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); 1190 | vec3 g; 1191 | g.x = a0.x * x0.x + h.x * x0.y; 1192 | g.yz = a0.yz * x12.xz + h.yz * x12.yw; 1193 | return 130.0 * dot(m, g); 1194 | } 1195 | `; 1196 | 1197 | var quadraticBezier = ` 1198 | float quadraticBezier (float x, float a, float b){ 1199 | // adapted from BEZMATH.PS (1993) 1200 | // by Don Lancaster, SYNERGETICS Inc. 1201 | // http://www.tinaja.com/text/bezmath.html 1202 | 1203 | float epsilon = 0.00001; 1204 | a = max(0., min(1., a)); 1205 | b = max(0., min(1., b)); 1206 | if (a == 0.5){ 1207 | a += epsilon; 1208 | } 1209 | 1210 | // solve t from x (an inverse operation) 1211 | float om2a = 1. - 2.*a; 1212 | float t = (sqrt(a*a + om2a*x) - a)/om2a; 1213 | float y = (1.-2.*b)*(t*t) + (2.*b)*t; 1214 | return y; 1215 | } 1216 | `; 1217 | -------------------------------------------------------------------------------- /js/TweenLite.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * VERSION: 2.1.3 3 | * DATE: 2019-05-17 4 | * UPDATES AND DOCS AT: http://greensock.com 5 | * 6 | * @license Copyright (c) 2008-2019, GreenSock. All rights reserved. 7 | * This work is subject to the terms at http://greensock.com/standard-license or for 8 | * Club GreenSock members, the software agreement that was issued with your membership. 9 | * 10 | * @author: Jack Doyle, jack@greensock.com 11 | */ 12 | !function(a,b){"use strict";var c={},d=a.document,e=a.GreenSockGlobals=a.GreenSockGlobals||a,f=e[b];if(f)return"undefined"!=typeof module&&module.exports&&(module.exports=f),f;var g,h,i,j,k,l=function(a){var b,c=a.split("."),d=e;for(b=0;b-1;)(k=r[f[p]]||new s(f[p],[])).gsClass?(i[p]=k.gsClass,q--):j&&k.sc.push(this);if(0===q&&g){if(m=("com.greensock."+d).split("."),n=m.pop(),o=l(m.join("."))[n]=this.gsClass=g.apply(g,i),h)if(e[n]=c[n]=o,"undefined"!=typeof module&&module.exports)if(d===b){module.exports=c[b]=o;for(p in c)o[p]=c[p]}else c[b]&&(c[b][n]=o);else"function"==typeof define&&define.amd&&define((a.GreenSockAMDPath?a.GreenSockAMDPath+"/":"")+d.split(".").pop(),[],function(){return o});for(p=0;p-1;)for(f=i[j],e=d?u("easing."+f,null,!0):m.easing[f]||{},g=k.length;--g>-1;)h=k[g],x[f+"."+h]=x[h+f]=e[h]=a.getRatio?a:a[h]||new a};for(i=w.prototype,i._calcEnd=!1,i.getRatio=function(a){if(this._func)return this._params[0]=a,this._func.apply(null,this._params);var b=this._type,c=this._power,d=1===b?1-a:2===b?a:.5>a?2*a:2*(1-a);return 1===c?d*=d:2===c?d*=d*d:3===c?d*=d*d*d:4===c&&(d*=d*d*d*d),1===b?1-d:2===b?d:.5>a?d/2:1-d/2},g=["Linear","Quad","Cubic","Quart","Quint,Strong"],h=g.length;--h>-1;)i=g[h]+",Power"+h,y(new w(null,null,1,h),i,"easeOut",!0),y(new w(null,null,2,h),i,"easeIn"+(0===h?",easeNone":"")),y(new w(null,null,3,h),i,"easeInOut");x.linear=m.easing.Linear.easeIn,x.swing=m.easing.Quad.easeInOut;var z=u("events.EventDispatcher",function(a){this._listeners={},this._eventTarget=a||this});i=z.prototype,i.addEventListener=function(a,b,c,d,e){e=e||0;var f,g,h=this._listeners[a],i=0;for(this!==j||k||j.wake(),null==h&&(this._listeners[a]=h=[]),g=h.length;--g>-1;)f=h[g],f.c===b&&f.s===c?h.splice(g,1):0===i&&f.pr-1;)if(d[c].c===b)return void d.splice(c,1)},i.dispatchEvent=function(a){var b,c,d,e=this._listeners[a];if(e)for(b=e.length,b>1&&(e=e.slice(0)),c=this._eventTarget;--b>-1;)d=e[b],d&&(d.up?d.c.call(d.s||c,{type:a,target:c}):d.c.call(d.s||c))};var A=a.requestAnimationFrame,B=a.cancelAnimationFrame,C=Date.now||function(){return(new Date).getTime()},D=C();for(g=["ms","moz","webkit","o"],h=g.length;--h>-1&&!A;)A=a[g[h]+"RequestAnimationFrame"],B=a[g[h]+"CancelAnimationFrame"]||a[g[h]+"CancelRequestAnimationFrame"];u("Ticker",function(a,b){var c,e,f,g,h,i=this,l=C(),m=b!==!1&&A?"auto":!1,o=500,q=33,r="tick",s=function(a){var b,d,j=C()-D;j>o&&(l+=j-q),D+=j,i.time=(D-l)/1e3,b=i.time-h,(!c||b>0||a===!0)&&(i.frame++,h+=b+(b>=g?.004:g-b),d=!0),a!==!0&&(f=e(s)),d&&i.dispatchEvent(r)};z.call(i),i.time=i.frame=0,i.tick=function(){s(!0)},i.lagSmoothing=function(a,b){return arguments.length?(o=a||1/n,void(q=Math.min(b,o,0))):1/n>o},i.sleep=function(){null!=f&&(m&&B?B(f):clearTimeout(f),e=p,f=null,i===j&&(k=!1))},i.wake=function(a){null!==f?i.sleep():a?l+=-D+(D=C()):i.frame>10&&(D=C()-o+5),e=0===c?p:m&&A?A:function(a){return setTimeout(a,1e3*(h-i.time)+1|0)},i===j&&(k=!0),s(2)},i.fps=function(a){return arguments.length?(c=a,g=1/(c||60),h=this.time+g,void i.wake()):c},i.useRAF=function(a){return arguments.length?(i.sleep(),m=a,void i.fps(c)):m},i.fps(a),setTimeout(function(){"auto"===m&&i.frame<5&&"hidden"!==(d||{}).visibilityState&&i.useRAF(!1)},1500)}),i=m.Ticker.prototype=new m.events.EventDispatcher,i.constructor=m.Ticker;var E=u("core.Animation",function(a,b){if(this.vars=b=b||{},this._duration=this._totalDuration=a||0,this._delay=Number(b.delay)||0,this._timeScale=1,this._active=!!b.immediateRender,this.data=b.data,this._reversed=!!b.reversed,Z){k||j.wake();var c=this.vars.useFrames?Y:Z;c.add(this,c._time),this.vars.paused&&this.paused(!0)}});j=E.ticker=new m.Ticker,i=E.prototype,i._dirty=i._gc=i._initted=i._paused=!1,i._totalTime=i._time=0,i._rawPrevTime=-1,i._next=i._last=i._onUpdate=i._timeline=i.timeline=null,i._paused=!1;var F=function(){k&&C()-D>2e3&&("hidden"!==(d||{}).visibilityState||!j.lagSmoothing())&&j.wake();var a=setTimeout(F,2e3);a.unref&&a.unref()};F(),i.play=function(a,b){return null!=a&&this.seek(a,b),this.reversed(!1).paused(!1)},i.pause=function(a,b){return null!=a&&this.seek(a,b),this.paused(!0)},i.resume=function(a,b){return null!=a&&this.seek(a,b),this.paused(!1)},i.seek=function(a,b){return this.totalTime(Number(a),b!==!1)},i.restart=function(a,b){return this.reversed(!1).paused(!1).totalTime(a?-this._delay:0,b!==!1,!0)},i.reverse=function(a,b){return null!=a&&this.seek(a||this.totalDuration(),b),this.reversed(!0).paused(!1)},i.render=function(a,b,c){},i.invalidate=function(){return this._time=this._totalTime=0,this._initted=this._gc=!1,this._rawPrevTime=-1,(this._gc||!this.timeline)&&this._enabled(!0),this},i.isActive=function(){var a,b=this._timeline,c=this._startTime;return!b||!this._gc&&!this._paused&&b.isActive()&&(a=b.rawTime(!0))>=c&&a-1;)"{self}"===a[b]&&(c[b]=this);return c},i._callback=function(a){var b=this.vars,c=b[a],d=b[a+"Params"],e=b[a+"Scope"]||b.callbackScope||this,f=d?d.length:0;switch(f){case 0:c.call(e);break;case 1:c.call(e,d[0]);break;case 2:c.call(e,d[0],d[1]);break;default:c.apply(e,d)}},i.eventCallback=function(a,b,c,d){if("on"===(a||"").substr(0,2)){var e=this.vars;if(1===arguments.length)return e[a];null==b?delete e[a]:(e[a]=b,e[a+"Params"]=q(c)&&-1!==c.join("").indexOf("{self}")?this._swapSelfInParams(c):c,e[a+"Scope"]=d),"onUpdate"===a&&(this._onUpdate=b)}return this},i.delay=function(a){return arguments.length?(this._timeline.smoothChildTiming&&this.startTime(this._startTime+a-this._delay),this._delay=a,this):this._delay},i.duration=function(a){return arguments.length?(this._duration=this._totalDuration=a,this._uncache(!0),this._timeline.smoothChildTiming&&this._time>0&&this._timethis._duration?this._duration:a,b)):this._time},i.totalTime=function(a,b,c){if(k||j.wake(),!arguments.length)return this._totalTime;if(this._timeline){if(0>a&&!c&&(a+=this.totalDuration()),this._timeline.smoothChildTiming){this._dirty&&this.totalDuration();var d=this._totalDuration,e=this._timeline;if(a>d&&!c&&(a=d),this._startTime=(this._paused?this._pauseTime:e._time)-(this._reversed?d-a:a)/this._timeScale,e._dirty||this._uncache(!1),e._timeline)for(;e._timeline;)e._timeline._time!==(e._startTime+e._totalTime)/e._timeScale&&e.totalTime(e._totalTime,!0),e=e._timeline}this._gc&&this._enabled(!0,!1),(this._totalTime!==a||0===this._duration)&&(K.length&&_(),this.render(a,b,!1),K.length&&_())}return this},i.progress=i.totalProgress=function(a,b){var c=this.duration();return arguments.length?this.totalTime(c*a,b):c?this._time/c:this.ratio},i.startTime=function(a){return arguments.length?(a!==this._startTime&&(this._startTime=a,this.timeline&&this.timeline._sortChildren&&this.timeline.add(this,a-this._delay)),this):this._startTime},i.endTime=function(a){return this._startTime+(0!=a?this.totalDuration():this.duration())/this._timeScale},i.timeScale=function(a){if(!arguments.length)return this._timeScale;var b,c;for(a=a||n,this._timeline&&this._timeline.smoothChildTiming&&(b=this._pauseTime,c=b||0===b?b:this._timeline.totalTime(),this._startTime=c-(c-this._startTime)*this._timeScale/a),this._timeScale=a,c=this.timeline;c&&c.timeline;)c._dirty=!0,c.totalDuration(),c=c.timeline;return this},i.reversed=function(a){return arguments.length?(a!=this._reversed&&(this._reversed=a,this.totalTime(this._timeline&&!this._timeline.smoothChildTiming?this.totalDuration()-this._totalTime:this._totalTime,!0)),this):this._reversed},i.paused=function(a){if(!arguments.length)return this._paused;var b,c,d=this._timeline;return a!=this._paused&&d&&(k||a||j.wake(),b=d.rawTime(),c=b-this._pauseTime,!a&&d.smoothChildTiming&&(this._startTime+=c,this._uncache(!1)),this._pauseTime=a?b:null,this._paused=a,this._active=this.isActive(),!a&&0!==c&&this._initted&&this.duration()&&(b=d.smoothChildTiming?this._totalTime:(b-this._startTime)/this._timeScale,this.render(b,b===this._totalTime,!0))),this._gc&&!a&&this._enabled(!0,!1),this};var G=u("core.SimpleTimeline",function(a){E.call(this,0,a),this.autoRemoveChildren=this.smoothChildTiming=!0});i=G.prototype=new E,i.constructor=G,i.kill()._gc=!1,i._first=i._last=i._recent=null,i._sortChildren=!1,i.add=i.insert=function(a,b,c,d){var e,f;if(a._startTime=Number(b||0)+a._delay,a._paused&&this!==a._timeline&&(a._pauseTime=this.rawTime()-(a._timeline.rawTime()-a._pauseTime)),a.timeline&&a.timeline._remove(a,!0),a.timeline=a._timeline=this,a._gc&&a._enabled(!0,!0),e=this._last,this._sortChildren)for(f=a._startTime;e&&e._startTime>f;)e=e._prev;return e?(a._next=e._next,e._next=a):(a._next=this._first,this._first=a),a._next?a._next._prev=a:this._last=a,a._prev=e,this._recent=a,this._timeline&&this._uncache(!0),this},i._remove=function(a,b){return a.timeline===this&&(b||a._enabled(!1,!0),a._prev?a._prev._next=a._next:this._first===a&&(this._first=a._next),a._next?a._next._prev=a._prev:this._last===a&&(this._last=a._prev),a._next=a._prev=a.timeline=null,a===this._recent&&(this._recent=this._last),this._timeline&&this._uncache(!0)),this},i.render=function(a,b,c){var d,e=this._first;for(this._totalTime=this._time=this._rawPrevTime=a;e;)d=e._next,(e._active||a>=e._startTime&&!e._paused&&!e._gc)&&(e._reversed?e.render((e._dirty?e.totalDuration():e._totalDuration)-(a-e._startTime)*e._timeScale,b,c):e.render((a-e._startTime)*e._timeScale,b,c)),e=d},i.rawTime=function(){return k||j.wake(),this._totalTime};var H=u("TweenLite",function(b,c,d){if(E.call(this,c,d),this.render=H.prototype.render,null==b)throw"Cannot tween a null target.";this.target=b="string"!=typeof b?b:H.selector(b)||b;var e,f,g,h=b.jquery||b.length&&b!==a&&b[0]&&(b[0]===a||b[0].nodeType&&b[0].style&&!b.nodeType),i=this.vars.overwrite;if(this._overwrite=i=null==i?X[H.defaultOverwrite]:"number"==typeof i?i>>0:X[i],(h||b instanceof Array||b.push&&q(b))&&"number"!=typeof b[0])for(this._targets=g=o(b),this._propLookup=[],this._siblings=[],e=0;e1&&ca(f,this,null,1,this._siblings[e])):(f=g[e--]=H.selector(f),"string"==typeof f&&g.splice(e+1,1)):g.splice(e--,1);else this._propLookup={},this._siblings=aa(b,this,!1),1===i&&this._siblings.length>1&&ca(b,this,null,1,this._siblings);(this.vars.immediateRender||0===c&&0===this._delay&&this.vars.immediateRender!==!1)&&(this._time=-n,this.render(Math.min(0,-this._delay)))},!0),I=function(b){return b&&b.length&&b!==a&&b[0]&&(b[0]===a||b[0].nodeType&&b[0].style&&!b.nodeType)},J=function(a,b){var c,d={};for(c in a)W[c]||c in b&&"transform"!==c&&"x"!==c&&"y"!==c&&"width"!==c&&"height"!==c&&"className"!==c&&"border"!==c||!(!T[c]||T[c]&&T[c]._autoCSS)||(d[c]=a[c],delete a[c]);a.css=d};i=H.prototype=new E,i.constructor=H,i.kill()._gc=!1,i.ratio=0,i._firstPT=i._targets=i._overwrittenProps=i._startAt=null,i._notifyPluginsOfEnabled=i._lazy=!1,H.version="2.1.3",H.defaultEase=i._ease=new w(null,null,1,1),H.defaultOverwrite="auto",H.ticker=j,H.autoSleep=120,H.lagSmoothing=function(a,b){j.lagSmoothing(a,b)},H.selector=a.$||a.jQuery||function(b){var c=a.$||a.jQuery;return c?(H.selector=c,c(b)):(d||(d=a.document),d?d.querySelectorAll?d.querySelectorAll(b):d.getElementById("#"===b.charAt(0)?b.substr(1):b):b)};var K=[],L={},M=/(?:(-|-=|\+=)?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/gi,N=/[\+-]=-?[\.\d]/,O=function(a){for(var b,c=this._firstPT,d=1e-6;c;)b=c.blob?1===a&&null!=this.end?this.end:a?this.join(""):this.start:c.c*a+c.s,c.m?b=c.m.call(this._tween,b,this._target||c.t,this._tween):d>b&&b>-d&&!c.blob&&(b=0),c.f?c.fp?c.t[c.p](c.fp,b):c.t[c.p](b):c.t[c.p]=b,c=c._next},P=function(a){return(1e3*a|0)/1e3+""},Q=function(a,b,c,d){var e,f,g,h,i,j,k,l=[],m=0,n="",o=0;for(l.start=a,l.end=b,a=l[0]=a+"",b=l[1]=b+"",c&&(c(l),a=l[0],b=l[1]),l.length=0,e=a.match(M)||[],f=b.match(M)||[],d&&(d._next=null,d.blob=1,l._firstPT=l._applyPT=d),i=f.length,h=0;i>h;h++)k=f[h],j=b.substr(m,b.indexOf(k,m)-m),n+=j||!h?j:",",m+=j.length,o?o=(o+1)%5:"rgba("===j.substr(-5)&&(o=1),k===e[h]||e.length<=h?n+=k:(n&&(l.push(n),n=""),g=parseFloat(e[h]),l.push(g),l._firstPT={_next:l._firstPT,t:l,p:l.length-1,s:g,c:("="===k.charAt(1)?parseInt(k.charAt(0)+"1",10)*parseFloat(k.substr(2)):parseFloat(k)-g)||0,f:0,m:o&&4>o?Math.round:P}),m+=k.length;return n+=b.substr(m),n&&l.push(n),l.setRatio=O,N.test(b)&&(l.end=null),l},R=function(a,b,c,d,e,f,g,h,i){"function"==typeof d&&(d=d(i||0,a));var j,k=typeof a[b],l="function"!==k?"":b.indexOf("set")||"function"!=typeof a["get"+b.substr(3)]?b:"get"+b.substr(3),m="get"!==c?c:l?g?a[l](g):a[l]():a[b],n="string"==typeof d&&"="===d.charAt(1),o={t:a,p:b,s:m,f:"function"===k,pg:0,n:e||b,m:f?"function"==typeof f?f:Math.round:0,pr:0,c:n?parseInt(d.charAt(0)+"1",10)*parseFloat(d.substr(2)):parseFloat(d)-m||0};return("number"!=typeof m||"number"!=typeof d&&!n)&&(g||isNaN(m)||!n&&isNaN(d)||"boolean"==typeof m||"boolean"==typeof d?(o.fp=g,j=Q(m,n?parseFloat(o.s)+o.c+(o.s+"").replace(/[0-9\-\.]/g,""):d,h||H.defaultStringFilter,o),o={t:j,p:"setRatio",s:0,c:1,f:2,pg:0,n:e||b,pr:0,m:0}):(o.s=parseFloat(m),n||(o.c=parseFloat(d)-o.s||0))),o.c?((o._next=this._firstPT)&&(o._next._prev=o),this._firstPT=o,o):void 0},S=H._internals={isArray:q,isSelector:I,lazyTweens:K,blobDif:Q},T=H._plugins={},U=S.tweenLookup={},V=0,W=S.reservedProps={ease:1,delay:1,overwrite:1,onComplete:1,onCompleteParams:1,onCompleteScope:1,useFrames:1,runBackwards:1,startAt:1,onUpdate:1,onUpdateParams:1,onUpdateScope:1,onStart:1,onStartParams:1,onStartScope:1,onReverseComplete:1,onReverseCompleteParams:1,onReverseCompleteScope:1,onRepeat:1,onRepeatParams:1,onRepeatScope:1,easeParams:1,yoyo:1,immediateRender:1,repeat:1,repeatDelay:1,data:1,paused:1,reversed:1,autoCSS:1,lazy:1,onOverwrite:1,callbackScope:1,stringFilter:1,id:1,yoyoEase:1,stagger:1},X={none:0,all:1,auto:2,concurrent:3,allOnStart:4,preexisting:5,"true":1,"false":0},Y=E._rootFramesTimeline=new G,Z=E._rootTimeline=new G,$=30,_=S.lazyRender=function(){var a,b,c=K.length;for(L={},a=0;c>a;a++)b=K[a],b&&b._lazy!==!1&&(b.render(b._lazy[0],b._lazy[1],!0),b._lazy=!1);K.length=0};Z._startTime=j.time,Y._startTime=j.frame,Z._active=Y._active=!0,setTimeout(_,1),E._updateRoot=H.render=function(){var a,b,c;if(K.length&&_(),Z.render((j.time-Z._startTime)*Z._timeScale,!1,!1),Y.render((j.frame-Y._startTime)*Y._timeScale,!1,!1),K.length&&_(),j.frame>=$){$=j.frame+(parseInt(H.autoSleep,10)||120);for(c in U){for(b=U[c].tweens,a=b.length;--a>-1;)b[a]._gc&&b.splice(a,1);0===b.length&&delete U[c]}if(c=Z._first,(!c||c._paused)&&H.autoSleep&&!Y._first&&1===j._listeners.tick.length){for(;c&&c._paused;)c=c._next;c||j.sleep()}}},j.addEventListener("tick",E._updateRoot);var aa=function(a,b,c){var d,e,f=a._gsTweenID;if(U[f||(a._gsTweenID=f="t"+V++)]||(U[f]={target:a,tweens:[]}),b&&(d=U[f].tweens,d[e=d.length]=b,c))for(;--e>-1;)d[e]===b&&d.splice(e,1);return U[f].tweens},ba=function(a,b,c,d){var e,f,g=a.vars.onOverwrite;return g&&(e=g(a,b,c,d)),g=H.onOverwrite,g&&(f=g(a,b,c,d)),e!==!1&&f!==!1},ca=function(a,b,c,d,e){var f,g,h,i;if(1===d||d>=4){for(i=e.length,f=0;i>f;f++)if((h=e[f])!==b)h._gc||h._kill(null,a,b)&&(g=!0);else if(5===d)break;return g}var j,k=b._startTime+n,l=[],m=0,o=0===b._duration;for(f=e.length;--f>-1;)(h=e[f])===b||h._gc||h._paused||(h._timeline!==b._timeline?(j=j||da(b,0,o),0===da(h,j,o)&&(l[m++]=h)):h._startTime<=k&&h._startTime+h.totalDuration()/h._timeScale>k&&((o||!h._initted)&&k-h._startTime<=2*n||(l[m++]=h)));for(f=m;--f>-1;)if(h=l[f],i=h._firstPT,2===d&&h._kill(c,a,b)&&(g=!0),2!==d||!h._firstPT&&h._initted&&i){if(2!==d&&!ba(h,b))continue;h._enabled(!1,!1)&&(g=!0)}return g},da=function(a,b,c){for(var d=a._timeline,e=d._timeScale,f=a._startTime;d._timeline;){if(f+=d._startTime,e*=d._timeScale,d._paused)return-100;d=d._timeline}return f/=e,f>b?f-b:c&&f===b||!a._initted&&2*n>f-b?n:(f+=a.totalDuration()/a._timeScale/e)>b+n?0:f-b-n};i._init=function(){var a,b,c,d,e,f,g=this.vars,h=this._overwrittenProps,i=this._duration,j=!!g.immediateRender,k=g.ease,l=this._startAt;if(g.startAt){l&&(l.render(-1,!0),l.kill()),e={};for(d in g.startAt)e[d]=g.startAt[d];if(e.data="isStart",e.overwrite=!1,e.immediateRender=!0,e.lazy=j&&g.lazy!==!1,e.startAt=e.delay=null,e.onUpdate=g.onUpdate,e.onUpdateParams=g.onUpdateParams,e.onUpdateScope=g.onUpdateScope||g.callbackScope||this,this._startAt=H.to(this.target||{},0,e),j)if(this._time>0)this._startAt=null;else if(0!==i)return}else if(g.runBackwards&&0!==i)if(l)l.render(-1,!0),l.kill(),this._startAt=null;else{0!==this._time&&(j=!1),c={};for(d in g)W[d]&&"autoCSS"!==d||(c[d]=g[d]);if(c.overwrite=0,c.data="isFromStart",c.lazy=j&&g.lazy!==!1,c.immediateRender=j,this._startAt=H.to(this.target,0,c),j){if(0===this._time)return}else this._startAt._init(),this._startAt._enabled(!1),this.vars.immediateRender&&(this._startAt=null)}if(this._ease=k=k?k instanceof w?k:"function"==typeof k?new w(k,g.easeParams):x[k]||H.defaultEase:H.defaultEase,g.easeParams instanceof Array&&k.config&&(this._ease=k.config.apply(k,g.easeParams)),this._easeType=this._ease._type,this._easePower=this._ease._power,this._firstPT=null,this._targets)for(f=this._targets.length,a=0;f>a;a++)this._initProps(this._targets[a],this._propLookup[a]={},this._siblings[a],h?h[a]:null,a)&&(b=!0);else b=this._initProps(this.target,this._propLookup,this._siblings,h,0);if(b&&H._onPluginEvent("_onInitAllProps",this),h&&(this._firstPT||"function"!=typeof this.target&&this._enabled(!1,!1)),g.runBackwards)for(c=this._firstPT;c;)c.s+=c.c,c.c=-c.c,c=c._next;this._onUpdate=g.onUpdate,this._initted=!0},i._initProps=function(b,c,d,e,f){var g,h,i,j,k,l;if(null==b)return!1;L[b._gsTweenID]&&_(),this.vars.css||b.style&&b!==a&&b.nodeType&&T.css&&this.vars.autoCSS!==!1&&J(this.vars,b);for(g in this.vars)if(l=this.vars[g],W[g])l&&(l instanceof Array||l.push&&q(l))&&-1!==l.join("").indexOf("{self}")&&(this.vars[g]=l=this._swapSelfInParams(l,this));else if(T[g]&&(j=new T[g])._onInitTween(b,this.vars[g],this,f)){for(this._firstPT=k={_next:this._firstPT,t:j,p:"setRatio",s:0,c:1,f:1,n:g,pg:1,pr:j._priority,m:0},h=j._overwriteProps.length;--h>-1;)c[j._overwriteProps[h]]=this._firstPT;(j._priority||j._onInitAllProps)&&(i=!0),(j._onDisable||j._onEnable)&&(this._notifyPluginsOfEnabled=!0),k._next&&(k._next._prev=k)}else c[g]=R.call(this,b,g,"get",l,g,0,null,this.vars.stringFilter,f);return e&&this._kill(e,b)?this._initProps(b,c,d,e,f):this._overwrite>1&&this._firstPT&&d.length>1&&ca(b,this,c,this._overwrite,d)?(this._kill(c,b),this._initProps(b,c,d,e,f)):(this._firstPT&&(this.vars.lazy!==!1&&this._duration||this.vars.lazy&&!this._duration)&&(L[b._gsTweenID]=!0),i)},i.render=function(a,b,c){var d,e,f,g,h=this,i=h._time,j=h._duration,k=h._rawPrevTime;if(a>=j-n&&a>=0)h._totalTime=h._time=j,h.ratio=h._ease._calcEnd?h._ease.getRatio(1):1,h._reversed||(d=!0,e="onComplete",c=c||h._timeline.autoRemoveChildren),0===j&&(h._initted||!h.vars.lazy||c)&&(h._startTime===h._timeline._duration&&(a=0),(0>k||0>=a&&a>=-n||k===n&&"isPause"!==h.data)&&k!==a&&(c=!0,k>n&&(e="onReverseComplete")),h._rawPrevTime=g=!b||a||k===a?a:n);else if(n>a)h._totalTime=h._time=0,h.ratio=h._ease._calcEnd?h._ease.getRatio(0):0,(0!==i||0===j&&k>0)&&(e="onReverseComplete",d=h._reversed),a>-n?a=0:0>a&&(h._active=!1,0===j&&(h._initted||!h.vars.lazy||c)&&(k>=0&&(k!==n||"isPause"!==h.data)&&(c=!0),h._rawPrevTime=g=!b||a||k===a?a:n)),(!h._initted||h._startAt&&h._startAt.progress())&&(c=!0);else if(h._totalTime=h._time=a,h._easeType){var l=a/j,m=h._easeType,o=h._easePower;(1===m||3===m&&l>=.5)&&(l=1-l),3===m&&(l*=2),1===o?l*=l:2===o?l*=l*l:3===o?l*=l*l*l:4===o&&(l*=l*l*l*l),h.ratio=1===m?1-l:2===m?l:.5>a/j?l/2:1-l/2}else h.ratio=h._ease.getRatio(a/j);if(h._time!==i||c){if(!h._initted){if(h._init(),!h._initted||h._gc)return;if(!c&&h._firstPT&&(h.vars.lazy!==!1&&h._duration||h.vars.lazy&&!h._duration))return h._time=h._totalTime=i,h._rawPrevTime=k,K.push(h),void(h._lazy=[a,b]);h._time&&!d?h.ratio=h._ease.getRatio(h._time/j):d&&h._ease._calcEnd&&(h.ratio=h._ease.getRatio(0===h._time?0:1))}for(h._lazy!==!1&&(h._lazy=!1),h._active||!h._paused&&h._time!==i&&a>=0&&(h._active=!0),0===i&&(h._startAt&&(a>=0?h._startAt.render(a,!0,c):e||(e="_dummyGS")),h.vars.onStart&&(0!==h._time||0===j)&&(b||h._callback("onStart"))),f=h._firstPT;f;)f.f?f.t[f.p](f.c*h.ratio+f.s):f.t[f.p]=f.c*h.ratio+f.s,f=f._next;h._onUpdate&&(0>a&&h._startAt&&a!==-1e-4&&h._startAt.render(a,!0,c),b||(h._time!==i||d||c)&&h._callback("onUpdate")),e&&(!h._gc||c)&&(0>a&&h._startAt&&!h._onUpdate&&a!==-1e-4&&h._startAt.render(a,!0,c),d&&(h._timeline.autoRemoveChildren&&h._enabled(!1,!1),h._active=!1),!b&&h.vars[e]&&h._callback(e),0===j&&h._rawPrevTime===n&&g!==n&&(h._rawPrevTime=0))}},i._kill=function(a,b,c){if("all"===a&&(a=null),null==a&&(null==b||b===this.target))return this._lazy=!1,this._enabled(!1,!1);b="string"!=typeof b?b||this._targets||this.target:H.selector(b)||b;var d,e,f,g,h,i,j,k,l,m=c&&this._time&&c._startTime===this._startTime&&this._timeline===c._timeline,n=this._firstPT;if((q(b)||I(b))&&"number"!=typeof b[0])for(d=b.length;--d>-1;)this._kill(a,b[d],c)&&(i=!0);else{if(this._targets){for(d=this._targets.length;--d>-1;)if(b===this._targets[d]){h=this._propLookup[d]||{},this._overwrittenProps=this._overwrittenProps||[],e=this._overwrittenProps[d]=a?this._overwrittenProps[d]||{}:"all";break}}else{if(b!==this.target)return!1;h=this._propLookup,e=this._overwrittenProps=a?this._overwrittenProps||{}:"all"}if(h){if(j=a||h,k=a!==e&&"all"!==e&&a!==h&&("object"!=typeof a||!a._tempKill),c&&(H.onOverwrite||this.vars.onOverwrite)){for(f in j)h[f]&&(l||(l=[]),l.push(f));if((l||!a)&&!ba(this,c,b,l))return!1}for(f in j)(g=h[f])&&(m&&(g.f?g.t[g.p](g.s):g.t[g.p]=g.s,i=!0),g.pg&&g.t._kill(j)&&(i=!0),g.pg&&0!==g.t._overwriteProps.length||(g._prev?g._prev._next=g._next:g===this._firstPT&&(this._firstPT=g._next),g._next&&(g._next._prev=g._prev),g._next=g._prev=null),delete h[f]),k&&(e[f]=1);!this._firstPT&&this._initted&&n&&this._enabled(!1,!1)}}return i},i.invalidate=function(){this._notifyPluginsOfEnabled&&H._onPluginEvent("_onDisable",this);var a=this._time;return this._firstPT=this._overwrittenProps=this._startAt=this._onUpdate=null,this._notifyPluginsOfEnabled=this._active=this._lazy=!1,this._propLookup=this._targets?{}:[],E.prototype.invalidate.call(this),this.vars.immediateRender&&(this._time=-n,this.render(a,!1,this.vars.lazy!==!1)),this},i._enabled=function(a,b){if(k||j.wake(),a&&this._gc){var c,d=this._targets;if(d)for(c=d.length;--c>-1;)this._siblings[c]=aa(d[c],this,!0);else this._siblings=aa(this.target,this,!0)}return E.prototype._enabled.call(this,a,b),this._notifyPluginsOfEnabled&&this._firstPT?H._onPluginEvent(a?"_onEnable":"_onDisable",this):!1},H.to=function(a,b,c){return new H(a,b,c)},H.from=function(a,b,c){return c.runBackwards=!0,c.immediateRender=0!=c.immediateRender,new H(a,b,c)},H.fromTo=function(a,b,c,d){return d.startAt=c,d.immediateRender=0!=d.immediateRender&&0!=c.immediateRender,new H(a,b,d)},H.delayedCall=function(a,b,c,d,e){return new H(b,0,{delay:a,onComplete:b,onCompleteParams:c,callbackScope:d,onReverseComplete:b,onReverseCompleteParams:c,immediateRender:!1,lazy:!1,useFrames:e,overwrite:0})},H.set=function(a,b){return new H(a,0,b)},H.getTweensOf=function(a,b){if(null==a)return[];a="string"!=typeof a?a:H.selector(a)||a;var c,d,e,f;if((q(a)||I(a))&&"number"!=typeof a[0]){for(c=a.length,d=[];--c>-1;)d=d.concat(H.getTweensOf(a[c],b));for(c=d.length;--c>-1;)for(f=d[c],e=c;--e>-1;)f===d[e]&&d.splice(c,1)}else if(a._gsTweenID)for(d=aa(a).concat(),c=d.length;--c>-1;)(d[c]._gc||b&&!d[c].isActive())&&d.splice(c,1);return d||[]},H.killTweensOf=H.killDelayedCallsTo=function(a,b,c){"object"==typeof b&&(c=b,b=!1);for(var d=H.getTweensOf(a,b),e=d.length;--e>-1;)d[e]._kill(c,a)};var ea=u("plugins.TweenPlugin",function(a,b){this._overwriteProps=(a||"").split(","),this._propName=this._overwriteProps[0],this._priority=b||0,this._super=ea.prototype},!0);if(i=ea.prototype,ea.version="1.19.0",ea.API=2,i._firstPT=null,i._addTween=R,i.setRatio=O,i._kill=function(a){var b,c=this._overwriteProps,d=this._firstPT;if(null!=a[this._propName])this._overwriteProps=[];else for(b=c.length;--b>-1;)null!=a[c[b]]&&c.splice(b,1);for(;d;)null!=a[d.n]&&(d._next&&(d._next._prev=d._prev),d._prev?(d._prev._next=d._next,d._prev=null):this._firstPT===d&&(this._firstPT=d._next)),d=d._next;return!1},i._mod=i._roundProps=function(a){for(var b,c=this._firstPT;c;)b=a[this._propName]||null!=c.n&&a[c.n.split(this._propName+"_").join("")],b&&"function"==typeof b&&(2===c.f?c.t._applyPT.m=b:c.m=b),c=c._next},H._onPluginEvent=function(a,b){var c,d,e,f,g,h=b._firstPT;if("_onInitAllProps"===a){for(;h;){for(g=h._next,d=e;d&&d.pr>h.pr;)d=d._next;(h._prev=d?d._prev:f)?h._prev._next=h:e=h,(h._next=d)?d._prev=h:f=h,h=g}h=b._firstPT=e}for(;h;)h.pg&&"function"==typeof h.t[a]&&h.t[a]()&&(c=!0),h=h._next;return c},ea.activate=function(a){for(var b=a.length;--b>-1;)a[b].API===ea.API&&(T[(new a[b])._propName]=a[b]);return!0},t.plugin=function(a){if(!(a&&a.propName&&a.init&&a.API))throw"illegal plugin definition.";var b,c=a.propName,d=a.priority||0,e=a.overwriteProps,f={init:"_onInitTween",set:"setRatio",kill:"_kill",round:"_mod",mod:"_mod",initAll:"_onInitAllProps"},g=u("plugins."+c.charAt(0).toUpperCase()+c.substr(1)+"Plugin",function(){ea.call(this,c,d),this._overwriteProps=e||[]},a.global===!0),h=g.prototype=new ea(c);h.constructor=g,g.API=a.API;for(b in f)"function"==typeof a[b]&&(h[f[b]]=a[b]);return g.version=a.version,ea.activate([g]),g},g=a._gsQueue){for(h=0;h {}, 25 | onToGridStart: ({ index }) => {}, 26 | onProgressChange: ({ index, progress }) => { 27 | let opacity = progress > 0 ? 0 : 1; 28 | smallImages[index].style.opacity = opacity; 29 | }, 30 | onToFullscreenStart: ({ index }) => { 31 | smallImages[index].style.opacity = 0; 32 | }, 33 | onToGridFinish: ({ lastIndex }) => { 34 | smallImages[lastIndex].style.opacity = 1; 35 | } 36 | }, 37 | options 38 | ) 39 | ); 40 | canvasWrapper.addEventListener("click", ev => { 41 | if (configurator.effect.isAnimating) return; 42 | 43 | configurator.effect.calculateMouse(ev); 44 | if (configurator.effect.isFullscreen) configurator.effect.toGrid(); 45 | if (!configurator.effect.isFullscreen) configurator.effect.toFullscreen(); 46 | }); 47 | 48 | configurator.init(); 49 | 50 | return configurator; 51 | } 52 | -------------------------------------------------------------------------------- /js/imagesloaded.pkgd.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * imagesLoaded PACKAGED v4.1.1 3 | * JavaScript is all like "You images are done yet or what?" 4 | * MIT License 5 | */ 6 | 7 | !function(t,e){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",e):"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}("undefined"!=typeof window?window:this,function(){function t(){}var e=t.prototype;return e.on=function(t,e){if(t&&e){var i=this._events=this._events||{},n=i[t]=i[t]||[];return-1==n.indexOf(e)&&n.push(e),this}},e.once=function(t,e){if(t&&e){this.on(t,e);var i=this._onceEvents=this._onceEvents||{},n=i[t]=i[t]||{};return n[e]=!0,this}},e.off=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=i.indexOf(e);return-1!=n&&i.splice(n,1),this}},e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=0,o=i[n];e=e||[];for(var r=this._onceEvents&&this._onceEvents[t];o;){var s=r&&r[o];s&&(this.off(t,o),delete r[o]),o.apply(this,e),n+=s?0:1,o=i[n]}return this}},t}),function(t,e){"use strict";"function"==typeof define&&define.amd?define(["ev-emitter/ev-emitter"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter")):t.imagesLoaded=e(t,t.EvEmitter)}(window,function(t,e){function i(t,e){for(var i in e)t[i]=e[i];return t}function n(t){var e=[];if(Array.isArray(t))e=t;else if("number"==typeof t.length)for(var i=0;i