UNPKG

@angular/material

Version:
475 lines (474 loc) 19.2 kB
import * as tslib_1 from "tslib"; /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ import { ChangeDetectionStrategy, Component, Directive, ElementRef, Input, NgModule, NgZone, Renderer2, ViewChild, ViewEncapsulation } from '@angular/core'; import { MdCommonModule, mixinColor } from '@angular/material/core'; /** * A single degree in radians. */ var DEGREE_IN_RADIANS = Math.PI / 180; /** * Duration of the indeterminate animation. */ var DURATION_INDETERMINATE = 667; /** * Duration of the indeterminate animation. */ var DURATION_DETERMINATE = 225; /** * Start animation value of the indeterminate animation */ var startIndeterminate = 3; /** * End animation value of the indeterminate animation */ var endIndeterminate = 80; /** * Maximum angle for the arc. The angle can't be exactly 360, because the arc becomes hidden. */ var MAX_ANGLE = 359.99 / 100; /** * Whether the user's browser supports requestAnimationFrame. */ var HAS_RAF = typeof requestAnimationFrame !== 'undefined'; /** * Default stroke width as a percentage of the viewBox. */ var PROGRESS_SPINNER_STROKE_WIDTH = 10; /** * Directive whose purpose is to add the mat- CSS styling to this selector. * \@docs-private */ var MdProgressSpinnerCssMatStyler = (function () { function MdProgressSpinnerCssMatStyler() { } return MdProgressSpinnerCssMatStyler; }()); MdProgressSpinnerCssMatStyler.decorators = [ { type: Directive, args: [{ selector: 'md-progress-spinner, mat-progress-spinner', host: { 'class': 'mat-progress-spinner' } },] }, ]; /** * @nocollapse */ MdProgressSpinnerCssMatStyler.ctorParameters = function () { return []; }; /** * \@docs-private */ var MdProgressSpinnerBase = (function () { /** * @param {?} _renderer * @param {?} _elementRef */ function MdProgressSpinnerBase(_renderer, _elementRef) { this._renderer = _renderer; this._elementRef = _elementRef; } return MdProgressSpinnerBase; }()); var _MdProgressSpinnerMixinBase = mixinColor(MdProgressSpinnerBase, 'primary'); /** * <md-progress-spinner> component. */ var MdProgressSpinner = (function (_super) { tslib_1.__extends(MdProgressSpinner, _super); /** * @param {?} renderer * @param {?} elementRef * @param {?} _ngZone */ function MdProgressSpinner(renderer, elementRef, _ngZone) { var _this = _super.call(this, renderer, elementRef) || this; _this._ngZone = _ngZone; /** * The id of the last requested animation. */ _this._lastAnimationId = 0; _this._mode = 'determinate'; /** * Stroke width of the progress spinner. By default uses 10px as stroke width. */ _this.strokeWidth = PROGRESS_SPINNER_STROKE_WIDTH; return _this; } Object.defineProperty(MdProgressSpinner.prototype, "_ariaValueMin", { /** * 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 * and/or max value are number values. * @return {?} */ get: function () { return this.mode == 'determinate' ? 0 : null; }, enumerable: true, configurable: true }); Object.defineProperty(MdProgressSpinner.prototype, "_ariaValueMax", { /** * @return {?} */ get: function () { return this.mode == 'determinate' ? 100 : null; }, enumerable: true, configurable: true }); Object.defineProperty(MdProgressSpinner.prototype, "interdeterminateInterval", { /** * \@docs-private * @return {?} */ get: function () { return this._interdeterminateInterval; }, /** * \@docs-private * @param {?} interval * @return {?} */ set: function (interval) { if (this._interdeterminateInterval) { clearInterval(this._interdeterminateInterval); } this._interdeterminateInterval = interval; }, enumerable: true, configurable: true }); /** * Clean up any animations that were running. * @return {?} */ MdProgressSpinner.prototype.ngOnDestroy = function () { this._cleanupIndeterminateAnimation(); }; Object.defineProperty(MdProgressSpinner.prototype, "value", { /** * Value of the progress circle. It is bound to the host as the attribute aria-valuenow. * @return {?} */ get: function () { if (this.mode == 'determinate') { return this._value; } return 0; }, /** * @param {?} v * @return {?} */ set: function (v) { if (v != null && this.mode == 'determinate') { var /** @type {?} */ newValue = clamp(v); this._animateCircle(this.value || 0, newValue); this._value = newValue; } }, enumerable: true, configurable: true }); Object.defineProperty(MdProgressSpinner.prototype, "mode", { /** * Mode of the progress circle * * Input must be one of the values from ProgressMode, defaults to 'determinate'. * mode is bound to the host as the attribute host. * @return {?} */ get: function () { return this._mode; }, /** * @param {?} mode * @return {?} */ set: function (mode) { if (mode !== this._mode) { if (mode === 'indeterminate') { this._startIndeterminateAnimation(); } else { this._cleanupIndeterminateAnimation(); this._animateCircle(0, this._value); } this._mode = mode; } }, enumerable: true, configurable: true }); /** * Animates the circle from one percentage value to another. * * @param {?} animateFrom The percentage of the circle filled starting the animation. * @param {?} animateTo The percentage of the circle filled ending the animation. * @param {?=} ease The easing function to manage the pace of change in the animation. * @param {?=} duration The length of time to show the animation, in milliseconds. * @param {?=} rotation The starting angle of the circle fill, with 0° represented at the top center * of the circle. * @return {?} */ MdProgressSpinner.prototype._animateCircle = function (animateFrom, animateTo, ease, duration, rotation) { var _this = this; if (ease === void 0) { ease = linearEase; } if (duration === void 0) { duration = DURATION_DETERMINATE; } if (rotation === void 0) { rotation = 0; } var /** @type {?} */ id = ++this._lastAnimationId; var /** @type {?} */ startTime = Date.now(); var /** @type {?} */ changeInValue = animateTo - animateFrom; // No need to animate it if the values are the same if (animateTo === animateFrom) { this._renderArc(animateTo, rotation); } else { var /** @type {?} */ animation_1 = function () { // If there is no requestAnimationFrame, skip ahead to the end of the animation. var /** @type {?} */ elapsedTime = HAS_RAF ? Math.max(0, Math.min(Date.now() - startTime, duration)) : duration; _this._renderArc(ease(elapsedTime, animateFrom, changeInValue, duration), rotation); // Prevent overlapping animations by checking if a new animation has been called for and // if the animation has lasted longer than the animation duration. if (id === _this._lastAnimationId && elapsedTime < duration) { requestAnimationFrame(animation_1); } }; // Run the animation outside of Angular's zone, in order to avoid // hitting ZoneJS and change detection on each frame. this._ngZone.runOutsideAngular(animation_1); } }; /** * Starts the indeterminate animation interval, if it is not already running. * @return {?} */ MdProgressSpinner.prototype._startIndeterminateAnimation = function () { var _this = this; var /** @type {?} */ rotationStartPoint = 0; var /** @type {?} */ start = startIndeterminate; var /** @type {?} */ end = endIndeterminate; var /** @type {?} */ duration = DURATION_INDETERMINATE; var /** @type {?} */ animate = function () { _this._animateCircle(start, end, materialEase, duration, rotationStartPoint); // Prevent rotation from reaching Number.MAX_SAFE_INTEGER. rotationStartPoint = (rotationStartPoint + end) % 100; var /** @type {?} */ temp = start; start = -end; end = -temp; }; if (!this.interdeterminateInterval) { this._ngZone.runOutsideAngular(function () { _this.interdeterminateInterval = setInterval(animate, duration + 50, 0, false); animate(); }); } }; /** * Removes interval, ending the animation. * @return {?} */ MdProgressSpinner.prototype._cleanupIndeterminateAnimation = function () { this.interdeterminateInterval = null; }; /** * Renders the arc onto the SVG element. Proxies `getArc` while setting the proper * DOM attribute on the `<path>`. * @param {?} currentValue * @param {?=} rotation * @return {?} */ MdProgressSpinner.prototype._renderArc = function (currentValue, rotation) { if (rotation === void 0) { rotation = 0; } if (this._path) { var /** @type {?} */ svgArc = getSvgArc(currentValue, rotation, this.strokeWidth); this._renderer.setAttribute(this._path.nativeElement, 'd', svgArc); } }; return MdProgressSpinner; }(_MdProgressSpinnerMixinBase)); MdProgressSpinner.decorators = [ { type: Component, args: [{ selector: 'md-progress-spinner, mat-progress-spinner', host: { 'role': 'progressbar', 'class': 'mat-progress-spinner', '[attr.aria-valuemin]': '_ariaValueMin', '[attr.aria-valuemax]': '_ariaValueMax', '[attr.aria-valuenow]': 'value', '[attr.mode]': 'mode', }, inputs: ['color'], template: "<svg viewBox=\"0 0 100 100\" preserveAspectRatio=\"xMidYMid meet\" focusable=\"false\"><path #path [style.strokeWidth]=\"strokeWidth\"></path></svg>", styles: [".mat-progress-spinner{display:block;height:100px;width:100px;overflow:hidden}.mat-progress-spinner svg{height:100%;width:100%;transform-origin:center}.mat-progress-spinner path{fill:transparent;transition:stroke .3s cubic-bezier(.35,0,.25,1)}.mat-progress-spinner[mode=indeterminate] svg{animation-duration:5.25s,2.887s;animation-name:mat-progress-spinner-sporadic-rotate,mat-progress-spinner-linear-rotate;animation-timing-function:cubic-bezier(.35,0,.25,1),linear;animation-iteration-count:infinite;transition:none}@keyframes mat-progress-spinner-linear-rotate{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes mat-progress-spinner-sporadic-rotate{12.5%{transform:rotate(135deg)}25%{transform:rotate(270deg)}37.5%{transform:rotate(405deg)}50%{transform:rotate(540deg)}62.5%{transform:rotate(675deg)}75%{transform:rotate(810deg)}87.5%{transform:rotate(945deg)}100%{transform:rotate(1080deg)}}"], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, preserveWhitespaces: false, },] }, ]; /** * @nocollapse */ MdProgressSpinner.ctorParameters = function () { return [ { type: Renderer2, }, { type: ElementRef, }, { type: NgZone, }, ]; }; MdProgressSpinner.propDecorators = { '_path': [{ type: ViewChild, args: ['path',] },], 'strokeWidth': [{ type: Input },], 'value': [{ type: Input },], 'mode': [{ type: Input },], }; /** * <md-spinner> component. * * This is a component definition to be used as a convenience reference to create an * indeterminate <md-progress-spinner> instance. */ var MdSpinner = (function (_super) { tslib_1.__extends(MdSpinner, _super); /** * @param {?} elementRef * @param {?} ngZone * @param {?} renderer */ function MdSpinner(elementRef, ngZone, renderer) { var _this = _super.call(this, renderer, elementRef, ngZone) || this; _this.mode = 'indeterminate'; return _this; } return MdSpinner; }(MdProgressSpinner)); MdSpinner.decorators = [ { type: Component, args: [{ selector: 'md-spinner, mat-spinner', host: { 'role': 'progressbar', 'mode': 'indeterminate', 'class': 'mat-spinner mat-progress-spinner', }, inputs: ['color'], template: "<svg viewBox=\"0 0 100 100\" preserveAspectRatio=\"xMidYMid meet\" focusable=\"false\"><path #path [style.strokeWidth]=\"strokeWidth\"></path></svg>", styles: [".mat-progress-spinner{display:block;height:100px;width:100px;overflow:hidden}.mat-progress-spinner svg{height:100%;width:100%;transform-origin:center}.mat-progress-spinner path{fill:transparent;transition:stroke .3s cubic-bezier(.35,0,.25,1)}.mat-progress-spinner[mode=indeterminate] svg{animation-duration:5.25s,2.887s;animation-name:mat-progress-spinner-sporadic-rotate,mat-progress-spinner-linear-rotate;animation-timing-function:cubic-bezier(.35,0,.25,1),linear;animation-iteration-count:infinite;transition:none}@keyframes mat-progress-spinner-linear-rotate{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes mat-progress-spinner-sporadic-rotate{12.5%{transform:rotate(135deg)}25%{transform:rotate(270deg)}37.5%{transform:rotate(405deg)}50%{transform:rotate(540deg)}62.5%{transform:rotate(675deg)}75%{transform:rotate(810deg)}87.5%{transform:rotate(945deg)}100%{transform:rotate(1080deg)}}"], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, preserveWhitespaces: false, },] }, ]; /** * @nocollapse */ MdSpinner.ctorParameters = function () { return [ { type: ElementRef, }, { type: NgZone, }, { type: Renderer2, }, ]; }; /** * Clamps a value to be between 0 and 100. * @param {?} v * @return {?} */ function clamp(v) { return Math.max(0, Math.min(100, v)); } /** * Converts Polar coordinates to Cartesian. * @param {?} radius * @param {?} pathRadius * @param {?} angleInDegrees * @return {?} */ function polarToCartesian(radius, pathRadius, angleInDegrees) { var /** @type {?} */ angleInRadians = (angleInDegrees - 90) * DEGREE_IN_RADIANS; return (radius + (pathRadius * Math.cos(angleInRadians))) + ',' + (radius + (pathRadius * Math.sin(angleInRadians))); } /** * Easing function for linear animation. * @param {?} currentTime * @param {?} startValue * @param {?} changeInValue * @param {?} duration * @return {?} */ function linearEase(currentTime, startValue, changeInValue, duration) { return changeInValue * currentTime / duration + startValue; } /** * Easing function to match material design indeterminate animation. * @param {?} currentTime * @param {?} startValue * @param {?} changeInValue * @param {?} duration * @return {?} */ function materialEase(currentTime, startValue, changeInValue, duration) { var /** @type {?} */ time = currentTime / duration; var /** @type {?} */ timeCubed = Math.pow(time, 3); var /** @type {?} */ timeQuad = Math.pow(time, 4); var /** @type {?} */ timeQuint = Math.pow(time, 5); return startValue + changeInValue * ((6 * timeQuint) + (-15 * timeQuad) + (10 * timeCubed)); } /** * Determines the path value to define the arc. Converting percentage values to to polar * coordinates on the circle, and then to cartesian coordinates in the viewport. * * @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, rotation, strokeWidth) { var /** @type {?} */ startPoint = rotation || 0; var /** @type {?} */ radius = 50; var /** @type {?} */ pathRadius = radius - strokeWidth; var /** @type {?} */ startAngle = startPoint * MAX_ANGLE; var /** @type {?} */ endAngle = currentValue * MAX_ANGLE; var /** @type {?} */ start = polarToCartesian(radius, pathRadius, startAngle); var /** @type {?} */ end = polarToCartesian(radius, pathRadius, endAngle + startAngle); var /** @type {?} */ arcSweep = endAngle < 0 ? 0 : 1; var /** @type {?} */ largeArcFlag; if (endAngle < 0) { largeArcFlag = endAngle >= -180 ? 0 : 1; } else { largeArcFlag = endAngle <= 180 ? 0 : 1; } return "M" + start + "A" + pathRadius + "," + pathRadius + " 0 " + largeArcFlag + "," + arcSweep + " " + end; } var MdProgressSpinnerModule = (function () { function MdProgressSpinnerModule() { } return MdProgressSpinnerModule; }()); MdProgressSpinnerModule.decorators = [ { type: NgModule, args: [{ imports: [MdCommonModule], exports: [ MdProgressSpinner, MdSpinner, MdCommonModule, MdProgressSpinnerCssMatStyler ], declarations: [ MdProgressSpinner, MdSpinner, MdProgressSpinnerCssMatStyler ], },] }, ]; /** * @nocollapse */ MdProgressSpinnerModule.ctorParameters = function () { return []; }; /** * Generated bundle index. Do not edit. */ export { MdProgressSpinnerModule, PROGRESS_SPINNER_STROKE_WIDTH, MdProgressSpinnerCssMatStyler, MdProgressSpinnerBase, _MdProgressSpinnerMixinBase, MdProgressSpinner, MdSpinner, MdProgressSpinner as MatProgressSpinner, MdProgressSpinnerBase as MatProgressSpinnerBase, MdProgressSpinnerCssMatStyler as MatProgressSpinnerCssMatStyler, MdProgressSpinnerModule as MatProgressSpinnerModule, MdSpinner as MatSpinner }; //# sourceMappingURL=progress-spinner.es5.js.map