├── README.md ├── css ├── common.css ├── reset.css ├── style1.css ├── style2.css └── style3.css ├── favicon.ico ├── fonts └── Le-Murmure.otf ├── img ├── demo1 │ ├── img1.jpg │ ├── img2.jpg │ └── img3.jpg ├── demo2 │ ├── img1.jpg │ ├── img2.jpg │ └── img3.jpg ├── demo3 │ ├── img1.jpg │ └── img2.jpg └── slash.svg ├── index.html ├── index2.html ├── index3.html └── js ├── EffectShell.js ├── Math.js ├── RGBShiftEffect.js ├── StretchEffect.js ├── TrailsEffect.js ├── TweenLite.min.js ├── imagesloaded.pkgd.min.js └── three.min.js /README.md: -------------------------------------------------------------------------------- 1 | # Motion Hover Effects 2 | 3 | Demos for the tutorial "How to Create Motion Hover Effects with Image Distortions using Three.js" by Niccolò Miranda and Clément Roche. 4 | 5 | ![Motion Hover Effects featured image](https://tympanus.net/codrops/wp-content/uploads/2019/10/demo3.jpg) 6 | 7 | [Article on Codrops](https://tympanus.net/codrops/?p=44003) 8 | 9 | [Demo](http://tympanus.net/Tutorials/MotionHoverEffects/) 10 | 11 | ## Credits 12 | 13 | - [Three.js](https://threejs.org/) 14 | - [GSAP](https://greensock.com/gsap/) 15 | - [Fit Plane to screen](https://gist.github.com/ayamflow/96a1f554c3f88eef2f9d0024fc42940f) 16 | - Images from [Unsplash.com](https://unsplash.com/) 17 | - [Le Murmure](https://velvetyne.fr/fonts/le-murmure/) font by Jérémy Landes and Alex Slobzheninov 18 | 19 | ## License 20 | 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. 21 | 22 | ## Misc 23 | 24 | Follow Niccolò: [Twitter](https://twitter.com/niccolomiranda), [Dribbble](https://dribbble.com/niccolomiranda), [Instagram](https://www.instagram.com/niccolomiranda/), [LinkedIn](https://www.linkedin.com/in/niccolomiranda/) 25 | 26 | Follow Clément: [Twitter](https://twitter.com/clementroche_), [LinkedIn](https://www.linkedin.com/in/clment-roche/), [Codepen](https://codepen.io/ClementRoche/) 27 | 28 | Follow Codrops: [Twitter](http://www.twitter.com/codrops), [Facebook](http://www.facebook.com/codrops), [GitHub](https://github.com/codrops), [Instagram](https://www.instagram.com/codropsss/) 29 | 30 | 31 | [© Codrops 2019](http://www.codrops.com) 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /css/common.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | body { 6 | margin: 0; 7 | min-height: 100vh; 8 | min-width: 100vw; 9 | } 10 | 11 | canvas { 12 | display: block; 13 | position: absolute; 14 | top: 0px; 15 | left: 0px; 16 | z-index: -1; 17 | pointer-events: none; 18 | } 19 | 20 | .link { 21 | cursor: pointer; 22 | } 23 | 24 | .link img { 25 | display: none; 26 | } 27 | -------------------------------------------------------------------------------- /css/reset.css: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v4.0 | 20180602 3 | License: none (public domain) 4 | */ 5 | 6 | html, body, div, span, applet, object, iframe, 7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 8 | a, abbr, acronym, address, big, cite, code, 9 | del, dfn, em, img, ins, kbd, q, s, samp, 10 | small, strike, strong, sub, sup, tt, var, 11 | b, u, i, center, 12 | dl, dt, dd, ol, ul, li, 13 | fieldset, form, label, legend, 14 | table, caption, tbody, tfoot, thead, tr, th, td, 15 | article, aside, canvas, details, embed, 16 | figure, figcaption, footer, header, hgroup, 17 | main, menu, nav, output, ruby, section, summary, 18 | time, mark, audio, video { 19 | margin: 0; 20 | padding: 0; 21 | border: 0; 22 | font-size: 100%; 23 | font: inherit; 24 | vertical-align: baseline; 25 | } 26 | /* HTML5 display-role reset for older browsers */ 27 | article, aside, details, figcaption, figure, 28 | footer, header, hgroup, main, menu, nav, section { 29 | display: block; 30 | } 31 | /* HTML5 hidden-attribute fix for newer browsers */ 32 | *[hidden] { 33 | display: none; 34 | } 35 | body { 36 | line-height: 1; 37 | } 38 | ol, ul { 39 | list-style: none; 40 | } 41 | blockquote, q { 42 | quotes: none; 43 | } 44 | blockquote:before, blockquote:after, 45 | q:before, q:after { 46 | content: ''; 47 | content: none; 48 | } 49 | table { 50 | border-collapse: collapse; 51 | border-spacing: 0; 52 | } -------------------------------------------------------------------------------- /css/style1.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | *, 4 | *::after, 5 | *::before { 6 | box-sizing: border-box; 7 | } 8 | 9 | 10 | body { 11 | font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; 12 | color: #333; 13 | font-size: 0.85rem; 14 | line-height: 0.85rem; 15 | font-weight: 400; 16 | letter-spacing: -0.02em; 17 | text-transform: uppercase; 18 | } 19 | 20 | h1 { 21 | display: inline-block; 22 | margin-top: 0px; 23 | margin-bottom: 0px; 24 | font-family: 'Le murmure', sans-serif; 25 | font-size: 7rem; 26 | line-height: 7rem; 27 | font-weight: 400; 28 | text-transform: uppercase; 29 | } 30 | 31 | .body { 32 | overflow: hidden; 33 | height: 100%; 34 | } 35 | 36 | .body { 37 | background-color: #b1a59f; 38 | } 39 | 40 | .app { 41 | z-index: 2; 42 | display: -webkit-box; 43 | display: -webkit-flex; 44 | display: -ms-flexbox; 45 | display: flex; 46 | width: 100%; 47 | height: 100vh; 48 | -webkit-box-orient: vertical; 49 | -webkit-box-direction: normal; 50 | -webkit-flex-direction: column; 51 | -ms-flex-direction: column; 52 | flex-direction: column; 53 | -webkit-box-pack: center; 54 | -webkit-justify-content: center; 55 | -ms-flex-pack: center; 56 | justify-content: center; 57 | -webkit-box-align: center; 58 | -webkit-align-items: center; 59 | -ms-flex-align: center; 60 | align-items: center; 61 | } 62 | 63 | .text { 64 | margin-top: 0.2rem; 65 | line-height: 1rem; 66 | } 67 | 68 | .link { 69 | display: -webkit-box; 70 | display: -webkit-flex; 71 | display: -ms-flexbox; 72 | display: flex; 73 | margin: 2.5rem 23px; 74 | -webkit-box-orient: vertical; 75 | -webkit-box-direction: normal; 76 | -webkit-flex-direction: column; 77 | -ms-flex-direction: column; 78 | flex-direction: column; 79 | -webkit-box-align: center; 80 | -webkit-align-items: center; 81 | -ms-flex-align: center; 82 | align-items: center; 83 | color: #333; 84 | text-decoration: none; 85 | } 86 | 87 | .h1 { 88 | padding-top: 0.9rem; 89 | line-height: 6rem; 90 | } 91 | 92 | .grid { 93 | position: relative; 94 | z-index: 3; 95 | } 96 | 97 | .grid-items { 98 | display: -webkit-box; 99 | display: -webkit-flex; 100 | display: -ms-flexbox; 101 | display: flex; 102 | -webkit-box-pack: center; 103 | -webkit-justify-content: center; 104 | -ms-flex-pack: center; 105 | justify-content: center; 106 | -webkit-box-align: center; 107 | -webkit-align-items: center; 108 | -ms-flex-align: center; 109 | align-items: center; 110 | } 111 | 112 | .grid-items.g2 { 113 | padding-left: 24px; 114 | -webkit-box-pack: start; 115 | -webkit-justify-content: flex-start; 116 | -ms-flex-pack: start; 117 | justify-content: flex-start; 118 | } 119 | 120 | .divider { 121 | width: 120px; 122 | height: 2px; 123 | background-color: #333; 124 | } 125 | 126 | .divider.d2 { 127 | width: 160px; 128 | } 129 | 130 | .divider.d3 { 131 | width: 320px; 132 | } 133 | 134 | .frame { 135 | position: fixed; 136 | left: 0%; 137 | top: 0%; 138 | right: 0%; 139 | bottom: 0%; 140 | z-index: 3; 141 | display: -webkit-box; 142 | display: -webkit-flex; 143 | display: -ms-flexbox; 144 | display: flex; 145 | width: 100%; 146 | height: 100vh; 147 | padding: 2rem 3rem; 148 | -webkit-box-orient: vertical; 149 | -webkit-box-direction: normal; 150 | -webkit-flex-direction: column; 151 | -ms-flex-direction: column; 152 | flex-direction: column; 153 | -webkit-box-pack: justify; 154 | -webkit-justify-content: space-between; 155 | -ms-flex-pack: justify; 156 | justify-content: space-between; 157 | } 158 | 159 | .frame__demos { 160 | text-align: center; 161 | } 162 | 163 | .frame__demo { 164 | display: inline-block; 165 | margin-right: 7px; 166 | margin-left: 7px; 167 | color: #333; 168 | text-decoration: none; 169 | } 170 | 171 | .frame__demo--current{ 172 | text-decoration: underline; 173 | } 174 | 175 | .frame__demo:hover{ 176 | text-decoration: underline; 177 | } 178 | 179 | .frame__wrap { 180 | display: -webkit-box; 181 | display: -webkit-flex; 182 | display: -ms-flexbox; 183 | display: flex; 184 | } 185 | 186 | .frame__credits { 187 | -webkit-box-flex: 1; 188 | -webkit-flex: 1; 189 | -ms-flex: 1; 190 | flex: 1; 191 | } 192 | 193 | .frame__title-wrap { 194 | display: -webkit-box; 195 | display: -webkit-flex; 196 | display: -ms-flexbox; 197 | display: flex; 198 | -webkit-box-orient: vertical; 199 | -webkit-box-direction: normal; 200 | -webkit-flex-direction: column; 201 | -ms-flex-direction: column; 202 | flex-direction: column; 203 | -webkit-box-pack: center; 204 | -webkit-justify-content: center; 205 | -ms-flex-pack: center; 206 | justify-content: center; 207 | -webkit-box-align: center; 208 | -webkit-align-items: center; 209 | -ms-flex-align: center; 210 | align-items: center; 211 | -webkit-box-flex: 1; 212 | -webkit-flex: 1; 213 | -ms-flex: 1; 214 | flex: 1; 215 | } 216 | 217 | .frame__links { 218 | display: -webkit-box; 219 | display: -webkit-flex; 220 | display: -ms-flexbox; 221 | display: flex; 222 | -webkit-box-pack: end; 223 | -webkit-justify-content: flex-end; 224 | -ms-flex-pack: end; 225 | justify-content: flex-end; 226 | -webkit-box-align: center; 227 | -webkit-align-items: center; 228 | -ms-flex-align: center; 229 | align-items: center; 230 | -webkit-box-flex: 1; 231 | -webkit-flex: 1; 232 | -ms-flex: 1; 233 | flex: 1; 234 | } 235 | 236 | .frame__role { 237 | margin-bottom: 2px; 238 | font-style: italic; 239 | text-transform: capitalize; 240 | } 241 | 242 | .frame__name { 243 | font-weight: 700; 244 | } 245 | 246 | .credit-wrap { 247 | margin-top: 12px; 248 | margin-bottom: 12px; 249 | } 250 | 251 | .italic { 252 | text-transform: none; 253 | } 254 | 255 | .frame__title { 256 | text-align: center; 257 | } 258 | 259 | .frame__init { 260 | margin-bottom: 5px; 261 | text-align: center; 262 | } 263 | 264 | .italic { 265 | text-transform: none; 266 | color: #333; 267 | font-style: italic; 268 | } 269 | 270 | .frame__link { 271 | color: #333; 272 | } 273 | 274 | .frame__link.fl_1:hover{ 275 | text-decoration: underline; 276 | } 277 | 278 | .frame__link.fl_1 { 279 | margin-left: 25px; 280 | text-decoration: none; 281 | text-transform: uppercase; 282 | } 283 | 284 | .frame__inner { 285 | display: -webkit-box; 286 | display: -webkit-flex; 287 | display: -ms-flexbox; 288 | display: flex; 289 | } 290 | 291 | @media (max-width: 991px) { 292 | .app { 293 | position: absolute; 294 | left: 0%; 295 | top: 0%; 296 | right: 0%; 297 | bottom: 0%; 298 | height: 100%; 299 | } 300 | 301 | .h1 { 302 | font-size: 6rem; 303 | } 304 | 305 | .divider { 306 | width: 90px; 307 | } 308 | 309 | .divider.d2 { 310 | width: 110px; 311 | } 312 | 313 | .divider.d3 { 314 | width: 280px; 315 | } 316 | 317 | .frame__demo { 318 | font-size: 0.75rem; 319 | } 320 | 321 | .frame__credits { 322 | -webkit-box-flex: 0; 323 | -webkit-flex: 0 auto; 324 | -ms-flex: 0 auto; 325 | flex: 0 auto; 326 | } 327 | 328 | .frame__links { 329 | -webkit-box-flex: 0; 330 | -webkit-flex: 0 auto; 331 | -ms-flex: 0 auto; 332 | flex: 0 auto; 333 | } 334 | 335 | .frame__role { 336 | font-size: 0.75rem; 337 | } 338 | 339 | .frame__title { 340 | font-size: 0.75rem; 341 | } 342 | 343 | .frame__init { 344 | font-size: 0.75rem; 345 | } 346 | 347 | .frame__link { 348 | font-size: 0.75rem; 349 | } 350 | 351 | .frame__link.fl_1 { 352 | margin-top: 8px; 353 | } 354 | 355 | .frame__inner { 356 | -webkit-box-orient: vertical; 357 | -webkit-box-direction: normal; 358 | -webkit-flex-direction: column; 359 | -ms-flex-direction: column; 360 | flex-direction: column; 361 | -webkit-box-align: end; 362 | -webkit-align-items: flex-end; 363 | -ms-flex-align: end; 364 | align-items: flex-end; 365 | } 366 | } 367 | 368 | @media (max-width: 767px) { 369 | .link { 370 | margin-top: 1.4rem; 371 | margin-bottom: 1.4rem; 372 | } 373 | 374 | .h1 { 375 | font-size: 5rem; 376 | line-height: 5rem; 377 | } 378 | 379 | .grid-items { 380 | -webkit-box-orient: vertical; 381 | -webkit-box-direction: normal; 382 | -webkit-flex-direction: column; 383 | -ms-flex-direction: column; 384 | flex-direction: column; 385 | } 386 | 387 | .divider { 388 | display: none; 389 | } 390 | 391 | .frame__role { 392 | font-size: 0.55rem; 393 | line-height: 0.55rem; 394 | } 395 | 396 | .italic { 397 | font-size: 0.55rem; 398 | } 399 | 400 | .frame__title { 401 | font-size: 0.55rem; 402 | line-height: 0.55rem; 403 | } 404 | 405 | .frame__link { 406 | font-size: 0.55rem; 407 | } 408 | } 409 | 410 | @media (max-width: 479px) { 411 | .text { 412 | font-size: 0.65rem; 413 | } 414 | 415 | .link { 416 | margin: 4vw 0px; 417 | } 418 | 419 | .h1 { 420 | padding-top: 1vw; 421 | font-size: 14vw; 422 | line-height: 11vw; 423 | } 424 | 425 | .frame { 426 | padding-right: 2rem; 427 | padding-left: 2rem; 428 | } 429 | 430 | .frame__demo { 431 | font-size: 0.55rem; 432 | line-height: 0.55rem; 433 | } 434 | 435 | .frame__wrap { 436 | -webkit-box-orient: vertical; 437 | -webkit-box-direction: normal; 438 | -webkit-flex-direction: column; 439 | -ms-flex-direction: column; 440 | flex-direction: column; 441 | -webkit-box-pack: center; 442 | -webkit-justify-content: center; 443 | -ms-flex-pack: center; 444 | justify-content: center; 445 | -webkit-box-align: center; 446 | -webkit-align-items: center; 447 | -ms-flex-align: center; 448 | align-items: center; 449 | } 450 | 451 | .frame__credits { 452 | margin-bottom: 1vw; 453 | -webkit-box-orient: vertical; 454 | -webkit-box-direction: normal; 455 | -webkit-flex-direction: column; 456 | -ms-flex-direction: column; 457 | flex-direction: column; 458 | -webkit-box-pack: center; 459 | -webkit-justify-content: center; 460 | -ms-flex-pack: center; 461 | justify-content: center; 462 | -webkit-box-align: center; 463 | -webkit-align-items: center; 464 | -ms-flex-align: center; 465 | align-items: center; 466 | text-align: center; 467 | } 468 | 469 | .frame__title-wrap { 470 | margin-bottom: 2vw; 471 | } 472 | 473 | .frame__role { 474 | font-size: 2vw; 475 | line-height: 2vw; 476 | } 477 | 478 | .frame__title { 479 | font-size: 2vw; 480 | line-height: 2vw; 481 | } 482 | 483 | .frame__init { 484 | margin-bottom: 0.3vw; 485 | } 486 | 487 | .frame__link { 488 | font-size: 2vw; 489 | line-height: 2vw; 490 | } 491 | 492 | .frame__link.fl_1 { 493 | margin-left: 0px; 494 | } 495 | 496 | .frame__inner { 497 | -webkit-box-pack: center; 498 | -webkit-justify-content: center; 499 | -ms-flex-pack: center; 500 | justify-content: center; 501 | -webkit-box-align: center; 502 | -webkit-align-items: center; 503 | -ms-flex-align: center; 504 | align-items: center; 505 | } 506 | } 507 | 508 | @font-face { 509 | font-family: 'Le murmure'; 510 | src: url('../fonts/Le-Murmure.otf') format('opentype'); 511 | font-weight: 400; 512 | font-style: normal; 513 | } 514 | -------------------------------------------------------------------------------- /css/style2.css: -------------------------------------------------------------------------------- 1 | *, 2 | *::after, 3 | *::before { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; 9 | color: #333; 10 | font-size: 0.85rem; 11 | line-height: 0.85rem; 12 | font-weight: 400; 13 | letter-spacing: -0.02em; 14 | text-transform: uppercase; 15 | } 16 | 17 | h1 { 18 | display: inline-block; 19 | margin-top: 0px; 20 | margin-bottom: 0px; 21 | font-family: 'Le murmure', sans-serif; 22 | font-size: 7rem; 23 | line-height: 7rem; 24 | font-weight: 400; 25 | text-transform: uppercase; 26 | } 27 | 28 | 29 | .body { 30 | overflow: hidden; 31 | height: 100%; 32 | } 33 | 34 | 35 | .body { 36 | background-color: #f1e9db; 37 | } 38 | 39 | .app { 40 | z-index: 2; 41 | display: -webkit-box; 42 | display: -webkit-flex; 43 | display: -ms-flexbox; 44 | display: flex; 45 | width: 100%; 46 | height: 100vh; 47 | -webkit-box-orient: vertical; 48 | -webkit-box-direction: normal; 49 | -webkit-flex-direction: column; 50 | -ms-flex-direction: column; 51 | flex-direction: column; 52 | -webkit-box-pack: center; 53 | -webkit-justify-content: center; 54 | -ms-flex-pack: center; 55 | justify-content: center; 56 | -webkit-box-align: center; 57 | -webkit-align-items: center; 58 | -ms-flex-align: center; 59 | align-items: center; 60 | } 61 | 62 | .text { 63 | margin-top: 0.2rem; 64 | line-height: 1rem; 65 | } 66 | 67 | .link { 68 | display: -webkit-box; 69 | display: -webkit-flex; 70 | display: -ms-flexbox; 71 | display: flex; 72 | margin: 2.5rem 23px; 73 | -webkit-box-orient: vertical; 74 | -webkit-box-direction: normal; 75 | -webkit-flex-direction: column; 76 | -ms-flex-direction: column; 77 | flex-direction: column; 78 | -webkit-box-align: center; 79 | -webkit-align-items: center; 80 | -ms-flex-align: center; 81 | align-items: center; 82 | color: #333; 83 | text-decoration: none; 84 | } 85 | 86 | 87 | .link img { 88 | display: none; 89 | } 90 | 91 | .h1 { 92 | padding-top: 0.9rem; 93 | line-height: 5.3rem; 94 | } 95 | 96 | .grid { 97 | position: relative; 98 | z-index: 3; 99 | } 100 | 101 | .frame { 102 | position: fixed; 103 | left: 0%; 104 | top: 0%; 105 | right: 0%; 106 | bottom: 0%; 107 | z-index: 3; 108 | display: -webkit-box; 109 | display: -webkit-flex; 110 | display: -ms-flexbox; 111 | display: flex; 112 | width: 100%; 113 | height: 100vh; 114 | padding: 2rem 3rem; 115 | -webkit-box-orient: vertical; 116 | -webkit-box-direction: normal; 117 | -webkit-flex-direction: column; 118 | -ms-flex-direction: column; 119 | flex-direction: column; 120 | -webkit-box-pack: justify; 121 | -webkit-justify-content: space-between; 122 | -ms-flex-pack: justify; 123 | justify-content: space-between; 124 | } 125 | 126 | .frame__demos { 127 | text-align: center; 128 | } 129 | 130 | .frame__init { 131 | margin-bottom: 5px; 132 | text-align: center; 133 | } 134 | 135 | .italic { 136 | text-transform: none; 137 | color: #333; 138 | font-style: italic; 139 | } 140 | 141 | .frame__demo { 142 | display: inline-block; 143 | margin-right: 7px; 144 | margin-left: 7px; 145 | color: #333; 146 | text-decoration: none; 147 | } 148 | 149 | .frame__demo:hover { 150 | text-decoration: underline; 151 | } 152 | 153 | .frame__demo { 154 | color: #333; 155 | } 156 | 157 | 158 | .frame__demo--current { 159 | text-decoration: underline; 160 | } 161 | 162 | .frame__wrap { 163 | display: -webkit-box; 164 | display: -webkit-flex; 165 | display: -ms-flexbox; 166 | display: flex; 167 | } 168 | 169 | .frame__credits { 170 | -webkit-box-flex: 1; 171 | -webkit-flex: 1; 172 | -ms-flex: 1; 173 | flex: 1; 174 | } 175 | 176 | .frame__title-wrap { 177 | display: -webkit-box; 178 | display: -webkit-flex; 179 | display: -ms-flexbox; 180 | display: flex; 181 | -webkit-box-orient: vertical; 182 | -webkit-box-direction: normal; 183 | -webkit-flex-direction: column; 184 | -ms-flex-direction: column; 185 | flex-direction: column; 186 | -webkit-box-pack: center; 187 | -webkit-justify-content: center; 188 | -ms-flex-pack: center; 189 | justify-content: center; 190 | -webkit-box-align: center; 191 | -webkit-align-items: center; 192 | -ms-flex-align: center; 193 | align-items: center; 194 | -webkit-box-flex: 1; 195 | -webkit-flex: 1; 196 | -ms-flex: 1; 197 | flex: 1; 198 | } 199 | 200 | .frame__links { 201 | display: -webkit-box; 202 | display: -webkit-flex; 203 | display: -ms-flexbox; 204 | display: flex; 205 | -webkit-box-pack: end; 206 | -webkit-justify-content: flex-end; 207 | -ms-flex-pack: end; 208 | justify-content: flex-end; 209 | -webkit-box-align: center; 210 | -webkit-align-items: center; 211 | -ms-flex-align: center; 212 | align-items: center; 213 | -webkit-box-flex: 1; 214 | -webkit-flex: 1; 215 | -ms-flex: 1; 216 | flex: 1; 217 | } 218 | 219 | .frame__role { 220 | margin-bottom: 2px; 221 | font-style: italic; 222 | text-transform: capitalize; 223 | } 224 | 225 | 226 | .credit-wrap { 227 | margin-top: 12px; 228 | margin-bottom: 12px; 229 | } 230 | 231 | .italic { 232 | text-transform: none; 233 | } 234 | 235 | .frame__title { 236 | text-align: center; 237 | } 238 | 239 | .frame__link { 240 | color: #333; 241 | } 242 | 243 | .frame__link.fl_1 { 244 | margin-left: 25px; 245 | text-decoration: none; 246 | text-transform: uppercase; 247 | } 248 | 249 | .frame__link.fl_1:hover { 250 | text-decoration: underline; 251 | } 252 | 253 | 254 | .frame__inner { 255 | display: -webkit-box; 256 | display: -webkit-flex; 257 | display: -ms-flexbox; 258 | display: flex; 259 | } 260 | 261 | .image { 262 | width: 5rem; 263 | } 264 | 265 | @media (max-width: 991px) { 266 | .app { 267 | position: absolute; 268 | left: 0%; 269 | top: 0%; 270 | right: 0%; 271 | bottom: 0%; 272 | height: 100%; 273 | } 274 | 275 | .h1 { 276 | font-size: 6rem; 277 | } 278 | 279 | 280 | .divider { 281 | width: 90px; 282 | } 283 | 284 | .divider.d2 { 285 | width: 110px; 286 | } 287 | 288 | .divider.d3 { 289 | width: 280px; 290 | } 291 | 292 | .frame__demo { 293 | font-size: 0.75rem; 294 | } 295 | 296 | .frame__credits { 297 | -webkit-box-flex: 0; 298 | -webkit-flex: 0 auto; 299 | -ms-flex: 0 auto; 300 | flex: 0 auto; 301 | } 302 | 303 | .frame__links { 304 | -webkit-box-flex: 0; 305 | -webkit-flex: 0 auto; 306 | -ms-flex: 0 auto; 307 | flex: 0 auto; 308 | } 309 | 310 | .frame__role { 311 | font-size: 0.75rem; 312 | } 313 | 314 | .frame__title { 315 | font-size: 0.75rem; 316 | } 317 | 318 | .frame__init { 319 | font-size: 0.75rem; 320 | margin-bottom: 5px; 321 | text-align: center; 322 | } 323 | 324 | .frame__link { 325 | font-size: 0.75rem; 326 | } 327 | 328 | .frame__link.fl_1 { 329 | margin-top: 8px; 330 | } 331 | 332 | .frame__inner { 333 | -webkit-box-orient: vertical; 334 | -webkit-box-direction: normal; 335 | -webkit-flex-direction: column; 336 | -ms-flex-direction: column; 337 | flex-direction: column; 338 | -webkit-box-align: end; 339 | -webkit-align-items: flex-end; 340 | -ms-flex-align: end; 341 | align-items: flex-end; 342 | } 343 | } 344 | 345 | @media (max-width: 767px) { 346 | .link { 347 | margin-top: 1.4rem; 348 | margin-bottom: 1.4rem; 349 | } 350 | 351 | .h1 { 352 | font-size: 5rem; 353 | line-height: 5rem; 354 | } 355 | 356 | 357 | .grid-items { 358 | -webkit-box-orient: vertical; 359 | -webkit-box-direction: normal; 360 | -webkit-flex-direction: column; 361 | -ms-flex-direction: column; 362 | flex-direction: column; 363 | } 364 | 365 | .divider { 366 | display: none; 367 | } 368 | 369 | .frame__role { 370 | font-size: 0.55rem; 371 | line-height: 0.55rem; 372 | } 373 | 374 | .italic { 375 | font-size: 0.55rem; 376 | } 377 | 378 | .frame__title { 379 | font-size: 0.55rem; 380 | line-height: 0.55rem; 381 | } 382 | 383 | .frame__link { 384 | font-size: 0.55rem; 385 | } 386 | 387 | .div-block { 388 | display: none; 389 | } 390 | } 391 | 392 | @media (max-width: 479px) { 393 | .text { 394 | font-size: 2vw; 395 | line-height: 2vw; 396 | } 397 | 398 | .link { 399 | margin: 10vw 0px; 400 | } 401 | 402 | .h1 { 403 | padding-top: 1vw; 404 | font-size: 14vw; 405 | line-height: 11vw; 406 | } 407 | 408 | .frame { 409 | padding-right: 2rem; 410 | padding-left: 2rem; 411 | } 412 | 413 | .frame__demo { 414 | font-size: 0.55rem; 415 | line-height: 0.55rem; 416 | } 417 | 418 | .frame__wrap { 419 | -webkit-box-orient: vertical; 420 | -webkit-box-direction: normal; 421 | -webkit-flex-direction: column; 422 | -ms-flex-direction: column; 423 | flex-direction: column; 424 | -webkit-box-pack: center; 425 | -webkit-justify-content: center; 426 | -ms-flex-pack: center; 427 | justify-content: center; 428 | -webkit-box-align: center; 429 | -webkit-align-items: center; 430 | -ms-flex-align: center; 431 | align-items: center; 432 | } 433 | 434 | .frame__credits { 435 | margin-bottom: 1vw; 436 | -webkit-box-orient: vertical; 437 | -webkit-box-direction: normal; 438 | -webkit-flex-direction: column; 439 | -ms-flex-direction: column; 440 | flex-direction: column; 441 | -webkit-box-pack: center; 442 | -webkit-justify-content: center; 443 | -ms-flex-pack: center; 444 | justify-content: center; 445 | -webkit-box-align: center; 446 | -webkit-align-items: center; 447 | -ms-flex-align: center; 448 | align-items: center; 449 | text-align: center; 450 | } 451 | 452 | .frame__title-wrap { 453 | margin-bottom: 2vw; 454 | } 455 | 456 | .frame__role { 457 | font-size: 2vw; 458 | line-height: 2vw; 459 | } 460 | 461 | .frame__title { 462 | font-size: 2vw; 463 | line-height: 2vw; 464 | } 465 | 466 | .frame__init { 467 | margin-bottom: 0.3vw; 468 | } 469 | 470 | .frame__link { 471 | font-size: 2vw; 472 | line-height: 2vw; 473 | } 474 | 475 | .frame__inner { 476 | -webkit-box-pack: center; 477 | -webkit-justify-content: center; 478 | -ms-flex-pack: center; 479 | justify-content: center; 480 | -webkit-box-align: center; 481 | -webkit-align-items: center; 482 | -ms-flex-align: center; 483 | align-items: center; 484 | } 485 | } 486 | 487 | @font-face { 488 | font-family: 'Le murmure'; 489 | src: url('../fonts/Le-Murmure.otf') format('opentype'); 490 | font-weight: 400; 491 | font-style: normal; 492 | } -------------------------------------------------------------------------------- /css/style3.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | *, 4 | *::after, 5 | *::before { 6 | box-sizing: border-box; 7 | } 8 | 9 | body { 10 | font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; 11 | color: #333; 12 | font-size: 0.85rem; 13 | line-height: 0.85rem; 14 | font-weight: 400; 15 | letter-spacing: -0.02em; 16 | text-transform: uppercase; 17 | } 18 | 19 | h1 { 20 | display: inline-block; 21 | margin-top: 0px; 22 | margin-bottom: 0px; 23 | font-family: 'Le murmure', sans-serif; 24 | font-size: 7rem; 25 | line-height: 7rem; 26 | font-weight: 400; 27 | text-transform: uppercase; 28 | } 29 | 30 | 31 | .body { 32 | overflow: hidden; 33 | height: 100%; 34 | } 35 | 36 | .body { 37 | background-color: #333; 38 | } 39 | 40 | .app { 41 | z-index: 2; 42 | display: -webkit-box; 43 | display: -webkit-flex; 44 | display: -ms-flexbox; 45 | display: flex; 46 | width: 100%; 47 | height: 100vh; 48 | -webkit-box-orient: vertical; 49 | -webkit-box-direction: normal; 50 | -webkit-flex-direction: column; 51 | -ms-flex-direction: column; 52 | flex-direction: column; 53 | -webkit-box-pack: center; 54 | -webkit-justify-content: center; 55 | -ms-flex-pack: center; 56 | justify-content: center; 57 | -webkit-box-align: center; 58 | -webkit-align-items: center; 59 | -ms-flex-align: center; 60 | align-items: center; 61 | } 62 | 63 | .text { 64 | margin-top: 0.2rem; 65 | line-height: 1rem; 66 | color: #f1e9db; 67 | } 68 | 69 | .link { 70 | display: -webkit-box; 71 | display: -webkit-flex; 72 | display: -ms-flexbox; 73 | display: flex; 74 | margin: 2.5rem 23px; 75 | -webkit-box-orient: vertical; 76 | -webkit-box-direction: normal; 77 | -webkit-flex-direction: column; 78 | -ms-flex-direction: column; 79 | flex-direction: column; 80 | -webkit-box-align: center; 81 | -webkit-align-items: center; 82 | -ms-flex-align: center; 83 | align-items: center; 84 | color: #333; 85 | text-decoration: none; 86 | } 87 | 88 | .link.l-d2 { 89 | margin-top: 3.7rem; 90 | margin-bottom: 3.7rem; 91 | } 92 | 93 | .h1 { 94 | padding-top: 0.9rem; 95 | line-height: 6rem; 96 | color: #f1e9db; 97 | } 98 | 99 | .grid { 100 | position: relative; 101 | z-index: 3; 102 | } 103 | 104 | .grid.g3 { 105 | display: -webkit-box; 106 | display: -webkit-flex; 107 | display: -ms-flexbox; 108 | display: flex; 109 | } 110 | 111 | .grid-items { 112 | display: -webkit-box; 113 | display: -webkit-flex; 114 | display: -ms-flexbox; 115 | display: flex; 116 | -webkit-box-pack: center; 117 | -webkit-justify-content: center; 118 | -ms-flex-pack: center; 119 | justify-content: center; 120 | -webkit-box-align: center; 121 | -webkit-align-items: center; 122 | -ms-flex-align: center; 123 | align-items: center; 124 | } 125 | 126 | .frame { 127 | position: fixed; 128 | left: 0%; 129 | top: 0%; 130 | right: 0%; 131 | bottom: 0%; 132 | z-index: 3; 133 | display: -webkit-box; 134 | display: -webkit-flex; 135 | display: -ms-flexbox; 136 | display: flex; 137 | width: 100%; 138 | height: 100vh; 139 | padding: 2rem 3rem; 140 | -webkit-box-orient: vertical; 141 | -webkit-box-direction: normal; 142 | -webkit-flex-direction: column; 143 | -ms-flex-direction: column; 144 | flex-direction: column; 145 | -webkit-box-pack: justify; 146 | -webkit-justify-content: space-between; 147 | -ms-flex-pack: justify; 148 | justify-content: space-between; 149 | } 150 | 151 | .frame__demos { 152 | text-align: center; 153 | } 154 | 155 | .frame__demo { 156 | display: inline-block; 157 | margin-right: 7px; 158 | margin-left: 7px; 159 | color: #f1e9db; 160 | text-decoration: none; 161 | } 162 | 163 | .frame__demo:hover { 164 | text-decoration: underline; 165 | } 166 | 167 | 168 | .frame__demo--current { 169 | text-decoration: underline; 170 | } 171 | 172 | .frame__wrap { 173 | display: -webkit-box; 174 | display: -webkit-flex; 175 | display: -ms-flexbox; 176 | display: flex; 177 | } 178 | 179 | .frame__credits { 180 | -webkit-box-flex: 1; 181 | -webkit-flex: 1; 182 | -ms-flex: 1; 183 | flex: 1; 184 | } 185 | 186 | .frame__title-wrap { 187 | display: -webkit-box; 188 | display: -webkit-flex; 189 | display: -ms-flexbox; 190 | display: flex; 191 | -webkit-box-orient: vertical; 192 | -webkit-box-direction: normal; 193 | -webkit-flex-direction: column; 194 | -ms-flex-direction: column; 195 | flex-direction: column; 196 | -webkit-box-pack: center; 197 | -webkit-justify-content: center; 198 | -ms-flex-pack: center; 199 | justify-content: center; 200 | -webkit-box-align: center; 201 | -webkit-align-items: center; 202 | -ms-flex-align: center; 203 | align-items: center; 204 | -webkit-box-flex: 1; 205 | -webkit-flex: 1; 206 | -ms-flex: 1; 207 | flex: 1; 208 | } 209 | 210 | .frame__links { 211 | display: -webkit-box; 212 | display: -webkit-flex; 213 | display: -ms-flexbox; 214 | display: flex; 215 | -webkit-box-pack: end; 216 | -webkit-justify-content: flex-end; 217 | -ms-flex-pack: end; 218 | justify-content: flex-end; 219 | -webkit-box-align: center; 220 | -webkit-align-items: center; 221 | -ms-flex-align: center; 222 | align-items: center; 223 | -webkit-box-flex: 1; 224 | -webkit-flex: 1; 225 | -ms-flex: 1; 226 | flex: 1; 227 | } 228 | 229 | 230 | 231 | .frame__role { 232 | margin-bottom: 2px; 233 | font-style: italic; 234 | text-transform: capitalize; 235 | color: #f1e9db; 236 | } 237 | 238 | 239 | .credit-wrap { 240 | margin-top: 12px; 241 | margin-bottom: 12px; 242 | } 243 | 244 | .frame__title { 245 | text-align: center; 246 | color: #f1e9db; 247 | } 248 | 249 | 250 | .frame__init { 251 | margin-bottom: 5px; 252 | text-align: center; 253 | } 254 | 255 | .italic { 256 | text-transform: none; 257 | color: #f1e9db; 258 | font-style: italic; 259 | } 260 | 261 | .frame__link { 262 | color: #f1e9db; 263 | } 264 | 265 | 266 | .frame__link.fl_1 { 267 | margin-left: 25px; 268 | text-decoration: none; 269 | text-transform: uppercase; 270 | } 271 | 272 | .frame__link.fl_1:hover { 273 | text-decoration: underline; 274 | } 275 | 276 | 277 | 278 | .frame__inner { 279 | display: -webkit-box; 280 | display: -webkit-flex; 281 | display: -ms-flexbox; 282 | display: flex; 283 | } 284 | 285 | .image { 286 | width: 5rem; 287 | } 288 | 289 | @media (max-width: 991px) { 290 | .app { 291 | position: absolute; 292 | left: 0%; 293 | top: 0%; 294 | right: 0%; 295 | bottom: 0%; 296 | height: 100%; 297 | } 298 | 299 | .h1 { 300 | font-size: 6rem; 301 | } 302 | 303 | 304 | .divider { 305 | width: 90px; 306 | } 307 | 308 | 309 | .frame__demo { 310 | font-size: 0.75rem; 311 | } 312 | 313 | .frame__credits { 314 | -webkit-box-flex: 0; 315 | -webkit-flex: 0 auto; 316 | -ms-flex: 0 auto; 317 | flex: 0 auto; 318 | } 319 | 320 | .frame__links { 321 | -webkit-box-flex: 0; 322 | -webkit-flex: 0 auto; 323 | -ms-flex: 0 auto; 324 | flex: 0 auto; 325 | } 326 | 327 | .frame__role { 328 | font-size: 0.75rem; 329 | } 330 | 331 | .frame__title { 332 | font-size: 0.75rem; 333 | } 334 | 335 | .frame__init { 336 | font-size: 0.75rem; 337 | } 338 | 339 | .frame__link { 340 | font-size: 0.75rem; 341 | } 342 | 343 | 344 | .frame__inner { 345 | -webkit-box-orient: vertical; 346 | -webkit-box-direction: normal; 347 | -webkit-flex-direction: column; 348 | -ms-flex-direction: column; 349 | flex-direction: column; 350 | -webkit-box-align: end; 351 | -webkit-align-items: flex-end; 352 | -ms-flex-align: end; 353 | align-items: flex-end; 354 | } 355 | } 356 | 357 | @media (max-width: 767px) { 358 | .link { 359 | margin-top: 1.4rem; 360 | margin-bottom: 1.4rem; 361 | } 362 | 363 | .h1 { 364 | font-size: 5rem; 365 | line-height: 5rem; 366 | } 367 | 368 | .grid.g3 { 369 | -webkit-box-orient: vertical; 370 | -webkit-box-direction: normal; 371 | -webkit-flex-direction: column; 372 | -ms-flex-direction: column; 373 | flex-direction: column; 374 | } 375 | 376 | .grid-items { 377 | -webkit-box-orient: vertical; 378 | -webkit-box-direction: normal; 379 | -webkit-flex-direction: column; 380 | -ms-flex-direction: column; 381 | flex-direction: column; 382 | } 383 | 384 | .divider { 385 | display: none; 386 | } 387 | 388 | .frame__role { 389 | font-size: 0.55rem; 390 | line-height: 0.55rem; 391 | } 392 | 393 | .italic { 394 | font-size: 0.55rem; 395 | } 396 | 397 | .frame__title { 398 | font-size: 0.55rem; 399 | line-height: 0.55rem; 400 | } 401 | 402 | .frame__link { 403 | font-size: 0.55rem; 404 | } 405 | 406 | .div-block { 407 | display: none; 408 | } 409 | } 410 | 411 | @media (max-width: 479px) { 412 | .text { 413 | font-size: 2vw; 414 | line-height: 2vw; 415 | } 416 | 417 | .link { 418 | margin: 10vw 0px; 419 | } 420 | 421 | 422 | .h1 { 423 | padding-top: 1vw; 424 | font-size: 14vw; 425 | line-height: 11vw; 426 | } 427 | 428 | .frame { 429 | padding-right: 2rem; 430 | padding-left: 2rem; 431 | } 432 | 433 | .frame__demo { 434 | font-size: 0.55rem; 435 | line-height: 0.55rem; 436 | } 437 | 438 | .frame__wrap { 439 | -webkit-box-orient: vertical; 440 | -webkit-box-direction: normal; 441 | -webkit-flex-direction: column; 442 | -ms-flex-direction: column; 443 | flex-direction: column; 444 | -webkit-box-pack: center; 445 | -webkit-justify-content: center; 446 | -ms-flex-pack: center; 447 | justify-content: center; 448 | -webkit-box-align: center; 449 | -webkit-align-items: center; 450 | -ms-flex-align: center; 451 | align-items: center; 452 | } 453 | 454 | .frame__credits { 455 | margin-bottom: 1vw; 456 | -webkit-box-orient: vertical; 457 | -webkit-box-direction: normal; 458 | -webkit-flex-direction: column; 459 | -ms-flex-direction: column; 460 | flex-direction: column; 461 | -webkit-box-pack: center; 462 | -webkit-justify-content: center; 463 | -ms-flex-pack: center; 464 | justify-content: center; 465 | -webkit-box-align: center; 466 | -webkit-align-items: center; 467 | -ms-flex-align: center; 468 | align-items: center; 469 | text-align: center; 470 | } 471 | 472 | .frame__title-wrap { 473 | margin-bottom: 2vw; 474 | } 475 | 476 | .frame__role { 477 | font-size: 2vw; 478 | line-height: 2vw; 479 | } 480 | 481 | .frame__title { 482 | font-size: 2vw; 483 | line-height: 2vw; 484 | } 485 | 486 | .frame__init { 487 | margin-bottom: 0.3vw; 488 | } 489 | 490 | .frame__link { 491 | font-size: 2vw; 492 | line-height: 2vw; 493 | } 494 | 495 | 496 | .frame__inner { 497 | -webkit-box-pack: center; 498 | -webkit-justify-content: center; 499 | -ms-flex-pack: center; 500 | justify-content: center; 501 | -webkit-box-align: center; 502 | -webkit-align-items: center; 503 | -ms-flex-align: center; 504 | align-items: center; 505 | } 506 | } 507 | 508 | @font-face { 509 | font-family: 'Le murmure'; 510 | src: url('../fonts/Le-Murmure.otf') format('opentype'); 511 | font-weight: 400; 512 | font-style: normal; 513 | } -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clementroche/motion-hover-effects/b9aaa953b3dd7a64186240f06e41a155d8bb419e/favicon.ico -------------------------------------------------------------------------------- /fonts/Le-Murmure.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clementroche/motion-hover-effects/b9aaa953b3dd7a64186240f06e41a155d8bb419e/fonts/Le-Murmure.otf -------------------------------------------------------------------------------- /img/demo1/img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clementroche/motion-hover-effects/b9aaa953b3dd7a64186240f06e41a155d8bb419e/img/demo1/img1.jpg -------------------------------------------------------------------------------- /img/demo1/img2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clementroche/motion-hover-effects/b9aaa953b3dd7a64186240f06e41a155d8bb419e/img/demo1/img2.jpg -------------------------------------------------------------------------------- /img/demo1/img3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clementroche/motion-hover-effects/b9aaa953b3dd7a64186240f06e41a155d8bb419e/img/demo1/img3.jpg -------------------------------------------------------------------------------- /img/demo2/img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clementroche/motion-hover-effects/b9aaa953b3dd7a64186240f06e41a155d8bb419e/img/demo2/img1.jpg -------------------------------------------------------------------------------- /img/demo2/img2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clementroche/motion-hover-effects/b9aaa953b3dd7a64186240f06e41a155d8bb419e/img/demo2/img2.jpg -------------------------------------------------------------------------------- /img/demo2/img3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clementroche/motion-hover-effects/b9aaa953b3dd7a64186240f06e41a155d8bb419e/img/demo2/img3.jpg -------------------------------------------------------------------------------- /img/demo3/img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clementroche/motion-hover-effects/b9aaa953b3dd7a64186240f06e41a155d8bb419e/img/demo3/img1.jpg -------------------------------------------------------------------------------- /img/demo3/img2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clementroche/motion-hover-effects/b9aaa953b3dd7a64186240f06e41a155d8bb419e/img/demo3/img2.jpg -------------------------------------------------------------------------------- /img/slash.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Motion Hover Effects | Demo 1 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 |
21 | Demo 1 22 | Demo 2 23 | Demo 3 24 |
25 |
26 |
27 |
28 |
art direction / dev / photography
29 | Niccolò miranda 30 |
31 |
32 |
Development
33 | Clément roche 34 |
35 |
36 |
37 |
presents
38 |
39 | How to Create Motion Hover Effects
with Image Distortions using Three.js 40 |
41 |
42 | 47 |
48 |
49 |
50 | 63 | 72 |
73 |
74 | 75 | 76 | 77 | 78 | 79 | 80 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /index2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Motion Hover Effects | Demo 2 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 |
21 | Demo 1 22 | Demo 2 23 | Demo 3 24 |
25 |
26 |
27 |
28 |
art direction / dev / photography
29 | Niccolò miranda 30 |
31 |
32 |
Development
33 | Clément roche 34 |
35 |
36 |
37 |
presents
38 |
39 | How to Create Motion Hover Effects
with Image Distortions using Three.js 40 |
41 |
42 | 47 |
48 |
49 |
50 | 51 |

