Skip to content

Commit c640f0c

Browse files
josephperrottjelbourn
authored andcommitted
feat(progress-bar): initial progress-bar impl. (#130)
Closes #40
1 parent 1a33a5b commit c640f0c

File tree

9 files changed

+608
-1
lines changed

9 files changed

+608
-1
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<!-- The background div is named as such because it appears below the other divs and is not sized based on values. -->
2+
<div class="md-progress-bar-background"></div>
3+
<div class="md-progress-bar-buffer" [style.transform]="bufferTransform()"></div>
4+
<div class="md-progress-bar-primary md-progress-bar-fill" [style.transform]="primaryTransform()"></div>
5+
<div class="md-progress-bar-secondary md-progress-bar-fill"></div>
Lines changed: 297 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
@import "variables";
2+
@import "default-theme";
3+
4+
$md-progress-bar-height: 5px !default;
5+
$md-progress-bar-full-animation-duration: 2s !default;
6+
$md-progress-bar-piece-animation-duration: 250ms !default;
7+
8+
// TODO(josephperrott): Find better way to inline svgs.
9+
/** In buffer mode a repeated SVG object is used as a background. Each of the following defines the SVG object for each
10+
of the class defined colors.
11+
12+
Each string is a URL encoded version of:
13+
14+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
15+
version="1.1" x="0px" y="0px" enable-background="new 0 0 5 2"
16+
xml:space="preserve" viewBox="0 0 5 2" preserveAspectRatio="none slice">
17+
<circle cx="1" cy="1" r="1" fill="{INJECTED_COLOR}"/>
18+
</svg>
19+
20+
*/
21+
$md-buffer-bubbles-primary: (
22+
"data:image/svg+xml;charset=UTF-8,%3Csvg%20version%3D%271.1%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27" +
23+
"%20xmlns%3Axlink%3D%27http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%27%20x%3D%270px%27%20y%3D%270px%27%20enable-backgroun" +
24+
"d%3D%27new%200%200%205%202%27%20xml%3Aspace%3D%27preserve%27%20viewBox%3D%270%200%205%202%27%20preserveAspectRatio" +
25+
"%3D%27none%20slice%27%3E%3Ccircle%20cx%3D%271%27%20cy%3D%271%27%20r%3D%271%27%20fill%3D%27" +
26+
md-color($md-primary, 100) + "%27%2F%3E%3C%2Fsvg%3E") !default;
27+
$md-buffer-bubbles-accent: (
28+
"data:image/svg+xml;charset=UTF-8,%3Csvg%20version%3D%271.1%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27" +
29+
"%20xmlns%3Axlink%3D%27http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%27%20x%3D%270px%27%20y%3D%270px%27%20enable-backgroun" +
30+
"d%3D%27new%200%200%205%202%27%20xml%3Aspace%3D%27preserve%27%20viewBox%3D%270%200%205%202%27%20preserveAspectRatio" +
31+
"%3D%27none%20slice%27%3E%3Ccircle%20cx%3D%271%27%20cy%3D%271%27%20r%3D%271%27%20fill%3D%27" +
32+
md-color($md-accent, 100) + "%27%2F%3E%3C%2Fsvg%3E") !default;
33+
$md-buffer-bubbles-warn: (
34+
"data:image/svg+xml;charset=UTF-8,%3Csvg%20version%3D%271.1%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27" +
35+
"%20xmlns%3Axlink%3D%27http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%27%20x%3D%270px%27%20y%3D%270px%27%20enable-backgroun" +
36+
"d%3D%27new%200%200%205%202%27%20xml%3Aspace%3D%27preserve%27%20viewBox%3D%270%200%205%202%27%20preserveAspectRatio" +
37+
"%3D%27none%20slice%27%3E%3Ccircle%20cx%3D%271%27%20cy%3D%271%27%20r%3D%271%27%20fill%3D%27" +
38+
md-color($md-warn, 100) + "%27%2F%3E%3C%2Fsvg%3E") !default;
39+
40+
:host {
41+
display: block;
42+
// Height is provided for md-progress-bar to act as a default.
43+
height: $md-progress-bar-height;
44+
overflow: hidden;
45+
position: relative;
46+
// translateZ is added to force the md-progress-bar into its own GPU layer.
47+
transform: translateZ(0);
48+
transition: opacity $md-progress-bar-piece-animation-duration linear;
49+
width: 100%;
50+
51+
// The progress bar background is used to show the bubble animation scrolling behind a buffering progress bar.
52+
.md-progress-bar-background {
53+
background: url($md-buffer-bubbles-primary);
54+
background-repeat: repeat-x;
55+
background-size: 10px 4px;
56+
height: 100%;
57+
position: absolute;
58+
visibility: hidden;
59+
width: 100%;
60+
}
61+
62+
/**
63+
* The progress bar buffer is the bar indicator showing the buffer value and is only visible beyond the current value
64+
* of the primary progress bar.
65+
*/
66+
.md-progress-bar-buffer {
67+
background-color: md-color($md-primary, 100);
68+
height: 100%;
69+
position: absolute;
70+
transform-origin: top left;
71+
transition: transform $md-progress-bar-piece-animation-duration ease;
72+
width: 100%;
73+
}
74+
75+
/**
76+
* The secondary progress bar is only used in the indeterminate animation, because of this it is hidden in other uses.
77+
*/
78+
.md-progress-bar-secondary {
79+
visibility: hidden;
80+
}
81+
82+
/**
83+
* The progress bar fill fills the progress bar with the indicator color.
84+
*/
85+
.md-progress-bar-fill {
86+
animation: none;
87+
height: 100%;
88+
position: absolute;
89+
transform-origin: top left;
90+
transition: transform $md-progress-bar-piece-animation-duration ease;
91+
width: 100%;
92+
}
93+
94+
/**
95+
* A pseudo element is created for each progress bar bar that fills with the indicator color.
96+
*/
97+
.md-progress-bar-fill::after {
98+
animation: none;
99+
background-color: md-color($md-primary, 600);
100+
content: '';
101+
display: inline-block;
102+
height: 100%;
103+
position: absolute;
104+
width: 100%;
105+
}
106+
107+
&[color="accent"] {
108+
.md-progress-bar-background {
109+
background: url($md-buffer-bubbles-accent);
110+
background-repeat: repeat-x;
111+
background-size: 10px 4px;
112+
}
113+
.md-progress-bar-buffer {
114+
background-color: md-color($md-accent, 100);
115+
}
116+
.md-progress-bar-fill::after {
117+
background-color: md-color($md-accent, 600);
118+
}
119+
}
120+
121+
&[color="warn"] {
122+
.md-progress-bar-background {
123+
background: url($md-buffer-bubbles-warn);
124+
background-repeat: repeat-x;
125+
background-size: 10px 4px;
126+
}
127+
.md-progress-bar-buffer {
128+
background-color: md-color($md-warn, 100);
129+
}
130+
.md-progress-bar-fill::after {
131+
background-color: md-color($md-warn, 600);
132+
}
133+
}
134+
135+
&[mode="query"] {
136+
transform: rotateZ(180deg);
137+
}
138+
139+
&[mode="indeterminate"],
140+
&[mode="query"] {
141+
.md-progress-bar-fill {
142+
transition: none;
143+
}
144+
.md-progress-bar-primary {
145+
animation: md-progress-bar-primary-indeterminate-translate $md-progress-bar-full-animation-duration infinite linear;
146+
left: -145.166611%;
147+
}
148+
.md-progress-bar-primary.md-progress-bar-fill::after {
149+
animation: md-progress-bar-primary-indeterminate-scale $md-progress-bar-full-animation-duration infinite linear;
150+
}
151+
.md-progress-bar-secondary {
152+
animation: md-progress-bar-secondary-indeterminate-translate $md-progress-bar-full-animation-duration infinite linear;
153+
left: -54.888891%;
154+
visibility: visible;
155+
}
156+
.md-progress-bar-secondary.md-progress-bar-fill::after {
157+
animation: md-progress-bar-secondary-indeterminate-scale $md-progress-bar-full-animation-duration infinite linear;
158+
}
159+
}
160+
161+
&[mode="buffer"] {
162+
.md-progress-bar-background {
163+
animation: md-progress-bar-background-scroll $md-progress-bar-piece-animation-duration infinite linear;
164+
visibility: visible;
165+
}
166+
}
167+
}
168+
169+
170+
// Reverse the apparent directionality of progress vars for rtl.
171+
:host-context([dir="rtl"]) {
172+
transform: rotateY(180deg);
173+
}
174+
175+
176+
/** The values used for animations in md-progress-bar, both timing and transformation, can be considered magic values.
177+
They are sourced from the Material Design example spec and duplicate the values of the original designers
178+
definitions.
179+
180+
181+
The indeterminate state is essentially made up of two progress bars, one primary (the one that is shown in both the
182+
determinate and indeterminate states) and one secondary, which essentially mirrors the primary progress bar in
183+
appearance but is only shown to assist with the indeterminate animations.
184+
185+
186+
KEYFRAME BLOCK DESCRIPTION
187+
primary-indeterminate-translate Translation of the primary progressbar across the screen
188+
primary-indeterminate-scale Scaling of the primary progressbar as it's being translated across the screen
189+
secondary-indeterminate-translate Translation of the secondary progressbar across the screen
190+
secondary-indeterminate-scale Scaling of the secondary progressbar as it's being translated across the screen
191+
192+
Because two different transform animations need to be applied at once, the translation is applied to the outer
193+
element and the scaling is applied to the inner element, which provides the illusion necessary to make the animation
194+
work.
195+
*/
196+
197+
// Progress Bar Timing functions:
198+
// $md-progress-bar-primary-indeterminate-translate-step-1 has no timing function.
199+
$md-progress-bar-primary-indeterminate-translate-step-2: cubic-bezier(.5, 0, .701732, .495819) !default;
200+
$md-progress-bar-primary-indeterminate-translate-step-3: cubic-bezier(.302435, .381352, .55, .956352) !default;
201+
// $md-progress-bar-primary-indeterminate-translate-step-4 has no timing function.
202+
203+
// $md-progress-bar-primary-indeterminate-scale-step-1 has no timing function
204+
$md-progress-bar-primary-indeterminate-scale-step-2: cubic-bezier(.334731, .124820, .785844, 1) !default;
205+
$md-progress-bar-primary-indeterminate-scale-step-3: cubic-bezier(.06, .11, .6, 1) !default;
206+
// $md-progress-bar-primary-indeterminate-scale-step-4 has no timing function
207+
208+
$md-progress-bar-secondary-indeterminate-translate-step-1: cubic-bezier(.15, 0, .515058, .409685) !default;
209+
$md-progress-bar-secondary-indeterminate-translate-step-2: cubic-bezier(.310330, .284058, .8, .733712) !default;
210+
$md-progress-bar-secondary-indeterminate-translate-step-3: cubic-bezier(.4, .627035, .6, .902026) !default;
211+
// $md-progress-bar-secondary-indeterminate-translate-step-4 has no timing function
212+
213+
$md-progress-bar-secondary-indeterminate-scale-step-1: cubic-bezier(.15, 0, .515058, .409685) !default;
214+
$md-progress-bar-secondary-indeterminate-scale-step-2: cubic-bezier(.310330, .284058, .8, .733712) !default;
215+
$md-progress-bar-secondary-indeterminate-scale-step-3: cubic-bezier(.4, .627035, .6, .902026) !default;
216+
// $md-progress-bar-secondary-indeterminate-scale-step-4 has no timing function
217+
218+
/** Animations for indeterminate and query mode. */
219+
// Primary indicator.
220+
@keyframes md-progress-bar-primary-indeterminate-translate {
221+
0% {
222+
transform: translateX(0px);
223+
}
224+
20% {
225+
animation-timing-function: $md-progress-bar-primary-indeterminate-translate-step-2;
226+
transform: translateX(0px);
227+
}
228+
59.15% {
229+
animation-timing-function: $md-progress-bar-primary-indeterminate-translate-step-3;
230+
transform: translateX(83.67142%);
231+
}
232+
100% {
233+
transform: translateX(200.611057%);
234+
}
235+
}
236+
237+
@keyframes md-progress-bar-primary-indeterminate-scale {
238+
0% {
239+
transform: scaleX(.08);
240+
}
241+
36.65% {
242+
animation-timing-function: $md-progress-bar-primary-indeterminate-scale-step-2;
243+
transform: scaleX(.08);
244+
}
245+
69.15% {
246+
animation-timing-function: $md-progress-bar-primary-indeterminate-scale-step-3;
247+
transform: scaleX(.661479);
248+
}
249+
100% {
250+
transform: scaleX(.08);
251+
}
252+
}
253+
254+
// Secondary indicator.
255+
@keyframes md-progress-bar-secondary-indeterminate-translate {
256+
0% {
257+
animation-timing-function: $md-progress-bar-secondary-indeterminate-translate-step-1;
258+
transform: translateX(0px);
259+
}
260+
25% {
261+
animation-timing-function: $md-progress-bar-secondary-indeterminate-translate-step-2;
262+
263+
transform: translateX(37.651913%);
264+
}
265+
48.35% {
266+
animation-timing-function: $md-progress-bar-secondary-indeterminate-translate-step-3;
267+
transform: translateX(84.386165%);
268+
}
269+
100% {
270+
transform: translateX(160.277782%);
271+
}
272+
}
273+
274+
@keyframes md-progress-bar-secondary-indeterminate-scale {
275+
0% {
276+
animation-timing-function: $md-progress-bar-secondary-indeterminate-scale-step-1;
277+
transform: scaleX(.08);
278+
}
279+
19.15% {
280+
animation-timing-function: $md-progress-bar-secondary-indeterminate-scale-step-2;
281+
transform: scaleX(.457104);
282+
}
283+
44.15% {
284+
animation-timing-function: $md-progress-bar-secondary-indeterminate-scale-step-3;
285+
transform: scaleX(.727960);
286+
}
287+
100% {
288+
transform: scaleX(.08);
289+
}
290+
}
291+
292+
/** Animation for buffer mode. */
293+
@keyframes md-progress-bar-background-scroll {
294+
to {
295+
transform: translateX(-10px);
296+
}
297+
}

0 commit comments

Comments
 (0)