Skip to content
This repository has been archived by the owner on Aug 29, 2023. It is now read-only.

Commit

Permalink
fix(linear_progress): Add aria, tests and better animations
Browse files Browse the repository at this point in the history
This set of changes adds expected progress-bar aria attributes. It also
adds a small unit test suite. Finally, the animations have been
converted to transforms in order to engage hardware acceleration,
particularly on mobile devices.

Fixes #297
  • Loading branch information
EisenbergEffect authored and ajoslin committed Sep 30, 2014
1 parent 7bb8ca3 commit 3b38627
Show file tree
Hide file tree
Showing 3 changed files with 198 additions and 129 deletions.
176 changes: 73 additions & 103 deletions src/components/linearProgress/_linearProgress.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,26 @@ $bar-height:5px;
.container {
overflow: hidden;
position: relative;
height: 0;
height: $bar-height;
background-color: $color-blue-100;
top: $bar-height;
@include transform(translate(0, 5px) scale(1, 0));
@include transition(all .3s linear);
}

.container.ready {
height: $bar-height;
top: 0;
@include transform(translate(0, 0) scale(1, 1));
}

.bar {
height: $bar-height;
background-color: $color-blue-500;
position: absolute;
width: 100%;
}

.bar1, .bar2 {
@include transition(width 0.2s linear);
@include transition(all 0.2s linear);
}

