OLD | NEW |
| (Empty) |
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.g
ithub.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/CONTRI
BUTORS.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/PATEN
TS.txt | |
9 | |
10 */ | |
11 /**************************/ | |
12 /* STYLES FOR THE SPINNER */ | |
13 /**************************/ | |
14 | |
15 /* | |
16 * Constants: | |
17 * STROKEWIDTH = 3px | |
18 * ARCSIZE = 270 degrees (amount of circle the arc takes up) | |
19 * ARCTIME = 1333ms (time it takes to expand and contract arc) | |
20 * ARCSTARTROT = 216 degrees (how much the start location of the arc | |
21 * should rotate each time, 216 gives us a | |
22 * 5 pointed star shape (it's 360/5 * 3). | |
23 * For a 7 pointed star, we might do | |
24 * 360/7 * 3 = 154.286) | |
25 * CONTAINERWIDTH = 28px | |
26 * SHRINK_TIME = 400ms | |
27 */ | |
28 | |
29 :host { | |
30 display: inline-block; | |
31 position: relative; | |
32 width: 28px; /* CONTAINERWIDTH */ | |
33 height: 28px; /* CONTAINERWIDTH */ | |
34 } | |
35 | |
36 #spinnerContainer { | |
37 width: 100%; | |
38 height: 100%; | |
39 | |
40 /* The spinner does not have any contents that would have to be | |
41 * flipped if the direction changes. Always use ltr so that the | |
42 * style works out correctly in both cases. */ | |
43 direction: ltr; | |
44 } | |
45 | |
46 #spinnerContainer.active { | |
47 /* duration: 360 * ARCTIME / (ARCSTARTROT + (360-ARCSIZE)) */ | |
48 -webkit-animation: container-rotate 1568ms linear infinite; | |
49 animation: container-rotate 1568ms linear infinite; | |
50 } | |
51 | |
52 @-webkit-keyframes container-rotate { | |
53 to { -webkit-transform: rotate(360deg) } | |
54 } | |
55 | |
56 @keyframes container-rotate { | |
57 to { transform: rotate(360deg) } | |
58 } | |
59 | |
60 .spinner-layer { | |
61 position: absolute; | |
62 width: 100%; | |
63 height: 100%; | |
64 opacity: 0; | |
65 } | |
66 | |
67 .layer-1 { | |
68 border-color: var(--paper-spinner-layer-1-color, --google-blue-500); | |
69 } | |
70 | |
71 .layer-2 { | |
72 border-color: var(--paper-spinner-layer-2-color, --google-red-500); | |
73 } | |
74 | |
75 .layer-3 { | |
76 border-color: var(--paper-spinner-layer-3-color, --google-yellow-500); | |
77 } | |
78 | |
79 .layer-4 { | |
80 border-color: var(--paper-spinner-layer-4-color, --google-blue-500); | |
81 } | |
82 | |
83 /** | |
84 * IMPORTANT NOTE ABOUT CSS ANIMATION PROPERTIES (keanulee): | |
85 * | |
86 * iOS Safari (tested on iOS 8.1) does not handle animation-delay very well - it
doesn't | |
87 * guarantee that the animation will start _exactly_ after that value. So we avo
id using | |
88 * animation-delay and instead set custom keyframes for each color (as layer-2un
dant as it | |
89 * seems). | |
90 * | |
91 * We write out each animation in full (instead of separating animation-name, | |
92 * animation-duration, etc.) because under the polyfill, Safari does not recogni
ze those | |
93 * specific properties properly, treats them as -webkit-animation, and overrides
the | |
94 * other animation rules. See https://github.com/Polymer/platform/issues/53. | |
95 */ | |
96 .active .spinner-layer.layer-1 { | |
97 /* durations: 4 * ARCTIME */ | |
98 -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) in
finite both, layer-1-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite
both; | |
99 animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite b
oth, layer-1-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both; | |
100 } | |
101 | |
102 .active .spinner-layer.layer-2 { | |
103 /* durations: 4 * ARCTIME */ | |
104 -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) in
finite both, layer-2-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite
both; | |
105 animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite b
oth, layer-2-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both; | |
106 } | |
107 | |
108 .active .spinner-layer.layer-3 { | |
109 /* durations: 4 * ARCTIME */ | |
110 -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) in
finite both, layer-3-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite
both; | |
111 animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite b
oth, layer-3-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both; | |
112 } | |
113 | |
114 .active .spinner-layer.layer-4 { | |
115 /* durations: 4 * ARCTIME */ | |
116 -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) in
finite both, layer-4-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite
both; | |
117 animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite b
oth, layer-4-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both; | |
118 } | |
119 | |
120 @-webkit-keyframes fill-unfill-rotate { | |
121 12.5% { -webkit-transform: rotate(135deg); } /* 0.5 * ARCSIZE */ | |
122 25% { -webkit-transform: rotate(270deg); } /* 1 * ARCSIZE */ | |
123 37.5% { -webkit-transform: rotate(405deg); } /* 1.5 * ARCSIZE */ | |
124 50% { -webkit-transform: rotate(540deg); } /* 2 * ARCSIZE */ | |
125 62.5% { -webkit-transform: rotate(675deg); } /* 2.5 * ARCSIZE */ | |
126 75% { -webkit-transform: rotate(810deg); } /* 3 * ARCSIZE */ | |
127 87.5% { -webkit-transform: rotate(945deg); } /* 3.5 * ARCSIZE */ | |
128 to { -webkit-transform: rotate(1080deg); } /* 4 * ARCSIZE */ | |
129 } | |
130 | |
131 @keyframes fill-unfill-rotate { | |
132 12.5% { transform: rotate(135deg); } /* 0.5 * ARCSIZE */ | |
133 25% { transform: rotate(270deg); } /* 1 * ARCSIZE */ | |
134 37.5% { transform: rotate(405deg); } /* 1.5 * ARCSIZE */ | |
135 50% { transform: rotate(540deg); } /* 2 * ARCSIZE */ | |
136 62.5% { transform: rotate(675deg); } /* 2.5 * ARCSIZE */ | |
137 75% { transform: rotate(810deg); } /* 3 * ARCSIZE */ | |
138 87.5% { transform: rotate(945deg); } /* 3.5 * ARCSIZE */ | |
139 to { transform: rotate(1080deg); } /* 4 * ARCSIZE */ | |
140 } | |
141 | |
142 /** | |
143 * HACK: Even though the intention is to have the current .spinner-layer at | |
144 * `opacity: 1`, we set it to `opacity: 0.99` instead since this forces Chrome | |
145 * to do proper subpixel rendering for the elements being animated. This is | |
146 * especially visible in Chrome 39 on Ubuntu 14.04. See: | |
147 * | |
148 * - https://github.com/Polymer/paper-spinner/issues/9 | |
149 * - https://code.google.com/p/chromium/issues/detail?id=436255 | |
150 */ | |
151 @-webkit-keyframes layer-1-fade-in-out { | |
152 from { opacity: 0.99; } | |
153 25% { opacity: 0.99; } | |
154 26% { opacity: 0; } | |
155 89% { opacity: 0; } | |
156 90% { opacity: 0.99; } | |
157 100% { opacity: 0.99; } | |
158 } | |
159 | |
160 @keyframes layer-1-fade-in-out { | |
161 from { opacity: 0.99; } | |
162 25% { opacity: 0.99; } | |
163 26% { opacity: 0; } | |
164 89% { opacity: 0; } | |
165 90% { opacity: 0.99; } | |
166 100% { opacity: 0.99; } | |
167 } | |
168 | |
169 @-webkit-keyframes layer-2-fade-in-out { | |
170 from { opacity: 0; } | |
171 15% { opacity: 0; } | |
172 25% { opacity: 0.99; } | |
173 50% { opacity: 0.99; } | |
174 51% { opacity: 0; } | |
175 } | |
176 | |
177 @keyframes layer-2-fade-in-out { | |
178 from { opacity: 0; } | |
179 15% { opacity: 0; } | |
180 25% { opacity: 0.99; } | |
181 50% { opacity: 0.99; } | |
182 51% { opacity: 0; } | |
183 } | |
184 | |
185 @-webkit-keyframes layer-3-fade-in-out { | |
186 from { opacity: 0; } | |
187 40% { opacity: 0; } | |
188 50% { opacity: 0.99; } | |
189 75% { opacity: 0.99; } | |
190 76% { opacity: 0; } | |
191 } | |
192 | |
193 @keyframes layer-3-fade-in-out { | |
194 from { opacity: 0; } | |
195 40% { opacity: 0; } | |
196 50% { opacity: 0.99; } | |
197 75% { opacity: 0.99; } | |
198 76% { opacity: 0; } | |
199 } | |
200 | |
201 @-webkit-keyframes layer-4-fade-in-out { | |
202 from { opacity: 0; } | |
203 65% { opacity: 0; } | |
204 75% { opacity: 0.99; } | |
205 90% { opacity: 0.99; } | |
206 100% { opacity: 0; } | |
207 } | |
208 | |
209 @keyframes layer-4-fade-in-out { | |
210 from { opacity: 0; } | |
211 65% { opacity: 0; } | |
212 75% { opacity: 0.99; } | |
213 90% { opacity: 0.99; } | |
214 100% { opacity: 0; } | |
215 } | |
216 | |
217 /** | |
218 * Patch the gap that appear between the two adjacent div.circle-clipper while t
he | |
219 * spinner is rotating (appears on Chrome 38, Safari 7.1, and IE 11). | |
220 * | |
221 * Update: the gap no longer appears on Chrome when .spinner-layer's opacity is
0.99, | |
222 * but still does on Safari and IE. | |
223 */ | |
224 .gap-patch { | |
225 position: absolute; | |
226 box-sizing: border-box; | |
227 top: 0; | |
228 left: 45%; | |
229 width: 10%; | |
230 height: 100%; | |
231 overflow: hidden; | |
232 border-color: inherit; | |
233 } | |
234 | |
235 .gap-patch .circle { | |
236 width: 1000%; | |
237 left: -450%; | |
238 } | |
239 | |
240 .circle-clipper { | |
241 display: inline-block; | |
242 position: relative; | |
243 width: 50%; | |
244 height: 100%; | |
245 overflow: hidden; | |
246 border-color: inherit; | |
247 } | |
248 | |
249 .circle-clipper .circle { | |
250 width: 200%; | |
251 } | |
252 | |
253 .circle { | |
254 box-sizing: border-box; | |
255 height: 100%; | |
256 border-width: 3px; /* STROKEWIDTH */ | |
257 border-style: solid; | |
258 border-color: inherit; | |
259 border-bottom-color: transparent !important; | |
260 border-radius: 50%; | |
261 -webkit-animation: none; | |
262 animation: none; | |
263 | |
264 @apply(--layout-fit); | |
265 } | |
266 | |
267 .circle-clipper.left .circle { | |
268 border-right-color: transparent !important; | |
269 -webkit-transform: rotate(129deg); | |
270 transform: rotate(129deg); | |
271 } | |
272 | |
273 .circle-clipper.right .circle { | |
274 left: -100%; | |
275 border-left-color: transparent !important; | |
276 -webkit-transform: rotate(-129deg); | |
277 transform: rotate(-129deg); | |
278 } | |
279 | |
280 .active .circle-clipper.left .circle { | |
281 /* duration: ARCTIME */ | |
282 -webkit-animation: left-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite bo
th; | |
283 animation: left-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both; | |
284 } | |
285 | |
286 .active .circle-clipper.right .circle { | |
287 /* duration: ARCTIME */ | |
288 -webkit-animation: right-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite b
oth; | |
289 animation: right-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both; | |
290 } | |
291 | |
292 @-webkit-keyframes left-spin { | |
293 from { -webkit-transform: rotate(130deg); } | |
294 50% { -webkit-transform: rotate(-5deg); } | |
295 to { -webkit-transform: rotate(130deg); } | |
296 } | |
297 | |
298 @keyframes left-spin { | |
299 from { transform: rotate(130deg); } | |
300 50% { transform: rotate(-5deg); } | |
301 to { transform: rotate(130deg); } | |
302 } | |
303 | |
304 @-webkit-keyframes right-spin { | |
305 from { -webkit-transform: rotate(-130deg); } | |
306 50% { -webkit-transform: rotate(5deg); } | |
307 to { -webkit-transform: rotate(-130deg); } | |
308 } | |
309 | |
310 @keyframes right-spin { | |
311 from { transform: rotate(-130deg); } | |
312 50% { transform: rotate(5deg); } | |
313 to { transform: rotate(-130deg); } | |
314 } | |
315 | |
316 #spinnerContainer.cooldown { | |
317 /* duration: SHRINK_TIME */ | |
318 -webkit-animation: container-rotate 1568ms linear infinite, fade-out 400ms cub
ic-bezier(0.4, 0.0, 0.2, 1); | |
319 animation: container-rotate 1568ms linear infinite, fade-out 400ms cubic-bezie
r(0.4, 0.0, 0.2, 1); | |
320 } | |
321 | |
322 @-webkit-keyframes fade-out { | |
323 from { opacity: 0.99; } | |
324 to { opacity: 0; } | |
325 } | |
326 | |
327 @keyframes fade-out { | |
328 from { opacity: 0.99; } | |
329 to { opacity: 0; } | |
330 } | |
OLD | NEW |