buckskin

52 |
people, arizona
53 | img1 54 |
55 | 56 |

antelope

57 |
arizona, usa
58 | img2 59 |
60 | 61 |

pulpit rock

62 |
fjords, norway
63 | img3 64 |
65 |
66 |
67 | 68 | 69 | 70 | 71 | 72 | 73 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /index3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Motion Hover Effects | Demo 3 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 |
21 | Demo 1 22 | Demo 2 23 | Demo 3 24 |
25 |
26 |
27 |
28 |
art direction / dev / photography
29 | Niccolò miranda 30 |
31 |
32 |
Development
33 | Clément roche 34 |
35 |
36 |
37 |
presents
38 |
39 | How to Create Motion Hover Effects
with Image Distortions using Three.js 40 |
41 |
42 | 48 |
49 |
50 |
51 | 52 |

los angeles

53 |
ranger pickup
54 | img1 55 |
56 |
57 | slash 58 |
59 | 60 |

california

61 |
city lights
62 | img2 63 |
64 |
65 |
66 | 67 | 68 | 69 | 70 | 71 | 72 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /js/EffectShell.js: -------------------------------------------------------------------------------- 1 | class EffectShell { 2 | constructor(container = document.body, itemsWrapper = null) { 3 | this.container = container 4 | this.itemsWrapper = itemsWrapper 5 | if (!this.container || !this.itemsWrapper) return 6 | this.setup() 7 | this.initEffectShell().then(() => { 8 | console.log('load finished') 9 | this.isLoaded = true 10 | if (this.isMouseOver) this.onMouseOver(this.tempItemIndex) 11 | this.tempItemIndex = null 12 | }) 13 | this.createEventsListeners() 14 | } 15 | 16 | setup() { 17 | window.addEventListener('resize', this.onWindowResize.bind(this), false) 18 | 19 | // renderer 20 | this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }) 21 | this.renderer.setSize(this.viewport.width, this.viewport.height) 22 | this.renderer.setPixelRatio(window.devicePixelRatio) 23 | this.container.appendChild(this.renderer.domElement) 24 | 25 | // scene 26 | this.scene = new THREE.Scene() 27 | 28 | // camera 29 | this.camera = new THREE.PerspectiveCamera( 30 | 40, 31 | this.viewport.aspectRatio, 32 | 0.1, 33 | 100 34 | ) 35 | this.camera.position.set(0, 0, 3) 36 | 37 | //mouse 38 | this.mouse = new THREE.Vector2() 39 | 40 | // console.log(this.viewSize) 41 | // let pg = new THREE.PlaneBufferGeometry( 42 | // this.viewSize.width, 43 | // this.viewSize.height, 44 | // 1, 45 | // 1 46 | // ) 47 | // let pm = new THREE.MeshBasicMaterial({ color: 0xff0000 }) 48 | // let mm = new THREE.Mesh(pg, pm) 49 | // this.scene.add(mm) 50 | 51 | // time 52 | this.timeSpeed = 2 53 | this.time = 0 54 | this.clock = new THREE.Clock() 55 | 56 | // animation loop 57 | this.renderer.setAnimationLoop(this.render.bind(this)) 58 | } 59 | 60 | render() { 61 | // called every frame 62 | this.time += this.clock.getDelta() * this.timeSpeed 63 | this.renderer.render(this.scene, this.camera) 64 | } 65 | 66 | initEffectShell() { 67 | let promises = [] 68 | 69 | this.items = this.itemsElements 70 | 71 | const THREEtextureLoader = new THREE.TextureLoader() 72 | this.items.forEach((item, index) => { 73 | // create textures 74 | promises.push( 75 | this.loadTexture( 76 | THREEtextureLoader, 77 | item.img ? item.img.src : null, 78 | index 79 | ) 80 | ) 81 | }) 82 | 83 | return new Promise((resolve, reject) => { 84 | // resolve textures promises 85 | Promise.all(promises).then(promises => { 86 | // all textures are loaded 87 | promises.forEach((promise, index) => { 88 | // assign texture to item 89 | this.items[index].texture = promise.texture 90 | }) 91 | resolve() 92 | }) 93 | }) 94 | } 95 | 96 | createEventsListeners() { 97 | this.items.forEach((item, index) => { 98 | item.element.addEventListener( 99 | 'mouseover', 100 | this._onMouseOver.bind(this, index), 101 | false 102 | ) 103 | }) 104 | 105 | this.container.addEventListener( 106 | 'mousemove', 107 | this._onMouseMove.bind(this), 108 | false 109 | ) 110 | this.itemsWrapper.addEventListener( 111 | 'mouseleave', 112 | this._onMouseLeave.bind(this), 113 | false 114 | ) 115 | } 116 | 117 | _onMouseLeave(event) { 118 | this.isMouseOver = false 119 | this.onMouseLeave(event) 120 | } 121 | 122 | _onMouseMove(event) { 123 | // get normalized mouse position on viewport 124 | this.mouse.x = (event.clientX / this.viewport.width) * 2 - 1 125 | this.mouse.y = -(event.clientY / this.viewport.height) * 2 + 1 126 | 127 | this.onMouseMove(event) 128 | } 129 | 130 | _onMouseOver(index, event) { 131 | this.tempItemIndex = index 132 | this.onMouseOver(index, event) 133 | } 134 | 135 | onWindowResize() { 136 | this.camera.aspect = this.viewport.aspectRatio 137 | this.camera.updateProjectionMatrix() 138 | this.renderer.setSize(this.viewport.width, this.viewport.height) 139 | } 140 | 141 | onUpdate() {} 142 | 143 | onMouseEnter(event) {} 144 | 145 | onMouseLeave(event) {} 146 | 147 | onMouseMove(event) {} 148 | 149 | onMouseOver(index, event) {} 150 | 151 | get viewport() { 152 | let width = this.container.clientWidth 153 | let height = this.container.clientHeight 154 | let aspectRatio = width / height 155 | return { 156 | width, 157 | height, 158 | aspectRatio 159 | } 160 | } 161 | 162 | get viewSize() { 163 | // fit plane to screen 164 | // https://gist.github.com/ayamflow/96a1f554c3f88eef2f9d0024fc42940f 165 | 166 | let distance = this.camera.position.z 167 | let vFov = (this.camera.fov * Math.PI) / 180 168 | let height = 2 * Math.tan(vFov / 2) * distance 169 | let width = height * this.viewport.aspectRatio 170 | return { width, height, vFov } 171 | } 172 | 173 | get itemsElements() { 174 | // convert NodeList to Array 175 | const items = [...this.itemsWrapper.querySelectorAll('.link')] 176 | 177 | //create Array of items including element, image and index 178 | return items.map((item, index) => ({ 179 | element: item, 180 | img: item.querySelector('img') || null, 181 | index: index 182 | })) 183 | } 184 | 185 | loadTexture(loader, url, index) { 186 | // https://threejs.org/docs/#api/en/loaders/TextureLoader 187 | return new Promise((resolve, reject) => { 188 | if (!url) { 189 | resolve({ texture: null, index }) 190 | return 191 | } 192 | // load a resource 193 | loader.load( 194 | // resource URL 195 | url, 196 | 197 | // onLoad callback 198 | texture => { 199 | resolve({ texture, index }) 200 | }, 201 | 202 | // onProgress callback currently not supported 203 | undefined, 204 | 205 | // onError callback 206 | error => { 207 | console.error('An error happened.', error) 208 | reject(error) 209 | } 210 | ) 211 | }) 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /js/Math.js: -------------------------------------------------------------------------------- 1 | Number.prototype.map = function(in_min, in_max, out_min, out_max) { 2 | return ((this - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min 3 | } -------------------------------------------------------------------------------- /js/RGBShiftEffect.js: -------------------------------------------------------------------------------- 1 | class RGBShiftEffect extends EffectShell { 2 | constructor(container = document.body, itemsWrapper = null, options = {}) { 3 | super(container, itemsWrapper) 4 | if (!this.container || !this.itemsWrapper) return 5 | 6 | options.strength = options.strength || 0.25 7 | this.options = options 8 | 9 | this.init() 10 | } 11 | 12 | init() { 13 | this.position = new THREE.Vector3(0, 0, 0) 14 | this.scale = new THREE.Vector3(1, 1, 1) 15 | this.geometry = new THREE.PlaneBufferGeometry(1, 1, 32, 32) 16 | this.uniforms = { 17 | uTime: { 18 | value: 0 19 | }, 20 | uTexture: { 21 | value: null 22 | }, 23 | uOffset: { 24 | value: new THREE.Vector2(0.0, 0.0) 25 | }, 26 | uAlpha: { 27 | value: 0 28 | } 29 | } 30 | this.material = new THREE.ShaderMaterial({ 31 | uniforms: this.uniforms, 32 | vertexShader: ` 33 | uniform vec2 uOffset; 34 | 35 | varying vec2 vUv; 36 | 37 | vec3 deformationCurve(vec3 position, vec2 uv, vec2 offset) { 38 | float M_PI = 3.1415926535897932384626433832795; 39 | position.x = position.x + (sin(uv.y * M_PI) * offset.x); 40 | position.y = position.y + (sin(uv.x * M_PI) * offset.y); 41 | return position; 42 | } 43 | 44 | void main() { 45 | vUv = uv; 46 | vec3 newPosition = position; 47 | newPosition = deformationCurve(position,uv,uOffset); 48 | gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 ); 49 | } 50 | `, 51 | fragmentShader: ` 52 | uniform sampler2D uTexture; 53 | uniform float uAlpha; 54 | uniform vec2 uOffset; 55 | 56 | varying vec2 vUv; 57 | 58 | vec3 rgbShift(sampler2D texture, vec2 uv, vec2 offset) { 59 | float r = texture2D(uTexture,vUv + uOffset).r; 60 | vec2 gb = texture2D(uTexture,vUv).gb; 61 | return vec3(r,gb); 62 | } 63 | 64 | void main() { 65 | vec3 color = rgbShift(uTexture,vUv,uOffset); 66 | gl_FragColor = vec4(color,uAlpha); 67 | } 68 | `, 69 | transparent: true 70 | }) 71 | this.plane = new THREE.Mesh(this.geometry, this.material) 72 | this.scene.add(this.plane) 73 | } 74 | 75 | onMouseEnter() { 76 | if (!this.currentItem || !this.isMouseOver) { 77 | this.isMouseOver = true 78 | // show plane 79 | TweenLite.to(this.uniforms.uAlpha, 0.5, { 80 | value: 1, 81 | ease: Power4.easeOut 82 | }) 83 | } 84 | } 85 | 86 | onMouseLeave(event) { 87 | TweenLite.to(this.uniforms.uAlpha, 0.5, { 88 | value: 0, 89 | ease: Power4.easeOut 90 | }) 91 | } 92 | 93 | onMouseMove(event) { 94 | // project mouse position to world coodinates 95 | let x = this.mouse.x.map( 96 | -1, 97 | 1, 98 | -this.viewSize.width / 2, 99 | this.viewSize.width / 2 100 | ) 101 | let y = this.mouse.y.map( 102 | -1, 103 | 1, 104 | -this.viewSize.height / 2, 105 | this.viewSize.height / 2 106 | ) 107 | 108 | this.position = new THREE.Vector3(x, y, 0) 109 | TweenLite.to(this.plane.position, 1, { 110 | x: x, 111 | y: y, 112 | ease: Power4.easeOut, 113 | onUpdate: this.onPositionUpdate.bind(this) 114 | }) 115 | } 116 | 117 | onPositionUpdate() { 118 | // compute offset 119 | let offset = this.plane.position 120 | .clone() 121 | .sub(this.position) 122 | .multiplyScalar(-this.options.strength) 123 | this.uniforms.uOffset.value = offset 124 | } 125 | 126 | onMouseOver(index, e) { 127 | if (!this.isLoaded) return 128 | this.onMouseEnter() 129 | if (this.currentItem && this.currentItem.index === index) return 130 | this.onTargetChange(index) 131 | } 132 | 133 | onTargetChange(index) { 134 | // item target changed 135 | this.currentItem = this.items[index] 136 | if (!this.currentItem.texture) return 137 | 138 | // compute image ratio 139 | let imageRatio = 140 | this.currentItem.img.naturalWidth / this.currentItem.img.naturalHeight 141 | this.scale = new THREE.Vector3(imageRatio, 1, 1) 142 | this.uniforms.uTexture.value = this.currentItem.texture 143 | this.plane.scale.copy(this.scale) 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /js/StretchEffect.js: -------------------------------------------------------------------------------- 1 | class StretchEffect extends EffectShell { 2 | constructor(container = document.body, itemsWrapper = null, options = {}) { 3 | super(container, itemsWrapper) 4 | if (!this.container || !this.itemsWrapper) return 5 | 6 | options.strength = options.strength || 0.25 7 | this.options = options 8 | 9 | this.init() 10 | } 11 | 12 | init() { 13 | this.position = new THREE.Vector3(0, 0, 0) 14 | this.scale = new THREE.Vector3(1, 1, 1) 15 | this.geometry = new THREE.PlaneBufferGeometry(1, 1, 32, 32) 16 | this.uniforms = { 17 | uTexture: { 18 | value: null 19 | }, 20 | uOffset: { 21 | value: new THREE.Vector2(0.0, 0.0) 22 | }, 23 | uAlpha: { 24 | value: 0 25 | } 26 | } 27 | this.material = new THREE.ShaderMaterial({ 28 | uniforms: this.uniforms, 29 | vertexShader: ` 30 | uniform vec2 uOffset; 31 | 32 | varying vec2 vUv; 33 | 34 | vec3 deformationCurve(vec3 position, vec2 uv, vec2 offset) { 35 | float M_PI = 3.1415926535897932384626433832795; 36 | position.x = position.x + (sin(uv.y * M_PI) * offset.x); 37 | position.y = position.y + (sin(uv.x * M_PI) * offset.y); 38 | return position; 39 | } 40 | 41 | void main() { 42 | vUv = uv + (uOffset * 2.); 43 | vec3 newPosition = position; 44 | newPosition = deformationCurve(position,uv,uOffset); 45 | gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 ); 46 | } 47 | `, 48 | fragmentShader: ` 49 | uniform sampler2D uTexture; 50 | uniform float uAlpha; 51 | 52 | varying vec2 vUv; 53 | 54 | vec2 scaleUV(vec2 uv,float scale) { 55 | float center = 0.5; 56 | return ((uv - center) * scale) + center; 57 | } 58 | 59 | void main() { 60 | vec3 color = texture2D(uTexture,scaleUV(vUv,0.8)).rgb; 61 | gl_FragColor = vec4(color,uAlpha); 62 | } 63 | `, 64 | transparent: true 65 | }) 66 | this.plane = new THREE.Mesh(this.geometry, this.material) 67 | this.scene.add(this.plane) 68 | } 69 | 70 | onMouseEnter() { 71 | if (!this.currentItem || !this.isMouseOver) { 72 | this.isMouseOver = true 73 | // show plane 74 | TweenLite.to(this.uniforms.uAlpha, 0.5, { 75 | value: 1, 76 | ease: Power4.easeOut 77 | }) 78 | } 79 | } 80 | 81 | onMouseLeave(event) { 82 | TweenLite.to(this.uniforms.uAlpha, 0.5, { 83 | value: 0, 84 | ease: Power4.easeOut 85 | }) 86 | } 87 | 88 | onMouseMove(event) { 89 | // project mouse position to world coodinates 90 | let x = this.mouse.x.map( 91 | -1, 92 | 1, 93 | -this.viewSize.width / 2, 94 | this.viewSize.width / 2 95 | ) 96 | let y = this.mouse.y.map( 97 | -1, 98 | 1, 99 | -this.viewSize.height / 2, 100 | this.viewSize.height / 2 101 | ) 102 | 103 | // update position 104 | this.position = new THREE.Vector3(x, y, 0) 105 | TweenLite.to(this.plane.position, 1, { 106 | x: x, 107 | y: y, 108 | ease: Power4.easeOut, 109 | onUpdate: this.onPositionUpdate.bind(this) 110 | }) 111 | } 112 | 113 | onPositionUpdate() { 114 | // compute offset 115 | let offset = this.plane.position 116 | .clone() 117 | .sub(this.position) 118 | .multiplyScalar(-this.options.strength) 119 | this.uniforms.uOffset.value = offset 120 | } 121 | 122 | onMouseOver(index, e) { 123 | if (!this.isLoaded) return 124 | this.onMouseEnter() 125 | if (this.currentItem && this.currentItem.index === index) return 126 | this.onTargetChange(index) 127 | } 128 | 129 | onTargetChange(index) { 130 | // item target changed 131 | this.currentItem = this.items[index] 132 | if (!this.currentItem.texture) return 133 | 134 | // compute image ratio 135 | let imageRatio = 136 | this.currentItem.img.naturalWidth / this.currentItem.img.naturalHeight 137 | this.scale = new THREE.Vector3(imageRatio, 1, 1) 138 | this.uniforms.uTexture.value = this.currentItem.texture 139 | this.plane.scale.copy(this.scale) 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /js/TrailsEffect.js: -------------------------------------------------------------------------------- 1 | class TrailsEffect extends EffectShell { 2 | constructor(container = document.body, itemsWrapper = null, options = {}) { 3 | super(container, itemsWrapper) 4 | if (!this.container || !this.itemsWrapper) return 5 | 6 | options.strength = options.strength || 0.25 7 | options.amount = options.amount || 5 8 | options.duration = options.duration || 0.5 9 | this.options = options 10 | 11 | this.init() 12 | } 13 | 14 | init() { 15 | this.position = new THREE.Vector3(0, 0, 0) 16 | this.scale = new THREE.Vector3(1, 1, 1) 17 | this.geometry = new THREE.PlaneBufferGeometry(1, 1, 16, 16) 18 | //shared uniforms 19 | this.uniforms = { 20 | uTime: { 21 | value: 0 22 | }, 23 | uTexture: { 24 | value: null 25 | }, 26 | uOffset: { 27 | value: new THREE.Vector2(0.0, 0.0) 28 | }, 29 | uAlpha: { 30 | value: 0 31 | } 32 | } 33 | this.material = new THREE.ShaderMaterial({ 34 | uniforms: this.uniforms, 35 | vertexShader: ` 36 | uniform vec2 uOffset; 37 | 38 | varying vec2 vUv; 39 | 40 | vec3 deformationCurve(vec3 position, vec2 uv, vec2 offset) { 41 | float M_PI = 3.1415926535897932384626433832795; 42 | position.x = position.x + (sin(uv.y * M_PI) * offset.x); 43 | position.y = position.y + (sin(uv.x * M_PI) * offset.y); 44 | return position; 45 | } 46 | 47 | void main() { 48 | vUv = uv; 49 | vec3 newPosition = position; 50 | newPosition = deformationCurve(position,uv,uOffset); 51 | gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 ); 52 | } 53 | `, 54 | fragmentShader: ` 55 | uniform sampler2D uTexture; 56 | uniform float uAlpha; 57 | uniform vec2 uOffset; 58 | 59 | varying vec2 vUv; 60 | 61 | void main() { 62 | vec3 color = texture2D(uTexture,vUv).rgb; 63 | gl_FragColor = vec4(color,uAlpha); 64 | } 65 | `, 66 | transparent: true 67 | }) 68 | this.plane = new THREE.Mesh(this.geometry, this.material) 69 | 70 | this.trails = [] 71 | for (let i = 0; i < this.options.amount; i++) { 72 | let plane = this.plane.clone() 73 | this.trails.push(plane) 74 | this.scene.add(plane) 75 | } 76 | } 77 | 78 | onMouseEnter() { 79 | if (!this.currentItem || !this.isMouseOver) { 80 | this.isMouseOver = true 81 | // show plane 82 | TweenLite.to(this.uniforms.uAlpha, 0.5, { 83 | value: 1, 84 | ease: Power4.easeOut 85 | }) 86 | } 87 | } 88 | 89 | onMouseLeave(event) { 90 | TweenLite.to(this.uniforms.uAlpha, 0.5, { 91 | value: 0, 92 | ease: Power4.easeOut 93 | }) 94 | } 95 | 96 | onMouseMove(event) { 97 | // project mouse position to world coodinates 98 | let x = this.mouse.x.map( 99 | -1, 100 | 1, 101 | -this.viewSize.width / 2, 102 | this.viewSize.width / 2 103 | ) 104 | let y = this.mouse.y.map( 105 | -1, 106 | 1, 107 | -this.viewSize.height / 2, 108 | this.viewSize.height / 2 109 | ) 110 | 111 | TweenLite.to(this.position, 1, { 112 | x: x, 113 | y: y, 114 | ease: Power4.easeOut, 115 | onUpdate: () => { 116 | // compute offset 117 | let offset = this.position 118 | .clone() 119 | .sub(new THREE.Vector3(x, y, 0)) 120 | .multiplyScalar(-this.options.strength) 121 | this.uniforms.uOffset.value = offset 122 | } 123 | }) 124 | 125 | this.trails.forEach((trail, index) => { 126 | let duration = 127 | this.options.duration * this.options.amount - 128 | this.options.duration * index 129 | TweenLite.to(trail.position, duration, { 130 | x: x, 131 | y: y, 132 | ease: Power4.easeOut 133 | }) 134 | }) 135 | } 136 | 137 | onMouseOver(index, e) { 138 | if (!this.isLoaded) return 139 | this.onMouseEnter() 140 | if (this.currentItem && this.currentItem.index === index) return 141 | this.onTargetChange(index) 142 | } 143 | 144 | onTargetChange(index) { 145 | // item target changed 146 | this.currentItem = this.items[index] 147 | if (!this.currentItem.texture) return 148 | 149 | // compute image ratio 150 | let imageRatio = 151 | this.currentItem.img.naturalWidth / this.currentItem.img.naturalHeight 152 | this.scale = new THREE.Vector3(imageRatio, 1, 1) 153 | this.uniforms.uTexture.value = this.currentItem.texture 154 | //this.plane.scale.copy(this.scale) 155 | this.trails.forEach(trail => { 156 | trail.scale.copy(this.scale) 157 | }) 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /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