Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/build.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ module.exports = {
'src/components/whiteframe/whiteframe.js',
'src/components/divider/divider.js',
'src/components/linearProgress/linearProgress.js',
'src/components/circularProgress/circularProgress.js',

// Non-visual Components
'src/components/swipe/swipe.js',
Expand Down
1 change: 1 addition & 0 deletions src/components/circularProgress/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Circular progress indicators, created with the `<material-circular-progress>` directive.
139 changes: 139 additions & 0 deletions src/components/circularProgress/_circularProgress.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
$circle-size:48px;
$circle-background:transparent;
$circle-color:$color-blue-500;
$inset-size:36px;
$inset-color:white;
$transition-length:.3s;
$shadow:6px 6px 10px rgba(0, 0, 0, 0.2);
material-circular-progress {
display: block;
width: $circle-size + 6;
height: $circle-size + 6;
background-color: $circle-background;
border-radius: 50%;
padding: 3px;

.wrapper1, .wrapper2 {
width: $circle-size;
height: $circle-size;
position: absolute;
border-radius: 50%;
}

.circle {
.mask, .fill, .shadow {
width: $circle-size;
height: $circle-size;
position: absolute;
border-radius: 50%;
}

.shadow { }

.mask, .fill {
-webkit-backface-visibility: hidden;
transition: -webkit-transform $transition-length;
transition: -ms-transform $transition-length;
transition: transform $transition-length;
}

.mask {
clip: rect(0px, $circle-size, $circle-size, $circle-size/2);
.fill {
clip: rect(0px, $circle-size/2, $circle-size, 0px);
background-color: $circle-color;
}
}
}

.inset {
width: $inset-size;
height: $inset-size;
position: absolute;
margin-left: ($circle-size - $inset-size)/2;
margin-top: ($circle-size - $inset-size)/2;
background-color: $inset-color;
border-radius: 50%;
}

&[mode=indeterminate] {
.wrapper1, .wrapper2 {
-ms-transform-origin: 50% 50%; /* IE 9 */
webkit-transform-origin: 50% 50%; /* Chrome, Safari, Opera */
transform-origin: 50% 50%;
}

.wrapper1{
@include animation(indeterminate_rotate1 3s infinite linear);
}

.wrapper2{
@include animation(indeterminate_rotate2 1.5s infinite linear);
}

.fill, .mask.full{
@include animation(indeterminate_size_fill 1.5s infinite linear);
}

.fill.fix {
@include animation(indeterminate_size_fix 1.5s infinite linear);
}
}
}

@include keyframes(indeterminate_rotate1) {
0%{
@include transform(rotate(0deg));
}
100%{
@include transform(rotate(360deg));
}
}

@include keyframes(indeterminate_rotate2) {
0%{
@include transform(rotate(0deg));
}
70%{
@include transform(rotate(0deg));
}
100%{
@include transform(rotate(360deg));
}
}

@include keyframes(indeterminate_size_fill) {
0%{
@include transform(rotate(5deg));
}
10%{
@include transform(rotate(5deg));
}
50%{
@include transform(rotate(135deg));
}
70%{
@include transform(rotate(135deg));
}
100%{
@include transform(rotate(5deg));
}
}

@include keyframes(indeterminate_size_fix) {
0%{
@include transform(rotate(10deg));
}
10%{
@include transform(rotate(10deg));
}
50%{
@include transform(rotate(270deg));
}
70%{
@include transform(rotate(270deg));
}
100%{
@include transform(rotate(10deg));
}
}
120 changes: 120 additions & 0 deletions src/components/circularProgress/circularProgress.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/**
* @ngdoc module
* @name material.components.circularProgress
* @description Circular Progress module!
*/
angular.module('material.components.circularProgress', [
'material.animations',
'material.services.aria'
])
.directive('materialCircularProgress', [
'$$rAF',
'$materialEffects',
MaterialCircularProgressDirective
]);

/**
* @ngdoc directive
* @name materialCircularProgress
* @module material.components.circularProgress
* @restrict E
*
* @description
* The circular progress directive is used to make loading content in your app as delightful and painless as possible by minimizing the amount of visual change a user sees before they can view and interact with content.
*
* For operations where the percentage of the operation completed can be determined, use a determinate indicator. They give users a quick sense of how long an operation will take.
*
* For operations where the user is asked to wait a moment while something finishes up, and it’s not necessary to expose what's happening behind the scenes and how long it will take, use an indeterminate indicator.
*
* @param {string} mode Select from one of two modes: determinate and indeterminate.
* @param {number=} value In determinate mode, this number represents the percentage of the circular progress. Default: 0
* @param {number=} diameter This specifies the diamter of the circular progress. Default: 48
*
* @usage
* <hljs lang="html">
* <material-circular-progress mode="determinate" value="..."></material-circular-progress>
*
* <material-circular-progress mode="determinate" ng-value="..."></material-circular-progress>
*
* <material-circular-progress mode="determinate" value="..." diameter="100"></material-circular-progress>
*
* <material-circular-progress mode="indeterminate"></material-circular-progress>
* </hljs>
*/
function MaterialCircularProgressDirective($$rAF, $materialEffects) {
var fillRotations = new Array(101),
fixRotations = new Array(101);

for (var i = 0; i < 101; i++) {
var percent = i / 100;
var rotation = Math.floor(percent * 180);

fillRotations[i] = 'rotate(' + rotation.toString() + 'deg)';
fixRotations[i] = 'rotate(' + (rotation * 2).toString() + 'deg)';
}

return {
restrict: 'E',
template:
'<div class="wrapper1"><div class="wrapper2"><div class="circle">' +
'<div class="mask full">' +
'<div class="fill"></div>' +
'</div>' +
'<div class="mask half">' +
'<div class="fill"></div>' +
'<div class="fill fix"></div>' +
'</div>' +
'<div class="shadow"></div>' +
'</div>' +
'<div class="inset"></div></div></div>',
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 circle = element[0],
fill = circle.querySelectorAll('.fill, .mask.full'),
fix = circle.querySelectorAll('.fill.fix'),
i, clamped, fillRotation, fixRotation;

var diameter = attr.diameter || 48;
var scale = diameter/48;

circle.style[$materialEffects.TRANSFORM] = 'scale(' + scale.toString() + ')';

attr.$observe('value', function(value) {
clamped = clamp(value);
fillRotation = fillRotations[clamped];
fixRotation = fixRotations[clamped];

element.attr('aria-valuenow', clamped);

for (i = 0; i < fill.length; i++) {
fill[i].style[$materialEffects.TRANSFORM] = fillRotation;
}

for (i = 0; i < fix.length; i++) {
fix[i].style[$materialEffects.TRANSFORM] = fixRotation;
}
});
}

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

if (value < 0) {
return 0;
}

return Math.ceil(value || 0);
}
}
18 changes: 18 additions & 0 deletions src/components/circularProgress/circularProgress.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
describe('materialCircularProgress', function() {
beforeEach(module('material.components.circularProgress'));

it('should update aria-valuenow', inject(function($compile, $rootScope) {
var element = $compile('<div>' +
'<material-circular-progress value="{{progress}}">' +
'</material-circular-progress>' +
'</div>')($rootScope);

$rootScope.$apply(function() {
$rootScope.progress = 50;
});

var progress = element.find('material-circular-progress');

expect(progress.eq(0).attr('aria-valuenow')).toEqual('50');
}));
});
7 changes: 7 additions & 0 deletions src/components/circularProgress/demo1/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<div ng-controller="AppCtrl" layout="vertical" layout-padding>
<h3>Determinate</h3>
<material-circular-progress mode="determinate" value="{{determinateValue}}"></material-circular-progress>

<h3>Indeterminate</h3>
<material-circular-progress mode="indeterminate"></material-circular-progress>
</div>
14 changes: 14 additions & 0 deletions src/components/circularProgress/demo1/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
angular.module('circularProgressDemo1', ['ngMaterial'])
.controller('AppCtrl', ['$scope', '$interval',
function($scope, $interval) {
$scope.mode = 'query';
$scope.determinateValue = 30;

$interval(function() {
$scope.determinateValue += 1;
if ($scope.determinateValue > 100) {
$scope.determinateValue = 30;
}
}, 100, 0, true);
}
]);
3 changes: 3 additions & 0 deletions src/components/circularProgress/demo1/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
body {
padding: 20px;
}
10 changes: 10 additions & 0 deletions src/components/circularProgress/module.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"module": "material.components.circularProgress",
"name": "Circular Progress",
"demos": {
"demo1": {
"name": "Circular Progress Basic Usage",
"files": ["demo1/*"]
}
}
}
3 changes: 2 additions & 1 deletion src/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@
"components/list/list",
"components/divider/divider",
"components/whiteframe/whiteframe",
"components/linearProgress/linearProgress";
"components/linearProgress/linearProgress",
"components/circularProgress/circularProgress";