Home | History | Annotate | Download | only in paper-spinner
      1 <!--
      2 @license
      3 Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
      4 This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
      5 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
      6 The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
      7 Code distributed by Google as part of the polymer project is also
      8 subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
      9 -->
     10 
     11 <dom-module id="paper-spinner-styles">
     12   <template>
     13     <style>
     14       /*
     15       /**************************/
     16       /* STYLES FOR THE SPINNER */
     17       /**************************/
     18 
     19       /*
     20        * Constants:
     21        *      ARCSIZE     = 270 degrees (amount of circle the arc takes up)
     22        *      ARCTIME     = 1333ms (time it takes to expand and contract arc)
     23        *      ARCSTARTROT = 216 degrees (how much the start location of the arc
     24        *                                should rotate each time, 216 gives us a
     25        *                                5 pointed star shape (it's 360/5 * 3).
     26        *                                For a 7 pointed star, we might do
     27        *                                360/7 * 3 = 154.286)
     28        *      SHRINK_TIME = 400ms
     29        */
     30 
     31       :host {
     32         display: inline-block;
     33         position: relative;
     34         width: 28px;
     35         height: 28px;
     36 
     37         /* 360 * ARCTIME / (ARCSTARTROT + (360-ARCSIZE)) */
     38         --paper-spinner-container-rotation-duration: 1568ms;
     39 
     40         /* ARCTIME */
     41         --paper-spinner-expand-contract-duration: 1333ms;
     42 
     43         /* 4 * ARCTIME */
     44         --paper-spinner-full-cycle-duration: 5332ms;
     45 
     46         /* SHRINK_TIME */
     47         --paper-spinner-cooldown-duration: 400ms;
     48       }
     49 
     50       #spinnerContainer {
     51         width: 100%;
     52         height: 100%;
     53 
     54         /* The spinner does not have any contents that would have to be
     55          * flipped if the direction changes. Always use ltr so that the
     56          * style works out correctly in both cases. */
     57         direction: ltr;
     58       }
     59 
     60       #spinnerContainer.active {
     61         -webkit-animation: container-rotate var(--paper-spinner-container-rotation-duration) linear infinite;
     62         animation: container-rotate var(--paper-spinner-container-rotation-duration) linear infinite;
     63       }
     64 
     65       @-webkit-keyframes container-rotate {
     66         to { -webkit-transform: rotate(360deg) }
     67       }
     68 
     69       @keyframes container-rotate {
     70         to { transform: rotate(360deg) }
     71       }
     72 
     73       .spinner-layer {
     74         position: absolute;
     75         width: 100%;
     76         height: 100%;
     77         opacity: 0;
     78         white-space: nowrap;
     79         border-color: var(--paper-spinner-color, --google-blue-500);
     80       }
     81 
     82       .layer-1 {
     83         border-color: var(--paper-spinner-layer-1-color, --google-blue-500);
     84       }
     85 
     86       .layer-2 {
     87         border-color: var(--paper-spinner-layer-2-color, --google-red-500);
     88       }
     89 
     90       .layer-3 {
     91         border-color: var(--paper-spinner-layer-3-color, --google-yellow-500);
     92       }
     93 
     94       .layer-4 {
     95         border-color: var(--paper-spinner-layer-4-color, --google-green-500);
     96       }
     97 
     98       /**
     99        * IMPORTANT NOTE ABOUT CSS ANIMATION PROPERTIES (keanulee):
    100        *
    101        * iOS Safari (tested on iOS 8.1) does not handle animation-delay very well - it doesn't
    102        * guarantee that the animation will start _exactly_ after that value. So we avoid using
    103        * animation-delay and instead set custom keyframes for each color (as layer-2undant as it
    104        * seems).
    105        */
    106       .active .spinner-layer {
    107         -webkit-animation-name: fill-unfill-rotate;
    108         -webkit-animation-duration: var(--paper-spinner-full-cycle-duration);
    109         -webkit-animation-timing-function: cubic-bezier(0.4, 0.0, 0.2, 1);
    110         -webkit-animation-iteration-count: infinite;
    111         animation-name: fill-unfill-rotate;
    112         animation-duration: var(--paper-spinner-full-cycle-duration);
    113         animation-timing-function: cubic-bezier(0.4, 0.0, 0.2, 1);
    114         animation-iteration-count: infinite;
    115         opacity: 1;
    116       }
    117 
    118       .active .spinner-layer.layer-1 {
    119         -webkit-animation-name: fill-unfill-rotate, layer-1-fade-in-out;
    120         animation-name: fill-unfill-rotate, layer-1-fade-in-out;
    121       }
    122 
    123       .active .spinner-layer.layer-2 {
    124         -webkit-animation-name: fill-unfill-rotate, layer-2-fade-in-out;
    125         animation-name: fill-unfill-rotate, layer-2-fade-in-out;
    126       }
    127 
    128       .active .spinner-layer.layer-3 {
    129         -webkit-animation-name: fill-unfill-rotate, layer-3-fade-in-out;
    130         animation-name: fill-unfill-rotate, layer-3-fade-in-out;
    131       }
    132 
    133       .active .spinner-layer.layer-4 {
    134         -webkit-animation-name: fill-unfill-rotate, layer-4-fade-in-out;
    135         animation-name: fill-unfill-rotate, layer-4-fade-in-out;
    136       }
    137 
    138       @-webkit-keyframes fill-unfill-rotate {
    139         12.5% { -webkit-transform: rotate(135deg) } /* 0.5 * ARCSIZE */
    140         25%   { -webkit-transform: rotate(270deg) } /* 1   * ARCSIZE */
    141         37.5% { -webkit-transform: rotate(405deg) } /* 1.5 * ARCSIZE */
    142         50%   { -webkit-transform: rotate(540deg) } /* 2   * ARCSIZE */
    143         62.5% { -webkit-transform: rotate(675deg) } /* 2.5 * ARCSIZE */
    144         75%   { -webkit-transform: rotate(810deg) } /* 3   * ARCSIZE */
    145         87.5% { -webkit-transform: rotate(945deg) } /* 3.5 * ARCSIZE */
    146         to    { -webkit-transform: rotate(1080deg) } /* 4   * ARCSIZE */
    147       }
    148 
    149       @keyframes fill-unfill-rotate {
    150         12.5% { transform: rotate(135deg) } /* 0.5 * ARCSIZE */
    151         25%   { transform: rotate(270deg) } /* 1   * ARCSIZE */
    152         37.5% { transform: rotate(405deg) } /* 1.5 * ARCSIZE */
    153         50%   { transform: rotate(540deg) } /* 2   * ARCSIZE */
    154         62.5% { transform: rotate(675deg) } /* 2.5 * ARCSIZE */
    155         75%   { transform: rotate(810deg) } /* 3   * ARCSIZE */
    156         87.5% { transform: rotate(945deg) } /* 3.5 * ARCSIZE */
    157         to    { transform: rotate(1080deg) } /* 4   * ARCSIZE */
    158       }
    159 
    160       @-webkit-keyframes layer-1-fade-in-out {
    161         0% { opacity: 1 }
    162         25% { opacity: 1 }
    163         26% { opacity: 0 }
    164         89% { opacity: 0 }
    165         90% { opacity: 1 }
    166         to { opacity: 1 }
    167       }
    168 
    169       @keyframes layer-1-fade-in-out {
    170         0% { opacity: 1 }
    171         25% { opacity: 1 }
    172         26% { opacity: 0 }
    173         89% { opacity: 0 }
    174         90% { opacity: 1 }
    175         to { opacity: 1 }
    176       }
    177 
    178       @-webkit-keyframes layer-2-fade-in-out {
    179         0% { opacity: 0 }
    180         15% { opacity: 0 }
    181         25% { opacity: 1 }
    182         50% { opacity: 1 }
    183         51% { opacity: 0 }
    184         to { opacity: 0 }
    185       }
    186 
    187       @keyframes layer-2-fade-in-out {
    188         0% { opacity: 0 }
    189         15% { opacity: 0 }
    190         25% { opacity: 1 }
    191         50% { opacity: 1 }
    192         51% { opacity: 0 }
    193         to { opacity: 0 }
    194       }
    195 
    196       @-webkit-keyframes layer-3-fade-in-out {
    197         0% { opacity: 0 }
    198         40% { opacity: 0 }
    199         50% { opacity: 1 }
    200         75% { opacity: 1 }
    201         76% { opacity: 0 }
    202         to { opacity: 0 }
    203       }
    204 
    205       @keyframes layer-3-fade-in-out {
    206         0% { opacity: 0 }
    207         40% { opacity: 0 }
    208         50% { opacity: 1 }
    209         75% { opacity: 1 }
    210         76% { opacity: 0 }
    211         to { opacity: 0 }
    212       }
    213 
    214       @-webkit-keyframes layer-4-fade-in-out {
    215         0% { opacity: 0 }
    216         65% { opacity: 0 }
    217         75% { opacity: 1 }
    218         90% { opacity: 1 }
    219         to { opacity: 0 }
    220       }
    221 
    222       @keyframes layer-4-fade-in-out {
    223         0% { opacity: 0 }
    224         65% { opacity: 0 }
    225         75% { opacity: 1 }
    226         90% { opacity: 1 }
    227         to { opacity: 0 }
    228       }
    229 
    230       .circle-clipper {
    231         display: inline-block;
    232         position: relative;
    233         width: 50%;
    234         height: 100%;
    235         overflow: hidden;
    236         border-color: inherit;
    237       }
    238 
    239       /**
    240        * Patch the gap that appear between the two adjacent div.circle-clipper while the
    241        * spinner is rotating (appears on Chrome 50, Safari 9.1.1, and Edge).
    242        */
    243       .spinner-layer::after {
    244         left: 45%;
    245         width: 10%;
    246         border-top-style: solid;
    247       }
    248 
    249       .spinner-layer::after,
    250       .circle-clipper::after {
    251         content: '';
    252         box-sizing: border-box;
    253         position: absolute;
    254         top: 0;
    255         border-width: var(--paper-spinner-stroke-width, 3px);
    256         border-color: inherit;
    257         border-radius: 50%;
    258       }
    259 
    260       .circle-clipper::after {
    261         bottom: 0;
    262         width: 200%;
    263         border-style: solid;
    264         border-bottom-color: transparent !important;
    265       }
    266 
    267       .circle-clipper.left::after {
    268         left: 0;
    269         border-right-color: transparent !important;
    270         -webkit-transform: rotate(129deg);
    271         transform: rotate(129deg);
    272       }
    273 
    274       .circle-clipper.right::after {
    275         left: -100%;
    276         border-left-color: transparent !important;
    277         -webkit-transform: rotate(-129deg);
    278         transform: rotate(-129deg);
    279       }
    280 
    281       .active .gap-patch::after,
    282       .active .circle-clipper::after {
    283         -webkit-animation-duration: var(--paper-spinner-expand-contract-duration);
    284         -webkit-animation-timing-function: cubic-bezier(0.4, 0.0, 0.2, 1);
    285         -webkit-animation-iteration-count: infinite;
    286         animation-duration: var(--paper-spinner-expand-contract-duration);
    287         animation-timing-function: cubic-bezier(0.4, 0.0, 0.2, 1);
    288         animation-iteration-count: infinite;
    289       }
    290 
    291       .active .circle-clipper.left::after {
    292         -webkit-animation-name: left-spin;
    293         animation-name: left-spin;
    294       }
    295 
    296       .active .circle-clipper.right::after {
    297         -webkit-animation-name: right-spin;
    298         animation-name: right-spin;
    299       }
    300 
    301       @-webkit-keyframes left-spin {
    302         0% { -webkit-transform: rotate(130deg) }
    303         50% { -webkit-transform: rotate(-5deg) }
    304         to { -webkit-transform: rotate(130deg) }
    305       }
    306 
    307       @keyframes left-spin {
    308         0% { transform: rotate(130deg) }
    309         50% { transform: rotate(-5deg) }
    310         to { transform: rotate(130deg) }
    311       }
    312 
    313       @-webkit-keyframes right-spin {
    314         0% { -webkit-transform: rotate(-130deg) }
    315         50% { -webkit-transform: rotate(5deg) }
    316         to { -webkit-transform: rotate(-130deg) }
    317       }
    318 
    319       @keyframes right-spin {
    320         0% { transform: rotate(-130deg) }
    321         50% { transform: rotate(5deg) }
    322         to { transform: rotate(-130deg) }
    323       }
    324 
    325       #spinnerContainer.cooldown {
    326         -webkit-animation: container-rotate var(--paper-spinner-container-rotation-duration) linear infinite, fade-out var(--paper-spinner-cooldown-duration) cubic-bezier(0.4, 0.0, 0.2, 1);
    327         animation: container-rotate var(--paper-spinner-container-rotation-duration) linear infinite, fade-out var(--paper-spinner-cooldown-duration) cubic-bezier(0.4, 0.0, 0.2, 1);
    328       }
    329 
    330       @-webkit-keyframes fade-out {
    331         0% { opacity: 1 }
    332         to { opacity: 0 }
    333       }
    334 
    335       @keyframes fade-out {
    336         0% { opacity: 1 }
    337         to { opacity: 0 }
    338       }
    339     </style>
    340   </template>
    341 </dom-module>
    342