Skip to content

Commit

Permalink
feat(progress-spinner): add support for custom stroke-width (#4113)
Browse files Browse the repository at this point in the history
Fixes #3934
  • Loading branch information
devversion authored and kara committed Apr 21, 2017
1 parent 3a29d67 commit b846a27
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/demo-app/progress-spinner/progress-spinner-demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ <h1>Determinate</h1>

<div class="demo-progress-spinner">
<md-progress-spinner [mode]="modeToggle ? 'indeterminate' : 'determinate'"
[value]="progressValue" color="primary"></md-progress-spinner>
[value]="progressValue" color="primary" [strokeWidth]="1"></md-progress-spinner>
<md-progress-spinner [mode]="modeToggle ? 'indeterminate' : 'determinate'"
[value]="progressValue" color="accent"></md-progress-spinner>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/lib/progress-spinner/progress-spinner.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
-->
<svg viewBox="0 0 100 100"
preserveAspectRatio="xMidYMid meet">
<path #path></path>
<path #path [style.strokeWidth]="strokeWidth"></path>
</svg>
2 changes: 0 additions & 2 deletions src/lib/progress-spinner/progress-spinner.scss
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ $mat-progress-spinner-viewport-size: 100px !default;
path {
fill: transparent;

// Stroke width of 10px defines stroke as 10% of the viewBox.
stroke-width: $mat-progress-spinner-stroke-width;
transition: stroke $swift-ease-in-duration $ease-in-out-curve-function;
}

Expand Down
30 changes: 29 additions & 1 deletion src/lib/progress-spinner/progress-spinner.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {TestBed, async} from '@angular/core/testing';
import {Component} from '@angular/core';
import {By} from '@angular/platform-browser';
import {MdProgressSpinnerModule} from './index';
import {PROGRESS_SPINNER_STROKE_WIDTH} from './progress-spinner';


describe('MdProgressSpinner', () => {
Expand All @@ -14,6 +15,7 @@ describe('MdProgressSpinner', () => {
IndeterminateProgressSpinner,
ProgressSpinnerWithValueAndBoundMode,
ProgressSpinnerWithColor,
ProgressSpinnerCustomStrokeWidth,
IndeterminateProgressSpinnerWithNgIf,
SpinnerWithNgIf,
SpinnerWithColor
Expand Down Expand Up @@ -108,6 +110,27 @@ describe('MdProgressSpinner', () => {
expect(progressElement.componentInstance.interdeterminateInterval).toBeFalsy();
});

it('should set a default stroke width', () => {
let fixture = TestBed.createComponent(BasicProgressSpinner);
let pathElement = fixture.nativeElement.querySelector('path');

fixture.detectChanges();

expect(parseInt(pathElement.style.strokeWidth))
.toBe(PROGRESS_SPINNER_STROKE_WIDTH, 'Expected the default stroke-width to be applied.');
});

it('should allow a custom stroke width', () => {
let fixture = TestBed.createComponent(ProgressSpinnerCustomStrokeWidth);
let pathElement = fixture.nativeElement.querySelector('path');

fixture.componentInstance.strokeWidth = 40;
fixture.detectChanges();

expect(parseInt(pathElement.style.strokeWidth))
.toBe(40, 'Expected the custom stroke width to be applied to the path element.');
});

it('should set the color class on the md-spinner', () => {
let fixture = TestBed.createComponent(SpinnerWithColor);
fixture.detectChanges();
Expand Down Expand Up @@ -159,7 +182,12 @@ describe('MdProgressSpinner', () => {


@Component({template: '<md-progress-spinner></md-progress-spinner>'})
class BasicProgressSpinner { }
class BasicProgressSpinner {}

@Component({template: '<md-progress-spinner [strokeWidth]="strokeWidth"></md-progress-spinner>'})
class ProgressSpinnerCustomStrokeWidth {
strokeWidth: number;
}

@Component({template: '<md-progress-spinner mode="indeterminate"></md-progress-spinner>'})
class IndeterminateProgressSpinner { }
Expand Down
15 changes: 11 additions & 4 deletions src/lib/progress-spinner/progress-spinner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ const DURATION_DETERMINATE = 225;
const startIndeterminate = 3;
/** End animation value of the indeterminate animation */
const endIndeterminate = 80;
/* Maximum angle for the arc. The angle can't be exactly 360, because the arc becomes hidden. */
/** Maximum angle for the arc. The angle can't be exactly 360, because the arc becomes hidden. */
const MAX_ANGLE = 359.99 / 100;
/** Whether the user's browser supports requestAnimationFrame. */
const HAS_RAF = typeof requestAnimationFrame !== 'undefined';
/** Default stroke width as a percentage of the viewBox. */
export const PROGRESS_SPINNER_STROKE_WIDTH = 10;

export type ProgressSpinnerMode = 'determinate' | 'indeterminate';

Expand Down Expand Up @@ -77,6 +79,9 @@ export class MdProgressSpinner implements OnDestroy {
private _value: number;
private _color: string = 'primary';

/** Stroke width of the progress spinner. By default uses 10px as stroke width. */
@Input() strokeWidth: number = PROGRESS_SPINNER_STROKE_WIDTH;

/**
* Values for aria max and min are only defined as numbers when in a determinate mode. We do this
* because voiceover does not report the progress indicator as indeterminate if the aria min
Expand Down Expand Up @@ -248,7 +253,8 @@ export class MdProgressSpinner implements OnDestroy {
*/
private _renderArc(currentValue: number, rotation = 0) {
if (this._path) {
this._renderer.setAttribute(this._path.nativeElement, 'd', getSvgArc(currentValue, rotation));
const svgArc = getSvgArc(currentValue, rotation, this.strokeWidth);
this._renderer.setAttribute(this._path.nativeElement, 'd', svgArc);
}
}
}
Expand Down Expand Up @@ -336,13 +342,14 @@ function materialEase(currentTime: number, startValue: number,
* @param currentValue The current percentage value of the progress circle, the percentage of the
* circle to fill.
* @param rotation The starting point of the circle with 0 being the 0 degree point.
* @param strokeWidth Stroke width of the progress spinner arc.
* @return A string for an SVG path representing a circle filled from the starting point to the
* percentage value provided.
*/
function getSvgArc(currentValue: number, rotation: number) {
function getSvgArc(currentValue: number, rotation: number, strokeWidth: number) {
let startPoint = rotation || 0;
let radius = 50;
let pathRadius = 40;
let pathRadius = radius - strokeWidth;

let startAngle = startPoint * MAX_ANGLE;
let endAngle = currentValue * MAX_ANGLE;
Expand Down

0 comments on commit b846a27

Please sign in to comment.