├── .gitignore ├── README.md ├── css ├── demo.css └── normalize.css ├── favicon.ico ├── index.html ├── index2.html ├── index3.html ├── index4.html ├── index5.html ├── index6.html └── js ├── demo.js ├── demo1.js ├── demo2.js ├── demo3.js ├── demo4.js ├── demo5.js ├── demo6.js └── easings.js /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Shape Overlays 2 | 3 | Multi-layered SVG shape overlays with adjustable values for a variety of effects. By Yoichi Kobayashi. 4 | 5 | ![Image Title](link) 6 | 7 | [Article on Codrops](https://tympanus.net/codrops/?p=32699) 8 | 9 | [Demo](http://tympanus.net/Development/ShapeOverlays/) 10 | 11 | ## Credits 12 | 13 | - [glsl-easings](https://github.com/glslify/glsl-easings) by glslify. 14 | 15 | ## License 16 | 17 | This resource can be used freely if integrated or build upon in personal or commercial projects such as websites, web apps and web templates intended for sale. It is not allowed to take the resource "as-is" and sell it, redistribute, re-publish it, or sell "pluginized" versions of it. Free plugins built using this resource should have a visible mention and link to the original work. Always consider the licenses of all included libraries, scripts and images used. 18 | 19 | ## Misc 20 | 21 | Follow Yoichi Kobayashi: [Twitter](https://twitter.com/ykob0123), [GitHub](https://github.com/ykob) 22 | 23 | Follow Codrops: [Twitter](http://www.twitter.com/codrops), [Facebook](http://www.facebook.com/codrops), [Google+](https://plus.google.com/101095823814290637419), [GitHub](https://github.com/codrops), [Pinterest](http://www.pinterest.com/codrops/), [Instagram](https://www.instagram.com/codropsss/) 24 | 25 | [© Codrops 2017](http://www.codrops.com) 26 | -------------------------------------------------------------------------------- /css/demo.css: -------------------------------------------------------------------------------- 1 | *, 2 | *::after, 3 | *::before { 4 | box-sizing: border-box; 5 | } 6 | 7 | html { 8 | background: #000; 9 | } 10 | 11 | body { 12 | font-family: 'Source Sans Pro', Avenir, 'Helvetica Neue', Helvetica, Arial, sans-serif; 13 | min-height: 100vh; 14 | color: #57585c; 15 | color: var(--color-text); 16 | background-color: #fff; 17 | background-color: var(--color-bg); 18 | -webkit-font-smoothing: antialiased; 19 | -moz-osx-font-smoothing: grayscale; 20 | } 21 | 22 | /* Color schemes */ 23 | .demo-1 { 24 | --color-text: #fff; 25 | --color-bg: #ddd; 26 | --color-link: #fff; 27 | --color-link-hover: #2735da; 28 | --color-info: #fff; 29 | --color-main-bg: #171619; 30 | --path-fill-1: #413f46; 31 | --path-fill-2: #e6e5ea; 32 | --path-fill-3: #cccccc; 33 | --color-title: #fff; 34 | --font-family-title: 'Montserrat', sans-serif; 35 | --font-size-title: 7vmax; 36 | --font-weight-title: 700; 37 | --color-menu: #171616; 38 | --color-menu-hover: #ffffff; 39 | --font-family-menu: 'Montserrat', sans-serif; 40 | --font-size-menu: 3vmax; 41 | --font-weight-menu: 700; 42 | --button-bg: #fff; 43 | --button-circle: #6b6b6b; 44 | --button-line: #222; 45 | } 46 | 47 | .demo-2 { 48 | --color-text: #fff; 49 | --color-bg: #333; 50 | --color-link: #fff; 51 | --color-link-hover: #f44e5e; 52 | --color-info: #fff; 53 | --color-main-bg: #efcb7b; 54 | --path-fill-1: #dce3f1; 55 | --path-fill-2: #869ccc; 56 | --path-fill-3: #30436f; 57 | --path-fill-4: #0d1831; 58 | --color-title: #fff; 59 | --font-family-title: inherit; 60 | --font-size-title: 6vmax; 61 | --font-weight-title: 200; 62 | --color-menu: #fff; 63 | --color-menu-hover: #fff; 64 | --font-family-menu: inherit; 65 | --font-size-menu: 4vmax; 66 | --font-weight-menu: 200; 67 | --button-bg: #fff; 68 | --button-circle: #fff; 69 | --button-line: #222; 70 | } 71 | 72 | .demo-3 { 73 | --color-text: #fbd54a; 74 | --color-bg: #333; 75 | --color-link: #4d4f5f; 76 | --color-link-hover: #bfb5b5; 77 | --color-info: #fff; 78 | --color-main-bg: #24262d; 79 | --path-fill-1: #000000; 80 | --path-fill-2: #1d1d1f; 81 | --path-fill-3: #fbd54a; 82 | --color-title: #fff; 83 | --font-family-title: 'Arapey', serif; 84 | --font-size-title: 5vmax; 85 | --font-weight-title: 400; 86 | --color-menu: #000000; 87 | --color-menu-hover: #fff; 88 | --font-family-menu: 'Arapey', serif; 89 | --font-size-menu: 4vmax; 90 | --font-weight-menu: 400; 91 | --button-bg: #fff; 92 | --button-circle: #ada4a4; 93 | --button-line: #222; 94 | } 95 | 96 | .demo-4 { 97 | --color-text: #fff; 98 | --color-bg: #333; 99 | --color-link: #1b198c; 100 | --color-link-hover: #d3eaa2; 101 | --color-info: #fff; 102 | --color-main-bg: #3735d0; 103 | --path-fill-1: #241e84; 104 | --path-fill-2: #d3eaa2; 105 | --color-title: #fff; 106 | --font-family-title: 'Pompiere', serif; 107 | --font-size-title: 6vmax; 108 | --font-weight-title: 300; 109 | --color-menu: #3735d0; 110 | --color-menu-hover: #b2dc53; 111 | --font-family-menu: var(--font-family-title); 112 | --font-size-menu: 4vmax; 113 | --font-weight-menu: 300; 114 | --button-bg: #b3dc53; 115 | --button-circle: #1b198b; 116 | --button-line: #fff; 117 | } 118 | 119 | .demo-5 { 120 | --color-text: #c04444; 121 | --color-bg: #333; 122 | --color-link: #2d2c2b; 123 | --color-link-hover: #c14343; 124 | --color-info: #fff; 125 | --color-main-bg: #ece7de; 126 | --path-fill-1: #c04444; 127 | --path-fill-2: #1b1a19; 128 | --color-title: inherit; 129 | --font-family-title: 'Playfair Display', serif; 130 | --font-size-title: 6vmax; 131 | --font-weight-title: 700; 132 | --color-menu: #ffffff; 133 | --color-menu-hover: #c14343; 134 | --font-family-menu: var(--font-family-title); 135 | --font-size-menu: 3.5vmax; 136 | --font-weight-menu: 400; 137 | --button-bg: #fff; 138 | --button-circle: #c14343; 139 | --button-line: #2d2c2b; 140 | } 141 | 142 | .demo-6 { 143 | --color-text: #120047; 144 | --color-bg: #333; 145 | --color-link: #110046; 146 | --color-link-hover: #e83779; 147 | --color-info: #fff; 148 | --color-main-bg: #7115d8; 149 | --path-fill-1: url(#gradient1); 150 | --path-fill-2: url(#gradient2); 151 | --path-fill-3: url(#gradient3); 152 | --color-title: inherit; 153 | --font-family-title: 'Rozha One', serif; 154 | --font-size-title: 8vmax; 155 | --font-weight-title: 400; 156 | --color-menu: #ffffff; 157 | --color-menu-hover: #c14343; 158 | --font-family-menu: var(--font-family-title); 159 | --font-size-menu: 3.5vmax; 160 | --font-weight-menu: 400; 161 | --button-bg: #120047; 162 | --button-circle: #9236f7; 163 | --button-line: #ffffff; 164 | } 165 | 166 | /* Fade effect */ 167 | .js body { 168 | opacity: 0; 169 | transition: opacity 0.3s; 170 | } 171 | 172 | .js body.render { 173 | opacity: 1; 174 | } 175 | 176 | a { 177 | text-decoration: none; 178 | color: #5d93d8; 179 | color: var(--color-link); 180 | outline: none; 181 | } 182 | 183 | a:hover, 184 | a:focus { 185 | color: #423c2b; 186 | color: var(--color-link-hover); 187 | outline: none; 188 | } 189 | 190 | .hidden { 191 | position: absolute; 192 | overflow: hidden; 193 | width: 0; 194 | height: 0; 195 | pointer-events: none; 196 | } 197 | 198 | /* Icons */ 199 | .icon { 200 | display: block; 201 | width: 1.5em; 202 | height: 1.5em; 203 | margin: 0 auto; 204 | fill: currentColor; 205 | } 206 | 207 | .icon--keyboard { 208 | display: none; 209 | } 210 | 211 | main { 212 | position: relative; 213 | width: 100%; 214 | min-height: 100vh; 215 | background-color: var(--color-main-bg); 216 | } 217 | 218 | .content { 219 | position: relative; 220 | display: flex; 221 | justify-content: center; 222 | align-items: center; 223 | min-height: 100vh; 224 | margin: 0 auto; 225 | pointer-events: none; 226 | } 227 | 228 | .content--fixed { 229 | position: fixed; 230 | top: 0; 231 | left: 0; 232 | display: grid; 233 | align-content: space-between; 234 | width: 100%; 235 | max-width: none; 236 | min-height: 0; 237 | height: 100vh; 238 | padding: 1.5em; 239 | grid-template-columns: 50% 50%; 240 | grid-template-rows: auto auto 4em; 241 | grid-template-areas: 'header ...' 242 | '... ...' 243 | 'github demos'; 244 | } 245 | 246 | .content--fixed a { 247 | pointer-events: auto; 248 | } 249 | 250 | /* Header */ 251 | .codrops-header { 252 | position: relative; 253 | z-index: 100; 254 | display: flex; 255 | flex-direction: row; 256 | align-items: flex-start; 257 | align-items: center; 258 | align-self: start; 259 | grid-area: header; 260 | justify-self: start; 261 | } 262 | 263 | .codrops-header__title { 264 | font-size: 1em; 265 | font-weight: bold; 266 | margin: 0; 267 | padding: 0.75em 0; 268 | } 269 | 270 | .info { 271 | margin: 0 0 0 1.25em; 272 | font-style: italic; 273 | color: var(--color-info); 274 | font-weight: bold; 275 | } 276 | 277 | .github { 278 | display: block; 279 | align-self: end; 280 | grid-area: github; 281 | justify-self: start; 282 | margin: 0.5em; 283 | } 284 | 285 | .demos { 286 | position: relative; 287 | display: block; 288 | align-self: end; 289 | text-align: center; 290 | grid-area: demos; 291 | margin-bottom: 0.5em; 292 | } 293 | 294 | .demo { 295 | margin: 0 0.15em; 296 | } 297 | 298 | .demo:hover, 299 | .demo:focus { 300 | opacity: 0.5; 301 | } 302 | 303 | .demo span { 304 | white-space: nowrap; 305 | text-transform: lowercase; 306 | pointer-events: none; 307 | } 308 | 309 | .demo span::before { 310 | content: '#'; 311 | } 312 | 313 | a.demo--current { 314 | pointer-events: none; 315 | } 316 | 317 | /* Top Navigation Style */ 318 | .codrops-links { 319 | position: relative; 320 | display: flex; 321 | justify-content: center; 322 | margin: 0 1em 0 0; 323 | text-align: center; 324 | white-space: nowrap; 325 | } 326 | 327 | .codrops-icon { 328 | display: inline-block; 329 | margin: 0.15em; 330 | padding: 0.25em; 331 | } 332 | 333 | .demo-title { 334 | color: var(--color-title); 335 | font-family: var(--font-family-title); 336 | font-size: var(--font-size-title); 337 | font-weight: var(--font-weight-title); 338 | } 339 | 340 | .global-menu { 341 | width: 100vw; 342 | height: 90vh; 343 | display: flex; 344 | justify-content: center; 345 | align-items: center; 346 | position: fixed; 347 | top: 0; 348 | left: 0; 349 | pointer-events: none; 350 | z-index: 100; 351 | } 352 | 353 | .demo-5 .global-menu { 354 | text-align: center; 355 | } 356 | 357 | .global-menu__item { 358 | color: var(--color-menu); 359 | font-family: var(--font-family-menu); 360 | font-size: var(--font-size-menu); 361 | font-weight: var(--font-weight-menu); 362 | opacity: 0; 363 | transform: translateY(-100%); 364 | pointer-events: none; 365 | display: block; 366 | margin: 0.25em 0; 367 | transition: transform 0.3s, opacity 0.3s; 368 | transition-timing-function: ease-in; 369 | } 370 | 371 | .global-menu__item--demo-2:nth-child(odd) { 372 | transform: translateY(-100%) rotate(10deg); 373 | } 374 | 375 | .global-menu__item--demo-2:nth-child(even) { 376 | transform: translateY(-100%) rotate(-10deg); 377 | } 378 | 379 | .global-menu__item--demo-3 { 380 | transition: transform 0.1s, opacity 0.1s; 381 | transform: translateY(100%); 382 | transition-timing-function: ease-out; 383 | } 384 | 385 | .global-menu__item--demo-4, 386 | .global-menu__item--demo-5 { 387 | transition: transform 0.1s, opacity 0.1s; 388 | transition-timing-function: ease-out; 389 | } 390 | 391 | .global-menu__item--demo-4 { 392 | transform: translateX(40%); 393 | } 394 | 395 | .global-menu__item--demo-5:nth-child(odd) { 396 | transform: translateX(100%) rotate(10deg) scale(0.5); 397 | } 398 | 399 | .global-menu__item--demo-5:nth-child(even) { 400 | transform: translateX(100%) rotate(-10deg) scale(0.5); 401 | } 402 | 403 | .global-menu__item--demo-6 { 404 | transform: translateY(100%); 405 | } 406 | 407 | .global-menu__item:hover { 408 | color: var(--color-menu-hover); 409 | } 410 | 411 | .global-menu__item.is-opened { 412 | opacity: 1; 413 | transform: translateY(0) rotate(0); 414 | pointer-events: auto; 415 | transition-timing-function: ease; 416 | } 417 | 418 | .global-menu__item--demo-4.is-opened, 419 | .global-menu__item--demo-5.is-opened { 420 | transform: translateX(0) rotate(0); 421 | } 422 | 423 | .global-menu__item--demo-4.is-opened { 424 | transition-timing-function: cubic-bezier(0.230, 1.000, 0.355, 1.400); 425 | } 426 | 427 | .global-menu__item:nth-of-type(1) { 428 | transition-delay: 0s; 429 | } 430 | 431 | .global-menu__item.is-opened:nth-of-type(1) { 432 | transition-delay: 0.85s; 433 | } 434 | 435 | .global-menu__item:nth-of-type(2) { 436 | transition-delay: 0.05s; 437 | } 438 | 439 | .global-menu__item.is-opened:nth-of-type(2) { 440 | transition-delay: 0.8s; 441 | } 442 | 443 | .global-menu__item:nth-of-type(3) { 444 | transition-delay: 0.1s; 445 | } 446 | 447 | .global-menu__item.is-opened:nth-of-type(3) { 448 | transition-delay: 0.75s; 449 | } 450 | 451 | .global-menu__item:nth-of-type(4) { 452 | transition-delay: 0.15s; 453 | } 454 | 455 | .global-menu__item.is-opened:nth-of-type(4) { 456 | transition-delay: 0.7s; 457 | } 458 | 459 | /* demo 2 */ 460 | .global-menu__item--demo-2:nth-of-type(1) { 461 | transition-delay: 0s; 462 | } 463 | 464 | .global-menu__item--demo-2.is-opened:nth-of-type(1) { 465 | transition-delay: 0.85s; 466 | } 467 | 468 | .global-menu__item--demo-2:nth-of-type(2) { 469 | transition-delay: 0.05s; 470 | } 471 | 472 | .global-menu__item--demo-2.is-opened:nth-of-type(2) { 473 | transition-delay: 0.8s; 474 | } 475 | 476 | .global-menu__item--demo-2:nth-of-type(3) { 477 | transition-delay: 0.1s; 478 | } 479 | 480 | .global-menu__item--demo-2.is-opened:nth-of-type(3) { 481 | transition-delay: 0.75s; 482 | } 483 | 484 | .global-menu__item--demo-2:nth-of-type(4) { 485 | transition-delay: 0.15s; 486 | } 487 | 488 | .global-menu__item--demo-2.is-opened:nth-of-type(4) { 489 | transition-delay: 0.7s; 490 | } 491 | 492 | /* demo 3 */ 493 | .global-menu__item--demo-3.is-opened { 494 | transition-duration: 0.3s; 495 | } 496 | 497 | .global-menu__item--demo-3:nth-of-type(1) { 498 | transition-delay: 0s; 499 | } 500 | 501 | .global-menu__item--demo-3.is-opened:nth-of-type(1) { 502 | transition-delay: 0.65s; 503 | } 504 | 505 | .global-menu__item--demo-3:nth-of-type(2) { 506 | transition-delay: 0s; 507 | } 508 | 509 | .global-menu__item--demo-3.is-opened:nth-of-type(2) { 510 | transition-delay: 0.7s; 511 | } 512 | 513 | .global-menu__item--demo-3:nth-of-type(3) { 514 | transition-delay: 0s; 515 | } 516 | 517 | .global-menu__item--demo-3.is-opened:nth-of-type(3) { 518 | transition-delay: 0.75s; 519 | } 520 | 521 | .global-menu__item--demo-3:nth-of-type(4) { 522 | transition-delay: 0s; 523 | } 524 | 525 | .global-menu__item--demo-3.is-opened:nth-of-type(4) { 526 | transition-delay: 0.8s; 527 | } 528 | 529 | /* demo 4 */ 530 | .global-menu__item--demo-4.is-opened { 531 | transition-duration: 0.6s; 532 | } 533 | 534 | .global-menu__item--demo-4:nth-of-type(1) { 535 | transition-delay: 0s; 536 | } 537 | 538 | .global-menu__item--demo-4.is-opened:nth-of-type(1) { 539 | transition-delay: 0.45s; 540 | } 541 | 542 | .global-menu__item--demo-4:nth-of-type(2) { 543 | transition-delay: 0.05s; 544 | } 545 | 546 | .global-menu__item--demo-4.is-opened:nth-of-type(2) { 547 | transition-delay: 0.5s; 548 | } 549 | 550 | .global-menu__item--demo-4:nth-of-type(3) { 551 | transition-delay: 0.1s; 552 | } 553 | 554 | .global-menu__item--demo-4.is-opened:nth-of-type(3) { 555 | transition-delay: 0.55s; 556 | } 557 | 558 | .global-menu__item--demo-4:nth-of-type(4) { 559 | transition-delay: 0.15s; 560 | } 561 | 562 | .global-menu__item--demo-4.is-opened:nth-of-type(4) { 563 | transition-delay: 0.6s; 564 | } 565 | 566 | /* demo 5 */ 567 | .global-menu__item--demo-5.is-opened { 568 | transition-duration: 0.4s; 569 | } 570 | 571 | .global-menu__item--demo-5:nth-of-type(1) { 572 | transition-delay: 0s; 573 | } 574 | 575 | .global-menu__item--demo-5.is-opened:nth-of-type(1) { 576 | transition-delay: 0.55s; 577 | } 578 | 579 | .global-menu__item--demo-5:nth-of-type(2) { 580 | transition-delay: 0.05s; 581 | } 582 | 583 | .global-menu__item--demo-5.is-opened:nth-of-type(2) { 584 | transition-delay: 0.6s; 585 | } 586 | 587 | .global-menu__item--demo-5:nth-of-type(3) { 588 | transition-delay: 0.1s; 589 | } 590 | 591 | .global-menu__item--demo-5.is-opened:nth-of-type(3) { 592 | transition-delay: 0.65s; 593 | } 594 | 595 | .global-menu__item--demo-5:nth-of-type(4) { 596 | transition-delay: 0.15s; 597 | } 598 | 599 | .global-menu__item--demo-5.is-opened:nth-of-type(4) { 600 | transition-delay: 0.7s; 601 | } 602 | 603 | /* demo 6 */ 604 | .global-menu__item--demo-6.is-opened { 605 | transition-duration: 0.8s; 606 | } 607 | 608 | .global-menu__item--demo-6:nth-of-type(1) { 609 | transition-delay: 0.25s; 610 | } 611 | 612 | .global-menu__item--demo-6.is-opened:nth-of-type(1) { 613 | transition-delay: 1s; 614 | } 615 | 616 | .global-menu__item--demo-6:nth-of-type(2) { 617 | transition-delay: 0.2s; 618 | } 619 | 620 | .global-menu__item--demo-6.is-opened:nth-of-type(2) { 621 | transition-delay: 1.1s; 622 | } 623 | 624 | .global-menu__item--demo-6:nth-of-type(3) { 625 | transition-delay: 0.15s; 626 | } 627 | 628 | .global-menu__item--demo-6.is-opened:nth-of-type(3) { 629 | transition-delay: 1.2s; 630 | } 631 | 632 | .global-menu__item--demo-6:nth-of-type(4) { 633 | transition-delay: 0.1s; 634 | } 635 | 636 | .global-menu__item--demo-6.is-opened:nth-of-type(4) { 637 | transition-delay: 1.3s; 638 | } 639 | 640 | .shape-overlays { 641 | width: 100vw; 642 | height: 100vh; 643 | pointer-events: none; 644 | position: fixed; 645 | top: 0; 646 | left: 0; 647 | } 648 | 649 | .shape-overlays.is-opened { 650 | pointer-events: auto; 651 | } 652 | 653 | .shape-overlays__path:nth-of-type(1) { 654 | fill: var(--path-fill-1); 655 | } 656 | 657 | .shape-overlays__path:nth-of-type(2) { 658 | fill: var(--path-fill-2); 659 | } 660 | 661 | .shape-overlays__path:nth-of-type(3) { 662 | fill: var(--path-fill-3); 663 | } 664 | 665 | .shape-overlays__path:nth-of-type(4) { 666 | fill: var(--path-fill-4); 667 | } 668 | 669 | @-webkit-keyframes intervalHamburgerBorder { 670 | 0% { 671 | opacity: 1; 672 | -webkit-transform: scale(1); 673 | transform: scale(1); 674 | } 675 | 80% { 676 | -webkit-transform: scale(1.6); 677 | transform: scale(1.6); 678 | } 679 | 100% { 680 | opacity: 0; 681 | -webkit-transform: scale(1.6); 682 | transform: scale(1.6); 683 | } 684 | } 685 | 686 | @keyframes intervalHamburgerBorder { 687 | 0% { 688 | opacity: 1; 689 | -webkit-transform: scale(1); 690 | transform: scale(1); 691 | } 692 | 80% { 693 | -webkit-transform: scale(1.6); 694 | transform: scale(1.6); 695 | } 696 | 100% { 697 | opacity: 0; 698 | -webkit-transform: scale(1.6); 699 | transform: scale(1.6); 700 | } 701 | } 702 | 703 | .hamburger { 704 | width: 64px; 705 | height: 64px; 706 | display: block; 707 | position: relative; 708 | cursor: pointer; 709 | position: absolute; 710 | top: 2.25em; 711 | right: 2.25em; 712 | z-index: 110; 713 | border-radius: 50%; 714 | background-color: var(--button-bg); 715 | pointer-events: auto; 716 | -webkit-tap-highlight-color: rgba(0,0,0,0); 717 | } 718 | 719 | .hamburger::after { 720 | width: 64px; 721 | height: 64px; 722 | box-sizing: border-box; 723 | content: ''; 724 | display: block; 725 | position: absolute; 726 | top: 0; 727 | left: 0; 728 | pointer-events: none; 729 | border: 4px solid var(--button-circle); 730 | border-radius: 50%; 731 | -webkit-animation-duration: 1.2s; 732 | animation-duration: 1.2s; 733 | -webkit-animation-name: intervalHamburgerBorder; 734 | animation-name: intervalHamburgerBorder; 735 | -webkit-animation-iteration-count: infinite; 736 | animation-iteration-count: infinite; 737 | } 738 | 739 | .hamburger__line { 740 | width: 28px; 741 | height: 2px; 742 | overflow: hidden; 743 | position: absolute; 744 | z-index: 10; 745 | } 746 | 747 | .hamburger__line-in { 748 | width: 84px; 749 | height: 2px; 750 | position: absolute; 751 | top: 0; 752 | left: 0; 753 | } 754 | 755 | .hamburger__line-in::before, 756 | .hamburger__line-in::after { 757 | width: 28px; 758 | height: 2px; 759 | content: ''; 760 | display: block; 761 | position: absolute; 762 | top: 0; 763 | background-color: var(--button-line); 764 | } 765 | 766 | .hamburger__line-in::before { 767 | left: -56px; 768 | } 769 | 770 | .hamburger__line-in::after { 771 | left: 0; 772 | } 773 | 774 | .hamburger__line--01, 775 | .hamburger__line--02, 776 | .hamburger__line--03, 777 | .hamburger__line--cross01, 778 | .hamburger__line--cross02 { 779 | left: 18px; 780 | } 781 | 782 | .hamburger__line--01 { 783 | top: 24.6px; 784 | } 785 | 786 | .hamburger__line--02, 787 | .hamburger__line--cross01, 788 | .hamburger__line--cross02 { 789 | top: 31px; 790 | } 791 | 792 | .hamburger__line--03 { 793 | top: 37.4px; 794 | } 795 | 796 | .hamburger__line--cross01 { 797 | -webkit-transform: rotate(45deg); 798 | transform: rotate(45deg); 799 | } 800 | 801 | .hamburger__line--cross02 { 802 | -webkit-transform: rotate(-45deg); 803 | transform: rotate(-45deg); 804 | } 805 | 806 | .hamburger__line { 807 | -webkit-transition-duration: 0.6s; 808 | transition-duration: 0.6s; 809 | -webkit-transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1); 810 | transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1); 811 | } 812 | 813 | .hamburger__line-in { 814 | -webkit-transition-duration: 0.6s; 815 | transition-duration: 0.6s; 816 | -webkit-transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1); 817 | transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1); 818 | } 819 | 820 | .hamburger__line-in::before, 821 | .hamburger__line-in::after { 822 | -webkit-transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1); 823 | transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1); 824 | -webkit-transition-property: -webkit-transform; 825 | transition-property: -webkit-transform; 826 | transition-property: transform; 827 | transition-property: transform, -webkit-transform; 828 | } 829 | 830 | .hamburger__line-in--cross01, 831 | .hamburger__line-in--cross02 { 832 | -webkit-transform: translateX(-33.3%); 833 | transform: translateX(-33.3%); 834 | } 835 | 836 | .hamburger__line-in--01 { 837 | -webkit-transition-delay: 0.2s; 838 | transition-delay: 0.2s; 839 | } 840 | 841 | .hamburger__line-in--02 { 842 | -webkit-transition-delay: 0.25s; 843 | transition-delay: 0.25s; 844 | } 845 | 846 | .hamburger__line-in--02::before, 847 | .hamburger__line-in--02::after { 848 | -webkit-transition-delay: 0.05s; 849 | transition-delay: 0.05s; 850 | } 851 | 852 | .hamburger__line-in--03 { 853 | -webkit-transition-delay: 0.3s; 854 | transition-delay: 0.3s; 855 | } 856 | 857 | .hamburger__line-in--03::before, 858 | .hamburger__line-in--03::after { 859 | -webkit-transition-delay: 0.1s; 860 | transition-delay: 0.1s; 861 | } 862 | 863 | .hamburger__line-in--cross01 { 864 | -webkit-transition-delay: 0.0s; 865 | transition-delay: 0.0s; 866 | } 867 | 868 | .hamburger__line-in--cross02 { 869 | -webkit-transition-delay: 0.05s; 870 | transition-delay: 0.05s; 871 | } 872 | 873 | .hamburger__line-in--cross02::before, 874 | .hamburger__line-in--cross02::after { 875 | -webkit-transition-delay: 0.1s; 876 | transition-delay: 0.1s; 877 | } 878 | 879 | .hamburger.is-opened-navi .hamburger__line-in--01, 880 | .hamburger.is-opened-navi .hamburger__line-in--02, 881 | .hamburger.is-opened-navi .hamburger__line-in--03 { 882 | -webkit-transform: translateX(33.3%); 883 | transform: translateX(33.3%); 884 | } 885 | 886 | .hamburger.is-opened-navi .hamburger__line-in--cross01, 887 | .hamburger.is-opened-navi .hamburger__line-in--cross02 { 888 | -webkit-transform: translateX(0); 889 | transform: translateX(0); 890 | } 891 | 892 | .hamburger.is-opened-navi .hamburger__line-in--01 { 893 | -webkit-transition-delay: 0s; 894 | transition-delay: 0s; 895 | } 896 | 897 | .hamburger.is-opened-navi .hamburger__line-in--02 { 898 | -webkit-transition-delay: 0.05s; 899 | transition-delay: 0.05s; 900 | } 901 | 902 | .hamburger.is-opened-navi .hamburger__line-in--03 { 903 | -webkit-transition-delay: 0.1s; 904 | transition-delay: 0.1s; 905 | } 906 | 907 | .hamburger.is-opened-navi .hamburger__line-in--cross01 { 908 | -webkit-transition-delay: 0.25s; 909 | transition-delay: 0.25s; 910 | } 911 | 912 | .hamburger.is-opened-navi .hamburger__line-in--cross02 { 913 | -webkit-transition-delay: 0.3s; 914 | transition-delay: 0.3s; 915 | } 916 | 917 | .hamburger:hover .hamburger__line-in::before, 918 | .hamburger:hover .hamburger__line-in::after { 919 | -webkit-transform: translateX(200%); 920 | transform: translateX(200%); 921 | } 922 | 923 | .hamburger:hover .hamburger__line-in--01::before, 924 | .hamburger:hover .hamburger__line-in--01::after, 925 | .hamburger:hover .hamburger__line-in--02::before, 926 | .hamburger:hover .hamburger__line-in--02::after, 927 | .hamburger:hover .hamburger__line-in--03::before, 928 | .hamburger:hover .hamburger__line-in--03::after { 929 | -webkit-transition-duration: 1s; 930 | transition-duration: 1s; 931 | } 932 | 933 | .hamburger:hover .hamburger__line-in--cross01::before, 934 | .hamburger:hover .hamburger__line-in--cross01::after, 935 | .hamburger:hover .hamburger__line-in--cross02::before, 936 | .hamburger:hover .hamburger__line-in--cross02::after { 937 | -webkit-transition-duration: 0s; 938 | transition-duration: 0s; 939 | } 940 | 941 | .hamburger.is-opened-navi:hover .hamburger__line-in--cross01::before, 942 | .hamburger.is-opened-navi:hover .hamburger__line-in--cross01::after, 943 | .hamburger.is-opened-navi:hover .hamburger__line-in--cross02::before, 944 | .hamburger.is-opened-navi:hover .hamburger__line-in--cross02::after { 945 | -webkit-transition-duration: 1s; 946 | transition-duration: 1s; 947 | } 948 | 949 | .hamburger.is-opened-navi:hover .hamburger__line-in--01::before, 950 | .hamburger.is-opened-navi:hover .hamburger__line-in--01::after, 951 | .hamburger.is-opened-navi:hover .hamburger__line-in--02::before, 952 | .hamburger.is-opened-navi:hover .hamburger__line-in--02::after, 953 | .hamburger.is-opened-navi:hover .hamburger__line-in--03::before, 954 | .hamburger.is-opened-navi:hover .hamburger__line-in--03::after { 955 | -webkit-transition-duration: 0s; 956 | transition-duration: 0s; 957 | } 958 | 959 | 960 | @media screen and (min-width: 55em) { 961 | .icon--keyboard { 962 | position: absolute; 963 | right: 0.55em; 964 | bottom: -30%; 965 | display: block; 966 | width: 54px; 967 | height: 46px; 968 | fill: var(--color-link); 969 | } 970 | .demos { 971 | display: flex; 972 | padding-right: 80px; 973 | justify-self: end; 974 | } 975 | .demo { 976 | display: block; 977 | width: 17px; 978 | height: 17px; 979 | margin: 0 4px; 980 | border-radius: 50%; 981 | background: var(--color-link); 982 | } 983 | a.demo--current { 984 | background: var(--color-link-hover); 985 | } 986 | .demo span { 987 | position: absolute; 988 | line-height: 1; 989 | right: 100%; 990 | display: none; 991 | margin: 0 1em 0 0; 992 | } 993 | .demo--current span { 994 | display: block; 995 | } 996 | } 997 | 998 | @media screen and (max-width: 55em) { 999 | html, 1000 | body { 1001 | overflow-x: hidden; 1002 | width: 100vw; 1003 | height: 100%; 1004 | } 1005 | .hamburger { 1006 | position: fixed; 1007 | top: 0.5em; 1008 | right: 0.5em; 1009 | transform: scale(0.75); 1010 | } 1011 | .content { 1012 | height: auto; 1013 | min-height: 0; 1014 | padding-bottom: 10em; 1015 | flex-direction: column; 1016 | } 1017 | .content--fixed { 1018 | position: relative; 1019 | z-index: 0; 1020 | display: block; 1021 | padding: 0.85em; 1022 | } 1023 | .codrops-header { 1024 | flex-direction: column; 1025 | align-items: center; 1026 | } 1027 | .codrops-header__title { 1028 | font-weight: bold; 1029 | padding-bottom: 0.25em; 1030 | text-align: center; 1031 | } 1032 | .github { 1033 | display: block; 1034 | margin: 1em auto; 1035 | } 1036 | .codrops-links { 1037 | margin: 0; 1038 | } 1039 | } 1040 | -------------------------------------------------------------------------------- /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;} -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ykob/shape-overlays/7e19145e968113e572356de6ca314809a10f0273/favicon.ico -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SVG Shape Overlays | Demo 1 | Codrops 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 40 |
41 |
42 |
43 | 47 |

SVG Shape Overlays

48 |
49 | 50 | 59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
Alloy
79 | 87 | 88 | 89 | 90 | 91 | 92 |
93 |
94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /index2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SVG Shape Overlays | Demo 2 | Codrops 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 40 |
41 |
42 |
43 | 47 |

SVG Shape Overlays

48 |
49 | 50 | 59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
Swim Gear
79 | 87 | 88 | 89 | 90 | 91 | 92 | 93 |
94 |
95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /index3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SVG Shape Overlays | Demo 3 | Codrops 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 40 |
41 |
42 |
43 | 47 |

SVG Shape Overlays

48 |
49 | 50 | 59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
Artificial Intelligence
79 | 87 | 88 | 89 | 90 | 91 | 92 |
93 |
94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /index4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SVG Shape Overlays | Demo 4 | Codrops 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 40 |
41 |
42 |
43 | 47 |

SVG Shape Overlays

48 |
49 | 50 | 59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
Human Pacifier
79 | 87 | 88 | 89 | 90 | 91 |
92 |
93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /index5.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SVG Shape Overlays | Demo 5 | Codrops 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 40 |
41 |
42 |
43 | 47 |

SVG Shape Overlays

48 |
49 | 50 | 59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
Land on Fire
79 | 87 | 88 | 89 | 90 | 91 |
92 |
93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /index6.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SVG Shape Overlays | Demo 6 | Codrops 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 39 |
40 |
41 |
42 | 46 |

SVG Shape Overlays

47 |
48 | 49 | 58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
Visualize
78 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 |
106 |
107 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /js/demo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * demo.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 2017, Codrops 9 | * http://www.codrops.com 10 | */ 11 | { 12 | setTimeout(() => document.body.classList.add('render'), 60); 13 | const navdemos = Array.from(document.querySelectorAll('nav.demos > .demo')); 14 | const total = navdemos.length; 15 | const current = navdemos.findIndex(el => el.classList.contains('demo--current')); 16 | const navigate = (linkEl) => { 17 | document.body.classList.remove('render'); 18 | document.body.addEventListener('transitionend', () => window.location = linkEl.href); 19 | }; 20 | navdemos.forEach(link => link.addEventListener('click', (ev) => { 21 | ev.preventDefault(); 22 | navigate(ev.target); 23 | })); 24 | document.addEventListener('keydown', (ev) => { 25 | const keyCode = ev.keyCode || ev.which; 26 | let linkEl; 27 | if ( keyCode === 37 ) { 28 | linkEl = current > 0 ? navdemos[current-1] : navdemos[total-1]; 29 | } 30 | else if ( keyCode === 39 ) { 31 | linkEl = current < total-1 ? navdemos[current+1] : navdemos[0]; 32 | } 33 | else { 34 | return false; 35 | } 36 | navigate(linkEl); 37 | }); 38 | } 39 | -------------------------------------------------------------------------------- /js/demo1.js: -------------------------------------------------------------------------------- 1 | class ShapeOverlays { 2 | constructor(elm) { 3 | this.elm = elm; 4 | this.path = elm.querySelectorAll('path'); 5 | this.numPoints = 18; 6 | this.duration = 600; 7 | this.delayPointsArray = []; 8 | this.delayPointsMax = 300; 9 | this.delayPerPath = 100; 10 | this.timeStart = Date.now(); 11 | this.isOpened = false; 12 | this.isAnimating = false; 13 | } 14 | toggle() { 15 | this.isAnimating = true; 16 | const range = 4 * Math.random() + 6; 17 | for (var i = 0; i < this.numPoints; i++) { 18 | const radian = i / (this.numPoints - 1) * Math.PI; 19 | this.delayPointsArray[i] = (Math.sin(-radian) + Math.sin(-radian * range) + 2) / 4 * this.delayPointsMax; 20 | } 21 | if (this.isOpened === false) { 22 | this.open(); 23 | } else { 24 | this.close(); 25 | } 26 | } 27 | open() { 28 | this.isOpened = true; 29 | this.elm.classList.add('is-opened'); 30 | this.timeStart = Date.now(); 31 | this.renderLoop(); 32 | } 33 | close() { 34 | this.isOpened = false; 35 | this.elm.classList.remove('is-opened'); 36 | this.timeStart = Date.now(); 37 | this.renderLoop(); 38 | } 39 | updatePath(time) { 40 | const points = []; 41 | for (var i = 0; i < this.numPoints + 1; i++) { 42 | points[i] = ease.cubicInOut(Math.min(Math.max(time - this.delayPointsArray[i], 0) / this.duration, 1)) * 100 43 | } 44 | 45 | let str = ''; 46 | str += (this.isOpened) ? `M 0 0 V ${points[0]} ` : `M 0 ${points[0]} `; 47 | for (var i = 0; i < this.numPoints - 1; i++) { 48 | const p = (i + 1) / (this.numPoints - 1) * 100; 49 | const cp = p - (1 / (this.numPoints - 1) * 100) / 2; 50 | str += `C ${cp} ${points[i]} ${cp} ${points[i + 1]} ${p} ${points[i + 1]} `; 51 | } 52 | str += (this.isOpened) ? `V 0 H 0` : `V 100 H 0`; 53 | return str; 54 | } 55 | render() { 56 | if (this.isOpened) { 57 | for (var i = 0; i < this.path.length; i++) { 58 | this.path[i].setAttribute('d', this.updatePath(Date.now() - (this.timeStart + this.delayPerPath * i))); 59 | } 60 | } else { 61 | for (var i = 0; i < this.path.length; i++) { 62 | this.path[i].setAttribute('d', this.updatePath(Date.now() - (this.timeStart + this.delayPerPath * (this.path.length - i - 1)))); 63 | } 64 | } 65 | } 66 | renderLoop() { 67 | this.render(); 68 | if (Date.now() - this.timeStart < this.duration + this.delayPerPath * (this.path.length - 1) + this.delayPointsMax) { 69 | requestAnimationFrame(() => { 70 | this.renderLoop(); 71 | }); 72 | } 73 | else { 74 | this.isAnimating = false; 75 | } 76 | } 77 | } 78 | 79 | (function() { 80 | const elmHamburger = document.querySelector('.hamburger'); 81 | const gNavItems = document.querySelectorAll('.global-menu__item'); 82 | const elmOverlay = document.querySelector('.shape-overlays'); 83 | const overlay = new ShapeOverlays(elmOverlay); 84 | 85 | elmHamburger.addEventListener('click', () => { 86 | if (overlay.isAnimating) { 87 | return false; 88 | } 89 | overlay.toggle(); 90 | if (overlay.isOpened === true) { 91 | elmHamburger.classList.add('is-opened-navi'); 92 | for (var i = 0; i < gNavItems.length; i++) { 93 | gNavItems[i].classList.add('is-opened'); 94 | } 95 | } else { 96 | elmHamburger.classList.remove('is-opened-navi'); 97 | for (var i = 0; i < gNavItems.length; i++) { 98 | gNavItems[i].classList.remove('is-opened'); 99 | } 100 | } 101 | }); 102 | }()); 103 | -------------------------------------------------------------------------------- /js/demo2.js: -------------------------------------------------------------------------------- 1 | class ShapeOverlays { 2 | constructor(elm) { 3 | this.elm = elm; 4 | this.path = elm.querySelectorAll('path'); 5 | this.numPoints = 4; 6 | this.duration = 800; 7 | this.delayPointsArray = []; 8 | this.delayPointsMax = 180; 9 | this.delayPerPath = 70; 10 | this.timeStart = Date.now(); 11 | this.isOpened = false; 12 | this.isAnimating = false; 13 | } 14 | toggle() { 15 | this.isAnimating = true; 16 | const range = Math.random() * Math.PI * 2; 17 | for (var i = 0; i < this.numPoints; i++) { 18 | const radian = (i / (this.numPoints - 1)) * Math.PI * 2; 19 | this.delayPointsArray[i] = (Math.sin(radian + range) + 1) / 2 * this.delayPointsMax; 20 | } 21 | if (this.isOpened === false) { 22 | this.open(); 23 | } else { 24 | this.close(); 25 | } 26 | } 27 | open() { 28 | this.isOpened = true; 29 | this.elm.classList.add('is-opened'); 30 | this.timeStart = Date.now(); 31 | this.renderLoop(); 32 | } 33 | close() { 34 | this.isOpened = false; 35 | this.elm.classList.remove('is-opened'); 36 | this.timeStart = Date.now(); 37 | this.renderLoop(); 38 | } 39 | updatePath(time) { 40 | const points = []; 41 | for (var i = 0; i < this.numPoints; i++) { 42 | points[i] = ease.cubicInOut(Math.min(Math.max(time - this.delayPointsArray[i], 0) / this.duration, 1)) * 100 43 | } 44 | 45 | let str = ''; 46 | str += (this.isOpened) ? `M 0 0 V ${points[0]} ` : `M 0 ${points[0]} `; 47 | for (var i = 0; i < this.numPoints - 1; i++) { 48 | const p = (i + 1) / (this.numPoints - 1) * 100; 49 | const cp = p - (1 / (this.numPoints - 1) * 100) / 2; 50 | str += `C ${cp} ${points[i]} ${cp} ${points[i + 1]} ${p} ${points[i + 1]} `; 51 | } 52 | str += (this.isOpened) ? `V 0 H 0` : `V 100 H 0`; 53 | return str; 54 | } 55 | render() { 56 | if (this.isOpened) { 57 | for (var i = 0; i < this.path.length; i++) { 58 | this.path[i].setAttribute('d', this.updatePath(Date.now() - (this.timeStart + this.delayPerPath * i))); 59 | } 60 | } else { 61 | for (var i = 0; i < this.path.length; i++) { 62 | this.path[i].setAttribute('d', this.updatePath(Date.now() - (this.timeStart + this.delayPerPath * (this.path.length - i - 1)))); 63 | } 64 | } 65 | } 66 | renderLoop() { 67 | this.render(); 68 | if (Date.now() - this.timeStart < this.duration + this.delayPerPath * (this.path.length - 1) + this.delayPointsMax) { 69 | requestAnimationFrame(() => { 70 | this.renderLoop(); 71 | }); 72 | } 73 | else { 74 | this.isAnimating = false; 75 | } 76 | } 77 | } 78 | 79 | (function() { 80 | const elmHamburger = document.querySelector('.hamburger'); 81 | const gNavItems = document.querySelectorAll('.global-menu__item'); 82 | const elmOverlay = document.querySelector('.shape-overlays'); 83 | const overlay = new ShapeOverlays(elmOverlay); 84 | 85 | elmHamburger.addEventListener('click', () => { 86 | if (overlay.isAnimating) { 87 | return false; 88 | } 89 | overlay.toggle(); 90 | if (overlay.isOpened === true) { 91 | elmHamburger.classList.add('is-opened-navi'); 92 | for (var i = 0; i < gNavItems.length; i++) { 93 | gNavItems[i].classList.add('is-opened'); 94 | } 95 | } else { 96 | elmHamburger.classList.remove('is-opened-navi'); 97 | for (var i = 0; i < gNavItems.length; i++) { 98 | gNavItems[i].classList.remove('is-opened'); 99 | } 100 | } 101 | }); 102 | }()); 103 | -------------------------------------------------------------------------------- /js/demo3.js: -------------------------------------------------------------------------------- 1 | class ShapeOverlays { 2 | constructor(elm) { 3 | this.elm = elm; 4 | this.path = elm.querySelectorAll('path'); 5 | this.numPoints = 2; 6 | this.duration = 600; 7 | this.delayPointsArray = []; 8 | this.delayPointsMax = 0; 9 | this.delayPerPath = 200; 10 | this.timeStart = Date.now(); 11 | this.isOpened = false; 12 | this.isAnimating = false; 13 | } 14 | toggle() { 15 | this.isAnimating = true; 16 | for (var i = 0; i < this.numPoints; i++) { 17 | this.delayPointsArray[i] = 0; 18 | } 19 | if (this.isOpened === false) { 20 | this.open(); 21 | } else { 22 | this.close(); 23 | } 24 | } 25 | open() { 26 | this.isOpened = true; 27 | this.elm.classList.add('is-opened'); 28 | this.timeStart = Date.now(); 29 | this.renderLoop(); 30 | } 31 | close() { 32 | this.isOpened = false; 33 | this.elm.classList.remove('is-opened'); 34 | this.timeStart = Date.now(); 35 | this.renderLoop(); 36 | } 37 | updatePath(time) { 38 | const points = []; 39 | for (var i = 0; i < this.numPoints; i++) { 40 | const thisEase = this.isOpened ? 41 | (i == 1) ? ease.cubicOut : ease.cubicInOut: 42 | (i == 1) ? ease.cubicInOut : ease.cubicOut; 43 | points[i] = thisEase(Math.min(Math.max(time - this.delayPointsArray[i], 0) / this.duration, 1)) * 100 44 | } 45 | 46 | let str = ''; 47 | str += (this.isOpened) ? `M 0 0 V ${points[0]} ` : `M 0 ${points[0]} `; 48 | for (var i = 0; i < this.numPoints - 1; i++) { 49 | const p = (i + 1) / (this.numPoints - 1) * 100; 50 | const cp = p - (1 / (this.numPoints - 1) * 100) / 2; 51 | str += `C ${cp} ${points[i]} ${cp} ${points[i + 1]} ${p} ${points[i + 1]} `; 52 | } 53 | str += (this.isOpened) ? `V 0 H 0` : `V 100 H 0`; 54 | return str; 55 | } 56 | render() { 57 | if (this.isOpened) { 58 | for (var i = 0; i < this.path.length; i++) { 59 | this.path[i].setAttribute('d', this.updatePath(Date.now() - (this.timeStart + this.delayPerPath * i))); 60 | } 61 | } else { 62 | for (var i = 0; i < this.path.length; i++) { 63 | this.path[i].setAttribute('d', this.updatePath(Date.now() - (this.timeStart + this.delayPerPath * (this.path.length - i - 1)))); 64 | } 65 | } 66 | } 67 | renderLoop() { 68 | this.render(); 69 | if (Date.now() - this.timeStart < this.duration + this.delayPerPath * (this.path.length - 1) + this.delayPointsMax) { 70 | requestAnimationFrame(() => { 71 | this.renderLoop(); 72 | }); 73 | } 74 | else { 75 | this.isAnimating = false; 76 | } 77 | } 78 | } 79 | 80 | (function() { 81 | const elmHamburger = document.querySelector('.hamburger'); 82 | const gNavItems = document.querySelectorAll('.global-menu__item'); 83 | const elmOverlay = document.querySelector('.shape-overlays'); 84 | const overlay = new ShapeOverlays(elmOverlay); 85 | 86 | elmHamburger.addEventListener('click', () => { 87 | if (overlay.isAnimating) { 88 | return false; 89 | } 90 | overlay.toggle(); 91 | if (overlay.isOpened === true) { 92 | elmHamburger.classList.add('is-opened-navi'); 93 | for (var i = 0; i < gNavItems.length; i++) { 94 | gNavItems[i].classList.add('is-opened'); 95 | } 96 | } else { 97 | elmHamburger.classList.remove('is-opened-navi'); 98 | for (var i = 0; i < gNavItems.length; i++) { 99 | gNavItems[i].classList.remove('is-opened'); 100 | } 101 | } 102 | }); 103 | }()); 104 | -------------------------------------------------------------------------------- /js/demo4.js: -------------------------------------------------------------------------------- 1 | class ShapeOverlays { 2 | constructor(elm) { 3 | this.elm = elm; 4 | this.path = elm.querySelectorAll('path'); 5 | this.numPoints = 4; 6 | this.duration = 1000; 7 | this.delayPointsArray = []; 8 | this.delayPointsMax = 0; 9 | this.delayPerPath = 60; 10 | this.timeStart = Date.now(); 11 | this.isOpened = false; 12 | this.isAnimating = false; 13 | } 14 | toggle() { 15 | this.isAnimating = true; 16 | for (var i = 0; i < this.numPoints; i++) { 17 | this.delayPointsArray[i] = 0; 18 | } 19 | if (this.isOpened === false) { 20 | this.open(); 21 | } else { 22 | this.close(); 23 | } 24 | } 25 | open() { 26 | this.isOpened = true; 27 | this.elm.classList.add('is-opened'); 28 | this.timeStart = Date.now(); 29 | this.renderLoop(); 30 | } 31 | close() { 32 | this.isOpened = false; 33 | this.elm.classList.remove('is-opened'); 34 | this.timeStart = Date.now(); 35 | this.renderLoop(); 36 | } 37 | updatePath(time) { 38 | const points = []; 39 | for (var i = 0; i < this.numPoints; i++) { 40 | const thisEase = (i % 2 === 1) ? ease.sineOut : ease.exponentialInOut; 41 | points[i] = (1 - thisEase(Math.min(Math.max(time - this.delayPointsArray[i], 0) / this.duration, 1))) * 100 42 | } 43 | 44 | let str = ''; 45 | str += (this.isOpened) ? `M 0 0 H ${points[0]}` : `M ${points[0]} 0`; 46 | for (var i = 0; i < this.numPoints - 1; i++) { 47 | const p = (i + 1) / (this.numPoints - 1) * 100; 48 | const cp = p - (1 / (this.numPoints - 1) * 100) / 2; 49 | str += `C ${points[i]} ${cp} ${points[i + 1]} ${cp} ${points[i + 1]} ${p} `; 50 | } 51 | str += (this.isOpened) ? `H 100 V 0` : `H 0 V 0`; 52 | return str; 53 | } 54 | render() { 55 | if (this.isOpened) { 56 | for (var i = 0; i < this.path.length; i++) { 57 | this.path[i].setAttribute('d', this.updatePath(Date.now() - (this.timeStart + this.delayPerPath * i))); 58 | } 59 | } else { 60 | for (var i = 0; i < this.path.length; i++) { 61 | this.path[i].setAttribute('d', this.updatePath(Date.now() - (this.timeStart + this.delayPerPath * (this.path.length - i - 1)))); 62 | } 63 | } 64 | } 65 | renderLoop() { 66 | this.render(); 67 | if (Date.now() - this.timeStart < this.duration + this.delayPerPath * (this.path.length - 1) + this.delayPointsMax) { 68 | requestAnimationFrame(() => { 69 | this.renderLoop(); 70 | }); 71 | } 72 | else { 73 | this.isAnimating = false; 74 | } 75 | } 76 | } 77 | 78 | (function() { 79 | const elmHamburger = document.querySelector('.hamburger'); 80 | const gNavItems = document.querySelectorAll('.global-menu__item'); 81 | const elmOverlay = document.querySelector('.shape-overlays'); 82 | const overlay = new ShapeOverlays(elmOverlay); 83 | 84 | elmHamburger.addEventListener('click', () => { 85 | if (overlay.isAnimating) { 86 | return false; 87 | } 88 | overlay.toggle(); 89 | if (overlay.isOpened === true) { 90 | elmHamburger.classList.add('is-opened-navi'); 91 | for (var i = 0; i < gNavItems.length; i++) { 92 | gNavItems[i].classList.add('is-opened'); 93 | } 94 | } else { 95 | elmHamburger.classList.remove('is-opened-navi'); 96 | for (var i = 0; i < gNavItems.length; i++) { 97 | gNavItems[i].classList.remove('is-opened'); 98 | } 99 | } 100 | }); 101 | }()); 102 | -------------------------------------------------------------------------------- /js/demo5.js: -------------------------------------------------------------------------------- 1 | class ShapeOverlays { 2 | constructor(elm) { 3 | this.elm = elm; 4 | this.path = elm.querySelectorAll('path'); 5 | this.numPoints = 85; 6 | this.duration = 500; 7 | this.delayPointsArray = []; 8 | this.delayPointsMax = 300; 9 | this.delayPerPath = 150; 10 | this.timeStart = Date.now(); 11 | this.isOpened = false; 12 | this.isAnimating = false; 13 | } 14 | toggle() { 15 | this.isAnimating = true; 16 | for (var i = 0; i < this.numPoints; i++) { 17 | this.delayPointsArray[i] = Math.random() * this.delayPointsMax; 18 | } 19 | if (this.isOpened === false) { 20 | this.open(); 21 | } else { 22 | this.close(); 23 | } 24 | } 25 | open() { 26 | this.isOpened = true; 27 | this.elm.classList.add('is-opened'); 28 | this.timeStart = Date.now(); 29 | this.renderLoop(); 30 | } 31 | close() { 32 | this.isOpened = false; 33 | this.elm.classList.remove('is-opened'); 34 | this.timeStart = Date.now(); 35 | this.renderLoop(); 36 | } 37 | updatePath(time) { 38 | const points = []; 39 | for (var i = 0; i < this.numPoints; i++) { 40 | points[i] = (1 - ease.cubicInOut(Math.min(Math.max(time - this.delayPointsArray[i], 0) / this.duration, 1))) * 100 41 | } 42 | 43 | let str = ''; 44 | str += (this.isOpened) ? `M 0 0 H ${points[0]}` : `M ${points[0]} 0`; 45 | for (var i = 0; i < this.numPoints - 1; i++) { 46 | const p = (i + 1) / (this.numPoints - 1) * 100; 47 | const cp = p - (1 / (this.numPoints - 1) * 100) / 2; 48 | str += `C ${points[i]} ${cp} ${points[i + 1]} ${cp} ${points[i + 1]} ${p} `; 49 | } 50 | str += (this.isOpened) ? `H 100 V 0` : `H 0 V 0`; 51 | return str; 52 | } 53 | render() { 54 | if (this.isOpened) { 55 | for (var i = 0; i < this.path.length; i++) { 56 | this.path[i].setAttribute('d', this.updatePath(Date.now() - (this.timeStart + this.delayPerPath * i))); 57 | } 58 | } else { 59 | for (var i = 0; i < this.path.length; i++) { 60 | this.path[i].setAttribute('d', this.updatePath(Date.now() - (this.timeStart + this.delayPerPath * (this.path.length - i - 1)))); 61 | } 62 | } 63 | } 64 | renderLoop() { 65 | this.render(); 66 | if (Date.now() - this.timeStart < this.duration + this.delayPerPath * (this.path.length - 1) + this.delayPointsMax) { 67 | requestAnimationFrame(() => { 68 | this.renderLoop(); 69 | }); 70 | } 71 | else { 72 | this.isAnimating = false; 73 | } 74 | } 75 | } 76 | 77 | (function() { 78 | const elmHamburger = document.querySelector('.hamburger'); 79 | const gNavItems = document.querySelectorAll('.global-menu__item'); 80 | const elmOverlay = document.querySelector('.shape-overlays'); 81 | const overlay = new ShapeOverlays(elmOverlay); 82 | 83 | elmHamburger.addEventListener('click', () => { 84 | if (overlay.isAnimating) { 85 | return false; 86 | } 87 | overlay.toggle(); 88 | if (overlay.isOpened === true) { 89 | elmHamburger.classList.add('is-opened-navi'); 90 | for (var i = 0; i < gNavItems.length; i++) { 91 | gNavItems[i].classList.add('is-opened'); 92 | } 93 | } else { 94 | elmHamburger.classList.remove('is-opened-navi'); 95 | for (var i = 0; i < gNavItems.length; i++) { 96 | gNavItems[i].classList.remove('is-opened'); 97 | } 98 | } 99 | }); 100 | }()); 101 | -------------------------------------------------------------------------------- /js/demo6.js: -------------------------------------------------------------------------------- 1 | class ShapeOverlays { 2 | constructor(elm) { 3 | this.elm = elm; 4 | this.path = elm.querySelectorAll('path'); 5 | this.numPoints = 10; 6 | this.duration = 900; 7 | this.delayPointsArray = []; 8 | this.delayPointsMax = 300; 9 | this.delayPerPath = 250; 10 | this.timeStart = Date.now(); 11 | this.isOpened = false; 12 | this.isAnimating = false; 13 | } 14 | toggle() { 15 | this.isAnimating = true; 16 | for (var i = 0; i < this.numPoints; i++) { 17 | this.delayPointsArray[i] = Math.random() * this.delayPointsMax; 18 | } 19 | if (this.isOpened === false) { 20 | this.open(); 21 | } else { 22 | this.close(); 23 | } 24 | } 25 | open() { 26 | this.isOpened = true; 27 | this.elm.classList.add('is-opened'); 28 | this.timeStart = Date.now(); 29 | this.renderLoop(); 30 | } 31 | close() { 32 | this.isOpened = false; 33 | this.elm.classList.remove('is-opened'); 34 | this.timeStart = Date.now(); 35 | this.renderLoop(); 36 | } 37 | updatePath(time) { 38 | const points = []; 39 | for (var i = 0; i < this.numPoints; i++) { 40 | points[i] = (1 - ease.cubicInOut(Math.min(Math.max(time - this.delayPointsArray[i], 0) / this.duration, 1))) * 100 41 | } 42 | 43 | let str = ''; 44 | str += (this.isOpened) ? `M 0 0 V ${points[0]}` : `M 0 ${points[0]}`; 45 | for (var i = 0; i < this.numPoints - 1; i++) { 46 | const p = (i + 1) / (this.numPoints - 1) * 100; 47 | const cp = p - (1 / (this.numPoints - 1) * 100) / 2; 48 | str += `C ${cp} ${points[i]} ${cp} ${points[i + 1]} ${p} ${points[i + 1]} `; 49 | } 50 | str += (this.isOpened) ? `V 100 H 0` : `V 0 H 0`; 51 | return str; 52 | } 53 | render() { 54 | if (this.isOpened) { 55 | for (var i = 0; i < this.path.length; i++) { 56 | this.path[i].setAttribute('d', this.updatePath(Date.now() - (this.timeStart + this.delayPerPath * i))); 57 | } 58 | } else { 59 | for (var i = 0; i < this.path.length; i++) { 60 | this.path[i].setAttribute('d', this.updatePath(Date.now() - (this.timeStart + this.delayPerPath * (this.path.length - i - 1)))); 61 | } 62 | } 63 | } 64 | renderLoop() { 65 | this.render(); 66 | if (Date.now() - this.timeStart < this.duration + this.delayPerPath * (this.path.length - 1) + this.delayPointsMax) { 67 | requestAnimationFrame(() => { 68 | this.renderLoop(); 69 | }); 70 | } 71 | else { 72 | this.isAnimating = false; 73 | } 74 | } 75 | } 76 | 77 | (function() { 78 | const elmHamburger = document.querySelector('.hamburger'); 79 | const gNavItems = document.querySelectorAll('.global-menu__item'); 80 | const elmOverlay = document.querySelector('.shape-overlays'); 81 | const overlay = new ShapeOverlays(elmOverlay); 82 | 83 | elmHamburger.addEventListener('click', () => { 84 | if (overlay.isAnimating) { 85 | return false; 86 | } 87 | overlay.toggle(); 88 | if (overlay.isOpened === true) { 89 | elmHamburger.classList.add('is-opened-navi'); 90 | for (var i = 0; i < gNavItems.length; i++) { 91 | gNavItems[i].classList.add('is-opened'); 92 | } 93 | } else { 94 | elmHamburger.classList.remove('is-opened-navi'); 95 | for (var i = 0; i < gNavItems.length; i++) { 96 | gNavItems[i].classList.remove('is-opened'); 97 | } 98 | } 99 | }); 100 | }()); 101 | -------------------------------------------------------------------------------- /js/easings.js: -------------------------------------------------------------------------------- 1 | // 2 | // these easing functions are based on the code of glsl-easing module. 3 | // https://github.com/glslify/glsl-easings 4 | // 5 | 6 | const ease = { 7 | exponentialIn: (t) => { 8 | return t == 0.0 ? t : Math.pow(2.0, 10.0 * (t - 1.0)); 9 | }, 10 | exponentialOut: (t) => { 11 | return t == 1.0 ? t : 1.0 - Math.pow(2.0, -10.0 * t); 12 | }, 13 | exponentialInOut: (t) => { 14 | return t == 0.0 || t == 1.0 15 | ? t 16 | : t < 0.5 17 | ? +0.5 * Math.pow(2.0, (20.0 * t) - 10.0) 18 | : -0.5 * Math.pow(2.0, 10.0 - (t * 20.0)) + 1.0; 19 | }, 20 | sineOut: (t) => { 21 | const HALF_PI = 1.5707963267948966; 22 | return Math.sin(t * HALF_PI); 23 | }, 24 | circularInOut: (t) => { 25 | return t < 0.5 26 | ? 0.5 * (1.0 - Math.sqrt(1.0 - 4.0 * t * t)) 27 | : 0.5 * (Math.sqrt((3.0 - 2.0 * t) * (2.0 * t - 1.0)) + 1.0); 28 | }, 29 | cubicIn: (t) => { 30 | return t * t * t; 31 | }, 32 | cubicOut: (t) => { 33 | const f = t - 1.0; 34 | return f * f * f + 1.0; 35 | }, 36 | cubicInOut: (t) => { 37 | return t < 0.5 38 | ? 4.0 * t * t * t 39 | : 0.5 * Math.pow(2.0 * t - 2.0, 3.0) + 1.0; 40 | }, 41 | quadraticOut: (t) => { 42 | return -t * (t - 2.0); 43 | }, 44 | quarticOut: (t) => { 45 | return Math.pow(t - 1.0, 3.0) * (1.0 - t) + 1.0; 46 | }, 47 | } 48 | --------------------------------------------------------------------------------