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 <link rel="import" href="../polymer/polymer.html"> 12 <link rel="import" href="../iron-flex-layout/iron-flex-layout.html"> 13 <link rel="import" href="../iron-range-behavior/iron-range-behavior.html"> 14 <link rel="import" href="../paper-styles/color.html"> 15 16 <!-- 17 Material design: [Progress & activity](https://www.google.com/design/spec/components/progress-activity.html) 18 19 The progress bars are for situations where the percentage completed can be 20 determined. They give users a quick sense of how much longer an operation 21 will take. 22 23 Example: 24 25 <paper-progress value="10"></paper-progress> 26 27 There is also a secondary progress which is useful for displaying intermediate 28 progress, such as the buffer level during a streaming playback progress bar. 29 30 Example: 31 32 <paper-progress value="10" secondary-progress="30"></paper-progress> 33 34 ### Styling progress bar: 35 36 To change the active progress bar color: 37 38 paper-progress { 39 --paper-progress-active-color: #e91e63; 40 } 41 42 To change the secondary progress bar color: 43 44 paper-progress { 45 --paper-progress-secondary-color: #f8bbd0; 46 } 47 48 To change the progress bar background color: 49 50 paper-progress { 51 --paper-progress-container-color: #64ffda; 52 } 53 54 Add the class `transiting` to a paper-progress to animate the progress bar when 55 the value changed. You can also customize the transition: 56 57 paper-progress { 58 --paper-progress-transition-duration: 0.08s; 59 --paper-progress-transition-timing-function: ease; 60 --paper-progress-transition-transition-delay: 0s; 61 } 62 63 The following mixins are available for styling: 64 65 Custom property | Description | Default 66 ----------------------------------------------|---------------------------------------------|-------------- 67 `--paper-progress-container-color` | Mixin applied to container | `--google-grey-300` 68 `--paper-progress-transition-duration` | Duration of the transition | `0.008s` 69 `--paper-progress-transition-timing-function` | The timing function for the transition | `ease` 70 `--paper-progress-transition-delay` | delay for the transition | `0s` 71 `--paper-progress-active-color` | The color of the active bar | `--google-green-500` 72 `--paper-progress-secondary-color` | The color of the secondary bar | `--google-green-100` 73 `--paper-progress-disabled-active-color` | The color of the active bar if disabled | `--google-grey-500` 74 `--paper-progress-disabled-secondary-color` | The color of the secondary bar if disabled | `--google-grey-300` 75 `--paper-progress-height` | The height of the progress bar | `4px` 76 77 @group Paper Elements 78 @element paper-progress 79 @hero hero.svg 80 @demo demo/index.html 81 --> 82 83 <dom-module id="paper-progress"> 84 <template> 85 <style> 86 :host { 87 display: block; 88 width: 200px; 89 position: relative; 90 overflow: hidden; 91 } 92 93 #progressContainer { 94 position: relative; 95 } 96 97 #progressContainer, 98 /* the stripe for the indeterminate animation*/ 99 .indeterminate::after { 100 height: var(--paper-progress-height, 4px); 101 } 102 103 #primaryProgress, 104 #secondaryProgress, 105 .indeterminate::after { 106 @apply(--layout-fit); 107 } 108 109 #progressContainer, 110 .indeterminate::after { 111 background: var(--paper-progress-container-color, --google-grey-300); 112 } 113 114 :host(.transiting) #primaryProgress, 115 :host(.transiting) #secondaryProgress { 116 -webkit-transition-property: -webkit-transform; 117 transition-property: transform; 118 119 /* Duration */ 120 -webkit-transition-duration: var(--paper-progress-transition-duration, 0.08s); 121 transition-duration: var(--paper-progress-transition-duration, 0.08s); 122 123 /* Timing function */ 124 -webkit-transition-timing-function: var(--paper-progress-transition-timing-function, ease); 125 transition-timing-function: var(--paper-progress-transition-timing-function, ease); 126 127 /* Delay */ 128 -webkit-transition-delay: var(--paper-progress-transition-delay, 0s); 129 transition-delay: var(--paper-progress-transition-delay, 0s); 130 } 131 132 #primaryProgress, 133 #secondaryProgress { 134 @apply(--layout-fit); 135 -webkit-transform-origin: left center; 136 transform-origin: left center; 137 -webkit-transform: scaleX(0); 138 transform: scaleX(0); 139 will-change: transform; 140 } 141 142 #primaryProgress { 143 background: var(--paper-progress-active-color, --google-green-500); 144 } 145 146 #secondaryProgress { 147 background: var(--paper-progress-secondary-color, --google-green-100); 148 } 149 150 :host([disabled]) #primaryProgress { 151 background: var(--paper-progress-disabled-active-color, --google-grey-500); 152 } 153 154 :host([disabled]) #secondaryProgress { 155 background: var(--paper-progress-disabled-secondary-color, --google-grey-300); 156 } 157 158 :host(:not([disabled])) #primaryProgress.indeterminate { 159 -webkit-transform-origin: right center; 160 transform-origin: right center; 161 -webkit-animation: indeterminate-bar 2s linear infinite; 162 animation: indeterminate-bar 2s linear infinite; 163 } 164 165 :host(:not([disabled])) #primaryProgress.indeterminate::after { 166 content: ""; 167 -webkit-transform-origin: center center; 168 transform-origin: center center; 169 170 -webkit-animation: indeterminate-splitter 2s linear infinite; 171 animation: indeterminate-splitter 2s linear infinite; 172 } 173 174 @-webkit-keyframes indeterminate-bar { 175 0% { 176 -webkit-transform: scaleX(1) translateX(-100%); 177 } 178 50% { 179 -webkit-transform: scaleX(1) translateX(0%); 180 } 181 75% { 182 -webkit-transform: scaleX(1) translateX(0%); 183 -webkit-animation-timing-function: cubic-bezier(.28,.62,.37,.91); 184 } 185 100% { 186 -webkit-transform: scaleX(0) translateX(0%); 187 } 188 } 189 190 @-webkit-keyframes indeterminate-splitter { 191 0% { 192 -webkit-transform: scaleX(.75) translateX(-125%); 193 } 194 30% { 195 -webkit-transform: scaleX(.75) translateX(-125%); 196 -webkit-animation-timing-function: cubic-bezier(.42,0,.6,.8); 197 } 198 90% { 199 -webkit-transform: scaleX(.75) translateX(125%); 200 } 201 100% { 202 -webkit-transform: scaleX(.75) translateX(125%); 203 } 204 } 205 206 @keyframes indeterminate-bar { 207 0% { 208 transform: scaleX(1) translateX(-100%); 209 } 210 50% { 211 transform: scaleX(1) translateX(0%); 212 } 213 75% { 214 transform: scaleX(1) translateX(0%); 215 animation-timing-function: cubic-bezier(.28,.62,.37,.91); 216 } 217 100% { 218 transform: scaleX(0) translateX(0%); 219 } 220 } 221 222 @keyframes indeterminate-splitter { 223 0% { 224 transform: scaleX(.75) translateX(-125%); 225 } 226 30% { 227 transform: scaleX(.75) translateX(-125%); 228 animation-timing-function: cubic-bezier(.42,0,.6,.8); 229 } 230 90% { 231 transform: scaleX(.75) translateX(125%); 232 } 233 100% { 234 transform: scaleX(.75) translateX(125%); 235 } 236 } 237 </style> 238 239 <div id="progressContainer"> 240 <div id="secondaryProgress" hidden$="[[_hideSecondaryProgress(secondaryRatio)]]"></div> 241 <div id="primaryProgress"></div> 242 </div> 243 </template> 244 </dom-module> 245 246 <script> 247 Polymer({ 248 is: 'paper-progress', 249 250 behaviors: [ 251 Polymer.IronRangeBehavior 252 ], 253 254 properties: { 255 /** 256 * The number that represents the current secondary progress. 257 */ 258 secondaryProgress: { 259 type: Number, 260 value: 0 261 }, 262 263 /** 264 * The secondary ratio 265 */ 266 secondaryRatio: { 267 type: Number, 268 value: 0, 269 readOnly: true 270 }, 271 272 /** 273 * Use an indeterminate progress indicator. 274 */ 275 indeterminate: { 276 type: Boolean, 277 value: false, 278 observer: '_toggleIndeterminate' 279 }, 280 281 /** 282 * True if the progress is disabled. 283 */ 284 disabled: { 285 type: Boolean, 286 value: false, 287 reflectToAttribute: true, 288 observer: '_disabledChanged' 289 } 290 }, 291 292 observers: [ 293 '_progressChanged(secondaryProgress, value, min, max)' 294 ], 295 296 hostAttributes: { 297 role: 'progressbar' 298 }, 299 300 _toggleIndeterminate: function(indeterminate) { 301 // If we use attribute/class binding, the animation sometimes doesn't translate properly 302 // on Safari 7.1. So instead, we toggle the class here in the update method. 303 this.toggleClass('indeterminate', indeterminate, this.$.primaryProgress); 304 }, 305 306 _transformProgress: function(progress, ratio) { 307 var transform = 'scaleX(' + (ratio / 100) + ')'; 308 progress.style.transform = progress.style.webkitTransform = transform; 309 }, 310 311 _mainRatioChanged: function(ratio) { 312 this._transformProgress(this.$.primaryProgress, ratio); 313 }, 314 315 _progressChanged: function(secondaryProgress, value, min, max) { 316 secondaryProgress = this._clampValue(secondaryProgress); 317 value = this._clampValue(value); 318 319 var secondaryRatio = this._calcRatio(secondaryProgress) * 100; 320 var mainRatio = this._calcRatio(value) * 100; 321 322 this._setSecondaryRatio(secondaryRatio); 323 this._transformProgress(this.$.secondaryProgress, secondaryRatio); 324 this._transformProgress(this.$.primaryProgress, mainRatio); 325 326 this.secondaryProgress = secondaryProgress; 327 328 this.setAttribute('aria-valuenow', value); 329 this.setAttribute('aria-valuemin', min); 330 this.setAttribute('aria-valuemax', max); 331 }, 332 333 _disabledChanged: function(disabled) { 334 this.setAttribute('aria-disabled', disabled ? 'true' : 'false'); 335 }, 336 337 _hideSecondaryProgress: function(secondaryRatio) { 338 return secondaryRatio === 0; 339 } 340 }); 341 </script> 342