refactor(spinners): rename loaders to spinners

This commit is contained in:
Adam Bradley
2015-01-20 13:05:06 -06:00
parent 838996815c
commit 6471995a0d
8 changed files with 177 additions and 152 deletions

View File

@@ -273,21 +273,6 @@
</li>
<!-- Loader -->
<li class="menu-section">
<a href="{{ page.versionHref }}/api/directive/ionLoader/" class="api-section">
Loader
</a>
<ul>
<li>
<a href="{{ page.versionHref }}/api/directive/ionLoader/">
ion-loader
</a>
</li>
</ul>
</li>
<!-- Loading -->
<li class="menu-section">
<a href="{{ page.versionHref }}/api/service/$ionicLoading/" class="api-section">
@@ -562,6 +547,21 @@
</li>
<!-- Spinner -->
<li class="menu-section">
<a href="{{ page.versionHref }}/api/directive/ionSpinner/" class="api-section">
Spinner
</a>
<ul>
<li>
<a href="{{ page.versionHref }}/api/directive/ionSpinner/">
ion-spinner
</a>
</li>
</ul>
</li>
<!-- Tabs -->
<li class="menu-section">
<a href="{{ page.versionHref }}/api/directive/ionTabs/" class="api-section">

View File

@@ -29,7 +29,7 @@
dur: DURATION
};
function createSvgElement(tagName, data, parent, loaderName) {
function createSvgElement(tagName, data, parent, spinnerName) {
var ele = document.createElement(SHORTCUTS[tagName] || tagName);
var k, x, y;
@@ -39,10 +39,10 @@
for (x = 0; x < data[k].length; x++) {
if (data[k][x].fn) {
for (y = 0; y < data[k][x].t; y++) {
createSvgElement(k, data[k][x].fn(y, loaderName), ele, loaderName);
createSvgElement(k, data[k][x].fn(y, spinnerName), ele, spinnerName);
}
} else {
createSvgElement(k, data[k][x], ele, loaderName);
createSvgElement(k, data[k][x], ele, spinnerName);
}
}
@@ -70,10 +70,10 @@
sw: 4,
lc: ROUND,
line: [{
fn: function(i, loaderName) {
fn: function(i, spinnerName) {
return {
y1: loaderName == 'ios' ? 17 : 12,
y2: loaderName == 'ios' ? 29 : 20,
y1: spinnerName == 'ios' ? 17 : 12,
y2: spinnerName == 'ios' ? 29 : 20,
t: TRANSLATE32 + ' rotate(' + (30 * i + (i < 6 ? 180: -180)) + ')',
a: [{
fn: function() {
@@ -92,7 +92,7 @@
}]
};
var loaders = {
var spinners = {
android: {
c: [{
@@ -110,49 +110,8 @@
'ios-small': IOS_SPINNER,
blip: {
f: NONE,
'fill-rule': 'evenodd',
sw: 3,
circle: [{
fn: function(i) {
return {
cx: 32,
cy: 32,
a: [{
fn: function() {
return {
an: 'r',
begin: (i * -1) + 's',
dur: '2s',
v: '0;24',
keyTimes: '0;1',
keySplines: '0.1,0.2,0.3,1',
calcMode: 'spline',
rc: INDEFINITE
};
},
t: 1
},{
fn: function() {
return {
an: STROKE_OPACITY,
begin: (i * -1) + 's',
dur: '2s',
v: '.2;1;.2;0',
rc: INDEFINITE
};
},
t: 1
}]
};
},
t: 2
}]
},
bubbles: {
sw: 0,
c: [{
fn: function(i) {
return {
@@ -296,6 +255,47 @@
}]
},
ripple: {
f: NONE,
'fill-rule': 'evenodd',
sw: 3,
circle: [{
fn: function(i) {
return {
cx: 32,
cy: 32,
a: [{
fn: function() {
return {
an: 'r',
begin: (i * -1) + 's',
dur: '2s',
v: '0;24',
keyTimes: '0;1',
keySplines: '0.1,0.2,0.3,1',
calcMode: 'spline',
rc: INDEFINITE
};
},
t: 1
},{
fn: function() {
return {
an: STROKE_OPACITY,
begin: (i * -1) + 's',
dur: '2s',
v: '.2;1;.2;0',
rc: INDEFINITE
};
},
t: 1
}]
};
},
t: 2
}]
},
spiral: {
defs: [{
linearGradient: [{
@@ -304,9 +304,10 @@
x1: 55, y1: 46, x2: 2, y2: 46,
stop: [{
offset: 0.1,
style: 'stop-color:white;stop-opacity:0'
class: 'stop1'
}, {
offset: 1
offset: 1,
class: 'stop2'
}]
}]
}],
@@ -386,26 +387,25 @@
IonicModule
.controller('$ionicLoader', [
.controller('$ionicSpinner', [
'$element',
'$attrs',
function($element, $attrs) {
var loaderName, loader;
var spinnerName, spinner;
this.init = function() {
loaderName = $attrs.icon || ionic.Platform.platform();
loader = loaders[loaderName];
if (!loader) {
loaderName = 'ios';
loader = loaders.ios;
spinnerName = $attrs.icon || ionic.Platform.platform();
spinner = spinners[spinnerName];
if (!spinner) {
spinnerName = 'ios';
spinner = spinners.ios;
}
var container = document.createElement('div');
createSvgElement('svg', {
viewBox: '0 0 64 64',
'class': 'loader loader-' + loaderName,
g: [ loaders[loaderName] ]
}, container, loaderName);
g: [ spinners[spinnerName] ]
}, container, spinnerName);
// Specifically for animations to work,
// Android 4.3 and below requires the element to be
@@ -414,10 +414,12 @@
$element.html(container.innerHTML);
this.start();
return spinnerName;
};
this.start = function() {
animations[loaderName] && animations[loaderName]($element[0])();
animations[spinnerName] && animations[spinnerName]($element[0])();
};
}]);

View File

@@ -54,11 +54,11 @@
* down, its progress would be `0.5`.
* @param {string=} pulling-icon The icon to display while the user is pulling down.
* Default: 'ion-android-arrow-down'.
* @param {string=} loader The {@link ionic.directive:ionLoader} icon to display
* after user lets go of the refresher. The SVG ionLoader is now the default, replacing
* rotating font icons.
* @param {string=} spinner The {@link ionic.directive:ionSpinner} icon to display
* after user lets go of the refresher. The SVG {@link ionic.directive:ionSpinner}
* is now the default, replacing rotating font icons.
* @param {string=} refreshing-icon The font icon to display after user lets go of the
* refresher. This is depreicated in favor of the SVG {@link ionic.directive:ionLoader}.
* refresher. This is depreicated in favor of the SVG {@link ionic.directive:ionSpinner}.
* @param {boolean=} disable-pulling-rotation Disables the rotation animation of the pulling
* icon when it reaches its activated threshold. To be used with a custom `pulling-icon`.
*
@@ -78,8 +78,8 @@ IonicModule
'</div>' +
'<div class="text-pulling" ng-bind-html="pullingText"></div>' +
'<div class="icon-refreshing">' +
'<ion-loader ng-if="showLoader" icon="{{loader}}"></ion-loader>' +
'<i ng-if="!showLoader" class="icon {{refreshingIcon}}"></i>' +
'<ion-spinner ng-if="showSpinner" icon="{{spinner}}"></ion-spinner>' +
'<i ng-if="!showSpinner" class="icon {{refreshingIcon}}"></i>' +
'</div>' +
'<div class="text-refreshing" ng-bind-html="refreshingText"></div>' +
'</div>' +
@@ -88,14 +88,14 @@ IonicModule
if (angular.isUndefined($attrs.pullingIcon)) {
$attrs.$set('pullingIcon', 'ion-android-arrow-down');
}
$scope.showLoader = angular.isUndefined($attrs.refreshingIcon);
$scope.showSpinner = angular.isUndefined($attrs.refreshingIcon);
$ionicBind($scope, $attrs, {
pullingIcon: '@',
pullingText: '@',
refreshingIcon: '@',
refreshingText: '@',
loader: '@',
spinner: '@',
disablePullingRotation: '@',
$onRefresh: '&onRefresh',
$onPulling: '&onPulling'

View File

@@ -1,20 +1,20 @@
/**
* @ngdoc directive
* @name ionLoader
* @name ionSpinner
* @module ionic
* @restrict E
*
* @description
* The `ionLoader` directive provides a variety of animated loaders, or spinners, if you
* will. The loader enables you to give your users feedback that the app is
* The `ionSpinner` directive provides a variety of animated spinners.
* Spinners enables you to give your users feedback that the app is
* processing/thinking/waiting/chillin' out, or whatever you'd like it to indicate.
* By default, the {@link ionic.directive:ionRefresher} feature uses this loader, rather
* By default, the {@link ionic.directive:ionRefresher} feature uses this spinner, rather
* than rotating font icons (previously included in [ionicons](http://ionicons.com/)).
* While font icons are great for simple or stationary graphics, they're not suited to
* provide great animations, which is why Ionic uses SVG instead.
*
* Ionic offers ten loaders out of the box, and by default, it will use the appropriate loader
* for the platform on which it's running. Under the hood, the `ionLoader` directive dynamically
* Ionic offers ten spinners out of the box, and by default, it will use the appropriate spinner
* for the platform on which it's running. Under the hood, the `ionSpinner` directive dynamically
* builds the required SVG element, which allows Ionic to provide all ten of the animated SVGs
* within 3KB.
*
@@ -24,7 +24,7 @@
* <code>android</code>
* </th>
* <td style="width:42px;height:42px;">
* <ion-loader icon="android" style="stroke:#4b8bf4;"></ion-loader>
* <ion-spinner icon="android" style="stroke:#4b8bf4;"></ion-spinner>
* </td>
* </tr>
* <tr>
@@ -32,7 +32,7 @@
* <code>ios</code>
* </th>
* <td style="width:42px;height:42px;">
* <ion-loader icon="ios" style="stroke:#69717d;"></ion-loader>
* <ion-spinner icon="ios" style="stroke:#69717d;"></ion-spinner>
* </td>
* </tr>
* <tr>
@@ -40,15 +40,7 @@
* <code>ios-small</code>
* </th>
* <td style="width:42px;height:42px;">
* <ion-loader icon="ios-small" style="stroke:#69717d;"></ion-loader>
* </td>
* </tr>
* <tr>
* <th style="vertical-align:middle">
* <code>blip</code>
* </th>
* <td style="width:42px;height:42px;">
* <ion-loader icon="blip" style="stroke:#333;"></ion-loader>
* <ion-spinner icon="ios-small" style="stroke:#69717d;"></ion-spinner>
* </td>
* </tr>
* <tr>
@@ -56,7 +48,7 @@
* <code>bubbles</code>
* </th>
* <td style="width:42px;height:42px;">
* <ion-loader icon="bubbles" style="stroke:#333;"></ion-loader>
* <ion-spinner icon="bubbles" style="stroke:#333;"></ion-spinner>
* </td>
* </tr>
* <tr>
@@ -64,7 +56,7 @@
* <code>circles</code>
* </th>
* <td style="width:42px;height:42px;">
* <ion-loader icon="circles" style="stroke:#333;"></ion-loader>
* <ion-spinner icon="circles" style="stroke:#333;"></ion-spinner>
* </td>
* </tr>
* <tr>
@@ -72,7 +64,7 @@
* <code>crescent</code>
* </th>
* <td style="width:42px;height:42px;">
* <ion-loader icon="crescent" style="stroke:#333;"></ion-loader>
* <ion-spinner icon="crescent" style="stroke:#333;"></ion-spinner>
* </td>
* </tr>
* <tr>
@@ -80,7 +72,7 @@
* <code>dots</code>
* </th>
* <td style="width:42px;height:42px;">
* <ion-loader icon="dots" style="stroke:#333;"></ion-loader>
* <ion-spinner icon="dots" style="stroke:#333;"></ion-spinner>
* </td>
* </tr>
* <tr>
@@ -88,7 +80,15 @@
* <code>lines</code>
* </th>
* <td style="width:42px;height:42px;">
* <ion-loader icon="lines" style="stroke:#333;"></ion-loader>
* <ion-spinner icon="lines" style="stroke:#333;"></ion-spinner>
* </td>
* </tr>
* <tr>
* <th style="vertical-align:middle">
* <code>ripple</code>
* </th>
* <td style="width:42px;height:42px;">
* <ion-spinner icon="ripple" style="stroke:#333;"></ion-spinner>
* </td>
* </tr>
* <tr>
@@ -96,30 +96,30 @@
* <code>spiral</code>
* </th>
* <td style="width:42px;height:42px;">
* <ion-loader icon="spiral" style="stroke:#333;"></ion-loader>
* <ion-spinner icon="spiral" style="stroke:#333;"></ion-spinner>
* </td>
* </tr>
* </table>
* <script src="http://code.ionicframework.com/nightly/js/ionic.bundle.min.js"></script>
*
* Each loader uses SVG with SMIL animations, however, the Android loader also uses JavaScript
* so it also works on Android 4.0-4.3. Additionally, each loader can be styled with CSS,
* Each spinner uses SVG with SMIL animations, however, the Android spinner also uses JavaScript
* so it also works on Android 4.0-4.3. Additionally, each spinner can be styled with CSS,
* and scaled to any size.
*
*
* @usage
* The following code would use the default loader for the platform it's running from. If it's neither
* 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
* <ion-loader></ion-loader>
* <ion-spinner></ion-spinner>
* ```
*
* By setting the `icon` attribute, you can specify which loader to use, no matter what
* By setting the `icon` attribute, you can specify which spinner to use, no matter what
* the platform is.
*
* ```html
* <ion-loader icon="spiral"></ion-loader>
* <ion-spinner icon="spiral"></ion-spinner>
* ```
*
* ## Styling SVG with CSS
@@ -128,21 +128,27 @@
* `fill` instead of `background-color`.
*
* ```css
* svg.loader {
* .spinner svg {
* width: 28px;
* height: 28px;
* stroke: #333;
* fill: #333;
* }
* ```
*
* By default, the spinners are designed to be above a light background color. If the spinner
* is going to be sitting on a dark background color you can add the `.spinner-inverse` CSS
* class to the directive.
*
*/
IonicModule
.directive('ionLoader', function() {
.directive('ionSpinner', function() {
return {
restrict: 'E',
controller: '$ionicLoader',
controller: '$ionicSpinner',
link: function($scope, $element, $attrs, ctrl) {
ctrl.init();
var spinnerName = ctrl.init();
$element.addClass('spinner spinner-' + spinnerName);
}
};
});

View File

@@ -1,28 +0,0 @@
/**
* Loaders (Spinners)
* --------------------------------------------------
*/
svg.loader {
width: 28px;
height: 28px;
stroke: #333;
fill: #333;
}
.loader-ios,
.loader-ios-small {
line {
stroke: #69717d;
}
}
.loader-android {
circle {
stroke: #4b8bf4;
}
}

45
scss/_spinner.scss Normal file
View File

@@ -0,0 +1,45 @@
/**
* Spinners
* --------------------------------------------------
*/
.spinner {
svg {
width: 28px;
height: 28px;
}
stroke: #444;
fill: #444;
&.spinner-inverse {
stroke: #fff;
fill: #fff;
}
}
.spinner-android {
stroke: #4b8bf4;
}
.spinner-ios,
.spinner-ios-small {
stroke: #69717d;
}
.spinner-spiral {
.stop1 {
stop-color: #fff;
stop-opacity: 0;
}
&.spinner-inverse {
.stop1 {
stop-color: #000;
}
.stop2 {
stop-color: #fff;
}
}
}

View File

@@ -28,7 +28,7 @@
"badge",
"slide-box",
"refresher",
"loaders",
"spinner",
// Forms
"form",

View File

@@ -80,13 +80,13 @@ describe('ionRefresher directive', function() {
expect(el[0].querySelector('.icon-pulling .super-icon')).toBeTruthy();
});
it('should have default loader', function() {
it('should have default spinner', function() {
var el = setup();
expect(el[0].querySelector('ion-loader')).toBeTruthy();
expect(el[0].querySelector('ion-spinner')).toBeTruthy();
});
it('should have loader', function() {
var el = setup('loader="android"');
expect(el[0].querySelector('.loader-android')).toBeTruthy();
it('should have spinner', function() {
var el = setup('spinner="android"');
expect(el[0].querySelector('.spinner-android')).toBeTruthy();
});
it('should allow custom refreshingIcon', function() {
var el = setup('refreshing-icon="monkey-icon"');