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
150 changes: 146 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,125 @@ 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;
}

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],
]);
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { VerticalAlignment, HorizontalAlignment, ConnectedFit } from './../utilities';
import { reverseAnimationResolver } from '../../../core/utils';
import { ConnectedFit, HorizontalAlignment, VerticalAlignment } from './../utilities';
import { BaseFitPositionStrategy } from './base-fit-position-strategy';

/**
Expand All @@ -10,9 +11,12 @@ export class AutoPositionStrategy extends BaseFitPositionStrategy {
/** @inheritdoc */
protected fitInViewport(element: HTMLElement, connectedFit: ConnectedFit) {
const transformString: string[] = [];
let flipped = false;
if (connectedFit.fitHorizontal.back < 0 || connectedFit.fitHorizontal.forward < 0) {
if (this.canFlipHorizontal(connectedFit)) {
this.flipHorizontal();
this.flipAnimation();
flipped = true;
} else {
const horizontalPush = this.horizontalPush(connectedFit);
transformString.push(`translateX(${horizontalPush}px)`);
Expand All @@ -22,6 +26,9 @@ export class AutoPositionStrategy extends BaseFitPositionStrategy {
if (connectedFit.fitVertical.back < 0 || connectedFit.fitVertical.forward < 0) {
if (this.canFlipVertical(connectedFit)) {
this.flipVertical();
if (!flipped) {
this.flipAnimation();
}
} else {
const verticalPush = this.verticalPush(connectedFit);
transformString.push(`translateY(${verticalPush}px)`);
Expand Down Expand Up @@ -150,4 +157,16 @@ export class AutoPositionStrategy extends BaseFitPositionStrategy {
return 0;
}
}

/**
* Changes open and close animation with opposite animation if one exists
*/
private flipAnimation() {
if (this.settings.openAnimation) {
this.settings.openAnimation = reverseAnimationResolver(this.settings.openAnimation);
}
if (this.settings.closeAnimation) {
this.settings.closeAnimation = reverseAnimationResolver(this.settings.closeAnimation);
}
}
}
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
6 changes: 5 additions & 1 deletion src/app/app.routing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ import { GridNestedPropsSampleComponent } from './grid-nested-props/grid-nested-
import { GridColumnActionsSampleComponent } from './grid-column-actions/grid-column-actions.sample';
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 appRoutes = [
{
Expand Down Expand Up @@ -202,11 +203,14 @@ const appRoutes = [
path: 'snackbar',
component: SnackbarSampleComponent
},

{
path: 'colors',
component: ColorsSampleComponent
},
{
path: 'animations',
component: AnimationsSampleComponent
},
{
path: 'shadows',
component: ShadowsSampleComponent
Expand Down
5 changes: 5 additions & 0 deletions src/app/routing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ import { GridNestedPropsSampleComponent } from './grid-nested-props/grid-nested-
import { GridColumnActionsSampleComponent } from './grid-column-actions/grid-column-actions.sample';
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 appRoutes = [
{
Expand Down Expand Up @@ -291,6 +292,10 @@ const appRoutes = [
path: 'colors',
component: ColorsSampleComponent
},
{
path: 'animations',
component: AnimationsSampleComponent
},
{
path: 'shadows',
component: ShadowsSampleComponent
Expand Down
35 changes: 35 additions & 0 deletions src/app/styleguide/animations/animations.sample.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<div class="sample-wrapper">
<article class="sample-column">
<h4 class="sample-title">Animations categories</h4>
<div>
<igx-list (onItemClicked)="categoryItemClicked($event)">
<igx-list-item
igxRipple
*ngFor="let category of animationsCategories"
>
<p>{{ category }}</p>
</igx-list-item>
</igx-list>
</div>
</article>
<article class="sample-column">
<h4 class="sample-title">Animations</h4>
<div>
<igx-list (onItemClicked)="playAnimation($event)">
<igx-list-item igxRipple *ngFor="let animation of animations">
<p>{{ animation.name }}</p>
</igx-list-item>
</igx-list>
</div>
</article>
<igx-dialog
#dialog
title="This dialog uses custom animations"
message="Click the button or outside to close"
class="custom-dialog"
rightButtonLabel="Close"
(onRightButtonSelect)="dialog.close()"
>
</igx-dialog>
</div>

8 changes: 8 additions & 0 deletions src/app/styleguide/animations/animations.sample.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.sample-wrapper {
display: flex;
}

.sample-title {
margin-left: 8px;
}

Loading