mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
refactor(spinners): rename loaders to spinners
This commit is contained in:
@@ -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">
|
||||
|
||||
@@ -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])();
|
||||
};
|
||||
|
||||
}]);
|
||||
16
js/angular/directive/refresher.js
vendored
16
js/angular/directive/refresher.js
vendored
@@ -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'
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -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
45
scss/_spinner.scss
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"badge",
|
||||
"slide-box",
|
||||
"refresher",
|
||||
"loaders",
|
||||
"spinner",
|
||||
|
||||
// Forms
|
||||
"form",
|
||||
|
||||
@@ -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"');
|
||||
|
||||
Reference in New Issue
Block a user