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