mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
Merge remote-tracking branch 'origin/master'
Conflicts: ionic/components/tap-click/ripple.ts
This commit is contained in:
27
demos/i18n/index.ts
Normal file
27
demos/i18n/index.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import {Component} from 'angular2/angular2';
|
||||
import {Control, ControlGroup} from 'angular2/forms';
|
||||
|
||||
import {IonicApp, App, Http} from 'ionic/ionic';
|
||||
|
||||
import {Translate, TranslatePipe} from 'ionic/ionic';
|
||||
|
||||
@App({
|
||||
templateUrl: 'main.html',
|
||||
pipes: [TranslatePipe]
|
||||
})
|
||||
class MyApp {
|
||||
constructor(app: IonicApp, trans: Translate) {
|
||||
this.app = app;
|
||||
this.trans = trans;
|
||||
|
||||
this.trans.translations('de', {
|
||||
'Location': 'lage'
|
||||
});
|
||||
|
||||
console.log(this.trans.translate('Location'));
|
||||
console.log(this.trans.translate('Location', 'de'));
|
||||
//this.trans.setLanguage('de');
|
||||
console.log(this.trans.translate('Location'));
|
||||
|
||||
}
|
||||
}
|
||||
5
demos/i18n/main.html
Normal file
5
demos/i18n/main.html
Normal file
@@ -0,0 +1,5 @@
|
||||
<ion-view>
|
||||
<ion-content>
|
||||
Hello! What is your {{ 'Location' | translate }}
|
||||
</ion-content>
|
||||
</ion-view>
|
||||
@@ -11,7 +11,7 @@ import {NavParams, NavController} from 'ionic/ionic';
|
||||
'<ion-content padding>' +
|
||||
'<h1>{{title}}</h1>' +
|
||||
'<p><button id="from1To2" secondary (click)="push()">(Push) Go to Second Page</button></p>' +
|
||||
'<p><button secondary [push-data]="pushData" [nav-push]="pushPage">(Nav-Push) Go to Second Page</button></p>' +
|
||||
'<p><button secondary [nav-push]="pushPage" [nav-params]="pushData">(Nav-Push) Go to Second Page</button></p>' +
|
||||
'<p><button danger (click)="setViews()">(setViews) Go to Third Page</button></p>' +
|
||||
'</ion-content>'
|
||||
})
|
||||
|
||||
@@ -408,6 +408,21 @@ export class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current time of the first animation
|
||||
* in the list. To get a specific time of an animation, call
|
||||
* subAnimationInstance.getCurrentTime()
|
||||
*/
|
||||
getCurrentTime() {
|
||||
if(this._chld.length > 0) {
|
||||
return this._chld[0].getCurrentTime();
|
||||
}
|
||||
if(this._ani.length > 0) {
|
||||
return this._ani[0].getCurrentTime();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
progressEnd(shouldComplete, rate=3) {
|
||||
let promises = [];
|
||||
|
||||
@@ -604,6 +619,10 @@ class Animate {
|
||||
}
|
||||
}
|
||||
|
||||
getCurrentTime() {
|
||||
return this.ani && this.ani.currentTime;
|
||||
}
|
||||
|
||||
playbackRate(value) {
|
||||
this.rate = value;
|
||||
if (this.ani) {
|
||||
|
||||
@@ -14,6 +14,7 @@ import {Popup} from '../popup/popup';
|
||||
import {FocusHolder} from '../form/focus-holder';
|
||||
import {Events} from '../../util/events';
|
||||
import {NavRegistry} from '../nav/nav-registry';
|
||||
import {Translate} from '../../translation/translate';
|
||||
|
||||
/**
|
||||
* @name IonicApp
|
||||
@@ -298,6 +299,8 @@ export function ionicBootstrap(rootComponentType, views, config) {
|
||||
let modal = new Modal(app, config);
|
||||
let popup = new Popup(app, config);
|
||||
let events = new Events();
|
||||
let translate = new Translate();
|
||||
console.log('Translate', translate);
|
||||
let navRegistry = new NavRegistry(views);
|
||||
|
||||
// add injectables that will be available to all child components
|
||||
@@ -312,6 +315,7 @@ export function ionicBootstrap(rootComponentType, views, config) {
|
||||
bind(Events).toValue(events),
|
||||
ROUTER_BINDINGS,
|
||||
bind(LocationStrategy).toClass(HashLocationStrategy),
|
||||
bind(Translate).toValue(translate),
|
||||
bind(NavRegistry).toValue(navRegistry)
|
||||
]);
|
||||
|
||||
|
||||
@@ -4,6 +4,16 @@ import {Animation} from '../../animations/animation';
|
||||
|
||||
|
||||
export class RippleActivator extends Activator {
|
||||
static TOUCH_DOWN_ACCEL = 512;
|
||||
static TOUCH_UP_ACCEL = 1024;
|
||||
static OPACITY_DECAY_VEL = 1.6;
|
||||
static OUTER_OPACITY_VEL = 1.2;
|
||||
|
||||
static OPACITY_OUT_DURATION = 750;
|
||||
|
||||
static EXPAND_OUT_PLAYBACK_RATE = 3.5;
|
||||
static DOWN_PLAYBACK_RATE = 0.65;
|
||||
static OPACITY_OUT_PLAYBACK_RATE = 1;
|
||||
|
||||
constructor(app, config) {
|
||||
super(app, config);
|
||||
@@ -17,7 +27,19 @@ export class RippleActivator extends Activator {
|
||||
super.downAction(ev, activatableEle, pointerX, pointerY);
|
||||
|
||||
// create a new ripple element
|
||||
let r = activatableEle.getBoundingClientRect();
|
||||
let r = targetEle.getBoundingClientRect();
|
||||
let w = r.width;
|
||||
let h = r.height;
|
||||
|
||||
let halfW = w/2;
|
||||
let halfH = h/2;
|
||||
let outerRadius = Math.sqrt(halfW * halfW + halfH * halfH);
|
||||
|
||||
let radiusDuration = (1000 * Math.sqrt(outerRadius / RippleActivator.TOUCH_DOWN_ACCEL) + 0.5);
|
||||
let outerDuration = 1000 * (1/RippleActivator.OUTER_OPACITY_VEL);
|
||||
|
||||
//console.log('Rippling', radiusDuration);
|
||||
|
||||
let x = Math.max(Math.abs(r.width - pointerX), pointerX) * 2;
|
||||
let y = Math.max(Math.abs(r.height - pointerY), pointerY) * 2;
|
||||
let size = (Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2))) - 10;
|
||||
@@ -34,14 +56,16 @@ export class RippleActivator extends Activator {
|
||||
activatableEle.appendChild(rippleEle);
|
||||
|
||||
let ripple = this.ripples[Date.now()] = { ele: rippleEle };
|
||||
ripple.outerRadius = outerRadius;
|
||||
ripple.radiusDuration = radiusDuration;
|
||||
|
||||
// expand the circle from the users starting point
|
||||
// start slow, and when they let up, then speed up the animation
|
||||
ripple.expand = new Animation(rippleEle, {renderDelay: 0});
|
||||
ripple.expand
|
||||
.fromTo('scale', '0.001', '1')
|
||||
.duration(300)
|
||||
.playbackRate(0.35)
|
||||
.duration(radiusDuration)
|
||||
.playbackRate(RippleActivator.DOWN_PLAYBACK_RATE)
|
||||
.onFinish(()=> {
|
||||
// finished expanding
|
||||
ripple.expand && ripple.expand.dispose();
|
||||
@@ -60,16 +84,26 @@ export class RippleActivator extends Activator {
|
||||
let ripple;
|
||||
for (let rippleId in this.ripples) {
|
||||
ripple = this.ripples[rippleId];
|
||||
if(ripple.expand) {
|
||||
let currentTime = ripple.expand.getCurrentTime();
|
||||
|
||||
// How much more time do we need to finish the radius animation?
|
||||
// Math: (radius/second) * ((total_radius_time) - current_time)
|
||||
let remainingTime = (ripple.outerRadius / ripple.radiusDuration) *
|
||||
((ripple.radiusDuration / RippleActivator.DOWN_PLAYBACK_RATE)- (currentTime));
|
||||
ripple.expand.remainingTime = remainingTime;
|
||||
}
|
||||
|
||||
if (!ripple.fade) {
|
||||
// ripple has not been let up yet
|
||||
// spped up the rate if the animation is still going
|
||||
setTimeout(() => {
|
||||
ripple.expand && ripple.expand.playbackRate(1);
|
||||
ripple.expand && ripple.expand.playbackRate(RippleActivator.EXPAND_OUT_PLAYBACK_RATE);
|
||||
ripple.fade = new Animation(ripple.ele);
|
||||
ripple.fade
|
||||
.fadeOut()
|
||||
.duration(750)
|
||||
.duration(ripple.epxand && ripple.expand.remaingTime || RippleActivator.OPACITY_OUT_DURATION)
|
||||
.playbackRate(RippleActivator.OPACITY_OUT_PLAYBACK_RATE)
|
||||
.onFinish(() => {
|
||||
ripple.fade && ripple.fade.dispose();
|
||||
ripple.fade = null;
|
||||
|
||||
@@ -24,3 +24,6 @@ export * from './transitions/ios-transition'
|
||||
export * from './transitions/md-transition'
|
||||
|
||||
export * from './platform/plugins'
|
||||
|
||||
export * from './translation/translate'
|
||||
export * from './translation/translate_pipe'
|
||||
|
||||
41
ionic/translation/translate.ts
Normal file
41
ionic/translation/translate.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import {Injectable} from 'angular2/angular2';
|
||||
|
||||
@Injectable()
|
||||
export class Translate {
|
||||
constructor() {
|
||||
this._transMap = {};
|
||||
}
|
||||
|
||||
translations(lang, map) {
|
||||
this._transMap[lang] = map;
|
||||
}
|
||||
|
||||
setLanguage(lang) {
|
||||
this._language = lang;
|
||||
}
|
||||
|
||||
getTranslations(lang) {
|
||||
return this._transMap[lang];
|
||||
}
|
||||
|
||||
translate(key, lang) {
|
||||
// If the language isn't specified and we have no overridden one, return the string passed.
|
||||
if(!lang && !this._language) {
|
||||
return key;
|
||||
}
|
||||
|
||||
let setLanguage = lang || this._language;
|
||||
|
||||
let map = this.getTranslations(setLanguage);
|
||||
|
||||
if(!map) {
|
||||
console.warn('I18N: No translation for key', key, 'using language', setLanguage);
|
||||
return '';
|
||||
}
|
||||
return this._getTranslation(map, key);
|
||||
}
|
||||
|
||||
_getTranslation(map, key) {
|
||||
return map && map[key] || '';
|
||||
}
|
||||
}
|
||||
30
ionic/translation/translate_pipe.ts
Normal file
30
ionic/translation/translate_pipe.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import {Injectable, Pipe, PipeTransform} from 'angular2/angular2';
|
||||
|
||||
import {Translate} from './translate';
|
||||
|
||||
/**
|
||||
* The Translate pipe makes it easy to translate strings.
|
||||
*
|
||||
* @usage
|
||||
* Translate using the current language or language set through Translate.setLanguage
|
||||
* {{ 'Please enter your location' | translate }}
|
||||
*
|
||||
* Translate using a specific language
|
||||
* {{ 'Please enter your location' | translate:"de" }}
|
||||
*/
|
||||
@Pipe({name: 'translate'})
|
||||
@Injectable()
|
||||
export class TranslatePipe implements PipeTransform {
|
||||
constructor(translate: Translate) {
|
||||
this.translate = translate;
|
||||
}
|
||||
transform(value, args) {
|
||||
let lang;
|
||||
if(args.length > 0) {
|
||||
lang = args[0];
|
||||
}
|
||||
return this.translate.translate(value, lang);
|
||||
}
|
||||
|
||||
supports(obj) { return true; }
|
||||
}
|
||||
Reference in New Issue
Block a user