Skip to content

Fix animations when content is flipped #8337

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Oct 29, 2020
269 changes: 265 additions & 4 deletions projects/igniteui-angular/src/lib/core/utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
import { Injectable, PLATFORM_ID, Inject } from '@angular/core';
import { AnimationReferenceMetadata } from '@angular/animations';
import { isPlatformBrowser } from '@angular/common';
import { Observable } from 'rxjs';
import { Inject, Injectable, PLATFORM_ID } from '@angular/core';
import merge from 'lodash.merge';
import ResizeObserver from 'resize-observer-polyfill';
import { Observable } from 'rxjs';
import {
blink, fadeIn, fadeOut, flipBottom, flipHorBck, flipHorFwd, flipLeft, flipRight, flipTop,
flipVerBck, flipVerFwd, growVerIn, growVerOut, heartbeat, pulsateBck, pulsateFwd, rotateInBl,
rotateInBottom, rotateInBr, rotateInCenter, rotateInDiagonal1, rotateInDiagonal2, rotateInHor,
rotateInLeft, rotateInRight, rotateInTl, rotateInTop, rotateInTr, rotateInVer, rotateOutBl,
rotateOutBottom, rotateOutBr, rotateOutCenter, rotateOutDiagonal1, rotateOutDiagonal2,
rotateOutHor, rotateOutLeft, rotateOutRight, rotateOutTl, rotateOutTop, rotateOutTr,
rotateOutVer, scaleInBl, scaleInBottom, scaleInBr, scaleInCenter, scaleInHorCenter,
scaleInHorLeft, scaleInHorRight, scaleInLeft, scaleInRight, scaleInTl, scaleInTop, scaleInTr,
scaleInVerBottom, scaleInVerCenter, scaleInVerTop, scaleOutBl, scaleOutBottom, scaleOutBr,
scaleOutCenter, scaleOutHorCenter, scaleOutHorLeft, scaleOutHorRight, scaleOutLeft,
scaleOutRight, scaleOutTl, scaleOutTop, scaleOutTr, scaleOutVerBottom, scaleOutVerCenter,
scaleOutVerTop, shakeBl, shakeBottom, shakeBr, shakeCenter, shakeHor, shakeLeft, shakeRight,
shakeTl, shakeTop, shakeTr, shakeVer, slideInBl, slideInBottom, slideInBr, slideInLeft,
slideInRight, slideInTl, slideInTop, slideInTr, slideOutBl, slideOutBottom, slideOutBr,
slideOutLeft, slideOutRight, slideOutTl, slideOutTop, slideOutTr, swingInBottomBck,
swingInBottomFwd, swingInLeftBck, swingInLeftFwd, swingInRightBck, swingInRightFwd,
swingInTopBck, swingInTopFwd, swingOutBottomBck, swingOutBottomFwd, swingOutLeftBck,
swingOutLefttFwd, swingOutRightBck, swingOutRightFwd, swingOutTopBck, swingOutTopFwd
} from '../animations/main';
import { setImmediate } from './setImmediate';
import merge from 'lodash.merge';

