Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

fix(progressLinear): sync logic, perf upgrades, fix animations #4454

Closed
wants to merge 1 commit into from
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
5 changes: 2 additions & 3 deletions src/components/autocomplete/autocomplete.scss
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,14 @@ md-autocomplete {
&.md-menu-showing {
z-index: $z-index-backdrop + 1;
}
md-progress-linear[md-mode=indeterminate] {
md-progress-linear .md-mode-indeterminate {
position: absolute;
bottom: 0; left: 0; width: 100%;
top: 20px; left: 0; width: 100%;
height: 3px;
transition: none;

.md-container {
transition: none;
top: auto;
height: 3px;
}
&.ng-enter {
Expand Down
9 changes: 8 additions & 1 deletion src/components/progressCircular/demoBasicUsage/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,12 @@ <h4>Theming </h4>
<md-progress-circular md-mode="{{vm.modes[4]}}" md-diameter="96"></md-progress-circular>
</div>


<hr ng-class="{'visible' : vm.activated}">

<div layout="row" id="loaders">

<p style="margin-right: 20px">Show Progress Circular Indicators: </p>
<p>Progress Circular Indicators: </p>

<h5>Off</h5>
<md-switch
Expand All @@ -39,5 +42,9 @@ <h5>On</h5>
</md-switch>
</div>

<p class="small">
Note: With above switch -- that simply clears the md-mode in each <code>&lt;md-progress-linear md-mode=""&gt;</code> element --
developers can easily disable the animations and hide their progress indicators.
</p>

</div>
26 changes: 26 additions & 0 deletions src/components/progressCircular/demoBasicUsage/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,29 @@ md-progress-circular {
#loaders > h5 {
padding-top: 8px;
}

#loaders > p {
margin-right: 20px;
}


p.small {
font-size: 0.8em;
margin-top: -18px;
}


hr {
width: 100%;
margin-top: 20px;
border-color: rgba(221, 221, 177, 0.1);
}

p.small > code {
font-size: 0.8em;
}


.visible {
border-color: rgba(221, 221, 177, 0);
}
114 changes: 82 additions & 32 deletions src/components/progressCircular/progress-circular.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,13 @@ angular.module('material.components.progressCircular', [
* not necessary to expose what's happening behind the scenes and how long it will take, use an
* indeterminate indicator.
*
* @param {string} md-mode Select from one of two modes: **'determinate'** and **'indeterminate'**.<br/>
* Note: if the `md-mode` value is undefined or not 1 of the two (2) valid modes, then `.ng-hide`
* @param {string} md-mode Select from one of two modes: **'determinate'** and **'indeterminate'**.
*
* Note: if the `md-mode` value is set as undefined or specified as not 1 of the two (2) valid modes, then `.ng-hide`
* will be auto-applied as a style to the component.
*
* Note: if not configured, the `md-mode="indeterminate"` will be auto injected as an attribute.
* If `value=""` is also specified, however, then `md-mode="determinate"` would be auto-injected instead.
* @param {number=} value In determinate mode, this number represents the percentage of the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought you could just add newlines in here rather than manually adding <br/>. I could be wrong, though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

* circular progress. Default: 0
* @param {number=} md-diameter This specifies the diamter of the circular progress. The value
Expand All @@ -46,7 +50,7 @@ angular.module('material.components.progressCircular', [
* <md-progress-circular md-mode="indeterminate"></md-progress-circular>
* </hljs>
*/
function MdProgressCircularDirective($mdConstant, $mdTheming, $mdUtil) {
function MdProgressCircularDirective($mdTheming, $mdUtil, $log) {
var DEFAULT_PROGRESS_SIZE = 100;
var DEFAULT_SCALING = 0.5;

Expand Down Expand Up @@ -87,43 +91,68 @@ function MdProgressCircularDirective($mdConstant, $mdTheming, $mdUtil) {
function postLink(scope, element, attr) {
$mdTheming(element);

var circle = element[0];
var circle = element;
var spinnerWrapper = angular.element(element.children()[0]);

var lastMode, toVendorCSS = $mdUtil.dom.animator.toCss;

// Update size/scaling of the progress indicator
// Watch the "value" and "md-mode" attributes
updateScale();
validateMode();
watchAttributes();

circle.style[$mdConstant.CSS.TRANSFORM] = 'scale(' + getDiameterRatio() + ')';

attr.$observe('value', function(value) {
var percentValue = clamp(value);
element.attr('aria-valuenow', percentValue);

if (attr.mdMode == "determinate") {
animateIndicator(percentValue);
}
});
/**
* Watch the value and md-mode attributes
*/
function watchAttributes() {
attr.$observe('value', function(value) {
var percentValue = clamp(value);
element.attr('aria-valuenow', percentValue);

if (mode() == MODE_DETERMINATE) {
animateIndicator(percentValue);
}
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a particular reason why the formatting has extra indentation here?

Also, should it be mode() === MODE_DETERMINATE (i.e. with the triple =)?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, contrary to what most of the JS world says, the Google JS styleguide uses == instead of ===. I struggle to break the === habit on this project. =p

attr.$observe('mdMode',function(mode){
switch( mode ) {
case MODE_DETERMINATE:
case MODE_INDETERMINATE:
spinnerWrapper.removeClass('ng-hide');
spinnerWrapper.removeClass( lastMode );
spinnerWrapper.addClass( lastMode = "md-mode-" + mode );
break;
default:
spinnerWrapper.removeClass( lastMode );
spinnerWrapper.addClass('ng-hide');
lastMode = undefined;
break;
}
});
}

attr.$observe('mdMode',function(mode){
switch( mode ) {
case MODE_DETERMINATE:
case MODE_INDETERMINATE:
spinnerWrapper.removeClass('ng-hide');
/**
* Update size/scaling of the progress indicator
* Watch the "value" and "md-mode" attributes
*/
function updateScale() {
circle.css(toVendorCSS({
transform : $mdUtil.supplant('scale( {0} )',[getDiameterRatio()])
}));
}

// Inject class selector instead of attribute selector
// (@see layout.js changes for IE performance issues)
/**
* Auto-defaults the mode to either `determinate` or `indeterminate` mode; if not specified
*/
function validateMode() {
if ( angular.isUndefined(attr.mdMode) ) {
var hasValue = angular.isDefined(attr.value);
var mode = hasValue ? MODE_DETERMINATE : MODE_INDETERMINATE;
var info = "Auto-adding the missing md-mode='{0}' to the ProgressCircular element";

if ( lastMode ) spinnerWrapper.removeClass( lastMode );
lastMode = "md-mode-" + mode;
if ( lastMode ) spinnerWrapper.addClass( lastMode );
$log.debug( $mdUtil.supplant(info, [mode]) );

break;
default:
spinnerWrapper.addClass('ng-hide');
element.attr("md-mode",mode);
attr['mdMode'] = mode;
}
});
}

var leftC, rightC, gap;

Expand All @@ -136,6 +165,8 @@ function MdProgressCircularDirective($mdConstant, $mdTheming, $mdUtil) {
* - use attribute selectors which had poor performances in IE
*/
function animateIndicator(value) {
if ( !mode() ) return;

leftC = leftC || angular.element(element[0].querySelector('.md-left > .md-half-circle'));
rightC = rightC || angular.element(element[0].querySelector('.md-right > .md-half-circle'));
gap = gap || angular.element(element[0].querySelector('.md-gap'));
Expand All @@ -146,7 +177,7 @@ function MdProgressCircularDirective($mdConstant, $mdTheming, $mdUtil) {
}),
leftStyles = removeEmptyValues({
transition: (value <= 50) ? "transform 0.1s linear" : "",
transform: $mdUtil.supplant("rotate({0}deg)", [value <= 50 ? 135 : ((((value - 50) / 50) * 180) + 135)])
transform: $mdUtil.supplant("rotate({0}deg)", [value <= 50 ? 135 : (((value - 50) / 50 * 180) + 135)])
}),
rightStyles = removeEmptyValues({
transition: (value >= 50) ? "transform 0.1s linear" : "",
Expand Down Expand Up @@ -174,6 +205,25 @@ function MdProgressCircularDirective($mdConstant, $mdTheming, $mdUtil) {
// should return ratio; DEFAULT_PROGRESS_SIZE === 100px is default size
return (value > 1) ? value / DEFAULT_PROGRESS_SIZE : value;
}

/**
* Is the md-mode a valid option?
*/
function mode() {
var value = attr.mdMode;
if ( value ) {
switch(value) {
case MODE_DETERMINATE :
case MODE_INDETERMINATE :
break;
default:
value = undefined;
break;
}
}
return value;
}

}

/**
Expand Down
107 changes: 58 additions & 49 deletions src/components/progressCircular/progress-circular.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,63 +7,72 @@ $progress-border-width : 10px;
$progress-circular-size : 10 * $progress-border-width !default;

md-progress-circular {
width: $progress-circular-size;
height: $progress-circular-size;
display: block;
position: relative;

width: $progress-circular-size;
height: $progress-circular-size;

padding-top: 0 !important;
margin-bottom: 0 !important;
overflow: hidden;

transform: scale(0.5);

.md-inner {
width: $progress-circular-size;
height: $progress-circular-size;
.md-spinner-wrapper {
display:block;
position: relative;
.md-gap {
position: absolute;
left: $progress-circular-size * 0.5 - 1;
right: $progress-circular-size * 0.5 - 1;
top: 0;
bottom: 0;
border-top-width: $progress-border-width;
border-top-style: solid;
box-sizing: border-box;
}
.md-left, .md-right {
position: absolute;
top: 0;
height: $progress-circular-size;
width: $progress-circular-size * 0.50;
overflow: hidden;
.md-half-circle {
position: absolute;
top: 0;
width: $progress-circular-size;
height: $progress-circular-size;
box-sizing: border-box;
border-width: $progress-border-width;
border-style: solid;
border-bottom-color: transparent;
border-radius: 50%;
}
}
.md-left {
left: 0;
.md-half-circle {
left: 0;
border-right-color: transparent;
}
}
.md-right {
right: 0;
.md-half-circle {
right: 0;
border-left-color: transparent;
}
}
overflow: hidden;

.md-inner {
width: $progress-circular-size;
height: $progress-circular-size;
position: relative;
.md-gap {
position: absolute;
left: $progress-circular-size * 0.5 - 1;
right: $progress-circular-size * 0.5 - 1;
top: 0;
bottom: 0;
border-top-width: $progress-border-width;
border-top-style: solid;
box-sizing: border-box;
}
.md-left, .md-right {
position: absolute;
top: 0;
height: $progress-circular-size;
width: $progress-circular-size * 0.50;
overflow: hidden;
.md-half-circle {
position: absolute;
top: 0;
width: $progress-circular-size;
height: $progress-circular-size;
box-sizing: border-box;
border-width: $progress-border-width;
border-style: solid;
border-bottom-color: transparent;
border-radius: 50%;
}
}
.md-left {
left: 0;
.md-half-circle {
left: 0;
border-right-color: transparent;
}
}
.md-right {
right: 0;
.md-half-circle {
right: 0;
border-left-color: transparent;
}
}
}
}


.md-spinner-wrapper.md-mode-indeterminate {
animation: outer-rotate $progress-circular-outer-duration linear infinite;
.md-inner {
Expand All @@ -88,7 +97,7 @@ md-progress-circular {
}
}

.ng-hide md-progress-circular, md-progress-circular.ng-hide {
md-progress-circular.ng-hide {
.md-spinner-wrapper {
animation: none;
.md-inner {
Expand Down
Loading