├── .gitignore ├── README.md ├── css ├── common.css ├── normalize.css ├── pater.css ├── style1.css ├── style2.css └── style3.css ├── favicon.ico ├── img ├── 1.png ├── 10.png ├── 11.png ├── 12.png ├── 13.png ├── 14.png ├── 15.png ├── 16.png ├── 17.png ├── 18.png ├── 19.png ├── 2.png ├── 20.png ├── 21.png ├── 22.png ├── 23.png ├── 24.png ├── 25.png ├── 3.png ├── 4.png ├── 5.png ├── 6.png ├── 7.png ├── 8.png ├── 9.png ├── c1.png ├── c2.png ├── c3.png ├── c4.png ├── c5.png ├── mandala.png ├── mandala2.png ├── mandala3.png └── sponsor │ ├── ipad1.png │ ├── ipad2.png │ ├── ipad3.png │ └── webydo-logo.png ├── index.html ├── index2.html ├── index3.html └── js ├── anime.min.js ├── charming.min.js ├── main.js ├── main2.js ├── main3.js └── textfx.js /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cubes Advent Calendar 2 | 3 | A 3D Advent calendar with fun hover effects and background color animations. Clicking the boxes opens another content level with different element animations. Inspired by [Adult Swim](http://www.adultswim.com/music/singles-2016/). Firefox support is [buggy](https://bugzilla.mozilla.org/show_bug.cgi?id=904304). 4 | 5 | ![Cubes Advent Calendar](http://tympanus.net/codrops/wp-content/uploads/2016/11/BoxesAdventCalendar.gif) 6 | 7 | [Article on Codrops](http://tympanus.net/codrops/?p=28603&preview=true) 8 | 9 | [Demo](http://tympanus.net/Development/CubesAdventCalendar/) 10 | 11 | ## License 12 | 13 | Integrate or build upon it for free in your personal or commercial projects. Don't republish, redistribute or sell "as-is". 14 | 15 | Read more here: [License](http://tympanus.net/codrops/licensing/) 16 | 17 | ## Credits 18 | 19 | - [anime.js](http://anime-js.com/) by Julian Garnier 20 | - [Charming.js](https://github.com/yuanqing/charming) by Yuan Qing 21 | - [Christmas vector patterns](http://www.freepik.com/free-vector/christmas-background-pixel_961323.htm) designed by Freepik. 22 | 23 | ## Misc 24 | 25 | Follow Codrops: [Twitter](http://www.twitter.com/codrops), [Facebook](http://www.facebook.com/pages/Codrops/159107397912), [Google+](https://plus.google.com/101095823814290637419), [GitHub](https://github.com/codrops), [Pinterest](http://www.pinterest.com/codrops/), [Instagram](https://www.instagram.com/codropsss/) 26 | 27 | [© Codrops 2016](http://www.codrops.com) 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /css/common.css: -------------------------------------------------------------------------------- 1 | *, 2 | *::after, 3 | *::before { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | font-family: 'Playfair Display', serif; 9 | color: #3f3f45; 10 | background: #f0f0f3; 11 | transition: background-color 0.8s; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | } 15 | 16 | a { 17 | color: #777785; 18 | outline: none; 19 | display: inline-block; 20 | position: relative; 21 | text-decoration: none; 22 | -webkit-transition: color 0.2s; 23 | transition: color 0.2s; 24 | } 25 | 26 | a.link::after { 27 | content: ''; 28 | position: absolute; 29 | top: 105%; 30 | width: 100%; 31 | border-bottom: 2px solid; 32 | left: 0; 33 | -webkit-transition: opacity 0.2s, -webkit-transform 0.2s; 34 | transition: opacity 0.2s, -webkit-transform 0.2s; 35 | } 36 | 37 | a.link:hover::after { 38 | opacity: 0; 39 | -webkit-transform: translate3d(0,3px,0); 40 | transform: translate3d(0,3px,0); 41 | } 42 | 43 | a:hover, 44 | a:focus { 45 | text-decoration: none; 46 | color: #3f3f45; 47 | } 48 | 49 | main { 50 | position: relative; 51 | display: -webkit-flex; 52 | display: -ms-flexbox; 53 | display: flex; 54 | -webkit-flex-direction: column; 55 | -ms-flex-direction: column; 56 | flex-direction: column; 57 | overflow-x: hidden; 58 | width: 100vw; 59 | height: 100vh; 60 | } 61 | 62 | .hidden { 63 | position: absolute; 64 | overflow: hidden; 65 | width: 0; 66 | height: 0; 67 | pointer-events: none; 68 | } 69 | 70 | 71 | /* Icons */ 72 | 73 | .icon { 74 | display: block; 75 | width: 1.5em; 76 | height: 1.5em; 77 | margin: 0 auto; 78 | fill: currentColor; 79 | } 80 | 81 | 82 | /* Header */ 83 | 84 | .codrops-header { 85 | position: relative; 86 | z-index: 1000; 87 | display: -webkit-flex; 88 | display: -ms-flexbox; 89 | display: flex; 90 | -webkit-flex-direction: row; 91 | -ms-flex-direction: row; 92 | flex-direction: row; 93 | -webkit-flex-wrap: wrap; 94 | -ms-flex-wrap: wrap; 95 | flex-wrap: wrap; 96 | -webkit-justify-content: space-between; 97 | -ms-flex-pack: justify; 98 | justify-content: space-between; 99 | -webkit-align-items: center; 100 | -ms-flex-align: center; 101 | align-items: center; 102 | -webkit-flex: none; 103 | -ms-flex: none; 104 | flex: none; 105 | width: 100%; 106 | padding: 0.5em 1.25em 0.5em 0.75em; 107 | background: #fff; 108 | } 109 | 110 | .codrops-header__main { 111 | display: -webkit-flex; 112 | display: -ms-flexbox; 113 | display: flex; 114 | -webkit-flex-direction: row; 115 | -ms-flex-direction: row; 116 | flex-direction: row; 117 | -webkit-flex-wrap: wrap; 118 | -ms-flex-wrap: wrap; 119 | flex-wrap: wrap; 120 | -webkit-align-items: center; 121 | -ms-flex-align: center; 122 | align-items: center; 123 | } 124 | 125 | .codrops-header__title { 126 | font-size: 1.5em; 127 | font-weight: 700; 128 | margin: 0; 129 | line-height: 0.8; 130 | padding: 0 0 0.1em 0; 131 | } 132 | 133 | .codrops-header__tagline { 134 | font-family: 'Avenir Next', Avenir, 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, sans-serif; 135 | padding: 0 0.5em 0 5vw; 136 | margin: 0 auto 0 0; 137 | } 138 | 139 | /* Top Navigation Style */ 140 | 141 | .codrops-links { 142 | position: relative; 143 | display: -webkit-flex; 144 | display: -ms-flexbox; 145 | display: flex; 146 | -webkit-justify-content: center; 147 | -ms-flex-pack: center; 148 | justify-content: center; 149 | text-align: center; 150 | white-space: nowrap; 151 | } 152 | 153 | .codrops-links::after { 154 | content: ''; 155 | position: absolute; 156 | top: 15%; 157 | left: 50%; 158 | width: 2px; 159 | height: 70%; 160 | opacity: 0.7; 161 | background: rgba(0, 0, 0, 0.25); 162 | -webkit-transform: rotate3d(0, 0, 1, 22.5deg); 163 | transform: rotate3d(0, 0, 1, 22.5deg); 164 | } 165 | 166 | .codrops-icon { 167 | display: inline-block; 168 | margin: 0.5em; 169 | padding: 0.5em; 170 | } 171 | 172 | /* Demo links */ 173 | 174 | .codrops-demos { 175 | margin: 0.25em 0; 176 | padding: 0 1em; 177 | font-weight: bold; 178 | } 179 | 180 | .codrops-demos a { 181 | display: inline-block; 182 | margin: 0 0.5em 0 0; 183 | } 184 | 185 | .codrops-demos a.current-demo { 186 | color: #333; 187 | } 188 | 189 | .codrops-demos a.current-demo::after { 190 | display: none; 191 | } 192 | 193 | 194 | /* Calendar */ 195 | 196 | .calendar-wrap { 197 | position: relative; 198 | } 199 | 200 | .js .calendar-wrap { 201 | -webkit-flex: 1; 202 | -ms-flex: 1; 203 | flex: 1; 204 | } 205 | 206 | .calendar { 207 | position: relative; 208 | width: 100%; 209 | height: 100%; 210 | margin: 0 auto; 211 | overflow: hidden; 212 | /* we always want 7 boxes in a row */ 213 | padding: 3em calc((100vw - (7 * (7vw + 1vw)))/2); 214 | } 215 | 216 | .js .calendar { 217 | position: absolute; 218 | -webkit-perspective: 1000px; 219 | perspective: 1000px; 220 | padding: 0 calc((100vw - (7 * (7vw + 1vw)))/2) 5em; 221 | } 222 | 223 | .no-js .calendar { 224 | display: -webkit-flex; 225 | display: -ms-flexbox; 226 | display: flex; 227 | -webkit-flex-wrap: wrap; 228 | -ms-flex-wrap: wrap; 229 | flex-wrap: wrap; 230 | -webkit-align-content: center; 231 | -ms-flex-line-pack: center; 232 | align-content: center; 233 | -webkit-align-items: center; 234 | -ms-flex-align: center; 235 | align-items: center; 236 | } 237 | 238 | 239 | /* Cubes container */ 240 | 241 | .cubes { 242 | display: -webkit-flex; 243 | display: -ms-flexbox; 244 | display: flex; 245 | -webkit-flex-wrap: wrap; 246 | -ms-flex-wrap: wrap; 247 | flex-wrap: wrap; 248 | -webkit-align-content: center; 249 | -ms-flex-line-pack: center; 250 | align-content: center; 251 | -webkit-align-items: center; 252 | -ms-flex-align: center; 253 | align-items: center; 254 | width: 100%; 255 | height: 100%; 256 | -webkit-transform-style: preserve-3d; 257 | transform-style: preserve-3d; 258 | } 259 | 260 | 261 | /* Single cube */ 262 | 263 | .cube { 264 | position: relative; 265 | display: block; 266 | -webkit-flex: none; 267 | -ms-flex: none; 268 | flex: none; 269 | width: 7vw; 270 | height: 7vw; 271 | margin: 0.5vw; 272 | } 273 | 274 | .js .cube { 275 | -webkit-flex: auto; 276 | -ms-flex: auto; 277 | flex: auto; 278 | -webkit-transform-style: preserve-3d; 279 | transform-style: preserve-3d; 280 | } 281 | 282 | 283 | /* push to the right weekday (we have to push 3 boxes) */ 284 | 285 | .js .cube:first-child { 286 | margin-left: calc(((7vw + 1vw) * 3) + 0.5vw); 287 | } 288 | 289 | .js .cube:not(.cube--inactive) { 290 | cursor: pointer; 291 | } 292 | 293 | 294 | /* cube sides and rotations */ 295 | 296 | .cube__side { 297 | position: absolute; 298 | top: 0; 299 | left: 0; 300 | width: inherit; 301 | height: inherit; 302 | -webkit-backface-visibility: hidden; 303 | backface-visibility: hidden; 304 | } 305 | 306 | .cube__side--front { 307 | position: relative; 308 | -webkit-transform: translateZ(3.5vw); 309 | transform: translateZ(3.5vw); 310 | } 311 | 312 | .cube__side--back { 313 | -webkit-transform: rotateY(180deg) translateZ(3.5vw); 314 | transform: rotateY(180deg) translateZ(3.5vw); 315 | } 316 | 317 | .cube__side--right { 318 | -webkit-transform: rotateY(90deg) translateZ(3.5vw); 319 | transform: rotateY(90deg) translateZ(3.5vw); 320 | } 321 | 322 | .cube__side--left { 323 | -webkit-transform: rotateY(-90deg) translateZ(3.5vw); 324 | transform: rotateY(-90deg) translateZ(3.5vw); 325 | } 326 | 327 | .cube__side--top { 328 | -webkit-transform: rotateX(90deg) translateZ(3.5vw); 329 | transform: rotateX(90deg) translateZ(3.5vw); 330 | } 331 | 332 | .cube__side--bottom { 333 | -webkit-transform: rotateX(-90deg) translateZ(3.5vw); 334 | transform: rotateX(-90deg) translateZ(3.5vw); 335 | } 336 | 337 | 338 | /* Cube counters and numbers */ 339 | 340 | 341 | /* Without JS we want an auto counter */ 342 | 343 | .no-js .calendar { 344 | counter-reset: boxes-counter; 345 | } 346 | 347 | .no-js .cube { 348 | counter-increment: boxes-counter; 349 | } 350 | 351 | .no-js .cube::after { 352 | content: counter(boxes-counter); 353 | } 354 | 355 | .cube__number, 356 | .no-js .cube::after { 357 | position: absolute; 358 | right: 0; 359 | bottom: 0; 360 | } 361 | 362 | 363 | /* canvas for snow */ 364 | 365 | .background { 366 | position: absolute; 367 | top: 0; 368 | left: 0; 369 | width: 100%; 370 | height: 100%; 371 | min-height: 100vh; 372 | transition: background-color 0.8s; 373 | } 374 | 375 | 376 | /* title that appears on hover */ 377 | 378 | .title { 379 | font-size: 3.25vw; 380 | font-weight: 700; 381 | position: absolute; 382 | right: 3vw; 383 | bottom: 3vw; 384 | margin: 0; 385 | white-space: nowrap; 386 | pointer-events: none; 387 | opacity: 0; 388 | } 389 | 390 | 391 | /* number before title */ 392 | 393 | .title::before { 394 | content: attr(data-number); 395 | display: inline-block; 396 | margin-right: 0.5em; 397 | color: white; 398 | } 399 | 400 | 401 | /* letter span for animations */ 402 | 403 | [class*='letter'] { 404 | position: relative; 405 | display: inline-block; 406 | white-space: pre; 407 | } 408 | 409 | [class*='letter']:blank { 410 | padding-right: 10em; 411 | } 412 | 413 | 414 | /* content wrap */ 415 | 416 | .content { 417 | position: relative; 418 | } 419 | 420 | .js .content { 421 | position: absolute; 422 | top: 0; 423 | left: 0; 424 | overflow: hidden; 425 | width: 100%; 426 | height: 100%; 427 | pointer-events: none; 428 | } 429 | 430 | 431 | /* individual content block */ 432 | 433 | .content__block { 434 | padding: 10vh 5vw; 435 | } 436 | 437 | .js .content__block { 438 | padding: 20vh 5vw; 439 | position: absolute; 440 | z-index: 100; 441 | display: -webkit-flex; 442 | display: -ms-flexbox; 443 | display: flex; 444 | -webkit-flex-direction: column; 445 | -ms-flex-direction: column; 446 | flex-direction: column; 447 | -webkit-justify-content: center; 448 | -ms-flex-pack: center; 449 | justify-content: center; 450 | width: 85%; 451 | height: 100%; 452 | padding: 3em 0 6em 7vw; 453 | -webkit-user-select: none; 454 | -moz-user-select: none; 455 | -ms-user-select: none; 456 | user-select: none; 457 | -webkit-touch-callout: none; 458 | -khtml-user-select: none; 459 | } 460 | 461 | .content__title { 462 | font-size: 7vw; 463 | line-height: 0.85; 464 | margin: 0; 465 | } 466 | 467 | .content__description { 468 | font-size: 2.25vw; 469 | margin: 1em 0; 470 | padding: 0 0 0 5vw; 471 | } 472 | 473 | .content__meta { 474 | font-family: 'Avenir Next', Avenir, 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, sans-serif; 475 | margin: 0; 476 | padding: 0 0 0 2vw; 477 | } 478 | 479 | .content__meta::before { 480 | content: '\2014'; 481 | } 482 | 483 | .content__number { 484 | position: absolute; 485 | } 486 | 487 | .btn-back { 488 | font-size: 2em; 489 | line-height: 2; 490 | position: absolute; 491 | z-index: 100; 492 | right: 0; 493 | bottom: 0; 494 | width: 2em; 495 | margin: 0; 496 | margin: 1em; 497 | padding: 0; 498 | pointer-events: auto; 499 | color: currentColor; 500 | border: 0; 501 | border: 2px solid; 502 | background: none; 503 | } 504 | 505 | .btn-back:focus { 506 | outline: none; 507 | } 508 | 509 | .no-js .content__number, 510 | .no-js .btn-back { 511 | display: none; 512 | } 513 | 514 | .js .content__block, 515 | .js .content__description, 516 | .js .content__meta, 517 | .js .content__number, 518 | .js .btn-back { 519 | opacity: 0; 520 | } 521 | 522 | .js .content__block--current { 523 | pointer-events: auto; 524 | opacity: 1; 525 | } 526 | 527 | @media screen and (max-width: 50.75em) { 528 | .calendar { 529 | padding: 3em calc((100vw - (7 * (14vw + 1vw)))/2); 530 | } 531 | .js .calendar { 532 | padding: 0 calc((100vw - (7 * (12vw + 1vw)))/2) 5em; 533 | } 534 | .cube { 535 | width: 12vw; 536 | height: 12vw; 537 | } 538 | /* push to the right weekday if in big view (we have to push 3 boxes) */ 539 | .js .cube:first-child { 540 | margin-left: calc(((12vw + 1vw) * 3) + 0.5vw); 541 | } 542 | .cube__side--front { 543 | -webkit-transform: translateZ(6vw); 544 | transform: translateZ(6vw); 545 | } 546 | .cube__side--back { 547 | -webkit-transform: rotateY(180deg) translateZ(6vw); 548 | transform: rotateY(180deg) translateZ(6vw); 549 | } 550 | .cube__side--right { 551 | -webkit-transform: rotateY(90deg) translateZ(6vw); 552 | transform: rotateY(90deg) translateZ(6vw); 553 | } 554 | .cube__side--left { 555 | -webkit-transform: rotateY(-90deg) translateZ(6vw); 556 | transform: rotateY(-90deg) translateZ(6vw); 557 | } 558 | .cube__side--top { 559 | -webkit-transform: rotateX(90deg) translateZ(6vw); 560 | transform: rotateX(90deg) translateZ(6vw); 561 | } 562 | .cube__side--bottom { 563 | -webkit-transform: rotateX(-90deg) translateZ(6vw); 564 | transform: rotateX(-90deg) translateZ(6vw); 565 | } 566 | .title { 567 | font-size: 5vw; 568 | } 569 | .content__description { 570 | font-size: 1.15em; 571 | padding: 0 0 0 0.5em; 572 | } 573 | .js .content__block { 574 | padding: 2em; 575 | width: 100%; 576 | } 577 | .btn-back { 578 | font-size: 1.25em; 579 | bottom: auto; 580 | top: 0; 581 | margin: 0.5em; 582 | } 583 | } 584 | 585 | @media screen and (max-width: 26em) { 586 | .codrops-header { 587 | font-size: 0.75em; 588 | } 589 | .codrops-header__tagline { 590 | display: none; 591 | } 592 | .codrops-header__title { 593 | font-size: 1.5em; 594 | } 595 | .codrops-demos { 596 | width: 100%; 597 | margin: 0; 598 | padding: 0.5em 1em; 599 | } 600 | } 601 | -------------------------------------------------------------------------------- /css/normalize.css: -------------------------------------------------------------------------------- 1 | article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block;}audio,canvas,video{display:inline-block;}audio:not([controls]){display:none;height:0;}[hidden]{display:none;}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;}body{margin:0;}a:focus{outline:thin dotted;}a:active,a:hover{outline:0;}h1{font-size:2em;margin:0.67em 0;}abbr[title]{border-bottom:1px dotted;}b,strong{font-weight:bold;}dfn{font-style:italic;}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0;}mark{background:#ff0;color:#000;}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em;}pre{white-space:pre-wrap;}q{quotes:"\201C" "\201D" "\2018" "\2019";}small{font-size:80%;}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sup{top:-0.5em;}sub{bottom:-0.25em;}img{border:0;}svg:not(:root){overflow:hidden;}figure{margin:0;}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em;}legend{border:0;padding:0;}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0;}button,input{line-height:normal;}button,select{text-transform:none;}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;}button[disabled],html input[disabled]{cursor:default;}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none;}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}textarea{overflow:auto;vertical-align:top;}table{border-collapse:collapse;border-spacing:0;} -------------------------------------------------------------------------------- /css/pater.css: -------------------------------------------------------------------------------- 1 | 2 | .pater { 3 | position: fixed; 4 | width: 320px; 5 | height: auto; 6 | bottom: 0; 7 | left: 0; 8 | padding: 1em 2em 2em 2em; 9 | font-family: 'Helvetica', Arial, sans-serif; 10 | color: #000; 11 | font-size: 0.85em; 12 | pointer-events: none; 13 | -webkit-touch-callout: none; 14 | -webkit-user-select: none; 15 | -khtml-user-select: none; 16 | -moz-user-select: none; 17 | -ms-user-select: none; 18 | user-select: none; 19 | z-index: 10000; 20 | } 21 | 22 | .pater:hover { 23 | pointer-events: auto; 24 | } 25 | 26 | .pater__title { 27 | line-height: 1; 28 | position: relative; 29 | z-index: 10; 30 | padding: 10px 0 8px 52px; 31 | cursor: default; 32 | color: #262628; 33 | background: url(../img/sponsor/webydo-logo.png) no-repeat 0% 50%; 34 | -webkit-transform: translateY(40px); 35 | transform: translateY(40px); 36 | opacity: 0; 37 | -webkit-transition: -webkit-transform 0.3s, opacity 0.3s; 38 | transition: transform 0.3s, opacity 0.3s; 39 | } 40 | 41 | .pater:hover .pater__title { 42 | opacity: 1; 43 | -webkit-transform: translateY(0); 44 | transform: translateY(0); 45 | } 46 | 47 | .pater__hidden { 48 | position: relative; 49 | z-index: 100; 50 | opacity: 0; 51 | -webkit-transition: opacity 0.3s; 52 | transition: opacity 0.3s; 53 | } 54 | 55 | .pater:hover .pater__hidden { 56 | opacity: 1; 57 | } 58 | 59 | .pater__description { 60 | line-height: 1.2; 61 | color: #747474; 62 | cursor: default; 63 | } 64 | 65 | .pater__sponsor { 66 | font-size: 0.875em; 67 | position: relative; 68 | display: block; 69 | z-index: 10; 70 | cursor: default; 71 | color: #262628; 72 | -webkit-transform: translate3d(139px,0px,0); 73 | transform: translate3d(139px,0px,0); 74 | -webkit-transition: -webkit-transform 0.3s, color 0.3s; 75 | transition: transform 0.3s, color 0.3s; 76 | } 77 | 78 | .pater:hover .pater__sponsor { 79 | color: #262628; 80 | -webkit-transform: translate3d(0,0,0); 81 | transform: translate3d(0,0,0); 82 | } 83 | 84 | .pater__button { 85 | background: #fec841; 86 | color: #262628; 87 | cursor: pointer; 88 | padding: 0.65em 1.25em; 89 | border-radius: 1.5em; 90 | display: inline-block; 91 | position: absolute; 92 | right: 0; 93 | top: 100%; 94 | margin: 0.5em 0 0; 95 | z-index: 100; 96 | line-height: 1; 97 | -webkit-transition: background-color 0.2s, color 0.2s; 98 | transition: background-color 0.2s, color 0.2s; 99 | } 100 | 101 | .pater__button:hover { 102 | background: #000; 103 | color: #fff; 104 | } 105 | 106 | .pater__effect { 107 | position: absolute; 108 | pointer-events: auto; 109 | width: 260px; 110 | top: -4.5em; 111 | left: 0; 112 | -webkit-transform: rotate(-22.5deg); 113 | transform: rotate(-22.5deg); 114 | } 115 | 116 | .pater__effect img { 117 | display: block; 118 | float: left; 119 | position: relative; 120 | -webkit-transition: -webkit-transform 0.3s; 121 | transition: transform 0.3s; 122 | } 123 | 124 | .pater__effect img:nth-child(2) { 125 | margin: 4em 0 0 -3em; 126 | } 127 | 128 | .pater__effect img:nth-child(3) { 129 | margin: -7em 0 0 0.5em; 130 | } 131 | 132 | .pater:hover .pater__effect img:nth-child(1) { 133 | -webkit-transform: translate3d(0,-110px,0); 134 | transform: translate3d(0,-110px,0); 135 | } 136 | 137 | .pater:hover .pater__effect img:nth-child(2) { 138 | -webkit-transform: translate3d(0,-130px,0); 139 | transform: translate3d(0,-130px,0); 140 | } 141 | 142 | .pater:hover .pater__effect img:nth-child(3) { 143 | -webkit-transform: translateY(55px); 144 | transform: translateY(55px); 145 | } 146 | 147 | .pater-responsive { 148 | position: fixed; 149 | display: none; 150 | bottom: 0; 151 | width: 100%; 152 | left: 0; 153 | z-index: 1000; 154 | font-size: 0.85em; 155 | padding: 1.5em 1em 1.5em 5em; 156 | color: #000; 157 | font-family: 'Helvetica Neue', Arial, sans-serif; 158 | background: #fff url(../img/sponsor/webydo-logo.png) no-repeat 0.75em 50%; 159 | } 160 | 161 | @media screen and (max-width: 50.75em) { 162 | .pater { 163 | display: none; 164 | } 165 | .pater-responsive { 166 | display: block; 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /css/style1.css: -------------------------------------------------------------------------------- 1 | .cube__side, 2 | .no-js .cube { 3 | border: 0.75vw solid #fff; 4 | outline: 1px solid #fff; 5 | background: #f0f0f0 url(../img/mandala.png) no-repeat center center; 6 | } 7 | 8 | .cube:not(.cube--inactive):nth-child(2n) .cube__side, 9 | .no-js .cube:not(.cube--inactive):nth-child(2n) { 10 | background-image: url(../img/mandala2.png); 11 | } 12 | 13 | .cube:not(.cube--inactive):nth-child(3n) .cube__side, 14 | .no-js .cube:not(.cube--inactive):nth-child(3n) { 15 | background-image: url(../img/mandala3.png); 16 | } 17 | 18 | .cube--inactive .cube__side, 19 | .no-js .cube--inactive { 20 | background: #e1e0e0; 21 | } 22 | 23 | 24 | /* With JS we insert a number span into the cube */ 25 | 26 | .cube__number, 27 | .no-js .cube::after { 28 | font-family: 'Avenir Next', Avenir, 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, sans-serif; 29 | font-weight: 700; 30 | line-height: 2.5; 31 | width: 2em; 32 | height: 2em; 33 | padding: 0 0 0 0.25em; 34 | text-align: center; 35 | letter-spacing: -0.05em; 36 | color: #fff; 37 | border-radius: 100% 0 0 0; 38 | background: #f8af8d; 39 | } 40 | 41 | .cube:nth-child(2n):not(.cube--inactive) .cube__number, 42 | .no-js .cube:nth-child(2n):not(.cube--inactive)::after { 43 | background: #f8d18d; 44 | } 45 | 46 | .cube:nth-child(3n):not(.cube--inactive) .cube__number, 47 | .no-js .cube:nth-child(3n):not(.cube--inactive)::after { 48 | background: #8df88d; 49 | } 50 | 51 | .cube--inactive .cube__number, 52 | .no-js .cube--inactive::after { 53 | background: #aaa; 54 | } 55 | 56 | .js .content__block { 57 | text-align: right; 58 | } 59 | 60 | .content__number { 61 | font-family: 'Avenir Next', Avenir, 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, sans-serif; 62 | font-size: 40vw; 63 | font-weight: bold; 64 | line-height: 0.5; 65 | right: 0; 66 | bottom: 30vh; 67 | text-indent: -0.175em; 68 | letter-spacing: -0.175em; 69 | color: #fff; 70 | } 71 | -------------------------------------------------------------------------------- /css/style2.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: 'Montserrat', sans-serif; 3 | } 4 | 5 | .cube__side, 6 | .no-js .cube { 7 | border: 10px solid; 8 | outline: 1px solid; 9 | background-color: currentColor; 10 | background-blend-mode: soft-light; 11 | } 12 | 13 | .cube:not(.cube--inactive):nth-child(1) .cube__side, 14 | .no-js .cube:not(.cube--inactive):nth-child(1) { 15 | background-image: url(../img/1.png); 16 | color: #f44336; 17 | } 18 | 19 | .cube:not(.cube--inactive):nth-child(2) .cube__side, 20 | .no-js .cube:not(.cube--inactive):nth-child(2) { 21 | background-image: url(../img/2.png); 22 | color: #e91e63; 23 | } 24 | 25 | .cube:not(.cube--inactive):nth-child(3) .cube__side, 26 | .no-js .cube:not(.cube--inactive):nth-child(3) { 27 | background-image: url(../img/3.png); 28 | color: #9c27b0; 29 | } 30 | 31 | .cube:not(.cube--inactive):nth-child(4) .cube__side, 32 | .no-js .cube:not(.cube--inactive):nth-child(4) { 33 | background-image: url(../img/4.png); 34 | color: #673ab7; 35 | } 36 | 37 | .cube:not(.cube--inactive):nth-child(5) .cube__side, 38 | .no-js .cube:not(.cube--inactive):nth-child(5) { 39 | background-image: url(../img/5.png); 40 | color: #3f51b5; 41 | } 42 | 43 | .cube:not(.cube--inactive):nth-child(6) .cube__side, 44 | .no-js .cube:not(.cube--inactive):nth-child(6) { 45 | background-image: url(../img/6.png); 46 | color: #2196f3; 47 | } 48 | 49 | .cube:not(.cube--inactive):nth-child(7) .cube__side, 50 | .no-js .cube:not(.cube--inactive):nth-child(7) { 51 | background-image: url(../img/7.png); 52 | color: #03a9f4; 53 | } 54 | 55 | .cube:not(.cube--inactive):nth-child(8) .cube__side, 56 | .no-js .cube:not(.cube--inactive):nth-child(8) { 57 | background-image: url(../img/8.png); 58 | color: #00bcd4; 59 | } 60 | 61 | .cube:not(.cube--inactive):nth-child(9) .cube__side, 62 | .no-js .cube:not(.cube--inactive):nth-child(9) { 63 | background-image: url(../img/9.png); 64 | color: #009688; 65 | } 66 | 67 | .cube:not(.cube--inactive):nth-child(10) .cube__side, 68 | .no-js .cube:not(.cube--inactive):nth-child(10) { 69 | background-image: url(../img/10.png); 70 | color: #4caf50; 71 | } 72 | 73 | .cube:not(.cube--inactive):nth-child(11) .cube__side, 74 | .no-js .cube:not(.cube--inactive):nth-child(11) { 75 | background-image: url(../img/11.png); 76 | color: #8bc34a; 77 | } 78 | 79 | .cube:not(.cube--inactive):nth-child(12) .cube__side, 80 | .no-js .cube:not(.cube--inactive):nth-child(12) { 81 | background-image: url(../img/12.png); 82 | color: #cddc39; 83 | } 84 | 85 | .cube:not(.cube--inactive):nth-child(13) .cube__side, 86 | .no-js .cube:not(.cube--inactive):nth-child(13) { 87 | background-image: url(../img/13.png); 88 | color: #ffeb3b; 89 | } 90 | 91 | .cube:not(.cube--inactive):nth-child(14) .cube__side, 92 | .no-js .cube:not(.cube--inactive):nth-child(14) { 93 | background-image: url(../img/14.png); 94 | color: #ffc107; 95 | } 96 | 97 | .cube:not(.cube--inactive):nth-child(15) .cube__side, 98 | .no-js .cube:not(.cube--inactive):nth-child(15) { 99 | background-image: url(../img/15.png); 100 | color: #ff9800; 101 | } 102 | 103 | .cube:not(.cube--inactive):nth-child(16) .cube__side, 104 | .no-js .cube:not(.cube--inactive):nth-child(16) { 105 | background-image: url(../img/16.png); 106 | color: #ff5722; 107 | } 108 | 109 | .cube:not(.cube--inactive):nth-child(17) .cube__side, 110 | .no-js .cube:not(.cube--inactive):nth-child(17) { 111 | background-image: url(../img/17.png); 112 | color: #795548; 113 | } 114 | 115 | .cube:not(.cube--inactive):nth-child(18) .cube__side, 116 | .no-js .cube:not(.cube--inactive):nth-child(18) { 117 | background-image: url(../img/18.png); 118 | color: #564545; 119 | } 120 | 121 | .cube:not(.cube--inactive):nth-child(19) .cube__side, 122 | .no-js .cube:not(.cube--inactive):nth-child(19) { 123 | background-image: url(../img/19.png); 124 | color: #607d8b; 125 | } 126 | 127 | .cube:not(.cube--inactive):nth-child(20) .cube__side, 128 | .no-js .cube:not(.cube--inactive):nth-child(20) { 129 | background-image: url(../img/20.png); 130 | color: #405d6b; 131 | } 132 | 133 | .cube:not(.cube--inactive):nth-child(21) .cube__side, 134 | .no-js .cube:not(.cube--inactive):nth-child(21) { 135 | background-image: url(../img/21.png); 136 | color: #9e9e9e; 137 | } 138 | 139 | .cube:not(.cube--inactive):nth-child(22) .cube__side, 140 | .no-js .cube:not(.cube--inactive):nth-child(22) { 141 | background-image: url(../img/22.png); 142 | color: #70737d; 143 | } 144 | 145 | .cube--inactive .cube__side, 146 | .no-js .cube--inactive { 147 | background: #2e2e37; 148 | } 149 | 150 | 151 | /* With JS we insert a number span into the cube */ 152 | 153 | .cube__number, 154 | .no-js .cube::after { 155 | bottom: auto; 156 | top: 0.15em; 157 | left: 0.25em; 158 | right: auto; 159 | line-height: 1; 160 | font-size: 2em; 161 | color: #fff; 162 | text-align: center; 163 | font-weight: bold; 164 | text-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); 165 | } 166 | 167 | 168 | @media screen and (max-width: 50.75em) { 169 | .cube__number, 170 | .no-js .cube::after { 171 | font-size: 1em; 172 | } 173 | } 174 | 175 | .js .content__block { 176 | width: 100%; 177 | text-align: center; 178 | left: 0; 179 | padding: 2em; 180 | } 181 | 182 | .js .content__description { 183 | padding: 0; 184 | max-width: 30em; 185 | margin: 2em auto 0.5em; 186 | } 187 | 188 | .js .content__meta { 189 | padding: 0; 190 | } 191 | 192 | .content__number { 193 | color: #fff; 194 | font-weight: bold; 195 | line-height: 0.5; 196 | letter-spacing: -0.175em; 197 | text-indent: -0.175em; 198 | font-size: 40vw; 199 | left: 50%; 200 | top: 50%; 201 | -webkit-transform: translate3d(-50%, -50%, 0); 202 | transform: translate3d(-50%, -50%, 0); 203 | font-family: 'Avenir Next', Avenir, 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, sans-serif; 204 | } 205 | -------------------------------------------------------------------------------- /css/style3.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #cc0019; 3 | color: #fceeb8; 4 | font-family: 'BioRhyme', serif; 5 | } 6 | 7 | a { 8 | color: #fff; 9 | } 10 | 11 | a:hover, 12 | a:focus { 13 | color: #fceeb8; 14 | } 15 | 16 | .codrops-header { 17 | background: none; 18 | } 19 | 20 | .codrops-header__tagline, 21 | .codrops-demos, 22 | .content__description, 23 | .content__meta { 24 | font-family: 'Roboto Condensed', sans-serif; 25 | } 26 | 27 | .codrops-demos a.current-demo { 28 | color: #fceeb8; 29 | } 30 | 31 | .calendar { 32 | -webkit-perspective: 2500px; 33 | perspective: 2500px; 34 | } 35 | 36 | .cube__side, 37 | .no-js .cube { 38 | border: 3px solid #fff; 39 | outline: 1px solid #fff; 40 | background: #f0f0f0 url(../img/c1.png) no-repeat center center; 41 | } 42 | 43 | .cube:not(.cube--inactive):nth-child(2n) .cube__side, 44 | .no-js .cube:not(.cube--inactive):nth-child(2n) { 45 | background-image: url(../img/c2.png); 46 | } 47 | 48 | .cube:not(.cube--inactive):nth-child(3n) .cube__side, 49 | .no-js .cube:not(.cube--inactive):nth-child(3n) { 50 | background-image: url(../img/c3.png); 51 | } 52 | 53 | .cube:not(.cube--inactive):nth-child(4n) .cube__side, 54 | .no-js .cube:not(.cube--inactive):nth-child(4n) { 55 | background-image: url(../img/c4.png); 56 | } 57 | 58 | .cube:not(.cube--inactive):nth-child(5n) .cube__side, 59 | .no-js .cube:not(.cube--inactive):nth-child(5n) { 60 | background-image: url(../img/c5.png); 61 | } 62 | 63 | .cube--inactive .cube__side, 64 | .no-js .cube--inactive { 65 | background: #e6e6e6; 66 | } 67 | 68 | 69 | /* With JS we insert a number span into the cube */ 70 | 71 | .cube__number, 72 | .no-js .cube::after { 73 | font-weight: 700; 74 | color: #cc0019; 75 | background: #fff; 76 | width: 100%; 77 | text-align: center; 78 | top: 50%; 79 | height: 1.5em; 80 | line-height: 1.5; 81 | bottom: auto; 82 | margin: -0.75em 0 0; 83 | } 84 | 85 | .cube--inactive .cube__number, 86 | .no-js .cube--inactive::after { 87 | color: #cac9c9; 88 | } 89 | 90 | .js .content__block { 91 | width: 100%; 92 | padding: 0 5vw 0 20vw; 93 | } 94 | 95 | .js .content__description { 96 | padding: 0 0 0 4vw; 97 | } 98 | 99 | .content__number { 100 | color: #000; 101 | font-weight: bold; 102 | line-height: 0.5; 103 | letter-spacing: -0.175em; 104 | font-size: 30vw; 105 | left: -5vw; 106 | bottom: 8vh; 107 | } 108 | 109 | .content__title { 110 | font-size: 6vw; 111 | } 112 | 113 | .title { 114 | color: #fceeb8; 115 | right: auto; 116 | left: 3vw; 117 | } 118 | 119 | @media screen and (max-width: 50.75em) { 120 | .js .content__block { 121 | padding: 4em 2em 0; 122 | -webkit-justify-content: flex-start; 123 | -ms-flex-pack: start; 124 | justify-content: flex-start; 125 | } 126 | .content__number { 127 | bottom: 30vh; 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/favicon.ico -------------------------------------------------------------------------------- /img/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/1.png -------------------------------------------------------------------------------- /img/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/10.png -------------------------------------------------------------------------------- /img/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/11.png -------------------------------------------------------------------------------- /img/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/12.png -------------------------------------------------------------------------------- /img/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/13.png -------------------------------------------------------------------------------- /img/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/14.png -------------------------------------------------------------------------------- /img/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/15.png -------------------------------------------------------------------------------- /img/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/16.png -------------------------------------------------------------------------------- /img/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/17.png -------------------------------------------------------------------------------- /img/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/18.png -------------------------------------------------------------------------------- /img/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/19.png -------------------------------------------------------------------------------- /img/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/2.png -------------------------------------------------------------------------------- /img/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/20.png -------------------------------------------------------------------------------- /img/21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/21.png -------------------------------------------------------------------------------- /img/22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/22.png -------------------------------------------------------------------------------- /img/23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/23.png -------------------------------------------------------------------------------- /img/24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/24.png -------------------------------------------------------------------------------- /img/25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/25.png -------------------------------------------------------------------------------- /img/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/3.png -------------------------------------------------------------------------------- /img/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/4.png -------------------------------------------------------------------------------- /img/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/5.png -------------------------------------------------------------------------------- /img/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/6.png -------------------------------------------------------------------------------- /img/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/7.png -------------------------------------------------------------------------------- /img/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/8.png -------------------------------------------------------------------------------- /img/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/9.png -------------------------------------------------------------------------------- /img/c1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/c1.png -------------------------------------------------------------------------------- /img/c2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/c2.png -------------------------------------------------------------------------------- /img/c3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/c3.png -------------------------------------------------------------------------------- /img/c4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/c4.png -------------------------------------------------------------------------------- /img/c5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/c5.png -------------------------------------------------------------------------------- /img/mandala.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/mandala.png -------------------------------------------------------------------------------- /img/mandala2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/mandala2.png -------------------------------------------------------------------------------- /img/mandala3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/mandala3.png -------------------------------------------------------------------------------- /img/sponsor/ipad1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/sponsor/ipad1.png -------------------------------------------------------------------------------- /img/sponsor/ipad2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/sponsor/ipad2.png -------------------------------------------------------------------------------- /img/sponsor/ipad3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/sponsor/ipad3.png -------------------------------------------------------------------------------- /img/sponsor/webydo-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/CubesAdventCalendar/45b4d6770398c5b6e5d029c6419f63407dae3554/img/sponsor/webydo-logo.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Cubes Advent Calendar | Demo 1 | Codrops 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 37 |
38 |
39 |
40 | 44 |

Cubes Advent Calendar

45 |
46 |

Inspired by Adult Swim. Firefox support is buggy.

47 | 52 | 53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |

Peaceful World

85 |

If everyone demanded peace instead of another television set, then there'd be peace.

86 | 87 |
88 |
89 |

Impossible

90 |

To be content with little is difficult; to be content with much, impossible.

91 | 92 |
93 |
94 |

Everything

95 |

The things you own end up owning you. It's only after you lose everything that you're free to do anything.

96 | 97 |
98 |
99 |

Hung Up

100 |

A lot of people get so hung up on what they can't have that they don't think for a second about whether they really want it.

101 | 102 |
103 |
104 |

Live Freely

105 |

It is the preoccupation with possessions, more than anything else that prevents us from living freely and nobly.

106 | 107 |
108 |
109 |

Tolerable Planet

110 |

What is the use of a house if you haven't got a tolerable planet to put it on?

111 | 112 |
113 |
114 |

Normal

115 |

Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for - in order to get to the job you need to pay for the clothes and the car, and the house you leave vacant all day so you can afford to live in it.

116 | 117 |
118 |
119 |

Superhero

120 |

The reality of loving God is loving him like he's a Superhero who actually saved you from stuff rather than a Santa Claus who merely gave you some stuff.

121 | 122 |
123 |
124 |

New Weariness

125 |

Every increased possession loads us with new weariness.

126 | 127 |
128 |
129 |

The Sinner

130 |

The Christmas tree, twinkling with lights, had a mountain of gifts piled up beneath it, like offerings to the great god of excess.

131 | 132 |
133 |
134 |

Intellectual Wealth

135 |

Whoever prefers the material comforts of life over intellectual wealth is like the owner of a palace who moves into the servants' quarters and leaves the sumptuous rooms empty.

136 | 137 |
138 |
139 |

Limiting Principle

140 |

An attitude to life which seeks fulfilment in the single-minded pursuit of wealth - in short, materialism - does not fit into this world, because it contains within itself no limiting principle, while the environment in which it is placed is strictly limited.

141 | 142 |
143 |
144 |

Quaintly Free

145 |

To have so little, and it of so little value, was to be quaintly free.

146 | 147 |
148 |
149 |

On A Level

150 |

I've always felt that your belongings have never been on a level with you.

151 | 152 |
153 |
154 |

Experiences

155 |

We all need new ideas, images, and experiences far more than we need new stoves or cars or computers.

156 | 157 |
158 |
159 |

Entrenched

160 |

We are being called upon to act against a prevailing culture, to undermine our own entrenched tendency to accumulate and to consume, and to refuse to define our individuality by our presumed ability to do whatever we want.

161 | 162 |
163 |
164 |

Happiness

165 |

The way of the consumerist culture is to spend so much energy chasing happiness that it has none left to be happy.

166 | 167 |
168 |
169 |

Working Jobs

170 |

Advertising has us chasing cars and clothes, working jobs we hate so we can buy shit we don't need.

171 | 172 |
173 |
174 |

Spending Billions

175 |

Our economy is based on spending billions to persuade people that happiness is buying things, and then insisting that the only way to have a viable economy is to make things for people to buy so they’ll have jobs and get enough money to buy things.

176 | 177 |
178 |
179 |

Principle Of Having

180 |

The real opposition is that between the ego-bound man, whose existence is structured by the principle of having, and the free man, who has overcome his egocentricity.

181 | 182 |
183 |
184 |

Enemies

185 |

Happy slaves are the bitterest enemies of freedom.

186 | 187 |
188 |
189 |

Better World

190 |

If you assume that there is no hope, you guarantee that there will be no hope. If you assume that there is an instinct for freedom, that there are opportunities to change things, then there is a possibility that you can contribute to making a better world.

191 | 192 |
193 |
0
194 | 195 |
196 |
197 |
198 | 199 | 200 | 201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /index2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Cubes Advent Calendar | Demo 2 | Codrops 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 37 |
38 |
39 |
40 | 44 |

Cubes Advent Calendar

45 |
46 |

Inspired by Adult Swim. Firefox support is buggy.

47 | 52 | 53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |

Peaceful World

85 |

If everyone demanded peace instead of another television set, then there'd be peace.

86 | 87 |
88 |
89 |

Impossible

90 |

To be content with little is difficult; to be content with much, impossible.

91 | 92 |
93 |
94 |

Everything

95 |

The things you own end up owning you. It's only after you lose everything that you're free to do anything.

96 | 97 |
98 |
99 |

Hung Up

100 |

A lot of people get so hung up on what they can't have that they don't think for a second about whether they really want it.

101 | 102 |
103 |
104 |

Live Freely

105 |

It is the preoccupation with possessions, more than anything else that prevents us from living freely and nobly.

106 | 107 |
108 |
109 |

Tolerable Planet

110 |

What is the use of a house if you haven't got a tolerable planet to put it on?

111 | 112 |
113 |
114 |

Normal

115 |

Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for - in order to get to the job you need to pay for the clothes and the car, and the house you leave vacant all day so you can afford to live in it.

116 | 117 |
118 |
119 |

Superhero

120 |

The reality of loving God is loving him like he's a Superhero who actually saved you from stuff rather than a Santa Claus who merely gave you some stuff.

121 | 122 |
123 |
124 |

New Weariness

125 |

Every increased possession loads us with new weariness.

126 | 127 |
128 |
129 |

The Sinner

130 |

The Christmas tree, twinkling with lights, had a mountain of gifts piled up beneath it, like offerings to the great god of excess.

131 | 132 |
133 |
134 |

Intellectual Wealth

135 |

Whoever prefers the material comforts of life over intellectual wealth is like the owner of a palace who moves into the servants' quarters and leaves the sumptuous rooms empty.

136 | 137 |
138 |
139 |

Limiting Principle

140 |

An attitude to life which seeks fulfilment in the single-minded pursuit of wealth - in short, materialism - does not fit into this world, because it contains within itself no limiting principle, while the environment in which it is placed is strictly limited.

141 | 142 |
143 |
144 |

Quaintly Free

145 |

To have so little, and it of so little value, was to be quaintly free.

146 | 147 |
148 |
149 |

On A Level

150 |

I've always felt that your belongings have never been on a level with you.

151 | 152 |
153 |
154 |

Experiences

155 |

We all need new ideas, images, and experiences far more than we need new stoves or cars or computers.

156 | 157 |
158 |
159 |

Entrenched

160 |

We are being called upon to act against a prevailing culture, to undermine our own entrenched tendency to accumulate and to consume, and to refuse to define our individuality by our presumed ability to do whatever we want.

161 | 162 |
163 |
164 |

Happiness

165 |

The way of the consumerist culture is to spend so much energy chasing happiness that it has none left to be happy.

166 | 167 |
168 |
169 |

Working Jobs

170 |

Advertising has us chasing cars and clothes, working jobs we hate so we can buy shit we don't need.

171 | 172 |
173 |
174 |

Spending Billions

175 |

Our economy is based on spending billions to persuade people that happiness is buying things, and then insisting that the only way to have a viable economy is to make things for people to buy so they’ll have jobs and get enough money to buy things.

176 | 177 |
178 |
179 |

Principle Of Having

180 |

The real opposition is that between the ego-bound man, whose existence is structured by the principle of having, and the free man, who has overcome his egocentricity.

181 | 182 |
183 |
184 |

Enemies

185 |

Happy slaves are the bitterest enemies of freedom.

186 | 187 |
188 |
189 |

Better World

190 |

If you assume that there is no hope, you guarantee that there will be no hope. If you assume that there is an instinct for freedom, that there are opportunities to change things, then there is a possibility that you can contribute to making a better world.

191 | 192 |
193 |
0
194 | 195 |
196 |
197 |
198 | 199 | 200 | 201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /index3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Cubes Advent Calendar | Demo 3 | Codrops 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 37 |
38 |
39 |
40 | 44 |

Cubes Advent Calendar

45 |
46 |

Inspired by Adult Swim. Firefox support is buggy.

47 | 52 | 53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |

Peaceful World

85 |

If everyone demanded peace instead of another television set, then there'd be peace.

86 | 87 |
88 |
89 |

Impossible

90 |

To be content with little is difficult; to be content with much, impossible.

91 | 92 |
93 |
94 |

Everything

95 |

The things you own end up owning you. It's only after you lose everything that you're free to do anything.

96 | 97 |
98 |
99 |

Hung Up

100 |

A lot of people get so hung up on what they can't have that they don't think for a second about whether they really want it.

101 | 102 |
103 |
104 |

Live Freely

105 |

It is the preoccupation with possessions, more than anything else that prevents us from living freely and nobly.

106 | 107 |
108 |
109 |

Tolerable Planet

110 |

What is the use of a house if you haven't got a tolerable planet to put it on?

111 | 112 |
113 |
114 |

Normal

115 |

Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for - in order to get to the job you need to pay for the clothes and the car, and the house you leave vacant all day so you can afford to live in it.

116 | 117 |
118 |
119 |

Superhero

120 |

The reality of loving God is loving him like he's a Superhero who actually saved you from stuff rather than a Santa Claus who merely gave you some stuff.

121 | 122 |
123 |
124 |

New Weariness

125 |

Every increased possession loads us with new weariness.

126 | 127 |
128 |
129 |

The Sinner

130 |

The Christmas tree, twinkling with lights, had a mountain of gifts piled up beneath it, like offerings to the great god of excess.

131 | 132 |
133 |
134 |

Intellectual Wealth

135 |

Whoever prefers the material comforts of life over intellectual wealth is like the owner of a palace who moves into the servants' quarters and leaves the sumptuous rooms empty.

136 | 137 |
138 |
139 |

Limiting Principle

140 |

An attitude to life which seeks fulfilment in the single-minded pursuit of wealth - in short, materialism - does not fit into this world, because it contains within itself no limiting principle, while the environment in which it is placed is strictly limited.

141 | 142 |
143 |
144 |

Quaintly Free

145 |

To have so little, and it of so little value, was to be quaintly free.

146 | 147 |
148 |
149 |

On A Level

150 |

I've always felt that your belongings have never been on a level with you.

151 | 152 |
153 |
154 |

Experiences

155 |

We all need new ideas, images, and experiences far more than we need new stoves or cars or computers.

156 | 157 |
158 |
159 |

Entrenched

160 |

We are being called upon to act against a prevailing culture, to undermine our own entrenched tendency to accumulate and to consume, and to refuse to define our individuality by our presumed ability to do whatever we want.

161 | 162 |
163 |
164 |

Happiness

165 |

The way of the consumerist culture is to spend so much energy chasing happiness that it has none left to be happy.

166 | 167 |
168 |
169 |

Working Jobs

170 |

Advertising has us chasing cars and clothes, working jobs we hate so we can buy shit we don't need.

171 | 172 |
173 |
174 |

Spending Billions

175 |

Our economy is based on spending billions to persuade people that happiness is buying things, and then insisting that the only way to have a viable economy is to make things for people to buy so they’ll have jobs and get enough money to buy things.

176 | 177 |
178 |
179 |

Principle Of Having

180 |

The real opposition is that between the ego-bound man, whose existence is structured by the principle of having, and the free man, who has overcome his egocentricity.

181 | 182 |
183 |
184 |

Enemies

185 |

Happy slaves are the bitterest enemies of freedom.

186 | 187 |
188 |
189 |

Better World

190 |

If you assume that there is no hope, you guarantee that there will be no hope. If you assume that there is an instinct for freedom, that there are opportunities to change things, then there is a possibility that you can contribute to making a better world.

191 | 192 |
193 |
0
194 | 195 |
196 |
197 |
198 | 199 | 200 | 201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /js/anime.min.js: -------------------------------------------------------------------------------- 1 | (function(u,r){"function"===typeof define&&define.amd?define([],r):"object"===typeof module&&module.exports?module.exports=r():u.anime=r()})(this,function(){var u={duration:1E3,delay:0,loop:!1,autoplay:!0,direction:"normal",easing:"easeOutElastic",elasticity:400,round:!1,begin:void 0,update:void 0,complete:void 0},r="translateX translateY translateZ rotate rotateX rotateY rotateZ scale scaleX scaleY scaleZ skewX skewY".split(" "),y,f={arr:function(a){return Array.isArray(a)},obj:function(a){return-1< 2 | Object.prototype.toString.call(a).indexOf("Object")},svg:function(a){return a instanceof SVGElement},dom:function(a){return a.nodeType||f.svg(a)},num:function(a){return!isNaN(parseInt(a))},str:function(a){return"string"===typeof a},fnc:function(a){return"function"===typeof a},und:function(a){return"undefined"===typeof a},nul:function(a){return"null"===typeof a},hex:function(a){return/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(a)},rgb:function(a){return/^rgb/.test(a)},hsl:function(a){return/^hsl/.test(a)}, 3 | col:function(a){return f.hex(a)||f.rgb(a)||f.hsl(a)}},D=function(){var a={},b={Sine:function(a){return 1-Math.cos(a*Math.PI/2)},Circ:function(a){return 1-Math.sqrt(1-a*a)},Elastic:function(a,b){if(0===a||1===a)return a;var d=1-Math.min(b,998)/1E3,g=a/1-1;return-(Math.pow(2,10*g)*Math.sin(2*(g-d/(2*Math.PI)*Math.asin(1))*Math.PI/d))},Back:function(a){return a*a*(3*a-2)},Bounce:function(a){for(var b,d=4;a<((b=Math.pow(2,--d))-1)/11;);return 1/Math.pow(4,3-d)-7.5625*Math.pow((3*b-2)/22-a,2)}};["Quad", 4 | "Cubic","Quart","Quint","Expo"].forEach(function(a,e){b[a]=function(a){return Math.pow(a,e+2)}});Object.keys(b).forEach(function(c){var e=b[c];a["easeIn"+c]=e;a["easeOut"+c]=function(a,b){return 1-e(1-a,b)};a["easeInOut"+c]=function(a,b){return.5>a?e(2*a,b)/2:1-e(-2*a+2,b)/2};a["easeOutIn"+c]=function(a,b){return.5>a?(1-e(1-2*a,b))/2:(e(2*a-1,b)+1)/2}});a.linear=function(a){return a};return a}(),z=function(a){return f.str(a)?a:a+""},E=function(a){return a.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}, 5 | F=function(a){if(f.col(a))return!1;try{return document.querySelectorAll(a)}catch(b){return!1}},A=function(a){return a.reduce(function(a,c){return a.concat(f.arr(c)?A(c):c)},[])},t=function(a){if(f.arr(a))return a;f.str(a)&&(a=F(a)||a);return a instanceof NodeList||a instanceof HTMLCollection?[].slice.call(a):[a]},G=function(a,b){return a.some(function(a){return a===b})},R=function(a,b){var c={};a.forEach(function(a){var d=JSON.stringify(b.map(function(b){return a[b]}));c[d]=c[d]||[];c[d].push(a)}); 6 | return Object.keys(c).map(function(a){return c[a]})},H=function(a){return a.filter(function(a,c,e){return e.indexOf(a)===c})},B=function(a){var b={},c;for(c in a)b[c]=a[c];return b},v=function(a,b){for(var c in b)a[c]=f.und(a[c])?b[c]:a[c];return a},S=function(a){a=a.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,function(a,b,c,m){return b+b+c+c+m+m});var b=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(a);a=parseInt(b[1],16);var c=parseInt(b[2],16),b=parseInt(b[3],16);return"rgb("+a+","+c+","+b+")"}, 7 | T=function(a){a=/hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/g.exec(a);var b=parseInt(a[1])/360,c=parseInt(a[2])/100,e=parseInt(a[3])/100;a=function(a,b,c){0>c&&(c+=1);1c?b:c<2/3?a+(b-a)*(2/3-c)*6:a};if(0==c)c=e=b=e;else var d=.5>e?e*(1+c):e+c-e*c,g=2*e-d,c=a(g,d,b+1/3),e=a(g,d,b),b=a(g,d,b-1/3);return"rgb("+255*c+","+255*e+","+255*b+")"},p=function(a){return/([\+\-]?[0-9|auto\.]+)(%|px|pt|em|rem|in|cm|mm|ex|pc|vw|vh|deg)?/.exec(a)[2]},I=function(a,b,c){return p(b)? 8 | b:-1=d.delay&&(d.begin(b),d.begin=void 0);c.current>=b.duration&&(d.loop?(c.start=a,"alternate"===d.direction&&C(b,!0),f.num(d.loop)&&d.loop--):(b.ended=!0,b.pause(),d.complete&&d.complete(b)),c.last=0)};b.seek=function(a){P(b,a/100*b.duration)};b.pause=function(){ba(b);var a=n.indexOf(b);-1 73 |
74 |
75 |
76 |
77 |
78 |
79 | 80 | */ 81 | this.cube = document.createElement('div'); 82 | this.cube.className = this.isActive ? 'cube' : 'cube cube--inactive'; 83 | this.cube.innerHTML = '
' + (this.number+1) + '
'; 84 | this.currentTransform = {translateZ: 0, rotateX: 0, rotateY: 0}; 85 | }; 86 | 87 | Day.prototype._rotate = function(ev) { 88 | anime.remove(this.cube); 89 | 90 | var dir = this._getDirection(ev), 91 | type = ev.type.toLowerCase() === 'mouseenter' ? 1 : -1, 92 | animationSettings = { 93 | targets: this.cube, 94 | duration: 500, 95 | easing: 'easeOutExpo' 96 | }; 97 | 98 | animationSettings.translateZ = { 99 | value: type === 1 ? 100 : 0, 100 | duration: 900, 101 | easing: 'easeOutExpo' 102 | }; 103 | 104 | switch(dir) { 105 | case 0 : // from/to top 106 | animationSettings.rotateX = type === 1 ? -180 : 0; 107 | animationSettings.rotateY = 0; 108 | break; 109 | case 1 : // from/to right 110 | animationSettings.rotateY = type === 1 ? -180 : 0; 111 | animationSettings.rotateX = 0; 112 | break; 113 | case 2 : // from/to bottom 114 | animationSettings.rotateX = type === 1 ? 180 : 0; 115 | animationSettings.rotateY = 0; 116 | break; 117 | case 3 : // from/to left 118 | animationSettings.rotateY = type === 1 ? 180 : 0; 119 | animationSettings.rotateX = 0; 120 | break; 121 | }; 122 | 123 | this.currentTransform = { 124 | translateZ: animationSettings.translateZ, 125 | rotateX: animationSettings.rotateX, 126 | rotateY: animationSettings.rotateY 127 | }; 128 | 129 | anime(animationSettings); 130 | }; 131 | 132 | Day.prototype._setContentTitleFx = function(contentTitleEl) { 133 | this.titlefx = new TextFx(contentTitleEl); 134 | this.titlefxSettings = { 135 | in: { 136 | duration: 800, 137 | delay: function(el, index) { return 650 + index*10; }, 138 | easing: 'easeOutExpo', 139 | opacity: { 140 | duration: 200, 141 | value: [0,1], 142 | easing:'linear' 143 | }, 144 | translateY: [100,0], 145 | rotateZ: function(el, index) { return [anime.random(-20,20), 0]; } 146 | }, 147 | out: { 148 | duration: 800, 149 | delay: 400, 150 | easing: 'easeInExpo', 151 | opacity: 0, 152 | translateY: 350 153 | } 154 | }; 155 | }; 156 | 157 | // From: https://codepen.io/noeldelgado/pen/pGwFx?editors=0110 by Noel Delgado (@noeldelgado). 158 | Day.prototype._getDirection = function(ev) { 159 | var obj = this.cube.querySelector('.cube__side--front'), 160 | w = obj.offsetWidth, 161 | h = obj.offsetHeight, 162 | bcr = obj.getBoundingClientRect(), 163 | x = (ev.pageX - (bcr.left + window.pageXOffset) - (w / 2) * (w > h ? (h / w) : 1)), 164 | y = (ev.pageY - (bcr.top + window.pageYOffset) - (h / 2) * (h > w ? (w / h) : 1)), 165 | d = Math.round( Math.atan2(y, x) / 1.57079633 + 5 ) % 4; 166 | 167 | return d; 168 | }; 169 | 170 | // The Calendar obj. 171 | function Calendar(el) { 172 | this.el = el; 173 | this.calendarDays = [].slice.call(this.el.querySelectorAll('.cube')); 174 | 175 | // Let´s build the days/cubes structure. 176 | this.cubes = document.createElement('div'); 177 | this.cubes.className = 'cubes'; 178 | this.el.appendChild(this.cubes); 179 | 180 | // Array of days (each day is represented by a 3D Cube) 181 | this.days = []; 182 | var self = this; 183 | this.calendarDays.forEach(function(d, pos) { 184 | // Get the bg color defined in the data-bg-color of each division. 185 | var day = new Day({ 186 | number: pos, 187 | color: d.getAttribute('data-bg-color') || '#f1f1f1', 188 | previewTitle: d.getAttribute('data-title') || '', 189 | inactive: d.hasAttribute('data-inactive') 190 | }), 191 | content = contents[pos]; 192 | 193 | if( content !== undefined ) { 194 | var contentTitle = contents[pos].querySelector('.content__title'); 195 | day._setContentTitleFx(contentTitle); 196 | } 197 | 198 | self.days.push(day); 199 | self.cubes.appendChild(day.cube); 200 | self.el.removeChild(d); 201 | self._initDayEvents(day); 202 | }); 203 | 204 | // structure to show each day preview (day + title + subtitle etc, when the user hovers one day/cube). 205 | this.dayPreview = document.createElement('h2'); 206 | this.dayPreview.className = 'title'; 207 | this.el.appendChild(this.dayPreview); 208 | 209 | this._initEvents(); 210 | } 211 | 212 | Calendar.prototype._initEvents = function() { 213 | var self = this; 214 | 215 | // Mousemove event / tilt functionality 216 | if( settings.tilt ) { 217 | this.mousemoveFn = function(ev) { 218 | if( self.isOpen ) { 219 | return false; 220 | }; 221 | requestAnimationFrame(function() { 222 | // Mouse position relative to the document. 223 | var mousepos = getMousePos(ev); 224 | self._rotateCalendar(mousepos); 225 | }); 226 | }; 227 | 228 | this.handleOrientation = function() { 229 | if( self.isOpen ) { 230 | return false; 231 | }; 232 | 233 | var y = event.gamma; 234 | // To make computation easier we shift the range of x and y to [0,180] 235 | y += 90; 236 | requestAnimationFrame(function() { 237 | // Transform values. 238 | var movement = {ry:40}, 239 | rotY = 2*movement.ry / 180 * y - movement.ry; 240 | 241 | self.cubes.style.WebkitTransform = self.cubes.style.transform = 'rotate3d(0,-1,0,' + rotY + 'deg)'; 242 | }); 243 | }; 244 | if( isMobile ) { 245 | window.addEventListener('deviceorientation', this.handleOrientation); 246 | } 247 | else { 248 | document.addEventListener('mousemove', this.mousemoveFn); 249 | } 250 | } 251 | 252 | this.backToCalendarFn = function(ev) { 253 | // If the calendar is currently animating then do nothing. 254 | if( !self.isOpen || self.isAnimating ) { 255 | return false; 256 | } 257 | self.isAnimating = true; 258 | self._hidePreviewTitle(); 259 | self._hideContent(); 260 | 261 | // Show the main container 262 | anime({ 263 | targets: self.el, 264 | duration: 1200, 265 | easing: 'easeInOutExpo', 266 | opacity: 1, 267 | complete: function() { 268 | self.isOpen = false; 269 | self.isAnimating = false; 270 | } 271 | }); 272 | 273 | for(var i = 0, totalDays = self.days.length; i < totalDays; ++i) { 274 | var day = self.days[i]; 275 | if( self.currentDayIdx === i ) { 276 | anime({ 277 | targets: day.cube, 278 | duration: 1200, 279 | delay: 1000, 280 | easing: 'easeOutExpo', 281 | scale: 1, 282 | translateY: 0, 283 | translateZ: [-1500,0], 284 | rotateX: 0, 285 | rotateY: 0 286 | }); 287 | day.isRotated = false; 288 | } 289 | else { 290 | anime({ 291 | targets: day.cube, 292 | duration: 1200, 293 | delay: 1000, 294 | easing: 'easeOutExpo', 295 | scale: 1, 296 | translateX: 0, 297 | translateY: 0, 298 | translateZ: [3000,0], 299 | rotateY: 0 300 | }); 301 | } 302 | } 303 | }; 304 | backCtrl.addEventListener('click', this.backToCalendarFn); 305 | }; 306 | 307 | Calendar.prototype._initDayEvents = function(day) { 308 | var self = this; 309 | 310 | // Day/Cube mouseenter/mouseleave event. 311 | var instance = day; 312 | if( !isMobile ) { 313 | instance.mouseenterFn = function(ev) { 314 | if( instance.isRotated || self.isOpen ) { 315 | return false; 316 | }; 317 | clearTimeout(colortimeout); 318 | instance.rotatetimeout = setTimeout(function() { 319 | colortimeout = setTimeout(function() { self._changeBGColor(instance.color); }, 30); 320 | instance._rotate(ev); 321 | self._showPreviewTitle(instance.previewTitle, instance.number); 322 | instance.isRotated = true; 323 | }, 30); 324 | }; 325 | instance.mouseleaveFn = function(ev) { 326 | if( self.isOpen ) { 327 | return false; 328 | }; 329 | clearTimeout(instance.rotatetimeout); 330 | clearTimeout(colortimeout); 331 | if( instance.isRotated ) { 332 | colortimeout = setTimeout(function() { self._resetBGColor(); }, 35); 333 | self._resetBGColor(); 334 | instance._rotate(ev); 335 | self._hidePreviewTitle(); 336 | instance.isRotated = false; 337 | } 338 | }; 339 | } 340 | // Day/Cube click event. 341 | instance.clickFn = function(ev) { 342 | // If the day is inactive or if the calendar is currently animating then do nothing. 343 | if( !instance.isActive || self.isAnimating ) { 344 | return false; 345 | } 346 | self.isAnimating = true; 347 | self.isOpen = true; 348 | self.currentDayIdx = instance.number; 349 | 350 | // Hide the main container 351 | anime({ 352 | targets: self.el, 353 | duration: 1200, 354 | easing: 'easeInOutExpo', 355 | opacity: 0, 356 | complete: function() { 357 | self.isAnimating = false; 358 | } 359 | }); 360 | 361 | for(var i = 0, totalDays = self.days.length; i < totalDays; ++i) { 362 | var day = self.days[i]; 363 | 364 | if( self.currentDayIdx === i ) { 365 | anime({ 366 | targets: day.cube, 367 | duration: 600, 368 | delay: 200, 369 | easing: 'easeInExpo', 370 | scale: 1.1, 371 | translateY: -window.innerHeight*2, 372 | translateZ: day.currentTransform.translateZ, 373 | rotateX: day.currentTransform.rotateX, 374 | rotateY: day.currentTransform.rotateY 375 | }); 376 | 377 | self._showContent(instance); 378 | } 379 | else { 380 | var bcr = day.cube.getBoundingClientRect(); 381 | anime({ 382 | targets: day.cube, 383 | duration: 1200, 384 | easing: 'easeInOutExpo', 385 | scale: 0.1, 386 | translateX: function(el, index) { 387 | return bcr.left + window.pageXOffset <= window.innerWidth/2 ? anime.random(-800,0) : anime.random(0,800); 388 | }, 389 | translateY: function(el, index) { 390 | return bcr.top + window.pageYOffset <= window.innerHeight/2 ? anime.random(-1400,-200) : anime.random(-200,600); 391 | }, 392 | translateZ: -1500, 393 | rotateY: function(el, index) { 394 | return bcr.left + window.pageXOffset <= window.innerWidth/2 ? anime.random(-40,0) : anime.random(0,40); 395 | } 396 | }); 397 | } 398 | } 399 | }; 400 | instance.cube.querySelector('.cube__side--front').addEventListener('mouseenter', instance.mouseenterFn); 401 | instance.cube.addEventListener('mouseleave', instance.mouseleaveFn); 402 | instance.cube.addEventListener('click', instance.clickFn); 403 | instance.cube.addEventListener('mousedown', function() { 404 | clearTimeout(instance.rotatetimeout ); 405 | }); 406 | }; 407 | 408 | Calendar.prototype._rotateCalendar = function(mousepos) { 409 | // Transform values. 410 | var movement = {rx:3, ry:3}, 411 | rotX = 2 * movement.rx / this.cubes.offsetHeight * mousepos.y - movement.rx, 412 | rotY = 2 * movement.ry / this.cubes.offsetWidth * mousepos.x - movement.ry; 413 | 414 | this.cubes.style.WebkitTransform = this.cubes.style.transform = 'rotate3d(-1,0,0,' + rotX + 'deg) rotate3d(0,1,0,' + rotY + 'deg)'; 415 | }; 416 | 417 | Calendar.prototype._showPreviewTitle = function(text, number) { 418 | this.dayPreview.innerHTML = text; 419 | this.dayPreview.setAttribute('data-number', parseInt(number+1)); 420 | 421 | this.txtfx = new TextFx(this.dayPreview); 422 | this.txtfx.hide(); 423 | this.dayPreview.style.opacity = 1; 424 | this.txtfx.show({ 425 | in: { 426 | duration: 800, 427 | delay: function(el, index) { return index*20; }, 428 | easing: 'easeOutElastic', 429 | opacity: 1, 430 | translateY: function(el, index) { 431 | return index%2 === 0 ? [-25, 0] : [25, 0]; 432 | } 433 | } 434 | }); 435 | }; 436 | 437 | Calendar.prototype._hidePreviewTitle = function() { 438 | var self = this; 439 | if( this.txtfx ) { 440 | this.txtfx.hide(); 441 | } 442 | this.dayPreview.style.opacity = 0; 443 | }; 444 | 445 | Calendar.prototype._showContent = function(day) { 446 | // The content box for the clicked day. 447 | var content = contents[this.currentDayIdx], 448 | title = content.querySelector('.content__title'), 449 | description = content.querySelector('.content__description'), 450 | meta = content.querySelector('.content__meta'); 451 | 452 | content.classList.add('content__block--current'); 453 | 454 | day.titlefx.hide(); 455 | day.titlefx.show(day.titlefxSettings); 456 | 457 | anime({ 458 | targets: [description, meta], 459 | duration: 800, 460 | delay: function(el, index) { return index === 0 ? 900 : 1000 }, 461 | easing: 'easeOutExpo', 462 | opacity: [0,1], 463 | translateY: [100,0] 464 | }); 465 | 466 | anime({ 467 | targets: backCtrl, 468 | duration: 1000, 469 | delay: 800, 470 | easing: 'easeOutExpo', 471 | opacity: [0,1], 472 | translateY: [50,0] 473 | }); 474 | 475 | contentNumber.innerHTML = this.currentDayIdx + 1; 476 | anime({ 477 | targets: contentNumber, 478 | duration: 500, 479 | delay: 800, 480 | easing: 'easeOutExpo', 481 | opacity: [0,1], 482 | translateX: [100,0] 483 | }); 484 | }; 485 | 486 | Calendar.prototype._hideContent = function() { 487 | var day = this.days[this.currentDayIdx], 488 | // The content box for the clicked day. 489 | content = contents[this.currentDayIdx], 490 | // The content title, description and meta for this day. 491 | title = content.querySelector('.content__title'), 492 | description = content.querySelector('.content__description'), 493 | meta = content.querySelector('.content__meta'); 494 | 495 | // The content number placeholder animation. 496 | anime({ 497 | targets: contentNumber, 498 | duration: 500, 499 | easing: 'easeInExpo', 500 | opacity: 0, 501 | translateX: 100 502 | }); 503 | 504 | // The back button animation. 505 | anime({ 506 | targets: backCtrl, 507 | duration: 1000, 508 | easing: 'easeInExpo', 509 | opacity: 0, 510 | translateY: 50 511 | }); 512 | 513 | // The description and meta animation. 514 | anime({ 515 | targets: [description, meta], 516 | duration: 800, 517 | delay: function(el, index) { return index === 0 ? 150 : 0 }, 518 | easing: 'easeInExpo', 519 | opacity: [1,0], 520 | translateY: [0,200] 521 | }); 522 | 523 | // The content title animation. 524 | day.titlefx.hide(day.titlefxSettings, function() { 525 | content.classList.remove('content__block--current'); 526 | }); 527 | }; 528 | 529 | Calendar.prototype._changeBGColor = function(color) { 530 | bgEl.style.backgroundColor = color; 531 | }; 532 | 533 | Calendar.prototype._resetBGColor = function() { 534 | bgEl.style.backgroundColor = defaultBgColor; 535 | }; 536 | 537 | // Snow obj. Based on // https://gist.github.com/OmShiv/4368164. 538 | function Snow() { 539 | this.canvas = document.createElement('canvas'); 540 | this.canvas.id = 'snow'; 541 | this.canvas.className = 'background'; 542 | this.canvas.style.background = defaultBgColor; 543 | document.body.insertBefore(this.canvas, document.body.firstElementChild); 544 | 545 | this.flakes = []; 546 | this.ctx = this.canvas.getContext('2d'); 547 | this.flakeCount = 300; 548 | this.mX = -100, 549 | this.mY = -100 550 | 551 | this.width = this.canvas.width = window.innerWidth; 552 | this.height = this.canvas.height = window.innerHeight; 553 | 554 | this._init(); 555 | } 556 | 557 | Snow.prototype._init = function() { 558 | var self = this; 559 | window.addEventListener('resize', function() { 560 | self.width = self.canvas.width = window.innerWidth; 561 | self.height = self.canvas.height = window.innerHeight; 562 | }); 563 | 564 | for(var i = 0; i < this.flakeCount; ++i) { 565 | var x = Math.floor(Math.random() * this.width), 566 | y = Math.floor(Math.random() * this.height), 567 | size = (Math.random()*3.5) + .5, 568 | speed = size*.5, 569 | opacity = (Math.random() * 0.5) + 0.1; 570 | 571 | this.flakes.push({ 572 | speed: speed, 573 | velY: speed, 574 | velX: 0, 575 | x: x, 576 | y: y, 577 | size: size, 578 | stepSize: (Math.random()) / 30, 579 | step: 0, 580 | opacity: opacity 581 | }); 582 | } 583 | 584 | this._snow(); 585 | }; 586 | 587 | Snow.prototype._snow = function() { 588 | this.ctx.clearRect(0, 0, this.width, this.height); 589 | 590 | for(var i = 0; i < this.flakeCount; ++i) { 591 | var flake = this.flakes[i], 592 | x = this.mX, 593 | y = this.mY, 594 | minDist = 150, 595 | x2 = flake.x, 596 | y2 = flake.y, 597 | dist = Math.sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)), 598 | dx = x2 - x, 599 | dy = y2 - y; 600 | 601 | if( dist < minDist ) { 602 | var force = minDist / (dist * dist), 603 | xcomp = (x - x2) / dist, 604 | ycomp = (y - y2) / dist, 605 | deltaV = force / 2; 606 | flake.velX -= deltaV * xcomp; 607 | flake.velY -= deltaV * ycomp; 608 | } 609 | else { 610 | flake.velX *= .98; 611 | if( flake.velY <= flake.speed ) { 612 | flake.velY = flake.speed 613 | } 614 | flake.velX += Math.cos(flake.step += .05) * flake.stepSize; 615 | } 616 | 617 | this.ctx.fillStyle = "rgba(255,255,255," + flake.opacity + ")"; 618 | flake.y += flake.velY; 619 | flake.x += flake.velX; 620 | 621 | if( flake.y >= this.height || flake.y <= 0 ) { 622 | this._reset(flake); 623 | } 624 | 625 | if( flake.x >= this.width || flake.x <= 0 ) { 626 | this._reset(flake); 627 | } 628 | 629 | this.ctx.beginPath(); 630 | this.ctx.arc(flake.x, flake.y, flake.size, 0, Math.PI * 2); 631 | this.ctx.fill(); 632 | } 633 | requestAnimationFrame(this._snow.bind(this)); 634 | }; 635 | 636 | Snow.prototype._reset = function(flake) { 637 | flake.x = Math.floor(Math.random() * this.width); 638 | flake.y = 0; 639 | flake.size = (Math.random() * 3.5) + .5; 640 | flake.speed = flake.size*.5, 641 | flake.velY = flake.speed; 642 | flake.velX = 0; 643 | flake.opacity = (Math.random() * 0.5) + 0.1; 644 | }; 645 | 646 | var calendarEl = document.querySelector('.calendar'), 647 | calendarDays = [].slice.call(calendarEl.children), 648 | settings = { 649 | snow: false, 650 | tilt: true 651 | }, 652 | bgEl = document.body, 653 | defaultBgColor = bgEl.style.backgroundColor, 654 | colortimeout, 655 | contentEl = document.querySelector('.content'), 656 | contents = contentEl.querySelectorAll('.content__block'), 657 | backCtrl = contentEl.querySelector('.btn-back'), 658 | contentNumber = contentEl.querySelector('.content__number'), 659 | isMobile = mobilecheck(); 660 | 661 | function init() { 662 | layout(); 663 | } 664 | 665 | function layout() { 666 | new Calendar(calendarEl); 667 | // If settings.snow === true then create the canvas element for the snow effect. 668 | if( settings.snow ) { 669 | var snow = new Snow(); 670 | bgEl = snow.canvas; 671 | } 672 | } 673 | 674 | init(); 675 | 676 | })(window); -------------------------------------------------------------------------------- /js/main2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * main.js 3 | * http://www.codrops.com 4 | * 5 | * Licensed under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 8 | * Copyright 2016, Codrops 9 | * http://www.codrops.com 10 | */ 11 | ;(function(window) { 12 | 13 | 'use strict'; 14 | 15 | // Helper vars and functions. 16 | function extend( a, b ) { 17 | for( var key in b ) { 18 | if( b.hasOwnProperty( key ) ) { 19 | a[key] = b[key]; 20 | } 21 | } 22 | return a; 23 | } 24 | // Equation of a line. 25 | function lineEq(y2, y1, x2, x1, currentVal) { 26 | // y = mx + b 27 | var m = (y2 - y1) / (x2 - x1), 28 | b = y1 - m * x1; 29 | 30 | return m * currentVal + b; 31 | } 32 | // From http://www.quirksmode.org/js/events_properties.html#position 33 | function getMousePos(e) { 34 | var posx = 0; 35 | var posy = 0; 36 | if (!e) var e = window.event; 37 | if (e.pageX || e.pageY) { 38 | posx = e.pageX; 39 | posy = e.pageY; 40 | } 41 | else if (e.clientX || e.clientY) { 42 | posx = e.clientX + document.body.scrollLeft 43 | + document.documentElement.scrollLeft; 44 | posy = e.clientY + document.body.scrollTop 45 | + document.documentElement.scrollTop; 46 | } 47 | return { 48 | x : posx, 49 | y : posy 50 | } 51 | } 52 | // Detect mobile. From: http://stackoverflow.com/a/11381730/989439 53 | function mobilecheck() { 54 | var check = false; 55 | (function(a){if(/(android|ipad|playbook|silk|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera); 56 | return check; 57 | } 58 | 59 | // The Day obj. 60 | function Day(options) { 61 | this.options = extend({}, this.options); 62 | extend(this.options, options); 63 | this.number = this.options.number; 64 | this.color = this.options.color; 65 | this.previewTitle = this.options.previewTitle; 66 | this.isActive = !this.options.inactive; 67 | this._layout(); 68 | } 69 | 70 | Day.prototype.options = { 71 | number: 0, 72 | color: '#f1f1f1', 73 | previewTitle: '', 74 | inactive: false 75 | }; 76 | 77 | // Build the 3D cube element. 78 | Day.prototype._layout = function() { 79 | /* The Cube structure: 80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 | */ 89 | this.cube = document.createElement('div'); 90 | this.cube.className = this.isActive ? 'cube' : 'cube cube--inactive'; 91 | this.cube.innerHTML = '
' + (this.number+1) + '
'; 92 | this.currentTransform = {translateZ: 0, rotateX: 0, rotateY: 0}; 93 | }; 94 | 95 | Day.prototype._rotate = function(ev) { 96 | anime.remove(this.cube); 97 | 98 | var dir = this._getDirection(ev), 99 | type = ev.type.toLowerCase() === 'mouseenter' ? 1 : -1, 100 | animationSettings = { 101 | targets: this.cube, 102 | duration: 1000, 103 | easing: 'easeOutElastic', 104 | translateZ: type === 1 ? 100 : 0 105 | }; 106 | 107 | switch(dir) { 108 | case 0 : // from/to top 109 | animationSettings.rotateX = type === 1 ? -180 : 0; 110 | animationSettings.rotateY = 0; 111 | break; 112 | case 1 : // from/to right 113 | animationSettings.rotateY = type === 1 ? -180 : 0; 114 | animationSettings.rotateX = 0; 115 | break; 116 | case 2 : // from/to bottom 117 | animationSettings.rotateX = type === 1 ? 180 : 0; 118 | animationSettings.rotateY = 0; 119 | break; 120 | case 3 : // from/to left 121 | animationSettings.rotateY = type === 1 ? 180 : 0; 122 | animationSettings.rotateX = 0; 123 | break; 124 | }; 125 | 126 | this.currentTransform = { 127 | translateZ: animationSettings.translateZ, 128 | rotateX: animationSettings.rotateX, 129 | rotateY: animationSettings.rotateY 130 | }; 131 | 132 | anime(animationSettings); 133 | }; 134 | 135 | Day.prototype._setContentTitleFx = function(contentTitleEl) { 136 | this.titlefx = new TextFx(contentTitleEl); 137 | this.titlefxSettings = { 138 | in: { 139 | duration: 800, 140 | delay: 650, 141 | easing: 'easeOutExpo', 142 | opacity: { 143 | duration: 200, 144 | value: [0,1], 145 | easing:'linear' 146 | }, 147 | translateY: function(el, index) { 148 | var p = el.parentNode, 149 | lastElOffW = p.lastElementChild.offsetWidth, 150 | firstElOffL = p.firstElementChild.offsetLeft, 151 | w = p.offsetWidth - lastElOffW - firstElOffL - (p.offsetWidth - lastElOffW - p.lastElementChild.offsetLeft), 152 | tyVal = lineEq(0, 200, firstElOffL + w/2, firstElOffL, el.offsetLeft); 153 | 154 | return [Math.abs(tyVal)+50,0]; 155 | }, 156 | rotateZ: function(el, index) { 157 | var p = el.parentNode, 158 | lastElOffW = p.lastElementChild.offsetWidth, 159 | firstElOffL = p.firstElementChild.offsetLeft, 160 | w = p.offsetWidth - lastElOffW - p.firstElementChild.offsetLeft - (p.offsetWidth - lastElOffW - p.lastElementChild.offsetLeft), 161 | rz = lineEq(90, -90,firstElOffL + w, firstElOffL, el.offsetLeft); 162 | 163 | return [rz,0]; 164 | } 165 | }, 166 | out: { 167 | duration: 800, 168 | delay: 400, 169 | easing: 'easeInExpo', 170 | opacity: 0, 171 | translateY: 350 172 | } 173 | }; 174 | }; 175 | 176 | // From: https://codepen.io/noeldelgado/pen/pGwFx?editors=0110 by Noel Delgado (@noeldelgado). 177 | Day.prototype._getDirection = function(ev) { 178 | var obj = this.cube.querySelector('.cube__side--front'), 179 | w = obj.offsetWidth, 180 | h = obj.offsetHeight, 181 | bcr = obj.getBoundingClientRect(), 182 | x = (ev.pageX - (bcr.left + window.pageXOffset) - (w / 2) * (w > h ? (h / w) : 1)), 183 | y = (ev.pageY - (bcr.top + window.pageYOffset) - (h / 2) * (h > w ? (w / h) : 1)), 184 | d = Math.round( Math.atan2(y, x) / 1.57079633 + 5 ) % 4; 185 | 186 | return d; 187 | }; 188 | 189 | // The Calendar obj. 190 | function Calendar(el) { 191 | this.el = el; 192 | this.calendarDays = [].slice.call(this.el.querySelectorAll('.cube')); 193 | 194 | // Let´s build the days/cubes structure. 195 | this.cubes = document.createElement('div'); 196 | this.cubes.className = 'cubes'; 197 | this.el.appendChild(this.cubes); 198 | 199 | // Array of days (each day is represented by a 3D Cube) 200 | this.days = []; 201 | var self = this; 202 | this.calendarDays.forEach(function(d, pos) { 203 | // Get the bg color defined in the data-bg-color of each division. 204 | var day = new Day({ 205 | number: pos, 206 | color: d.getAttribute('data-bg-color') || '#f1f1f1', 207 | previewTitle: d.getAttribute('data-title') || '', 208 | inactive: d.hasAttribute('data-inactive') 209 | }), 210 | content = contents[pos]; 211 | 212 | if( content !== undefined ) { 213 | var contentTitle = contents[pos].querySelector('.content__title'); 214 | day._setContentTitleFx(contentTitle); 215 | } 216 | 217 | self.days.push(day); 218 | self.cubes.appendChild(day.cube); 219 | self.el.removeChild(d); 220 | self._initDayEvents(day); 221 | }); 222 | 223 | // structure to show each day preview (day + title + subtitle etc, when the user hovers one day/cube). 224 | this.dayPreview = document.createElement('h2'); 225 | this.dayPreview.className = 'title'; 226 | this.el.appendChild(this.dayPreview); 227 | 228 | this._initEvents(); 229 | } 230 | 231 | Calendar.prototype._initEvents = function() { 232 | var self = this; 233 | 234 | // Mousemove event / tilt functionality 235 | if( settings.tilt ) { 236 | this.mousemoveFn = function(ev) { 237 | if( self.isOpen ) { 238 | return false; 239 | }; 240 | requestAnimationFrame(function() { 241 | // Mouse position relative to the document. 242 | var mousepos = getMousePos(ev); 243 | self._rotateCalendar(mousepos); 244 | }); 245 | }; 246 | 247 | this.handleOrientation = function() { 248 | if( self.isOpen ) { 249 | return false; 250 | }; 251 | 252 | var y = event.gamma; 253 | // To make computation easier we shift the range of x and y to [0,180] 254 | y += 90; 255 | requestAnimationFrame(function() { 256 | // Transform values. 257 | var movement = {ry:40}, 258 | rotY = 2*movement.ry / 180 * y - movement.ry; 259 | 260 | self.cubes.style.WebkitTransform = self.cubes.style.transform = 'rotate3d(0,-1,0,' + rotY + 'deg)'; 261 | }); 262 | }; 263 | if( isMobile ) { 264 | window.addEventListener('deviceorientation', this.handleOrientation); 265 | } 266 | else { 267 | document.addEventListener('mousemove', this.mousemoveFn); 268 | } 269 | } 270 | 271 | this.backToCalendarFn = function(ev) { 272 | // If the calendar is currently animating then do nothing. 273 | if( !self.isOpen || self.isAnimating ) { 274 | return false; 275 | } 276 | self.isAnimating = true; 277 | self._hidePreviewTitle(); 278 | self._hideContent(); 279 | 280 | // Show the main container 281 | anime({ 282 | targets: self.el, 283 | duration: 1400, 284 | easing: 'easeInOutExpo', 285 | opacity: 1, 286 | complete: function() { 287 | self.isOpen = false; 288 | self.isAnimating = false; 289 | } 290 | }); 291 | 292 | var win = {w:window.innerWidth, h:window.innerHeight}; 293 | for(var i = 0, totalDays = self.days.length; i < totalDays; ++i) { 294 | var day = self.days[i]; 295 | if( self.currentDayIdx === i ) { 296 | anime({ 297 | targets: day.cube, 298 | duration: 1200, 299 | delay: 1000, 300 | easing: 'easeOutExpo', 301 | scale: [0,1], 302 | translateY: 0, 303 | translateZ: [-1500,0], 304 | rotateX: 0, 305 | rotateY: 0 306 | }); 307 | day.isRotated = false; 308 | } 309 | else { 310 | anime({ 311 | targets: day.cube, 312 | duration: 700, 313 | delay: function(el, index) { 314 | return 1000 + anime.random(0,100); 315 | }, 316 | easing: 'easeOutExpo', 317 | translateX: [day.currentTransform.translateX < 0 ? -win.w : win.w,0], 318 | translateY: [day.currentTransform.translateY < 0 ? -win.h : win.h,0], 319 | rotateY: [day.currentTransform.rotateY,0] 320 | }); 321 | } 322 | } 323 | }; 324 | backCtrl.addEventListener('click', this.backToCalendarFn); 325 | }; 326 | 327 | Calendar.prototype._initDayEvents = function(day) { 328 | var self = this; 329 | 330 | // Day/Cube mouseenter/mouseleave event. 331 | var instance = day; 332 | if( !isMobile ) { 333 | instance.mouseenterFn = function(ev) { 334 | if( instance.isRotated || self.isOpen ) { 335 | return false; 336 | }; 337 | clearTimeout(colortimeout); 338 | instance.rotatetimeout = setTimeout(function() { 339 | colortimeout = setTimeout(function() { self._changeBGColor(instance.color); }, 30); 340 | instance._rotate(ev); 341 | self._showPreviewTitle(instance.previewTitle, instance.number); 342 | instance.isRotated = true; 343 | }, 30); 344 | }; 345 | instance.mouseleaveFn = function(ev) { 346 | if( self.isOpen ) { 347 | return false; 348 | }; 349 | clearTimeout(instance.rotatetimeout); 350 | clearTimeout(colortimeout); 351 | if( instance.isRotated ) { 352 | colortimeout = setTimeout(function() { self._resetBGColor(); }, 35); 353 | instance._rotate(ev); 354 | self._hidePreviewTitle(); 355 | instance.isRotated = false; 356 | } 357 | }; 358 | } 359 | // Day/Cube click event. 360 | instance.clickFn = function(ev) { 361 | // If the day is inactive or if the calendar is currently animating then do nothing. 362 | if( !instance.isActive || self.isAnimating ) { 363 | return false; 364 | } 365 | self.isAnimating = true; 366 | self.isOpen = true; 367 | self.currentDayIdx = instance.number; 368 | 369 | // Hide the main container 370 | anime({ 371 | targets: self.el, 372 | duration: 1400, 373 | easing: 'easeInOutExpo', 374 | opacity: 0, 375 | complete: function() { 376 | self.isAnimating = false; 377 | } 378 | }); 379 | 380 | var win = {w:window.innerWidth, h:window.innerHeight}; 381 | for(var i = 0, totalDays = self.days.length; i < totalDays; ++i) { 382 | var day = self.days[i]; 383 | 384 | if( self.currentDayIdx === i ) { 385 | anime({ 386 | targets: day.cube, 387 | duration: 1000, 388 | easing: 'easeInOutExpo', 389 | scale: 0, 390 | translateZ: -1500, 391 | rotateX: day.currentTransform.rotateX, 392 | rotateY: day.currentTransform.rotateY 393 | }); 394 | self._showContent(instance); 395 | } 396 | else { 397 | var bcr = day.cube.getBoundingClientRect(), 398 | l = bcr.left + window.pageXOffset, 399 | t = bcr.top + window.pageYOffset; 400 | 401 | anime({ 402 | targets: day.cube, 403 | duration: 1200, 404 | easing: 'easeInOutExpo', 405 | translateX: function(el, index) { 406 | day.currentTransform.translateX = l <= win.w/2 && t <= win.h/2 || l <= win.w/2 && t > win.h/2 ? anime.random(-800,-400) : anime.random(800,400); 407 | return day.currentTransform.translateX; 408 | }, 409 | translateY: function(el, index) { 410 | day.currentTransform.translateY = l <= win.w/2 && t <= win.h/2 || l > win.w/2 && t <= win.h/2 ? anime.random(-800,400) : anime.random(800,400); 411 | return day.currentTransform.translateY; 412 | }, 413 | rotateY: function(el, index) { 414 | day.currentTransform.rotateY = l <= win.w/2 && t <= win.h/2 || l <= win.w/2 && t > win.h/2 ? anime.random(90,40) : anime.random(-90,-40); 415 | return day.currentTransform.rotateY; 416 | } 417 | }); 418 | } 419 | } 420 | }; 421 | instance.cube.querySelector('.cube__side--front').addEventListener('mouseenter', instance.mouseenterFn); 422 | instance.cube.addEventListener('mouseleave', instance.mouseleaveFn); 423 | instance.cube.addEventListener('click', instance.clickFn); 424 | instance.cube.addEventListener('mousedown', function() { 425 | clearTimeout(instance.rotatetimeout ); 426 | }); 427 | }; 428 | 429 | Calendar.prototype._rotateCalendar = function(mousepos) { 430 | // Transform values. 431 | var movement = {rx:3, ry:3}, 432 | rotX = 2 * movement.rx / this.cubes.offsetHeight * mousepos.y - movement.rx, 433 | rotY = 2 * movement.ry / this.cubes.offsetWidth * mousepos.x - movement.ry; 434 | 435 | this.cubes.style.WebkitTransform = this.cubes.style.transform = 'rotate3d(-1,0,0,' + rotX + 'deg) rotate3d(0,1,0,' + rotY + 'deg)'; 436 | }; 437 | 438 | Calendar.prototype._showPreviewTitle = function(text, number) { 439 | this.dayPreview.innerHTML = text; 440 | this.dayPreview.setAttribute('data-number', parseInt(number+1)); 441 | 442 | this.txtfx = new TextFx(this.dayPreview); 443 | this.txtfx.hide(); 444 | this.dayPreview.style.opacity = 1; 445 | this.txtfx.show({ 446 | in: { 447 | duration: 800, 448 | delay: function(el, index, total) { return index*40; }, 449 | easing: 'easeOutElastic', 450 | opacity: 1, 451 | translateY: function(el, index) { 452 | return index%2 === 0 ? [-25, 0] : [25, 0]; 453 | }, 454 | rotateZ: [45,0] 455 | } 456 | }); 457 | }; 458 | 459 | Calendar.prototype._hidePreviewTitle = function() { 460 | var self = this; 461 | if( this.txtfx ) { 462 | this.txtfx.hide(); 463 | } 464 | this.dayPreview.style.opacity = 0; 465 | }; 466 | 467 | Calendar.prototype._showContent = function(day) { 468 | // The content box for the clicked day. 469 | var content = contents[this.currentDayIdx], 470 | title = content.querySelector('.content__title'), 471 | description = content.querySelector('.content__description'), 472 | meta = content.querySelector('.content__meta'); 473 | 474 | content.classList.add('content__block--current'); 475 | 476 | day.titlefx.hide(); 477 | day.titlefx.show(day.titlefxSettings); 478 | 479 | anime({ 480 | targets: [description, meta], 481 | duration: 800, 482 | delay: function(el, index) { return index === 0 ? 900 : 1000 }, 483 | easing: 'easeOutExpo', 484 | opacity: [0,1], 485 | translateY: [100,0] 486 | }); 487 | 488 | anime({ 489 | targets: backCtrl, 490 | duration: 1000, 491 | delay: 800, 492 | easing: 'easeOutExpo', 493 | opacity: [0,1], 494 | translateY: [50,0] 495 | }); 496 | 497 | contentNumber.innerHTML = this.currentDayIdx + 1; 498 | anime({ 499 | targets: contentNumber, 500 | duration: 500, 501 | delay: 800, 502 | easing: 'easeOutExpo', 503 | opacity: [0,1], 504 | translateX: ['-50%','-50%'], 505 | translateY: ['-100%','-50%'] 506 | }); 507 | }; 508 | 509 | Calendar.prototype._hideContent = function() { 510 | var day = this.days[this.currentDayIdx], 511 | // The content box for the clicked day. 512 | content = contents[this.currentDayIdx], 513 | // The content title, description and meta for this day. 514 | title = content.querySelector('.content__title'), 515 | description = content.querySelector('.content__description'), 516 | meta = content.querySelector('.content__meta'); 517 | 518 | // The content number placeholder animation. 519 | anime({ 520 | targets: contentNumber, 521 | duration: 500, 522 | easing: 'easeInExpo', 523 | opacity: 0, 524 | translateX: ['-50%','-50%'], 525 | translateY: ['-50%','100%'] 526 | }); 527 | 528 | // The back button animation. 529 | anime({ 530 | targets: backCtrl, 531 | duration: 1000, 532 | easing: 'easeInExpo', 533 | opacity: 0, 534 | translateY: 50 535 | }); 536 | 537 | // The description and meta animation. 538 | anime({ 539 | targets: [description, meta], 540 | duration: 800, 541 | delay: function(el, index) { return index === 0 ? 150 : 0 }, 542 | easing: 'easeInExpo', 543 | opacity: [1,0], 544 | translateY: [0,200] 545 | }); 546 | 547 | // The content title animation. 548 | day.titlefx.hide(day.titlefxSettings, function() { 549 | content.classList.remove('content__block--current'); 550 | }); 551 | }; 552 | 553 | Calendar.prototype._changeBGColor = function(color) { 554 | bgEl.style.backgroundColor = color; 555 | }; 556 | 557 | Calendar.prototype._resetBGColor = function() { 558 | bgEl.style.backgroundColor = defaultBgColor; 559 | }; 560 | 561 | // Snow obj. Based on // https://gist.github.com/OmShiv/4368164. 562 | function Snow() { 563 | this.canvas = document.createElement('canvas'); 564 | this.canvas.id = 'snow'; 565 | this.canvas.className = 'background'; 566 | this.canvas.style.background = defaultBgColor; 567 | document.body.insertBefore(this.canvas, document.body.firstElementChild); 568 | 569 | this.flakes = []; 570 | this.ctx = this.canvas.getContext('2d'); 571 | this.flakeCount = 300; 572 | this.mX = -100, 573 | this.mY = -100 574 | 575 | this.width = this.canvas.width = window.innerWidth; 576 | this.height = this.canvas.height = window.innerHeight; 577 | 578 | this._init(); 579 | } 580 | 581 | Snow.prototype._init = function() { 582 | var self = this; 583 | window.addEventListener('resize', function() { 584 | self.width = self.canvas.width = window.innerWidth; 585 | self.height = self.canvas.height = window.innerHeight; 586 | }); 587 | 588 | for(var i = 0; i < this.flakeCount; ++i) { 589 | var x = Math.floor(Math.random() * this.width), 590 | y = Math.floor(Math.random() * this.height), 591 | size = (Math.random()*3.5) + .5, 592 | speed = size*.5, 593 | opacity = (Math.random() * 0.5) + 0.1; 594 | 595 | this.flakes.push({ 596 | speed: speed, 597 | velY: speed, 598 | velX: 0, 599 | x: x, 600 | y: y, 601 | size: size, 602 | stepSize: (Math.random()) / 30, 603 | step: 0, 604 | opacity: opacity 605 | }); 606 | } 607 | 608 | this._snow(); 609 | }; 610 | 611 | Snow.prototype._snow = function() { 612 | this.ctx.clearRect(0, 0, this.width, this.height); 613 | 614 | for(var i = 0; i < this.flakeCount; ++i) { 615 | var flake = this.flakes[i], 616 | x = this.mX, 617 | y = this.mY, 618 | minDist = 150, 619 | x2 = flake.x, 620 | y2 = flake.y, 621 | dist = Math.sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)), 622 | dx = x2 - x, 623 | dy = y2 - y; 624 | 625 | if( dist < minDist ) { 626 | var force = minDist / (dist * dist), 627 | xcomp = (x - x2) / dist, 628 | ycomp = (y - y2) / dist, 629 | deltaV = force / 2; 630 | flake.velX -= deltaV * xcomp; 631 | flake.velY -= deltaV * ycomp; 632 | } 633 | else { 634 | flake.velX *= .98; 635 | if( flake.velY <= flake.speed ) { 636 | flake.velY = flake.speed 637 | } 638 | flake.velX += Math.cos(flake.step += .05) * flake.stepSize; 639 | } 640 | 641 | this.ctx.fillStyle = "rgba(255,255,255," + flake.opacity + ")"; 642 | flake.y += flake.velY; 643 | flake.x += flake.velX; 644 | 645 | if( flake.y >= this.height || flake.y <= 0 ) { 646 | this._reset(flake); 647 | } 648 | 649 | if( flake.x >= this.width || flake.x <= 0 ) { 650 | this._reset(flake); 651 | } 652 | 653 | this.ctx.beginPath(); 654 | this.ctx.arc(flake.x, flake.y, flake.size, 0, Math.PI * 2); 655 | this.ctx.fill(); 656 | } 657 | requestAnimationFrame(this._snow.bind(this)); 658 | }; 659 | 660 | Snow.prototype._reset = function(flake) { 661 | flake.x = Math.floor(Math.random() * this.width); 662 | flake.y = 0; 663 | flake.size = (Math.random() * 3.5) + .5; 664 | flake.speed = flake.size*.5, 665 | flake.velY = flake.speed; 666 | flake.velX = 0; 667 | flake.opacity = (Math.random() * 0.5) + 0.1; 668 | }; 669 | 670 | var calendarEl = document.querySelector('.calendar'), 671 | calendarDays = [].slice.call(calendarEl.children), 672 | settings = { 673 | snow: false, 674 | tilt: true 675 | }, 676 | bgEl = document.body, 677 | defaultBgColor = bgEl.style.backgroundColor, 678 | colortimeout, 679 | contentEl = document.querySelector('.content'), 680 | contents = contentEl.querySelectorAll('.content__block'), 681 | backCtrl = contentEl.querySelector('.btn-back'), 682 | contentNumber = contentEl.querySelector('.content__number'), 683 | isMobile = mobilecheck(); 684 | 685 | function init() { 686 | layout(); 687 | } 688 | 689 | function layout() { 690 | new Calendar(calendarEl); 691 | // If settings.snow === true then create the canvas element for the snow effect. 692 | if( settings.snow ) { 693 | var snow = new Snow(); 694 | bgEl = snow.canvas; 695 | } 696 | } 697 | 698 | init(); 699 | 700 | })(window); -------------------------------------------------------------------------------- /js/main3.js: -------------------------------------------------------------------------------- 1 | /** 2 | * main.js 3 | * http://www.codrops.com 4 | * 5 | * Licensed under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 8 | * Copyright 2016, Codrops 9 | * http://www.codrops.com 10 | */ 11 | ;(function(window) { 12 | 13 | 'use strict'; 14 | 15 | // Helper vars and functions. 16 | function extend( a, b ) { 17 | for( var key in b ) { 18 | if( b.hasOwnProperty( key ) ) { 19 | a[key] = b[key]; 20 | } 21 | } 22 | return a; 23 | } 24 | // From http://www.quirksmode.org/js/events_properties.html#position 25 | function getMousePos(e) { 26 | var posx = 0; 27 | var posy = 0; 28 | if (!e) var e = window.event; 29 | if (e.pageX || e.pageY) { 30 | posx = e.pageX; 31 | posy = e.pageY; 32 | } 33 | else if (e.clientX || e.clientY) { 34 | posx = e.clientX + document.body.scrollLeft 35 | + document.documentElement.scrollLeft; 36 | posy = e.clientY + document.body.scrollTop 37 | + document.documentElement.scrollTop; 38 | } 39 | return { 40 | x : posx, 41 | y : posy 42 | } 43 | } 44 | // Detect mobile. From: http://stackoverflow.com/a/11381730/989439 45 | function mobilecheck() { 46 | var check = false; 47 | (function(a){if(/(android|ipad|playbook|silk|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera); 48 | return check; 49 | } 50 | 51 | // The Day obj. 52 | function Day(options) { 53 | this.options = extend({}, this.options); 54 | extend(this.options, options); 55 | this.number = this.options.number; 56 | this.color = this.options.color; 57 | this.previewTitle = this.options.previewTitle; 58 | this.isActive = !this.options.inactive; 59 | this._layout(); 60 | } 61 | 62 | Day.prototype.options = { 63 | number: 0, 64 | color: '#f1f1f1', 65 | previewTitle: '', 66 | inactive: false 67 | }; 68 | 69 | // Build the 3D cube element. 70 | Day.prototype._layout = function() { 71 | /* The Cube structure: 72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | */ 81 | this.cube = document.createElement('div'); 82 | this.cube.className = this.isActive ? 'cube' : 'cube cube--inactive'; 83 | this.cube.innerHTML = '
' + (this.number+1) + '
'; 84 | this.currentTransform = {translateZ: 0, rotateX: 0, rotateY: 0}; 85 | }; 86 | 87 | Day.prototype._rotate = function(ev) { 88 | anime.remove(this.cube); 89 | 90 | var dir = this._getDirection(ev), 91 | type = ev.type.toLowerCase() === 'mouseenter' ? 1 : -1, 92 | animationSettings = { 93 | targets: this.cube, 94 | duration: 500, 95 | easing: 'easeOutQuart', 96 | translateZ: type === 1 ? 100 : 0 97 | }; 98 | 99 | switch(dir) { 100 | case 0 : // from/to top 101 | animationSettings.rotateX = type === 1 ? -180 : 0; 102 | animationSettings.rotateY = 0; 103 | break; 104 | case 1 : // from/to right 105 | animationSettings.rotateY = type === 1 ? -180 : 0; 106 | animationSettings.rotateX = 0; 107 | break; 108 | case 2 : // from/to bottom 109 | animationSettings.rotateX = type === 1 ? 180 : 0; 110 | animationSettings.rotateY = 0; 111 | break; 112 | case 3 : // from/to left 113 | animationSettings.rotateY = type === 1 ? 180 : 0; 114 | animationSettings.rotateX = 0; 115 | break; 116 | }; 117 | 118 | this.currentTransform = { 119 | translateZ: animationSettings.translateZ, 120 | rotateX: animationSettings.rotateX, 121 | rotateY: animationSettings.rotateY 122 | }; 123 | 124 | anime(animationSettings); 125 | }; 126 | 127 | Day.prototype._setContentTitleFx = function(contentTitleEl) { 128 | this.titlefx = new TextFx(contentTitleEl); 129 | this.titlefxSettings = { 130 | in: { 131 | duration: 800, 132 | delay: function(el, index) { return 900 + index*20; }, 133 | easing: 'easeOutExpo', 134 | opacity: { 135 | duration: 200, 136 | value: [0,1], 137 | easing:'linear' 138 | }, 139 | rotateZ: function(el, index) { return [anime.random(-10,10), 0]; }, 140 | translateY: function(el, index) { 141 | return [anime.random(-200,-100),0]; 142 | } 143 | }, 144 | out: { 145 | duration: 800, 146 | delay: 300, 147 | easing: 'easeInExpo', 148 | opacity: 0, 149 | translateY: -350 150 | } 151 | }; 152 | }; 153 | 154 | // From: https://codepen.io/noeldelgado/pen/pGwFx?editors=0110 by Noel Delgado (@noeldelgado). 155 | Day.prototype._getDirection = function(ev) { 156 | var obj = this.cube.querySelector('.cube__side--front'), 157 | w = obj.offsetWidth, 158 | h = obj.offsetHeight, 159 | bcr = obj.getBoundingClientRect(), 160 | x = (ev.pageX - (bcr.left + window.pageXOffset) - (w / 2) * (w > h ? (h / w) : 1)), 161 | y = (ev.pageY - (bcr.top + window.pageYOffset) - (h / 2) * (h > w ? (w / h) : 1)), 162 | d = Math.round( Math.atan2(y, x) / 1.57079633 + 5 ) % 4; 163 | 164 | return d; 165 | }; 166 | 167 | // The Calendar obj. 168 | function Calendar(el) { 169 | this.el = el; 170 | this.calendarDays = [].slice.call(this.el.querySelectorAll('.cube')); 171 | 172 | // Let´s build the days/cubes structure. 173 | this.cubes = document.createElement('div'); 174 | this.cubes.className = 'cubes'; 175 | this.el.appendChild(this.cubes); 176 | 177 | // Array of days (each day is represented by a 3D Cube) 178 | this.days = []; 179 | var self = this; 180 | this.calendarDays.forEach(function(d, pos) { 181 | // Get the bg color defined in the data-bg-color of each division. 182 | var day = new Day({ 183 | number: pos, 184 | color: d.getAttribute('data-bg-color') || '#f1f1f1', 185 | previewTitle: d.getAttribute('data-title') || '', 186 | inactive: d.hasAttribute('data-inactive') 187 | }), 188 | content = contents[pos]; 189 | 190 | if( content !== undefined ) { 191 | var contentTitle = contents[pos].querySelector('.content__title'); 192 | day._setContentTitleFx(contentTitle); 193 | } 194 | 195 | self.days.push(day); 196 | self.cubes.appendChild(day.cube); 197 | self.el.removeChild(d); 198 | self._initDayEvents(day); 199 | }); 200 | 201 | // structure to show each day preview (day + title + subtitle etc, when the user hovers one day/cube). 202 | this.dayPreview = document.createElement('h2'); 203 | this.dayPreview.className = 'title'; 204 | this.el.appendChild(this.dayPreview); 205 | 206 | this._initEvents(); 207 | } 208 | 209 | Calendar.prototype._initEvents = function() { 210 | var self = this; 211 | 212 | // Mousemove event / tilt functionality 213 | if( settings.tilt ) { 214 | this.mousemoveFn = function(ev) { 215 | if( self.isOpen ) { 216 | return false; 217 | }; 218 | requestAnimationFrame(function() { 219 | // Mouse position relative to the document. 220 | var mousepos = getMousePos(ev); 221 | self._rotateCalendar(mousepos); 222 | }); 223 | }; 224 | 225 | this.handleOrientation = function() { 226 | if( self.isOpen ) { 227 | return false; 228 | }; 229 | 230 | var y = event.gamma; 231 | // To make computation easier we shift the range of x and y to [0,180] 232 | y += 90; 233 | requestAnimationFrame(function() { 234 | // Transform values. 235 | var movement = {ry:40}, 236 | rotY = 2*movement.ry / 180 * y - movement.ry; 237 | 238 | self.cubes.style.WebkitTransform = self.cubes.style.transform = 'rotate3d(0,-1,0,' + rotY + 'deg)'; 239 | }); 240 | }; 241 | if( isMobile ) { 242 | window.addEventListener('deviceorientation', this.handleOrientation); 243 | } 244 | else { 245 | document.addEventListener('mousemove', this.mousemoveFn); 246 | } 247 | } 248 | 249 | this.backToCalendarFn = function(ev) { 250 | // If the calendar is currently animating then do nothing. 251 | if( !self.isOpen || self.isAnimating ) { 252 | return false; 253 | } 254 | self.isAnimating = true; 255 | self._hidePreviewTitle(); 256 | self._hideContent(); 257 | 258 | // Show the main container 259 | anime({ 260 | targets: self.el, 261 | duration: 1400, 262 | easing: 'easeInOutExpo', 263 | opacity: 1 264 | }); 265 | 266 | for(var i = 0, totalDays = self.days.length; i < totalDays; ++i) { 267 | var day = self.days[i], isCurrent = self.currentDayIdx === i; 268 | 269 | if( isCurrent ) { 270 | day.isRotated = false; 271 | } 272 | 273 | anime({ 274 | targets: day.cube, 275 | duration: 500, 276 | delay: isCurrent ? 1000 : function(el, index) { 277 | return 1100 + anime.random(0,300); 278 | }, 279 | easing: 'easeOutBack', 280 | scale: [0,1], 281 | translateZ: 0, 282 | rotateX: 0, 283 | rotateY: 0, 284 | complete: isCurrent ? function() { 285 | self.isOpen = false; 286 | self.isAnimating = false; 287 | } : null 288 | }); 289 | } 290 | }; 291 | backCtrl.addEventListener('click', this.backToCalendarFn); 292 | }; 293 | 294 | Calendar.prototype._initDayEvents = function(day) { 295 | var self = this; 296 | 297 | // Day/Cube mouseenter/mouseleave event. 298 | var instance = day; 299 | if( !isMobile ) { 300 | instance.mouseenterFn = function(ev) { 301 | if( instance.isRotated || self.isOpen ) { 302 | return false; 303 | }; 304 | clearTimeout(colortimeout); 305 | instance.rotatetimeout = setTimeout(function() { 306 | colortimeout = setTimeout(function() { self._changeBGColor(instance.color); }, 30); 307 | instance._rotate(ev); 308 | self._showPreviewTitle(instance.previewTitle, instance.number); 309 | instance.isRotated = true; 310 | }, 30); 311 | }; 312 | instance.mouseleaveFn = function(ev) { 313 | if( self.isOpen ) { 314 | return false; 315 | }; 316 | clearTimeout(instance.rotatetimeout); 317 | clearTimeout(colortimeout); 318 | if( instance.isRotated ) { 319 | colortimeout = setTimeout(function() { self._resetBGColor(); }, 35); 320 | instance._rotate(ev); 321 | self._hidePreviewTitle(); 322 | instance.isRotated = false; 323 | } 324 | }; 325 | } 326 | // Day/Cube click event. 327 | instance.clickFn = function(ev) { 328 | // If the day is inactive or if the calendar is currently animating then do nothing. 329 | if( !instance.isActive || self.isAnimating ) { 330 | return false; 331 | } 332 | self.isAnimating = true; 333 | self.isOpen = true; 334 | self.currentDayIdx = instance.number; 335 | 336 | // Hide the main container 337 | anime({ 338 | targets: self.el, 339 | duration: 1400, 340 | easing: 'easeInOutExpo', 341 | opacity: 0, 342 | complete: function() { 343 | self.isAnimating = false; 344 | } 345 | }); 346 | 347 | for(var i = 0, totalDays = self.days.length; i < totalDays; ++i) { 348 | var day = self.days[i], 349 | isCurrent = self.currentDayIdx === i 350 | 351 | if( isCurrent ) { 352 | self._showContent(instance); 353 | } 354 | 355 | anime({ 356 | targets: day.cube, 357 | duration: 500, 358 | delay: isCurrent ? 600 : function() { return anime.random(0,300); }, 359 | easing: isCurrent ? 'easeOutCubic' : 'easeInBack', 360 | scale: 0, 361 | translateZ: isCurrent ? -1000 : function() { return anime.random(-1000,-400); }, 362 | rotateX: isCurrent ? -180 : function() { return anime.random(-180,180); }, 363 | rotateY: isCurrent ? -180 : function() { return anime.random(-180,180); } 364 | }); 365 | } 366 | }; 367 | instance.cube.querySelector('.cube__side--front').addEventListener('mouseenter', instance.mouseenterFn); 368 | instance.cube.addEventListener('mouseleave', instance.mouseleaveFn); 369 | instance.cube.addEventListener('click', instance.clickFn); 370 | instance.cube.addEventListener('mousedown', function() { 371 | clearTimeout(instance.rotatetimeout ); 372 | }); 373 | }; 374 | 375 | Calendar.prototype._rotateCalendar = function(mousepos) { 376 | // Transform values. 377 | var movement = {rx:3, ry:3}, 378 | rotX = 2 * movement.rx / this.cubes.offsetHeight * mousepos.y - movement.rx, 379 | rotY = 2 * movement.ry / this.cubes.offsetWidth * mousepos.x - movement.ry; 380 | 381 | this.cubes.style.WebkitTransform = this.cubes.style.transform = 'rotate3d(-1,0,0,' + rotX + 'deg) rotate3d(0,1,0,' + rotY + 'deg)'; 382 | }; 383 | 384 | Calendar.prototype._showPreviewTitle = function(text, number) { 385 | this.dayPreview.innerHTML = text; 386 | this.dayPreview.setAttribute('data-number', parseInt(number+1)); 387 | 388 | this.txtfx = new TextFx(this.dayPreview); 389 | this.txtfx.hide(); 390 | this.dayPreview.style.opacity = 1; 391 | this.txtfx.show({ 392 | in: { 393 | duration: 700, 394 | delay: function(el, index) { return index*20; }, 395 | easing: 'easeOutCirc', 396 | opacity: 1, 397 | translateX: function(el, index) { 398 | return [(50+index*10),0] 399 | } 400 | } 401 | }); 402 | }; 403 | 404 | Calendar.prototype._hidePreviewTitle = function() { 405 | var self = this; 406 | if( this.txtfx ) { 407 | this.txtfx.hide(); 408 | } 409 | this.dayPreview.style.opacity = 0; 410 | }; 411 | 412 | Calendar.prototype._showContent = function(day) { 413 | // The content box for the clicked day. 414 | var content = contents[this.currentDayIdx], 415 | title = content.querySelector('.content__title'), 416 | description = content.querySelector('.content__description'), 417 | meta = content.querySelector('.content__meta'); 418 | 419 | content.classList.add('content__block--current'); 420 | 421 | day.titlefx.hide(); 422 | day.titlefx.show(day.titlefxSettings); 423 | 424 | anime({ 425 | targets: [description, meta], 426 | duration: 800, 427 | delay: function(el, index) { return index === 0 ? 1000 : 1100 }, 428 | easing: 'easeOutExpo', 429 | opacity: [0,1], 430 | translateY: [100,0] 431 | }); 432 | 433 | anime({ 434 | targets: backCtrl, 435 | duration: 1100, 436 | delay: 800, 437 | easing: 'easeOutExpo', 438 | opacity: [0,1], 439 | translateY: [50,0] 440 | }); 441 | 442 | contentNumber.innerHTML = this.currentDayIdx + 1; 443 | anime({ 444 | targets: contentNumber, 445 | duration: 500, 446 | delay: 900, 447 | easing: 'easeOutExpo', 448 | opacity: [0,1], 449 | translateX: [-200,0] 450 | }); 451 | }; 452 | 453 | Calendar.prototype._hideContent = function() { 454 | var day = this.days[this.currentDayIdx], 455 | // The content box for the clicked day. 456 | content = contents[this.currentDayIdx], 457 | // The content title, description and meta for this day. 458 | title = content.querySelector('.content__title'), 459 | description = content.querySelector('.content__description'), 460 | meta = content.querySelector('.content__meta'); 461 | 462 | // The content number placeholder animation. 463 | anime({ 464 | targets: contentNumber, 465 | duration: 800, 466 | easing: 'easeInExpo', 467 | opacity: 0, 468 | translateX: -200 469 | }); 470 | 471 | // The back button animation. 472 | anime({ 473 | targets: backCtrl, 474 | duration: 1000, 475 | easing: 'easeInExpo', 476 | opacity: 0, 477 | translateY: 50 478 | }); 479 | 480 | // The description and meta animation. 481 | anime({ 482 | targets: [description, meta], 483 | duration: 800, 484 | delay: function(el, index) { return index === 0 ? 150 : 0 }, 485 | easing: 'easeInExpo', 486 | opacity: [1,0], 487 | translateY: [0,200] 488 | }); 489 | 490 | // The content title animation. 491 | var bcr = day.cube.getBoundingClientRect(); 492 | day.titlefx.hide(day.titlefxSettings, function() { 493 | content.classList.remove('content__block--current'); 494 | }); 495 | }; 496 | 497 | Calendar.prototype._changeBGColor = function(color) { 498 | bgEl.style.backgroundColor = color; 499 | }; 500 | 501 | Calendar.prototype._resetBGColor = function() { 502 | bgEl.style.backgroundColor = defaultBgColor; 503 | }; 504 | 505 | // Snow obj. Based on // https://gist.github.com/OmShiv/4368164. 506 | function Snow() { 507 | this.canvas = document.createElement('canvas'); 508 | this.canvas.id = 'snow'; 509 | this.canvas.className = 'background'; 510 | this.canvas.style.background = defaultBgColor; 511 | document.body.insertBefore(this.canvas, document.body.firstElementChild); 512 | 513 | this.flakes = []; 514 | this.ctx = this.canvas.getContext('2d'); 515 | this.flakeCount = 300; 516 | this.mX = -100, 517 | this.mY = -100 518 | 519 | this.width = this.canvas.width = window.innerWidth; 520 | this.height = this.canvas.height = window.innerHeight; 521 | 522 | this._init(); 523 | } 524 | 525 | Snow.prototype._init = function() { 526 | var self = this; 527 | window.addEventListener('resize', function() { 528 | self.width = self.canvas.width = window.innerWidth; 529 | self.height = self.canvas.height = window.innerHeight; 530 | }); 531 | 532 | for(var i = 0; i < this.flakeCount; ++i) { 533 | var x = Math.floor(Math.random() * this.width), 534 | y = Math.floor(Math.random() * this.height), 535 | size = (Math.random()*3.5) + .5, 536 | speed = size*.5, 537 | opacity = (Math.random() * 0.5) + 0.1; 538 | 539 | this.flakes.push({ 540 | speed: speed, 541 | velY: speed, 542 | velX: 0, 543 | x: x, 544 | y: y, 545 | size: size, 546 | stepSize: (Math.random()) / 30, 547 | step: 0, 548 | opacity: opacity 549 | }); 550 | } 551 | 552 | this._snow(); 553 | }; 554 | 555 | Snow.prototype._snow = function() { 556 | this.ctx.clearRect(0, 0, this.width, this.height); 557 | 558 | for(var i = 0; i < this.flakeCount; ++i) { 559 | var flake = this.flakes[i], 560 | x = this.mX, 561 | y = this.mY, 562 | minDist = 150, 563 | x2 = flake.x, 564 | y2 = flake.y, 565 | dist = Math.sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)), 566 | dx = x2 - x, 567 | dy = y2 - y; 568 | 569 | if( dist < minDist ) { 570 | var force = minDist / (dist * dist), 571 | xcomp = (x - x2) / dist, 572 | ycomp = (y - y2) / dist, 573 | deltaV = force / 2; 574 | flake.velX -= deltaV * xcomp; 575 | flake.velY -= deltaV * ycomp; 576 | } 577 | else { 578 | flake.velX *= .98; 579 | if( flake.velY <= flake.speed ) { 580 | flake.velY = flake.speed 581 | } 582 | flake.velX += Math.cos(flake.step += .05) * flake.stepSize; 583 | } 584 | 585 | this.ctx.fillStyle = "rgba(255,255,255," + flake.opacity + ")"; 586 | flake.y += flake.velY; 587 | flake.x += flake.velX; 588 | 589 | if( flake.y >= this.height || flake.y <= 0 ) { 590 | this._reset(flake); 591 | } 592 | 593 | if( flake.x >= this.width || flake.x <= 0 ) { 594 | this._reset(flake); 595 | } 596 | 597 | this.ctx.beginPath(); 598 | this.ctx.arc(flake.x, flake.y, flake.size, 0, Math.PI * 2); 599 | this.ctx.fill(); 600 | } 601 | requestAnimationFrame(this._snow.bind(this)); 602 | }; 603 | 604 | Snow.prototype._reset = function(flake) { 605 | flake.x = Math.floor(Math.random() * this.width); 606 | flake.y = 0; 607 | flake.size = (Math.random() * 3.5) + .5; 608 | flake.speed = flake.size*.5, 609 | flake.velY = flake.speed; 610 | flake.velX = 0; 611 | flake.opacity = (Math.random() * 0.5) + 0.1; 612 | }; 613 | 614 | var calendarEl = document.querySelector('.calendar'), 615 | calendarDays = [].slice.call(calendarEl.children), 616 | settings = { 617 | snow: true, 618 | tilt: false 619 | }, 620 | bgEl = document.body, 621 | defaultBgColor = bgEl.style.backgroundColor, 622 | colortimeout, 623 | contentEl = document.querySelector('.content'), 624 | contents = contentEl.querySelectorAll('.content__block'), 625 | backCtrl = contentEl.querySelector('.btn-back'), 626 | contentNumber = contentEl.querySelector('.content__number'), 627 | isMobile = mobilecheck(); 628 | 629 | function init() { 630 | layout(); 631 | } 632 | 633 | function layout() { 634 | new Calendar(calendarEl); 635 | // If settings.snow === true then create the canvas element for the snow effect. 636 | if( settings.snow ) { 637 | var snow = new Snow(); 638 | bgEl = snow.canvas; 639 | } 640 | } 641 | 642 | init(); 643 | 644 | })(window); -------------------------------------------------------------------------------- /js/textfx.js: -------------------------------------------------------------------------------- 1 | /** 2 | * TextFx.js 3 | * http://www.codrops.com 4 | * 5 | * Licensed under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 8 | * Copyright 2016, Codrops 9 | * http://www.codrops.com 10 | */ 11 | ;(function(window) { 12 | 13 | 'use strict'; 14 | 15 | /** 16 | * Equation of a line. 17 | */ 18 | function lineEq(y2, y1, x2, x1, currentVal) { 19 | // y = mx + b 20 | var m = (y2 - y1) / (x2 - x1), 21 | b = y1 - m * x1; 22 | 23 | return m * currentVal + b; 24 | } 25 | 26 | function TextFx(el) { 27 | this.el = el; 28 | this._init(); 29 | } 30 | 31 | TextFx.prototype.effects = { 32 | 'fx1' : { 33 | in: { 34 | duration: 1000, 35 | delay: function(el, index) { return 75+index*40; }, 36 | easing: 'easeOutElastic', 37 | elasticity: 650, 38 | opacity: { 39 | value: 1, 40 | easing: 'easeOutExpo', 41 | }, 42 | translateY: ['50%','0%'] 43 | }, 44 | out: { 45 | duration: 400, 46 | delay: function(el, index) { return index*40; }, 47 | easing: 'easeOutExpo', 48 | opacity: 0, 49 | translateY: '-100%' 50 | } 51 | }, 52 | 'fx2' : { 53 | in: { 54 | duration: 700, 55 | delay: function(el, index) { return index*50; }, 56 | easing: 'easeOutCirc', 57 | opacity: 1, 58 | translateX: function(el, index) { 59 | return [(50+index*10),0] 60 | } 61 | }, 62 | out: { 63 | duration: 0, 64 | opacity: 0 65 | } 66 | }, 67 | 'fx3' : { 68 | in: { 69 | duration: 800, 70 | delay: function(el, index) { return index*50; }, 71 | easing: 'easeOutElastic', 72 | opacity: 1, 73 | translateY: function(el, index) { 74 | return index%2 === 0 ? ['-80%', '0%'] : ['80%', '0%']; 75 | } 76 | }, 77 | out: { 78 | duration: 800, 79 | delay: function(el, index) { return index*50; }, 80 | easing: 'easeOutExpo', 81 | opacity: 0, 82 | translateY: function(el, index) { 83 | return index%2 === 0 ? '80%' : '-80%'; 84 | } 85 | } 86 | }, 87 | 'fx4' : { 88 | in: { 89 | duration: 700, 90 | delay: function(el, index) { return (el.parentNode.children.length-index-1)*80; }, 91 | easing: 'easeOutElastic', 92 | opacity: 1, 93 | translateY: function(el, index) { 94 | return index%2 === 0 ? ['-80%', '0%'] : ['80%', '0%']; 95 | }, 96 | rotateZ: [90,0] 97 | }, 98 | out: { 99 | duration: 500, 100 | delay: function(el, index) { return (el.parentNode.children.length-index-1)*80; }, 101 | easing: 'easeOutExpo', 102 | opacity: 0, 103 | translateY: function(el, index) { 104 | return index%2 === 0 ? '80%' : '-80%'; 105 | }, 106 | rotateZ: function(el, index) { 107 | return index%2 === 0 ? -25 : 25; 108 | } 109 | } 110 | }, 111 | 'fx5' : { 112 | perspective: 1000, 113 | in: { 114 | duration: 700, 115 | delay: function(el, index) { return 550+index*50; }, 116 | easing: 'easeOutQuint', 117 | opacity: { 118 | value: 1, 119 | easing: 'linear', 120 | }, 121 | translateY: ['-150%','0%'], 122 | rotateY: [180,0] 123 | }, 124 | out: { 125 | duration: 700, 126 | delay: function(el, index) { return index*60; }, 127 | easing: 'easeInQuint', 128 | opacity: { 129 | value: 0, 130 | easing: 'linear', 131 | }, 132 | translateY: '150%', 133 | rotateY: -180 134 | } 135 | }, 136 | 'fx6' : { 137 | in: { 138 | duration: 600, 139 | easing: 'easeOutQuart', 140 | opacity: 1, 141 | translateY: function(el, index) { 142 | return index%2 === 0 ? ['-40%', '0%'] : ['40%', '0%']; 143 | }, 144 | rotateZ: [10,0] 145 | }, 146 | out: { 147 | duration: 0, 148 | opacity: 0 149 | } 150 | }, 151 | 'fx7' : { 152 | in: { 153 | duration: 250, 154 | delay: function(el, index) { return 200+index*25; }, 155 | easing: 'easeOutCubic', 156 | opacity: 1, 157 | translateY: ['-50%','0%'] 158 | }, 159 | out: { 160 | duration: 250, 161 | delay: function(el, index) { return index*25; }, 162 | easing: 'easeOutCubic', 163 | opacity: 0, 164 | translateY: '50%' 165 | } 166 | }, 167 | 'fx8' : { 168 | in: { 169 | duration: 400, 170 | delay: function(el, index) { return 150+(el.parentNode.children.length-index-1)*20; }, 171 | easing: 'easeOutQuad', 172 | opacity: 1, 173 | translateY: ['100%','0%'] 174 | }, 175 | out: { 176 | duration: 400, 177 | delay: function(el, index) { return (el.parentNode.children.length-index-1)*20; }, 178 | easing: 'easeInOutQuad', 179 | opacity: 0, 180 | translateY: '-100%' 181 | } 182 | }, 183 | 'fx9' : { 184 | perspective: 1000, 185 | origin: '50% 100%', 186 | in: { 187 | duration: 400, 188 | delay: function(el, index) { return index*50; }, 189 | easing: 'easeOutSine', 190 | opacity: 1, 191 | rotateY: [-90,0] 192 | }, 193 | out: { 194 | duration: 200, 195 | delay: function(el, index) { return index*50; }, 196 | easing: 'easeOutSine', 197 | opacity: 0, 198 | rotateY: 45 199 | } 200 | }, 201 | 'fx10' : { 202 | in: { 203 | duration: 1000, 204 | delay: function(el, index) { return 100+index*30; }, 205 | easing: 'easeOutElastic', 206 | elasticity: anime.random(400, 700), 207 | opacity: 1, 208 | rotateZ: function(el, index) { 209 | return [anime.random(20,40),0]; 210 | } 211 | }, 212 | out: { 213 | duration: 0, 214 | opacity: 0 215 | } 216 | }, 217 | 'fx11' : { 218 | perspective: 1000, 219 | origin: '50% 100%', 220 | in: { 221 | duration: 400, 222 | delay: function(el, index) { return 200+index*20; }, 223 | easing: 'easeOutExpo', 224 | opacity: 1, 225 | rotateY: [-90,0] 226 | }, 227 | out: { 228 | duration: 400, 229 | delay: function(el, index) { return index*20; }, 230 | easing: 'easeOutExpo', 231 | opacity: 0, 232 | rotateY: 90 233 | } 234 | }, 235 | 'fx12' : { 236 | perspective: 1000, 237 | origin: '50% 100%', 238 | in: { 239 | duration: 400, 240 | delay: function(el, index) { return 200+index*30; }, 241 | easing: 'easeOutExpo', 242 | opacity: 1, 243 | rotateX: [90,0] 244 | }, 245 | out: { 246 | duration: 400, 247 | delay: function(el, index) { return index*30; }, 248 | easing: 'easeOutExpo', 249 | opacity: 0, 250 | rotateX: -90 251 | } 252 | }, 253 | 'fx13' : { 254 | in: { 255 | duration: 800, 256 | easing: 'easeOutExpo', 257 | opacity: 1, 258 | translateY: function(el, index) { 259 | var p = el.parentNode, 260 | lastElOffW = p.lastElementChild.offsetWidth, 261 | firstElOffL = p.firstElementChild.offsetLeft, 262 | w = p.offsetWidth - lastElOffW - firstElOffL - (p.offsetWidth - lastElOffW - p.lastElementChild.offsetLeft), 263 | tyVal = lineEq(0, 200, firstElOffL + w/2, firstElOffL, el.offsetLeft); 264 | 265 | return [Math.abs(tyVal)+50+'%','0%']; 266 | }, 267 | rotateZ: function(el, index) { 268 | var p = el.parentNode, 269 | lastElOffW = p.lastElementChild.offsetWidth, 270 | firstElOffL = p.firstElementChild.offsetLeft, 271 | w = p.offsetWidth - lastElOffW - p.firstElementChild.offsetLeft - (p.offsetWidth - lastElOffW - p.lastElementChild.offsetLeft), 272 | rz = lineEq(90, -90,firstElOffL + w, firstElOffL, el.offsetLeft); 273 | 274 | return [rz,0]; 275 | } 276 | }, 277 | out: { 278 | duration: 500, 279 | easing: 'easeOutExpo', 280 | opacity: 0, 281 | translateY: '-150%' 282 | } 283 | }, 284 | 'fx14' : { 285 | in: { 286 | duration: 500, 287 | easing: 'easeOutExpo', 288 | delay: function(el, index) { return 200+index*30; }, 289 | opacity: 1, 290 | rotateZ: [20,0], 291 | translateY: function(el, index) { 292 | var p = el.parentNode, 293 | lastElOffW = p.lastElementChild.offsetWidth, 294 | firstElOffL = p.firstElementChild.offsetLeft, 295 | w = p.offsetWidth - lastElOffW - firstElOffL - (p.offsetWidth - lastElOffW - p.lastElementChild.offsetLeft), 296 | tyVal = lineEq(-130, -60, firstElOffL+w, firstElOffL, el.offsetLeft); 297 | 298 | return [Math.abs(tyVal)+'%','0%']; 299 | } 300 | }, 301 | out: { 302 | duration: 400, 303 | easing: 'easeOutExpo', 304 | delay: function(el, index) { return (el.parentNode.children.length-index-1)*30; }, 305 | opacity: 0, 306 | rotateZ: 20, 307 | translateY: function(el, index) { 308 | var p = el.parentNode, 309 | lastElOffW = p.lastElementChild.offsetWidth, 310 | firstElOffL = p.firstElementChild.offsetLeft, 311 | w = p.offsetWidth - lastElOffW - firstElOffL - (p.offsetWidth - lastElOffW - p.lastElementChild.offsetLeft), 312 | tyVal = lineEq(-60, -130, firstElOffL+w, firstElOffL, el.offsetLeft); 313 | 314 | return tyVal+'%'; 315 | } 316 | } 317 | }, 318 | 'fx15' : { 319 | perspective: 1000, 320 | in: { 321 | duration: 400, 322 | delay: function(el, index) { return 100+index*50; }, 323 | easing: 'easeOutExpo', 324 | opacity: 1, 325 | rotateX: [110,0] 326 | }, 327 | out: { 328 | duration: 400, 329 | delay: function(el, index) { return index*50; }, 330 | easing: 'easeOutExpo', 331 | opacity: 0, 332 | rotateX: -110 333 | } 334 | }, 335 | 'fx16' : { 336 | in: { 337 | duration: function(el, index) { return anime.random(800,1000) }, 338 | delay: function(el, index) { return anime.random(0,75) }, 339 | easing: 'easeInOutExpo', 340 | opacity: 1, 341 | translateY: ['-300%','0%'], 342 | rotateZ: function(el, index) { return [anime.random(-50,50), 0]; } 343 | }, 344 | out: { 345 | duration: function(el, index) { return anime.random(800,1000) }, 346 | delay: function(el, index) { return anime.random(0,80) }, 347 | easing: 'easeInOutExpo', 348 | opacity: 0, 349 | translateY: '300%', 350 | rotateZ: function(el, index) { return anime.random(-50,50); } 351 | } 352 | }, 353 | 'fx17' : { 354 | in: { 355 | duration: 650, 356 | easing: 'easeOutQuint', 357 | delay: function(el, index) { return 450+(el.parentNode.children.length-index-1)*30; }, 358 | opacity: 1, 359 | translateX: function(el, index) { 360 | return [-1*el.offsetLeft,0]; 361 | } 362 | }, 363 | out: { 364 | duration: 1, 365 | delay: 400, 366 | opacity: 0 367 | } 368 | }, 369 | 'fx18' : { 370 | in: { 371 | duration: 800, 372 | delay: function(el, index) { return 600+index*150; }, 373 | easing: 'easeInOutQuint', 374 | opacity: 1, 375 | scaleY: [8,1], 376 | scaleX: [0.5,1], 377 | translateY: ['-100%','0%'] 378 | }, 379 | out: { 380 | duration: 800, 381 | delay: function(el, index) { return index*150; }, 382 | easing: 'easeInQuint', 383 | opacity: 0, 384 | scaleY: { 385 | value: 8, 386 | delay: function(el, index) { return 100+index*150; }, 387 | }, 388 | scaleX: 0.5, 389 | translateY: '100%' 390 | } 391 | } 392 | }; 393 | 394 | TextFx.prototype._init = function() { 395 | // Split word(s) into letters/spans. 396 | charming(this.el, {classPrefix: 'letter'}); 397 | this.letters = [].slice.call(this.el.querySelectorAll('span')); 398 | this.lettersTotal = this.letters.length; 399 | }; 400 | 401 | TextFx.prototype.show = function(effect, callback) { 402 | arguments.length ? this._animate('in', effect, callback) : this.letters.forEach(function(letter) { letter.style.opacity = 1; }); 403 | }; 404 | 405 | TextFx.prototype.hide = function(effect, callback) { 406 | if( arguments.length ) { 407 | this._animate('out', effect, callback); 408 | } 409 | else { 410 | anime.remove(this.letters); 411 | this.letters.forEach(function(letter) { letter.style.opacity = 0; }) 412 | } 413 | }; 414 | 415 | TextFx.prototype._animate = function(direction, effect, callback) { 416 | var effecSettings = typeof effect === 'string' ? this.effects[effect] : effect; 417 | 418 | if( effecSettings.perspective != undefined ) { 419 | this.el.style.WebkitPerspective = this.el.style.perspective = effecSettings.perspective + 'px'; 420 | } 421 | if( effecSettings.origin != undefined ) { 422 | this.letters.forEach(function(letter) { 423 | letter.style.WebkitTransformOrigin = letter.style.transformOrigin = effecSettings.origin; 424 | }); 425 | } 426 | 427 | // Custom effect 428 | var iscustom = this._checkCustomFx(direction, effect, callback); 429 | 430 | var animOpts = effecSettings[direction]; 431 | animOpts.targets = this.letters; 432 | 433 | if( !iscustom ) { 434 | animOpts.complete = callback; 435 | } 436 | 437 | anime(animOpts); 438 | }; 439 | 440 | /** 441 | * Extra stuff for an effect.. this is just an example for effect 17. 442 | * TODO! (for now, just some quick way to implement something different only for fx17) 443 | */ 444 | TextFx.prototype._checkCustomFx = function(direction, effect, callback) { 445 | var custom = typeof effect === 'string' && effect === 'fx17' && direction === 'out'; 446 | 447 | if( custom ) { 448 | var tmp = document.createElement('div'); 449 | tmp.style.width = tmp.style.height = '100%'; 450 | tmp.style.top = tmp.style.left = 0; 451 | tmp.style.background = '#e24b1e'; 452 | tmp.style.position = 'absolute'; 453 | tmp.style.WebkitTransform = tmp.style.transform = 'scale3d(0,1,1)'; 454 | tmp.style.WebkitTransformOrigin = tmp.style.transformOrigin = '0% 50%'; 455 | this.el.appendChild(tmp); 456 | var self = this; 457 | anime({ 458 | targets: tmp, 459 | duration: 400, 460 | easing: 'easeInOutCubic', 461 | scaleX: [0,1], 462 | complete: function() { 463 | tmp.style.WebkitTransformOrigin = tmp.style.transformOrigin = '100% 50%'; 464 | anime({ 465 | targets: tmp, 466 | duration: 400, 467 | easing: 'easeInOutCubic', 468 | scaleX: [1,0], 469 | complete: function() { 470 | self.el.removeChild(tmp); 471 | if( typeof callback === 'function' ) { 472 | callback(); 473 | } 474 | } 475 | }); 476 | } 477 | }); 478 | } 479 | 480 | return custom; 481 | }; 482 | 483 | window.TextFx = TextFx; 484 | 485 | })(window); --------------------------------------------------------------------------------