/**
* @hidden
Expand Down Expand Up @@ -395,7 +416,6 @@ export function resolveNestedPath(obj: any, path: string) {
return current;
}


/**
*
* Given a property access path in the format `x.y.z` and a value
Expand Down Expand Up @@ -451,3 +471,244 @@ export function yieldingLoop(count: number, chunkSize: number, callback: (index:
}

export function mkenum<T extends { [index: string]: U }, U extends string>(x: T) { return x; }

export function reverseAnimationResolver(animation: AnimationReferenceMetadata): AnimationReferenceMetadata {
return oppositeAnimation.get(animation) ?? animation;
}

export function isHorizontalAnimation(animation: AnimationReferenceMetadata): boolean {
return horizontalAnimations.includes(animation);
}

export function isVerticalAnimation(animation: AnimationReferenceMetadata): boolean {
return verticalAnimations.includes(animation);
}

const oppositeAnimation: Map<AnimationReferenceMetadata, AnimationReferenceMetadata> = new Map([
[fadeIn, fadeIn],
[fadeOut, fadeOut],
[flipTop, flipBottom],
[flipBottom, flipTop],
[flipRight, flipLeft],
[flipLeft, flipRight],
[flipHorFwd, flipHorBck],
[flipHorBck, flipHorFwd],
[flipVerFwd, flipVerBck],
[flipVerBck, flipVerFwd],
[growVerIn, growVerIn],
[growVerOut, growVerOut],
[heartbeat, heartbeat],
[pulsateFwd, pulsateBck],
[pulsateBck, pulsateFwd],
[blink, blink],
[shakeHor, shakeHor],
[shakeVer, shakeVer],
[shakeTop, shakeTop],
[shakeBottom, shakeBottom],
[shakeRight, shakeRight],
[shakeLeft, shakeLeft],
[shakeCenter, shakeCenter],
[shakeTr, shakeTr],
[shakeBr, shakeBr],
[shakeBl, shakeBl],
[shakeTl, shakeTl],
[rotateInCenter, rotateInCenter],
[rotateOutCenter, rotateOutCenter],
[rotateInTop, rotateInBottom],
[rotateOutTop, rotateOutBottom],
[rotateInRight, rotateInLeft],
[rotateOutRight, rotateOutLeft],
[rotateInLeft, rotateInRight],
[rotateOutLeft, rotateOutRight],
[rotateInBottom, rotateInTop],
[rotateOutBottom, rotateOutTop],
[rotateInTr, rotateInBl],
[rotateOutTr, rotateOutBl],
[rotateInBr, rotateInTl],
[rotateOutBr, rotateOutTl],
[rotateInBl, rotateInTr],
[rotateOutBl, rotateOutTr],
[rotateInTl, rotateInBr],
[rotateOutTl, rotateOutBr],
[rotateInDiagonal1, rotateInDiagonal1],
[rotateOutDiagonal1, rotateOutDiagonal1],
[rotateInDiagonal2, rotateInDiagonal2],
[rotateOutDiagonal2, rotateOutDiagonal2],
[rotateInHor, rotateInHor],
[rotateOutHor, rotateOutHor],
[rotateInVer, rotateInVer],
[rotateOutVer, rotateOutVer],
[scaleInTop, scaleInBottom],
[scaleOutTop, scaleOutBottom],
[scaleInRight, scaleInLeft],
[scaleOutRight, scaleOutLeft],
[scaleInBottom, scaleInTop],
[scaleOutBottom, scaleOutTop],
[scaleInLeft, scaleInRight],
[scaleOutLeft, scaleOutRight],
[scaleInCenter, scaleInCenter],
[scaleOutCenter, scaleOutCenter],
[scaleInTr, scaleInBl],
[scaleOutTr, scaleOutBl],
[scaleInBr, scaleInTl],
[scaleOutBr, scaleOutTl],
[scaleInBl, scaleInTr],
[scaleOutBl, scaleOutTr],
[scaleInTl, scaleInBr],
[scaleOutTl, scaleOutBr],
[scaleInVerTop, scaleInVerBottom],
[scaleOutVerTop, scaleOutVerBottom],
[scaleInVerBottom, scaleInVerTop],
[scaleOutVerBottom, scaleOutVerTop],
[scaleInVerCenter, scaleInVerCenter],
[scaleOutVerCenter, scaleOutVerCenter],
[scaleInHorCenter, scaleInHorCenter],
[scaleOutHorCenter, scaleOutHorCenter],
[scaleInHorLeft, scaleInHorRight],
[scaleOutHorLeft, scaleOutHorRight],
[scaleInHorRight, scaleInHorLeft],
[scaleOutHorRight, scaleOutHorLeft],
[slideInTop, slideInBottom],
[slideOutTop, slideOutBottom],
[slideInRight, slideInLeft],
[slideOutRight, slideOutLeft],
[slideInBottom, slideInTop],
[slideOutBottom, slideOutTop],
[slideInLeft, slideInRight],
[slideOutLeft, slideOutRight],
[slideInTr, slideInBl],
[slideOutTr, slideOutBl],
[slideInBr, slideInTl],
[slideOutBr, slideOutTl],
[slideInBl, slideInTr],
[slideOutBl, slideOutTr],
[slideInTl, slideInBr],
[slideOutTl, slideOutBr],
[swingInTopFwd, swingInBottomFwd],
[swingOutTopFwd, swingOutBottomFwd],
[swingInRightFwd, swingInLeftFwd],
[swingOutRightFwd, swingOutLefttFwd],
[swingInLeftFwd, swingInRightFwd],
[swingOutLefttFwd, swingOutRightFwd],
[swingInBottomFwd, swingInTopFwd],
[swingOutBottomFwd, swingOutTopFwd],
[swingInTopBck, swingInBottomBck],
[swingOutTopBck, swingOutBottomBck],
[swingInRightBck, swingInLeftBck],
[swingOutRightBck, swingOutLeftBck],
[swingInBottomBck, swingInTopBck],
[swingOutBottomBck, swingOutTopBck],
[swingInLeftBck, swingInRightBck],
[swingOutLeftBck, swingOutRightBck],
]);

const horizontalAnimations: AnimationReferenceMetadata[] = [
flipRight,
flipLeft,
flipVerFwd,
flipVerBck,
rotateInRight,
rotateOutRight,
rotateInLeft,
rotateOutLeft,
rotateInTr,
rotateOutTr,
rotateInBr,
rotateOutBr,
rotateInBl,
rotateOutBl,
rotateInTl,
rotateOutTl,
scaleInRight,
scaleOutRight,
scaleInLeft,
scaleOutLeft,
scaleInTr,
scaleOutTr,
scaleInBr,
scaleOutBr,
scaleInBl,
scaleOutBl,
scaleInTl,
scaleOutTl,
scaleInHorLeft,
scaleOutHorLeft,
scaleInHorRight,
scaleOutHorRight,
slideInRight,
slideOutRight,
slideInLeft,
slideOutLeft,
slideInTr,
slideOutTr,
slideInBr,
slideOutBr,
slideInBl,
slideOutBl,
slideInTl,
slideOutTl,
swingInRightFwd,
swingOutRightFwd,
swingInLeftFwd,
swingOutLefttFwd,
swingInRightBck,
swingOutRightBck,
swingInLeftBck,
swingOutLeftBck,
];
const verticalAnimations: AnimationReferenceMetadata[] = [
flipTop,
flipBottom,
flipHorFwd,
flipHorBck,
growVerIn,
growVerOut,
rotateInTop,
rotateOutTop,
rotateInBottom,
rotateOutBottom,
rotateInTr,
rotateOutTr,
rotateInBr,
rotateOutBr,
rotateInBl,
rotateOutBl,
rotateInTl,
rotateOutTl,
scaleInTop,
scaleOutTop,
scaleInBottom,
scaleOutBottom,
scaleInTr,
scaleOutTr,
scaleInBr,
scaleOutBr,
scaleInBl,
scaleOutBl,
scaleInTl,
scaleOutTl,
scaleInVerTop,
scaleOutVerTop,
scaleInVerBottom,
scaleOutVerBottom,
slideInTop,
slideOutTop,
slideInBottom,
slideOutBottom,
slideInTr,
slideOutTr,
slideInBr,
slideOutBr,
slideInBl,
slideOutBl,
slideInTl,
slideOutTl,
swingInTopFwd,
swingOutTopFwd,
swingInBottomFwd,
swingOutBottomFwd,
swingInTopBck,
swingOutTopBck,
swingInBottomBck,
swingOutBottomBck,
];
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { VerticalAlignment, HorizontalAlignment, ConnectedFit } from './../utilities';
import { AnimationReferenceMetadata } from '@angular/animations';
import { isHorizontalAnimation, isVerticalAnimation, reverseAnimationResolver } from '../../../core/utils';
import { ConnectedFit, HorizontalAlignment, VerticalAlignment } from './../utilities';
import { BaseFitPositionStrategy } from './base-fit-position-strategy';

/**
Expand All @@ -13,6 +15,7 @@ export class AutoPositionStrategy extends BaseFitPositionStrategy {
if (connectedFit.fitHorizontal.back < 0 || connectedFit.fitHorizontal.forward < 0) {
if (this.canFlipHorizontal(connectedFit)) {
this.flipHorizontal();
this.flipAnimation(FlipDirection.horizontal);
} else {
const horizontalPush = this.horizontalPush(connectedFit);
transformString.push(`translateX(${horizontalPush}px)`);
Expand All @@ -22,6 +25,7 @@ export class AutoPositionStrategy extends BaseFitPositionStrategy {
if (connectedFit.fitVertical.back < 0 || connectedFit.fitVertical.forward < 0) {
if (this.canFlipVertical(connectedFit)) {
this.flipVertical();
this.flipAnimation(FlipDirection.vertical);
} else {
const verticalPush = this.verticalPush(connectedFit);
transformString.push(`translateY(${verticalPush}px)`);
Expand Down Expand Up @@ -150,4 +154,45 @@ export class AutoPositionStrategy extends BaseFitPositionStrategy {
return 0;
}
}

/**
* Changes open and close animation with reverse animation if one exists
* @param flipDirection direction for which to change the animations
*/
private flipAnimation(flipDirection: FlipDirection): void {
if (this.settings.openAnimation) {
this.settings.openAnimation = this.updateAnimation(this.settings.openAnimation, flipDirection);
}
if (this.settings.closeAnimation) {
this.settings.closeAnimation = this.updateAnimation(this.settings.closeAnimation, flipDirection);
}
}

