import {Component, Input} from 'angular2/core';
import {NgStyle} from 'angular2/common';
import {Config} from '../../config/config';
/**
* @name Spinner
* @description
* The `ion-spinner` component provides a variety of animated SVG spinners.
* Spinners enables you to give users feedback that the app is actively
* processing/thinking/waiting/chillin’ out, or whatever you’d like it to indicate.
* By default, the `ion-refresher` feature uses this spinner component while it's
* the refresher is in the `refreshing` state.
*
* Ionic offers a handful of spinners out of the box, and by default, it will use
* the appropriate spinner for the platform on which it’s running.
*
*
*
*
* ios
*
*
*
*
*
*
*
* ios-small
*
*
*
*
*
*
*
* bubbles
*
*
*
*
*
*
*
* circles
*
*
*
*
*
*
*
* crescent
*
*
*
*
*
*
*
* dots
*
*
*
*
*
*
*
* @usage
* The following code would use the default spinner for the platform it's
* running from. If it's neither iOS or Android, it'll default to use `ios`.
*
* ```html
*
* ```
*
* By setting the `name` property, you can specify which predefined spinner to
* use, no matter what the platform is.
*
* ```html
*
* ```
*
* ## Styling SVG with CSS
* One cool thing about SVG is its ability to be styled with CSS! One thing to note
* is that some of the CSS properties on an SVG element have different names. For
* example, SVG uses the term `stroke` instead of `border`, and `fill` instead
* of `background-color`.
*
* ```css
* ion-spinner svg {
* width: 28px;
* height: 28px;
* stroke: #444;
* fill: #222;
* }
* ```
*/
@Component({
selector: 'ion-spinner',
template:
'' +
'',
directives: [NgStyle],
host: {
'[class]': '_applied',
'[class.spinner-paused]': 'paused'
}
})
export class Spinner {
private _c: any[];
private _l: any[];
private _name: string;
private _dur: number = null;
private _init: boolean;
private _applied: string;
/**
* @input {string} SVG spinner name.
*/
@Input()
get name(): string {
return this._name;
}
set name(val: string) {
this._name = val;
this.load();
}
/**
* @input {string} How long it takes it to do one loop.
*/
@Input()
get duration(): number {
return this._dur;
}
set duration(val: number) {
this._dur = val;
this.load();
}
/**
* @input {string} If the animation is paused or not. Defaults to `false`.
*/
@Input() paused: boolean = false;
constructor(private _config: Config) {}
ngOnInit() {
this._init = true;
this.load();
}
load() {
if (this._init) {
this._l = [];
this._c = [];
var name = this._name || this._config.get('spinner', 'ios');
const spinner = SPINNERS[name];
if (spinner) {
this._applied = 'spinner-' + name;
if (spinner.lines) {
for (var i = 0, l = spinner.lines; i < l; i++) {
this._l.push( this._loadEle(spinner, i, l) );
}
} else if (spinner.circles) {
for (var i = 0, l = spinner.circles; i < l; i++) {
this._c.push( this._loadEle(spinner, i, l) );
}
}
}
}
}
_loadEle(spinner: any, index: number, total: number) {
let duration = this._dur || spinner.dur
let data = spinner.fn(duration, index, total);
data.style.animationDuration = duration + 'ms';
return data;
}
}
const SPINNERS = {
ios: {
dur: 1000,
lines: 12,
fn: function(dur, index, total) {
return {
y1: 17,
y2: 29,
style: {
transform: 'rotate(' + (30 * index + (index < 6 ? 180 : -180)) + 'deg)',
animationDelay: -(dur - ((dur / total) * index)) + 'ms'
}
}
}
},
'ios-small': {
dur: 1000,
lines: 12,
fn: function(dur, index, total) {
return {
y1: 12,
y2: 20,
style: {
transform: 'rotate(' + (30 * index + (index < 6 ? 180 : -180)) + 'deg)',
animationDelay: -(dur - ((dur / total) * index)) + 'ms'
}
}
}
},
bubbles: {
dur: 1000,
circles: 9,
fn: function(dur, index, total) {
return {
r: 5,
style: {
top: 9 * Math.sin(2 * Math.PI * index / total),
left: 9 * Math.cos(2 * Math.PI * index / total),
animationDelay: -(dur - ((dur / total) * index)) + 'ms'
}
}
}
},
circles: {
dur: 1000,
circles: 8,
fn: function(dur, index, total) {
return {
r: 5,
style: {
top: 9 * Math.sin(2 * Math.PI * index / total),
left: 9 * Math.cos(2 * Math.PI * index / total),
animationDelay: -(dur - ((dur / total) * index)) + 'ms'
}
}
}
},
crescent: {
dur: 750,
circles: 1,
fn: function(dur) {
return {
r: 26,
style: {}
}
}
},
dots: {
dur: 750,
circles: 3,
fn: function(dur, index, total) {
return {
r: 6,
style: {
left: (9 - (9 * index)),
animationDelay: -(110 * index) + 'ms'
}
}
}
}
};