Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

Commit bee04f3

Browse files
crisbetohansl
authored andcommitted
feat(panel): configurable animation duration (#9570)
* Adds the ability to specify the duration of an animation the panel. * Fixes the `MdPanelAnimation` not showing up in the docs. Fixes #9177.
1 parent d81ca23 commit bee04f3

File tree

5 files changed

+142
-16
lines changed

5 files changed

+142
-16
lines changed

src/components/panel/demoPanelAnimations/index.html

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
<div class="demo-md-panel-animation md-padding" ng-controller="AnimationCtrl as ctrl">
22
<h2>Animations</h2>
33
<div layout="row">
4-
<div flex="33">
5-
OpenFrom:
4+
<div flex="25">
5+
<h3>OpenFrom:</h3>
66
<md-radio-group ng-model="ctrl.openFrom">
77
<md-radio-button value="button">Button</md-radio-button>
88
<md-radio-button value="corner">Top/Left Corner</md-radio-button>
99
<md-radio-button value="bottom">Bottom Center</md-radio-button>
1010
</md-radio-group>
1111
</div>
1212

13-
<div flex="33">
14-
CloseTo:
13+
<div flex="25">
14+
<h3>CloseTo:</h3>
1515
<md-radio-group ng-model="ctrl.closeTo">
1616
<md-radio-button value="button">Button</md-radio-button>
1717
<md-radio-button value="corner">Top/Left Corner</md-radio-button>
1818
<md-radio-button value="bottom">Bottom Center</md-radio-button>
1919
</md-radio-group>
2020
</div>
2121

22-
<div flex="33">
23-
AnimationType:
22+
<div flex="25">
23+
<h3>AnimationType:</h3>
2424
<md-radio-group ng-model="ctrl.animationType">
2525
<md-radio-button value="none">None</md-radio-button>
2626
<md-radio-button value="slide">Slide</md-radio-button>
@@ -29,6 +29,33 @@ <h2>Animations</h2>
2929
<md-radio-button value="custom">Custom</md-radio-button>
3030
</md-radio-group>
3131
</div>
32+
33+
<div flex="25">
34+
<h3>Duration:</h3>
35+
<md-input-container>
36+
<label>All animations</label>
37+
<input
38+
type="number"
39+
ng-model="ctrl.duration"
40+
ng-change="ctrl.separateDurations.open = ctrl.separateDurations.close = ctrl.duration">
41+
</md-input-container>
42+
43+
<md-input-container>
44+
<label>Open animation</label>
45+
<input
46+
type="number"
47+
ng-model="ctrl.separateDurations.open"
48+
ng-change="ctrl.duration = null">
49+
</md-input-container>
50+
51+
<md-input-container>
52+
<label>Close animation</label>
53+
<input
54+
type="number"
55+
ng-model="ctrl.separateDurations.close"
56+
ng-change="ctrl.duration = null">
57+
</md-input-container>
58+
</div>
3259
</div>
3360

3461
<div class="demo-md-panel-content">

src/components/panel/demoPanelAnimations/script.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@ function AnimationCtrl($mdPanel) {
1010
this._mdPanel = $mdPanel;
1111
this.openFrom = 'button';
1212
this.closeTo = 'button';
13-
this.animationType = 'none';
13+
this.animationType = 'scale';
14+
this.duration = 300;
15+
this.separateDurations = {
16+
open: this.duration,
17+
close: this.duration
18+
};
1419
}
1520

1621

@@ -22,6 +27,8 @@ AnimationCtrl.prototype.showDialog = function() {
2227

2328
var animation = this._mdPanel.newPanelAnimation();
2429

30+
animation.duration(this.duration || this.separateDurations);
31+
2532
switch(this.openFrom) {
2633
case 'button':
2734
animation.openFrom('.animation-target');

src/components/panel/panel.js

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -636,24 +636,27 @@ angular
636636
* MdPanelAnimation *
637637
*****************************************************************************/
638638

639-
640639
/**
641640
* @ngdoc type
642641
* @name MdPanelAnimation
642+
* @module material.components.panel
643643
* @description
644644
* Animation configuration object. To use, create an MdPanelAnimation with the
645645
* desired properties, then pass the object as part of $mdPanel creation.
646646
*
647-
* Example:
647+
* @usage
648648
*
649+
* <hljs lang="js">
649650
* var panelAnimation = new MdPanelAnimation()
650651
* .openFrom(myButtonEl)
652+
* .duration(1337)
651653
* .closeTo('.my-button')
652654
* .withAnimation($mdPanel.animation.SCALE);
653655
*
654656
* $mdPanel.create({
655657
* animation: panelAnimation
656658
* });
659+
* </hljs>
657660
*/
658661

659662
/**
@@ -702,6 +705,18 @@ angular
702705
* @returns {!MdPanelAnimation}
703706
*/
704707

708+
/**
709+
* @ngdoc method
710+
* @name MdPanelAnimation#duration
711+
* @description
712+
* Specifies the duration of the animation in milliseconds. The `duration`
713+
* method accepts either a number or an object with separate open and close
714+
* durations.
715+
*
716+
* @param {number|{open: number, close: number}} duration
717+
* @returns {!MdPanelAnimation}
718+
*/
719+
705720

706721
/*****************************************************************************
707722
* IMPLEMENTATION *
@@ -1466,13 +1481,19 @@ MdPanelRef.prototype._createBackdrop = function() {
14661481
open: '_md-opaque-enter',
14671482
close: '_md-opaque-leave'
14681483
});
1484+
1485+
if (this.config.animation) {
1486+
backdropAnimation.duration(this.config.animation._rawDuration);
1487+
}
1488+
14691489
var backdropConfig = {
14701490
animation: backdropAnimation,
14711491
attachTo: this.config.attachTo,
14721492
focusOnOpen: false,
14731493
panelClass: '_md-panel-backdrop',
14741494
zIndex: this.config.zIndex - 1
14751495
};
1496+
14761497
this._backdropRef = this._$mdPanel.create(backdropConfig);
14771498
}
14781499
if (!this._backdropRef.isAttached) {
@@ -1610,7 +1631,7 @@ MdPanelRef.prototype._configureScrollListener = function() {
16101631
* @private
16111632
*/
16121633
MdPanelRef.prototype._configureTrapFocus = function() {
1613-
// Focus doesn't remain instead of the panel without this.
1634+
// Focus doesn't remain inside of the panel without this.
16141635
this.panelEl.attr('tabIndex', '-1');
16151636
if (this.config['trapFocus']) {
16161637
var element = this.panelEl;
@@ -2449,6 +2470,15 @@ function MdPanelAnimation($injector) {
24492470

24502471
/** @private {string|{open: string, close: string}} */
24512472
this._animationClass = '';
2473+
2474+
/** @private {number} */
2475+
this._openDuration;
2476+
2477+
/** @private {number} */
2478+
this._closeDuration;
2479+
2480+
/** @private {number|{open: number, close: number}} */
2481+
this._rawDuration;
24522482
}
24532483

24542484

@@ -2496,6 +2526,30 @@ MdPanelAnimation.prototype.closeTo = function(closeTo) {
24962526
return this;
24972527
};
24982528

2529+
/**
2530+
* Specifies the duration of the animation in milliseconds.
2531+
* @param {number|{open: number, close: number}} duration
2532+
* @returns {!MdPanelAnimation}
2533+
*/
2534+
MdPanelAnimation.prototype.duration = function(duration) {
2535+
if (duration) {
2536+
if (angular.isNumber(duration)) {
2537+
this._openDuration = this._closeDuration = toSeconds(duration);
2538+
} else if (angular.isObject(duration)) {
2539+
this._openDuration = toSeconds(duration.open);
2540+
this._closeDuration = toSeconds(duration.close);
2541+
}
2542+
}
2543+
2544+
// Save the original value so it can be passed to the backdrop.
2545+
this._rawDuration = duration;
2546+
2547+
return this;
2548+
2549+
function toSeconds(value) {
2550+
if (angular.isNumber(value)) return value / 1000;
2551+
}
2552+
};
24992553

25002554
/**
25012555
* Returns the element and bounds for the animation target.
@@ -2598,6 +2652,8 @@ MdPanelAnimation.prototype.animateOpen = function(panelEl) {
25982652
}
25992653
}
26002654

2655+
animationOptions.duration = this._openDuration;
2656+
26012657
return animator
26022658
.translate3d(panelEl, openFrom, openTo, animationOptions);
26032659
};
@@ -2661,6 +2717,8 @@ MdPanelAnimation.prototype.animateClose = function(panelEl) {
26612717
}
26622718
}
26632719

2720+
reverseAnimationOptions.duration = this._closeDuration;
2721+
26642722
return animator
26652723
.translate3d(panelEl, closeFrom, closeTo, reverseAnimationOptions);
26662724
};

src/components/panel/panel.spec.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2211,6 +2211,38 @@ describe('$mdPanel', function() {
22112211
expect(animation._closeTo.bounds).toEqual(inputRect);
22122212
});
22132213
});
2214+
2215+
describe('should determine the animation duration when', function() {
2216+
it('provided a value in milliseconds', function() {
2217+
var animation = mdPanelAnimation.duration(1300);
2218+
2219+
expect(animation._openDuration).toBe(1.3);
2220+
});
2221+
2222+
it('provided a number', function() {
2223+
var animation = mdPanelAnimation.duration(2000);
2224+
2225+
expect(animation._openDuration).toEqual(animation._closeDuration);
2226+
expect(animation._openDuration).toBe(2);
2227+
});
2228+
2229+
it('provided an object', function() {
2230+
var animation = mdPanelAnimation.duration({
2231+
open: 1200,
2232+
close: 600
2233+
});
2234+
2235+
expect(animation._openDuration).toBe(1.2);
2236+
expect(animation._closeDuration).toBe(0.6);
2237+
});
2238+
2239+
it('provided an invalid value', function() {
2240+
var animation = mdPanelAnimation.duration('very fast');
2241+
2242+
expect(animation._openDuration).toBeFalsy();
2243+
expect(animation._closeDuration).toBeFalsy();
2244+
});
2245+
});
22142246
});
22152247

22162248
describe('interceptor logic: ', function() {

src/core/util/animation/animate.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@ function AnimateDomUtils($mdUtil, $q, $timeout, $mdConstant, $animateCss) {
2121
*
2222
*/
2323
translate3d : function( target, from, to, options ) {
24-
return $animateCss(target,{
25-
from:from,
26-
to:to,
27-
addClass:options.transitionInClass,
28-
removeClass:options.transitionOutClass
24+
return $animateCss(target, {
25+
from: from,
26+
to: to,
27+
addClass: options.transitionInClass,
28+
removeClass: options.transitionOutClass,
29+
duration: options.duration
2930
})
3031
.start()
3132
.then(function(){
@@ -40,7 +41,8 @@ function AnimateDomUtils($mdUtil, $q, $timeout, $mdConstant, $animateCss) {
4041
return $animateCss(target, {
4142
to: newFrom || from,
4243
addClass: options.transitionOutClass,
43-
removeClass: options.transitionInClass
44+
removeClass: options.transitionInClass,
45+
duration: options.duration
4446
}).start();
4547

4648
}

0 commit comments

Comments
 (0)