123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- // animation vars
- $duration: 0.35s;
- $bounce: cubic-bezier(0.375, 1.495, 0.610, 0.780);
- // dimensions
- $height: 300px;
- $width: 200px;
- .flipper-card {
- box-shadow: 0 10px 5px -5px rgba(#000, 0.2);
- height: $height;
- left: 50%;
- line-height: $height;
- margin: -($height / 2) 0 0 -($width / 2);
- perspective: 500px;
- position: absolute;
- text-align: center;
- top: 50%;
- transform: translateZ(0);
- width: $width;
- // the basic "card"
- // there are four of these: top current, top next, bottom current, and bottom next
- span {
- background: #202020;
- color: #f8f8f8;
- display: block;
- font-size: 250px;
- left: 0;
- position: absolute;
- top: 0;
- text-shadow: 0 1px 0 (#000 + 40), 0 2px 0 (#000 + 30), 0 3px 0 (#000 + 20), 0 4px 0 (#000 + 10), 0 5px 0 #000, 0 0 10px rgba(#000, 0.8);
- transform-origin: 0 150px 0;
- width: 100%;
- // the dividing line in the center
- &:before {
- border-bottom: 2px solid #000;
- content: '';
- left: 0;
- position: absolute;
- width: 100%;
- }
- // a shadow fill that adds some convexity on the card surfaces
- &:after {
- box-shadow: inset 0 0 60px rgba(#000, 0.35);
- content: '';
- height: 100%;
- left: 0;
- position: absolute;
- top: 0;
- width: 100%;
- }
- }
- // two-digit numbers get the 'small' class
- .small {
- font-size: 175px;
- }
- .top {
- // top card sit above the bottom ones, so if we give them the same
- // border radius they'll create some crunchiness.
- // instead, go one pixel smaller
- border-top-left-radius: 11px;
- border-top-right-radius: 11px;
- // creating a light shine on the top of the card
- box-shadow: inset 0 2px rgba(#000, 0.9), inset 0 3px 0 rgba(#fff, 0.4);
- // top cards are only 50% height, and overflow-hidden
- // so they only show the top of their number
- height: 50%;
- overflow: hidden;
- &:before {
- bottom: 0;
- }
- &:after {
- // top card needs to get darker as it curves downward
- background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15));
- border-top-left-radius: 11px;
- border-top-right-radius: 11px;
- }
- }
- .bottom {
- // bottom cards are 100% height, but their top half is hidden by "top" cards
- // this was the best way I could think of to show the bottom cards in half, but
- // there's probably another way using display: table-cell and vertical-align.
- // ew.
- border-radius: 10px;
- height: 100%;
- &:before {
- top: 50%;
- }
- &:after {
- border-radius: 10px;
- background: linear-gradient(rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.1) 50%, rgba(255, 255, 255, 0));
- }
- }
- // styles that only apply when counting "down"
- &.down {
- .top {
- // use a higher number than the bottoms to prevent crunchy border radiuses
- border-top-left-radius: 11px;
- border-top-right-radius: 11px;
- height: 50%;
- &.current {
- // required to prevent safari bug: https://bugs.webkit.org/show_bug.cgi?id=61824
- transform-style: flat;
- z-index: 3;
- }
- &.next {
- // when counting down, the next top card is rotated towards the user (and invisible)
- transform: rotate3d(1, 0, 0, -90deg);
- z-index: 4;
- }
- }
- .bottom {
- border-radius: 10px;
- &.current {
- z-index: 2;
- }
- &.next {
- z-index: 1;
- }
- }
- &.changing {
- .bottom.current {
- box-shadow: 0 75px 5px -20px rgba(#000, 0.3);
- transform: rotate3d(1, 0, 0, 90deg);
- // the current bottom card rotates up to hide itself, and reveal the next one
- transition: transform 0.35s ease-in, box-shadow 0.35s ease-in;
- }
- }
- &.changing,
- &.changed {
- .top.next {
- // and the next top card rotates into view (after $duration)
- transition: transform 0.35s ease-out 0.35s;
- transform: none;
- }
- }
- }
- &.up {
- .top {
- height: 50%;
- &.current {
- z-index: 4;
- }
- &.next {
- z-index: 3
- }
- }
- .bottom {
- &.current {
- z-index: 1;
- }
- &.next {
- box-shadow: 0 75px 5px -20px rgba(#000, 0.3);
- // when counting "up", the next bottom card begins pointed at the user...
- transform: rotate3d(1, 0, 0, 90deg);
- z-index: 2;
- }
- }
- &.changing {
- .top.current {
- // and the current top card does the rotating
- transform: rotate3d(1, 0, 0, -90deg);
- // when the card is "dropping" it should be faster
- transition: transform 0.2625s ease-in, box-shadow 0.2625s ease-in;
- }
- }
- &.changing,
- &.changed {
- .bottom.next {
- box-shadow: 0 0 0 0 rgba(#000, 0);
- // add a little bounce at the moment the card finishes falling
- transition: box-shadow 0.175s cubic-bezier(0.375, 1.495, 0.61, 0.78) 0.35s, transform 0.35s cubic-bezier(0.375, 1.495, 0.61, 0.78) 0.35s;
- transform: rotate3d(1, 0, 0, 0);
- }
- }
- }
- &.changed {
- .top.current,
- .bottom.current {
- display: none;
- }
- }
- }
|