feat(ripple): better ripple

This commit is contained in:
Max Lynch
2015-09-25 11:18:16 -05:00
parent 7601c9fd2b
commit 60f4d65e63
2 changed files with 57 additions and 4 deletions

View File

@@ -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.currentTime;
}
playbackRate(value) {
this.rate = value;
if (this.ani) {

View File

@@ -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 = 2;
static DOWN_PLAYBACK_RATE = 0.45;
static OPACITY_OUT_PLAYBACK_RATE = 1;
constructor(app, config) {
super(app, config);
@@ -17,6 +27,18 @@ export class RippleActivator extends Activator {
// create a new ripple element
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;
@@ -33,14 +55,16 @@ export class RippleActivator extends Activator {
targetEle.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();
@@ -59,16 +83,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;