&[mode=determinate] {
Expand All @@ -37,15 +38,11 @@ $bar-height:5px;

&[mode=indeterminate] {
.bar1 {
left: 50%;
width: 10%;
@include animation(indeterminate1 5s infinite linear);
@include animation(indeterminate1 4s infinite linear);
}

.bar2 {
left: 0%;
width: 0%;
@include animation(indeterminate2 5s infinite linear);
@include animation(indeterminate2 4s infinite linear);
}
}

Expand All @@ -61,7 +58,7 @@ $bar-height:5px;
width: 100%;
margin-top: 0px;
position: absolute;
background: radial-gradient(#d0d9ff 0%, #d0d9ff 20%, transparent 50%);
background: radial-gradient(#d0d9ff 0%, #d0d9ff 16%, transparent 42%);
background-color: transparent;
background-size: 10px 10px;
background-position: 0px -23px;
Expand All @@ -75,151 +72,124 @@ $bar-height:5px;

&[mode=query] {
.bar2 {
left: 50%;
width: 10%;
@include animation(query .8s infinite cubic-bezier(0.390, 0.575, 0.565, 1.000));
}
}
}

@include keyframes(indeterminate1) {
0% {
width: 0%;
left: 0%;
@include transform(translateX(-25%) scale(.5, 1));
}
10% {
width: 30%;
left: 100%;
@include transform(translateX(25%) scale(.5, 1));
}
19.99% {
width: 30%;
left: 100%;
@include transform(translateX(50%) scale(0, 1));
}
20% {
width: 0%;
left: 0%;
@include transform(translateX(-37.5%) scale(.25, 1));
}
30% {
width: 80%;
left: 100%;
@include transform(translateX(37.5%) scale(.25, 1));
}
30.01% {
width: 0%;
left: 0%;
34.99% {
@include transform(translateX(50%) scale(0, 1));
}
40% {
width: 5%;
left: 30%;
36.99% {
@include transform(translateX(50%) scale(0, 1));
}
50% {
width: 50%;
left: 100%;
37% {
@include transform(translateX(-37.5%) scale(.25, 1));
}
50.01% {
width: 0%;
left: 0%;
47% {
@include transform(translateX(20%) scale(.25, 1));
}
60% {
width: 60%;
left: 20%;
52% {
@include transform(translateX(35%) scale(.05, 1));
}
70% {
width: 5%;
left: 100%;
55% {
@include transform(translateX(35%) scale(.1, 1));
}
58% {
@include transform(translateX(50%) scale(.1, 1));
}
61.99% {
@include transform(translateX(50%) scale(0, 1));
}
70.01% {
width: 0%;
left: 0%;
69.99% {
@include transform(translateX(50%) scale(0, 1));
}
70% {
@include transform(translateX(-37.5%) scale(.25, 1));
}
80% {
width: 50%;
left: 30%;
@include transform(translateX(20%) scale(.25, 1));
}
85% {
@include transform(translateX(35%) scale(.05, 1));
}
88% {
@include transform(translateX(35%) scale(.1, 1));
}
91% {
@include transform(translateX(50%) scale(.1, 1));
}
92.99% {
@include transform(translateX(50%) scale(0, 1));
}
90% {
width: 10%;
left: 80%;
93% {
@include transform(translateX(-50%) scale(0, 1));
}
100% {
width: 20%;
left: 100%;
@include transform(translateX(-25%) scale(.5, 1));
}
}

@include keyframes(indeterminate2) {
0% {
width: 0%;
left: 0%;
@include transform(translateX(-50%) scale(0, 1));
}
10% {
width: 60%;
}
19.99% {
width: 40%;
left: 100%;
25.99%{
@include transform(translateX(-50%) scale(0, 1));
}
20% {
width: 0%;
left: 0%;
28% {
@include transform(translateX(-37.5%) scale(.25, 1));
}
25% {
width: 10%;
left: 10%;
38% {
@include transform(translateX(37.5%) scale(.25, 1));
}
30% {
width: 40%;
left: 30%;
42.99% {
@include transform(translateX(50%) scale(0, 1));
}
40% {
width: 60%;
left: 100%;
46.99% {
@include transform(translateX(50%) scale(0, 1));
}
40.01% {
width: 0%;
left: 0%;
49.99% {
@include transform(translateX(50%) scale(0, 1));
}
50% {
width: 10%;
left: 40%;
@include transform(translateX(-50%) scale(0, 1));
}
60% {
width: 30%;
left: 100%;
}
60.01% {
width: 0%;
left: 0%;
@include transform(translateX(-25%) scale(.5, 1));
}
70% {
width: 10%;
left: 40%;
@include transform(translateX(25%) scale(.5, 1));
}
80% {
width: 5%;
left: 100%;
}
80.01% {
width: 0%;
left: 0%;
}
90% {
width: 70%;
left: 10%;
}
100% {
width: 10%;
left: 100%;
79.99% {
@include transform(translateX(50%) scale(0, 1));
}
}

@include keyframes(query) {
0% {
width: 30%;
left: 70%;
opacity: 1;
@include transform(translateX(35%) scale(.3, 1));
}
100% {
width: 0%;
left: 0%;
opacity: 0;
@include transform(translateX(-50%) scale(0, 1));
}
}

Expand Down
85 changes: 60 additions & 25 deletions src/components/linearProgress/linearProgress.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ angular.module('material.components.linearProgress', [
'material.animations',
'material.services.aria'
])
.directive('materialLinearProgress', ['$timeout', MaterialLinearProgressDirective]);
.directive('materialLinearProgress', [
'$$rAF',
'$materialEffects',
MaterialLinearProgressDirective
]);

/**
* @ngdoc directive
Expand Down Expand Up @@ -39,46 +43,77 @@ angular.module('material.components.linearProgress', [
* <material-linear-progress mode="query"></material-linear-progress>
* </hljs>
*/
function MaterialLinearProgressDirective($timeout) {
function MaterialLinearProgressDirective($$rAF, $materialEffects) {

return {
restrict: 'E',
template: '<div class="container">' +
'<div class="dashed"></div>' +
'<div class="bar bar1"></div>' +
'<div class="bar bar2"></div>' +
'</div>',
link: function(scope, element, attr) {
var bar1 = angular.element(element[0].querySelector('.bar1')),
bar2 = angular.element(element[0].querySelector('.bar2')),
container = angular.element(element[0].querySelector('.container'));
compile: compile
};

function compile(tElement, tAttrs, transclude) {
tElement.attr('aria-valuemin', 0);
tElement.attr('aria-valuemax', 100);
tElement.attr('role', 'progressbar');

return postLink;
}
function postLink(scope, element, attr) {
var bar1Style = element[0].querySelector('.bar1').style,
bar2Style = element[0].querySelector('.bar2').style,
container = angular.element(element[0].querySelector('.container'));

attr.$observe('value', function(value) {
bar2.css('width', clamp(value).toString() + '%');
});
attr.$observe('value', function(value) {
if (attr.mode == 'query') {
return;
}

attr.$observe('secondaryvalue', function(value) {
bar1.css('width', clamp(value).toString() + '%');
});
var clamped = clamp(value);
element.attr('aria-valuenow', clamped);
bar2Style[$materialEffects.TRANSFORM] = linearProgressTransforms[clamped];
});

$timeout(function() {
container.addClass('ready');
});
attr.$observe('secondaryvalue', function(value) {
bar1Style[$materialEffects.TRANSFORM] = linearProgressTransforms[clamp(value)];
});

$$rAF(function() {
container.addClass('ready');
});
}

function clamp(value) {
if (value > 100) {
return 100;
}
};

if (value < 0) {
return 0;
}

return Math.ceil(value || 0);
}
}


// **********************************************************
// Private Methods
// **********************************************************

function clamp(value) {
if (value > 100) {
return 100;
var linearProgressTransforms = (function() {
var values = new Array(101);
for(var i = 0; i < 101; i++){
values[i] = makeTransform(i);
}

if (value < 0) {
return 0;
}
return values;

return value || 0;
}
function makeTransform(value){
var scale = value/100;
var translateX = (value-100)/2;
return 'translateX(' + translateX.toString() + '%) scale(' + scale.toString() + ', 1)';
}
})();
Loading

0 comments on commit 3b38627

Please sign in to comment.