A nice moving bookshelf animation done only with css animations.
From Dribbble : https://dribbble.com/shots/2332418-Book-shelf-Loader-Icon
A Pen by Grélard Antoine on CodePen.
A nice moving bookshelf animation done only with css animations.
From Dribbble : https://dribbble.com/shots/2332418-Book-shelf-Loader-Icon
A Pen by Grélard Antoine on CodePen.
| <div class="bookshelf_wrapper"> | |
| <ul class="books_list"> | |
| <li class="book_item first"></li> | |
| <li class="book_item second"></li> | |
| <li class="book_item third"></li> | |
| <li class="book_item fourth"></li> | |
| <li class="book_item fifth"></li> | |
| <li class="book_item sixth"></li> | |
| </ul> | |
| <div class="shelf"></div> | |
| </div> |
| $thickness : 5px; | |
| $duration : 2500; | |
| $delay : $duration/6; | |
| @mixin polka($size, $dot, $base, $accent){ | |
| background: $base; | |
| background-image: radial-gradient($accent $dot, transparent 0); | |
| background-size:$size $size; | |
| background-position: 0 -2.5px; | |
| } | |
| body { | |
| background-color: #1e6cc7; | |
| width: 100%; | |
| height: 100vh; | |
| margin: 0; | |
| } | |
| .bookshelf_wrapper { | |
| position: relative; | |
| top: 60%; | |
| left: 50%; | |
| transform: translate(-50%, -50%); | |
| } | |
| .books_list { | |
| margin: 0 auto; | |
| width: 300px; | |
| padding: 0; | |
| } | |
| .book_item { | |
| position: absolute; | |
| top: -120px; | |
| box-sizing: border-box; | |
| list-style: none; | |
| width: 40px; | |
| height: 120px; | |
| opacity: 0; | |
| background-color: #1e6cc7; | |
| border: $thickness solid white; | |
| transform-origin: bottom left; | |
| transform: translateX(300px); | |
| animation: travel #{$duration}ms linear infinite; | |
| &.first { | |
| top: -140px; | |
| height: 140px; | |
| &:before, | |
| &:after { | |
| content:''; | |
| position: absolute; | |
| top: 10px; | |
| left: 0; | |
| width: 100%; | |
| height: $thickness; | |
| background-color: white; | |
| } | |
| &:after { | |
| top: initial; | |
| bottom: 10px; | |
| } | |
| } | |
| &.second, | |
| &.fifth { | |
| &:before, | |
| &:after { | |
| box-sizing: border-box; | |
| content:''; | |
| position: absolute; | |
| top: 10px; | |
| left: 0; | |
| width: 100%; | |
| height: $thickness*3.5; | |
| border-top: $thickness solid white; | |
| border-bottom: $thickness solid white; | |
| } | |
| &:after { | |
| top: initial; | |
| bottom: 10px; | |
| } | |
| } | |
| &.third { | |
| &:before, | |
| &:after { | |
| box-sizing: border-box; | |
| content:''; | |
| position: absolute; | |
| top: 10px; | |
| left: 9px; | |
| width: 12px; | |
| height: 12px; | |
| border-radius: 50%; | |
| border: $thickness solid white; | |
| } | |
| &:after { | |
| top: initial; | |
| bottom: 10px; | |
| } | |
| } | |
| &.fourth { | |
| top: -130px; | |
| height: 130px; | |
| &:before { | |
| box-sizing: border-box; | |
| content:''; | |
| position: absolute; | |
| top: 46px; | |
| left: 0; | |
| width: 100%; | |
| height: $thickness*3.5; | |
| border-top: $thickness solid white; | |
| border-bottom: $thickness solid white; | |
| } | |
| } | |
| &.fifth { | |
| top: -100px; | |
| height: 100px; | |
| } | |
| &.sixth { | |
| top: -140px; | |
| height: 140px; | |
| &:before { | |
| box-sizing: border-box; | |
| content:''; | |
| position: absolute; | |
| bottom: 31px; | |
| left: 0px; | |
| width: 100%; | |
| height: $thickness; | |
| background-color: white; | |
| } | |
| &:after { | |
| box-sizing: border-box; | |
| content:''; | |
| position: absolute; | |
| bottom: 10px; | |
| left: 9px; | |
| width: 12px; | |
| height: 12px; | |
| border-radius: 50%; | |
| border: $thickness solid white; | |
| } | |
| } | |
| &:nth-child(2) { | |
| animation-delay: #{$delay*1}ms; | |
| } | |
| &:nth-child(3) { | |
| animation-delay: #{$delay*2}ms; | |
| } | |
| &:nth-child(4) { | |
| animation-delay: #{$delay*3}ms; | |
| } | |
| &:nth-child(5) { | |
| animation-delay: #{$delay*4}ms; | |
| } | |
| &:nth-child(6) { | |
| animation-delay: #{$delay*5}ms; | |
| } | |
| } | |
| .shelf { | |
| width: 300px; | |
| height: $thickness; | |
| margin: 0 auto; | |
| background-color: white; | |
| position: relative; | |
| &:before, | |
| &:after { | |
| content:''; | |
| position : absolute; | |
| width: 100%; | |
| height: 100%; | |
| @include polka(10px, 30%, #1e6cc7, rgba(255,255,255,0.5)); | |
| top: 200%; | |
| left: 5%; | |
| animation: move #{$duration/10}ms linear infinite; | |
| } | |
| &:after { | |
| top: 400%; | |
| left: 7.5%; | |
| } | |
| } | |
| @keyframes move { | |
| from { | |
| background-position-x: 0; | |
| } | |
| to { | |
| background-position-x: 10px; | |
| } | |
| } | |
| @keyframes travel { | |
| 0% { | |
| opacity: 0; | |
| transform: translateX(300px) rotateZ(0deg) scaleY(1); | |
| } | |
| 6.5% { | |
| transform: translateX(279.5px) rotateZ(0deg) scaleY(1.1); | |
| } | |
| 8.8% { | |
| transform: translateX(273.6px) rotateZ(0deg) scaleY(1); | |
| } | |
| 10% { | |
| opacity: 1; | |
| transform: translateX(270px) rotateZ(0deg); | |
| } | |
| 17.6% { | |
| transform: translateX(247.2px) rotateZ(-30deg); | |
| } | |
| 45% { | |
| transform: translateX(165px) rotateZ(-30deg); | |
| } | |
| 49.5% { | |
| transform: translateX(151.5px) rotateZ(-45deg); | |
| } | |
| 61.5% { | |
| transform: translateX(115.5px) rotateZ(-45deg); | |
| } | |
| 67% { | |
| transform: translateX(99px) rotateZ(-60deg); | |
| } | |
| 76% { | |
| transform: translateX(72px) rotateZ(-60deg); | |
| } | |
| 83.5% { | |
| opacity: 1; | |
| transform: translateX(49.5px) rotateZ(-90deg); | |
| } | |
| 90% { | |
| opacity: 0; | |
| } | |
| 100% { | |
| opacity: 0; | |
| transform: translateX(0px) rotateZ(-90deg); | |
| } | |
| } |
fascinating!