• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!--
2@license
3Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
4This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
5The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
6The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
7Code distributed by Google as part of the polymer project is also
8subject 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