/**
* Tries to find the reverse animation according to provided direction
* @param animation animation to update
* @param direction required animation direction
* @returns reverse animation in given direction if one exists
*/
private updateAnimation(animation: AnimationReferenceMetadata, direction: FlipDirection): AnimationReferenceMetadata {
switch (direction) {
case FlipDirection.horizontal:
if (isHorizontalAnimation(animation)) {
return reverseAnimationResolver(animation);
}
break;
case FlipDirection.vertical:
if (isVerticalAnimation(animation)) {
return reverseAnimationResolver(animation);
}
break;
}

return animation;
}
}

enum FlipDirection {
horizontal,
vertical
}
5 changes: 5 additions & 0 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,11 @@ export class AppComponent implements OnInit {
].sort((componentLink1, componentLink2) => componentLink1.name > componentLink2.name ? 1 : -1);

styleLinks = [
{
link: '/animations',
icon: 'color_lens',
name: 'Animations'
},
{
link: '/colors',
icon: 'color_lens',
Expand Down
2 changes: 2 additions & 0 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ import { GridColumnActionsSampleComponent } from './grid-column-actions/grid-col
import { IgxColumnGroupingDirective } from './grid-column-actions/custom-action-directive';
import { GridAddRowSampleComponent } from './grid-add-row/grid-add-row.sample';
import { HierarchicalGridAddRowSampleComponent } from './hierarchical-grid-add-row/hierarchical-grid-add-row.sample';
import { AnimationsSampleComponent } from './styleguide/animations/animations.sample';

const components = [
ActionStripSampleComponent,
Expand Down Expand Up @@ -228,6 +229,7 @@ const components = [
TreeGridLoadOnDemandSampleComponent,
CustomContentComponent,
ColorsSampleComponent,
AnimationsSampleComponent,
ShadowsSampleComponent,
TypographySampleComponent,
RadioSampleComponent,
Expand Down
Loading