Transitions in Angular












16















I have created a Layout Manager in Angular which can take in Components and then Display it in View and add animations to it while each component is shown in View and Goes out of view .



At a single instance of time either one panel or max of two panels can be shown in view .



This is the Stackblitz link to the Same the problem with this is the transitions are not smooth and also it does appear as streamlined as it should be the design is as follows .



Design



Now what i am trying to achieve is when the app is loaded 1-2 are shown by default but as i change the panels the transitions change like for eg



1-3 as 2 is moving out of view it should slide left and easeout and 3 should should in and ease out. and then if from 1-3 we go to 2-3 1 should ease out to the right and 2 should slide in .



Also the panels can take some percentages(33 %, 66% or 100% ) of the screen width .



I am not sure if i am able to explain it properly I have been stuck on this for weeks with transitions if anyone can help it will be awesome, Thanks



Thanks to Saddam who helped create this Animation this is exactly what i want from animations - https://imgur.com/a/qZ3vtDb this is for visual purpose only










share|improve this question

























  • Please explain more about your issue, for ex 1-2 is panel1 and panel2 what should happen to them when page is loaded, how the transition would be.

    – Just code
    Dec 27 '18 at 5:32











  • When the page loads we can have a transition from left to right or simply have no transitions when the page loads first time after then the transition starts depending upon which panel is in and out of view

    – Rahul Singh
    Dec 27 '18 at 5:36











  • Have you tried angular animations?

    – Sergey
    Dec 31 '18 at 12:10






  • 3





    Unfortunately I haven't managed to understand what exactly you want to achieve except of some kind of animation. However, you could try to learn Angular Animations it should help blog.angularindepth.com/… . Also if you made a some kind of animations (in any graphical editor) there is a chance that we would better understand your desire.

    – Sergey
    Dec 31 '18 at 12:17













  • i have looked into animations in a lot of detail and gone through it several times and i agree with you a graphical animation will be really help ful i will try and see it this is possible as i am not versed in any graphical editors

    – Rahul Singh
    Jan 2 at 6:45


















16















I have created a Layout Manager in Angular which can take in Components and then Display it in View and add animations to it while each component is shown in View and Goes out of view .



At a single instance of time either one panel or max of two panels can be shown in view .



This is the Stackblitz link to the Same the problem with this is the transitions are not smooth and also it does appear as streamlined as it should be the design is as follows .



Design



Now what i am trying to achieve is when the app is loaded 1-2 are shown by default but as i change the panels the transitions change like for eg



1-3 as 2 is moving out of view it should slide left and easeout and 3 should should in and ease out. and then if from 1-3 we go to 2-3 1 should ease out to the right and 2 should slide in .



Also the panels can take some percentages(33 %, 66% or 100% ) of the screen width .



I am not sure if i am able to explain it properly I have been stuck on this for weeks with transitions if anyone can help it will be awesome, Thanks



Thanks to Saddam who helped create this Animation this is exactly what i want from animations - https://imgur.com/a/qZ3vtDb this is for visual purpose only










share|improve this question

























  • Please explain more about your issue, for ex 1-2 is panel1 and panel2 what should happen to them when page is loaded, how the transition would be.

    – Just code
    Dec 27 '18 at 5:32











  • When the page loads we can have a transition from left to right or simply have no transitions when the page loads first time after then the transition starts depending upon which panel is in and out of view

    – Rahul Singh
    Dec 27 '18 at 5:36











  • Have you tried angular animations?

    – Sergey
    Dec 31 '18 at 12:10






  • 3





    Unfortunately I haven't managed to understand what exactly you want to achieve except of some kind of animation. However, you could try to learn Angular Animations it should help blog.angularindepth.com/… . Also if you made a some kind of animations (in any graphical editor) there is a chance that we would better understand your desire.

    – Sergey
    Dec 31 '18 at 12:17













  • i have looked into animations in a lot of detail and gone through it several times and i agree with you a graphical animation will be really help ful i will try and see it this is possible as i am not versed in any graphical editors

    – Rahul Singh
    Jan 2 at 6:45
















16












16








16


2






I have created a Layout Manager in Angular which can take in Components and then Display it in View and add animations to it while each component is shown in View and Goes out of view .



At a single instance of time either one panel or max of two panels can be shown in view .



This is the Stackblitz link to the Same the problem with this is the transitions are not smooth and also it does appear as streamlined as it should be the design is as follows .



Design



Now what i am trying to achieve is when the app is loaded 1-2 are shown by default but as i change the panels the transitions change like for eg



1-3 as 2 is moving out of view it should slide left and easeout and 3 should should in and ease out. and then if from 1-3 we go to 2-3 1 should ease out to the right and 2 should slide in .



Also the panels can take some percentages(33 %, 66% or 100% ) of the screen width .



I am not sure if i am able to explain it properly I have been stuck on this for weeks with transitions if anyone can help it will be awesome, Thanks



Thanks to Saddam who helped create this Animation this is exactly what i want from animations - https://imgur.com/a/qZ3vtDb this is for visual purpose only










share|improve this question
















I have created a Layout Manager in Angular which can take in Components and then Display it in View and add animations to it while each component is shown in View and Goes out of view .



At a single instance of time either one panel or max of two panels can be shown in view .



This is the Stackblitz link to the Same the problem with this is the transitions are not smooth and also it does appear as streamlined as it should be the design is as follows .



Design



Now what i am trying to achieve is when the app is loaded 1-2 are shown by default but as i change the panels the transitions change like for eg



1-3 as 2 is moving out of view it should slide left and easeout and 3 should should in and ease out. and then if from 1-3 we go to 2-3 1 should ease out to the right and 2 should slide in .



Also the panels can take some percentages(33 %, 66% or 100% ) of the screen width .



I am not sure if i am able to explain it properly I have been stuck on this for weeks with transitions if anyone can help it will be awesome, Thanks



Thanks to Saddam who helped create this Animation this is exactly what i want from animations - https://imgur.com/a/qZ3vtDb this is for visual purpose only







angular css-transitions angular-animations






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 4 at 9:22







Rahul Singh

















asked Dec 24 '18 at 7:18









Rahul SinghRahul Singh

10.5k32149




10.5k32149













  • Please explain more about your issue, for ex 1-2 is panel1 and panel2 what should happen to them when page is loaded, how the transition would be.

    – Just code
    Dec 27 '18 at 5:32











  • When the page loads we can have a transition from left to right or simply have no transitions when the page loads first time after then the transition starts depending upon which panel is in and out of view

    – Rahul Singh
    Dec 27 '18 at 5:36











  • Have you tried angular animations?

    – Sergey
    Dec 31 '18 at 12:10






  • 3





    Unfortunately I haven't managed to understand what exactly you want to achieve except of some kind of animation. However, you could try to learn Angular Animations it should help blog.angularindepth.com/… . Also if you made a some kind of animations (in any graphical editor) there is a chance that we would better understand your desire.

    – Sergey
    Dec 31 '18 at 12:17













  • i have looked into animations in a lot of detail and gone through it several times and i agree with you a graphical animation will be really help ful i will try and see it this is possible as i am not versed in any graphical editors

    – Rahul Singh
    Jan 2 at 6:45





















  • Please explain more about your issue, for ex 1-2 is panel1 and panel2 what should happen to them when page is loaded, how the transition would be.

    – Just code
    Dec 27 '18 at 5:32











  • When the page loads we can have a transition from left to right or simply have no transitions when the page loads first time after then the transition starts depending upon which panel is in and out of view

    – Rahul Singh
    Dec 27 '18 at 5:36











  • Have you tried angular animations?

    – Sergey
    Dec 31 '18 at 12:10






  • 3





    Unfortunately I haven't managed to understand what exactly you want to achieve except of some kind of animation. However, you could try to learn Angular Animations it should help blog.angularindepth.com/… . Also if you made a some kind of animations (in any graphical editor) there is a chance that we would better understand your desire.

    – Sergey
    Dec 31 '18 at 12:17













  • i have looked into animations in a lot of detail and gone through it several times and i agree with you a graphical animation will be really help ful i will try and see it this is possible as i am not versed in any graphical editors

    – Rahul Singh
    Jan 2 at 6:45



















Please explain more about your issue, for ex 1-2 is panel1 and panel2 what should happen to them when page is loaded, how the transition would be.

– Just code
Dec 27 '18 at 5:32





Please explain more about your issue, for ex 1-2 is panel1 and panel2 what should happen to them when page is loaded, how the transition would be.

– Just code
Dec 27 '18 at 5:32













When the page loads we can have a transition from left to right or simply have no transitions when the page loads first time after then the transition starts depending upon which panel is in and out of view

– Rahul Singh
Dec 27 '18 at 5:36





When the page loads we can have a transition from left to right or simply have no transitions when the page loads first time after then the transition starts depending upon which panel is in and out of view

– Rahul Singh
Dec 27 '18 at 5:36













Have you tried angular animations?

– Sergey
Dec 31 '18 at 12:10





Have you tried angular animations?

– Sergey
Dec 31 '18 at 12:10




3




3





Unfortunately I haven't managed to understand what exactly you want to achieve except of some kind of animation. However, you could try to learn Angular Animations it should help blog.angularindepth.com/… . Also if you made a some kind of animations (in any graphical editor) there is a chance that we would better understand your desire.

– Sergey
Dec 31 '18 at 12:17







Unfortunately I haven't managed to understand what exactly you want to achieve except of some kind of animation. However, you could try to learn Angular Animations it should help blog.angularindepth.com/… . Also if you made a some kind of animations (in any graphical editor) there is a chance that we would better understand your desire.

– Sergey
Dec 31 '18 at 12:17















i have looked into animations in a lot of detail and gone through it several times and i agree with you a graphical animation will be really help ful i will try and see it this is possible as i am not versed in any graphical editors

– Rahul Singh
Jan 2 at 6:45







i have looked into animations in a lot of detail and gone through it several times and i agree with you a graphical animation will be really help ful i will try and see it this is possible as i am not versed in any graphical editors

– Rahul Singh
Jan 2 at 6:45














1 Answer
1






active

oldest

votes


















5





+100









I have changed the PanelComponent in your StackBlitz sample to work in the way the provided animation is showing.



You need just three states. One when the component is initially outside on the right. From there it moves into view this is the second state. After that it moves out of view to the left the third state. Once it is out of view to the left you move it back to the right initial state so it can come back in when needed.



Here is the code for the changed panel component:



import { Component, ContentChild, QueryList,HostBinding,Input,ElementRef } from '@angular/core';
import {
trigger,
state,
style,
animate,
transition
} from '@angular/animations';

@Component({
selector: 'my-panel',
templateUrl: './panel.component.html',
styleUrls:['./panel.component.css'],
animations: [
trigger('transition', [
state('right', style({
transform: 'translateX(100%)',
opacity: 0
})),
state('inview', style({
})),
state('left', style({
transform: 'translateX(-100%)',
opacity: 0
})),
transition('right => inview', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-out`,style({
transform: 'translateX(0)',
opacity: 1 }))
]),
transition('inview => left', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-in`,style({
transform: 'translateX(-100%)',
opacity: 0 }))
])
])]
})
export class PanelComponent {
public static readonly ANIMATION_DURATION = 500;
@Input() destroyOnHidden: boolean = false;
@Input() id : string = null;
@ContentChild('layout') contentChild : QueryList<ElementRef>;
@HostBinding('style.width') componentWidth = null;
@HostBinding('style.height') componentHeight = null;
@HostBinding('style.overflow') componentOverflow = null;
public state: string = null;

public getId() {
return this.id;
}

constructor() {
this.state = 'right';
}

public setInViewStyle(width: string, height: string, overflow: string): void {
this.componentWidth = width + '%';
this.componentHeight = height + '%';
this.componentOverflow = overflow;
this.state = 'inview';
}

public setDefault(): void {
this.state = 'right';
}

public moveOut(): void {
this.state = 'left';
}


public transitionDoneHide(): void {
if(this.state === 'right') {
console.log('hiding transition done');
this.componentWidth = '0' + '%';
this.componentHeight = '0' + '%';
this.componentOverflow = 'hidden';
}
}
}


As you see I have split the setStyle into two methods setInViewStyle and moveOut. The setInViewStyle sets the panel style and moves it into view. The moveOut method moves the panel out of view to the left. Because of this I have also changed the layout manager method panelTransformation.



Here is the changed code:



panelTransformation(transitions) {
if (transitions) {
let movement = null;
let panelsToRemove = ;
let panelsToAdd = ;
if (this.previousPanels) {
panelsToRemove = this.previousPanels.filter((panel) => transitions.panel.indexOf(panel) < 0);
panelsToAdd = transitions.panel.filter((panel) => this.previousPanels.indexOf(panel) < 0);
} else {
panelsToAdd = transitions.panel
}

if (panelsToRemove.length > 0) {
for (let panelToRemove of panelsToRemove) {
this.idPanelMap.get(panelToRemove).moveOut();
}
// wait for fade out to finish then start fade in
timer(PanelComponent.ANIMATION_DURATION + 100).subscribe(() => {
for (let panelToAdd of panelsToAdd) {
this.idPanelMap.get(panelToAdd).setInViewStyle(transitions.width[transitions.panel.indexOf(panelToAdd)], '100', 'initial');
}
for (let panelToRemove of panelsToRemove) {
this.idPanelMap.get(panelToRemove).setDefault();
}
});
} else { // first time so just fade in
for (let panelToAdd of panelsToAdd) {
this.idPanelMap.get(panelToAdd).setInViewStyle(transitions.width[transitions.panel.indexOf(panelToAdd)], '100', 'initial');
}
}

this.previousPanels = transitions.panel;
}
}


As you can see I have completely changed the logic so I first move out panels that have to be removed wait for the animation to finish and then move in the new panels.
Here is a link to my StackBlitz sample that implements all this so you can also see it working.



As requested in the comment I provide also another sample with moving in both directions. This makes things more complicated. I had to add one more transition for the move in the other direction. And added the possibility to set the direction in the moveOut method. In my opinion it does not look so good because it can have some flicker.
The new panel component code:



import { Component, ContentChild, QueryList,HostBinding,Input,ElementRef } from '@angular/core';
import {
trigger,
state,
style,
animate,
transition
} from '@angular/animations';
import { timer } from 'rxjs';

@Component({
selector: 'my-panel',
templateUrl: './panel.component.html',
styleUrls:['./panel.component.css'],
animations: [
trigger('transition', [
state('right', style({
transform: 'translateX(100%)',
opacity: 0
})),
state('inview', style({
})),
state('left', style({
transform: 'translateX(-100%)',
opacity: 0
})),
transition('right => inview', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-out`,style({
transform: 'translateX(0)',
opacity: 1 }))
]),
transition('inview => left', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-in`,style({
transform: 'translateX(-100%)',
opacity: 0 }))
]),
transition('inview => right', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-in`,style( {
transform: 'translateX(100%)',
opacity: 0
}))
]),
transition('left => inview', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-out`,style({
transform: 'translateX(0)',
opacity: 1 }))
])
])]
})
export class PanelComponent {
public static readonly ANIMATION_DURATION = 500;
public static readonly ANIMATION_DELAY = 100;
@Input() destroyOnHidden: boolean = false;
@Input() id : string = null;
@ContentChild('layout') contentChild : QueryList<ElementRef>;
@HostBinding('style.width') componentWidth = null;
@HostBinding('style.height') componentHeight = null;
@HostBinding('style.overflow') componentOverflow = null;
public state: string = null;
private lastDirection: 'left' | 'right';

public getId() {
return this.id;
}

constructor() {
this.state = 'right';
}

public setInViewStyle(width: string, height: string, overflow: string): void {
this.componentWidth = width + '%';
this.componentHeight = height + '%';
this.componentOverflow = overflow;
this.state = 'inview';
}

public setDefault(): void {
this.state = 'right';
}

public moveOut(direction: 'left' | 'right'): void {
this.lastDirection = direction;
this.state = direction;
}


public transitionDoneHide(): void {
if(this.state === this.lastDirection) {
if (this.lastDirection === 'right') {
timer(PanelComponent.ANIMATION_DELAY).subscribe(() => this.hide());
} else {
this.hide();
}
console.log('hiding transition done');

}
}

private hide() {
this.componentWidth = '0' + '%';
this.componentHeight = '0' + '%';
this.componentOverflow = 'hidden';
}
}


In the panelTransformation method I added the logic to set the direction for moving out to right if it is the first panel.
This is the updated code:



panelTransformation(transitions) {
if (transitions) {
let movement = null;
let panelsToRemove = ;
let panelsToAdd = ;
if (this.previousPanels) {
panelsToRemove = this.previousPanels.filter((panel) => transitions.panel.indexOf(panel) < 0);
panelsToAdd = transitions.panel.filter((panel) => this.previousPanels.indexOf(panel) < 0);
} else {
panelsToAdd = transitions.panel
}

if (panelsToRemove.length > 0) {
for (let panelToRemove of panelsToRemove) {
let direction: 'left' | 'right' = 'left';
// if it is the first panel we move out right
if (this.previousPanels.indexOf(panelToRemove) === 0) {
direction = 'right';
}
this.idPanelMap.get(panelToRemove).moveOut(direction);
}
// wait for fade out to finish then start fade in
timer(PanelComponent.ANIMATION_DURATION + PanelComponent.ANIMATION_DELAY).subscribe(() => {
for (let panelToAdd of panelsToAdd) {
this.idPanelMap.get(panelToAdd).setInViewStyle(transitions.width[transitions.panel.indexOf(panelToAdd)], '100', 'initial');
}
for (let panelToRemove of panelsToRemove) {
this.idPanelMap.get(panelToRemove).setDefault();
}
});
} else { // first time so just fade in
for (let panelToAdd of panelsToAdd) {
this.idPanelMap.get(panelToAdd).setInViewStyle(transitions.width[transitions.panel.indexOf(panelToAdd)], '100', 'initial');
}
}

this.previousPanels = transitions.panel;
}
}


And also the StackBlitz sample for this implementation.






share|improve this answer


























  • really thank you i guess you have nailed it but one slight thing i would ask on this . in the example when we given panel 1 and 2 and then go to panel 2 and 3 it works great but from that view when we move to panel 1 and 2 again panel 1 should come from left don't you thing it is coming from right . any pointers how we control the direction as the order of panel is fixed for us 1 -> 2 -> -> 3- >4

    – Rahul Singh
    Jan 11 at 7:44













  • Please let me know if we can give the direction of the transition here , it would look great right as the panels are in order. even if you are not able to give anything on this i will give it to you thanks a ton. looking forward for your reply

    – Rahul Singh
    Jan 11 at 7:45











  • I have added another implementation to the answer where you can specify the direction of the animation.

    – AlesD
    Jan 11 at 23:13











  • AlesD i get it there is some flicker i will try and refine the same thanks a ton, even 500 bounty was less for your answer i got some real insights on how we can achieve this thanks

    – Rahul Singh
    Jan 14 at 5:41













Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53910367%2ftransitions-in-angular%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









5





+100









I have changed the PanelComponent in your StackBlitz sample to work in the way the provided animation is showing.



You need just three states. One when the component is initially outside on the right. From there it moves into view this is the second state. After that it moves out of view to the left the third state. Once it is out of view to the left you move it back to the right initial state so it can come back in when needed.



Here is the code for the changed panel component:



import { Component, ContentChild, QueryList,HostBinding,Input,ElementRef } from '@angular/core';
import {
trigger,
state,
style,
animate,
transition
} from '@angular/animations';

@Component({
selector: 'my-panel',
templateUrl: './panel.component.html',
styleUrls:['./panel.component.css'],
animations: [
trigger('transition', [
state('right', style({
transform: 'translateX(100%)',
opacity: 0
})),
state('inview', style({
})),
state('left', style({
transform: 'translateX(-100%)',
opacity: 0
})),
transition('right => inview', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-out`,style({
transform: 'translateX(0)',
opacity: 1 }))
]),
transition('inview => left', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-in`,style({
transform: 'translateX(-100%)',
opacity: 0 }))
])
])]
})
export class PanelComponent {
public static readonly ANIMATION_DURATION = 500;
@Input() destroyOnHidden: boolean = false;
@Input() id : string = null;
@ContentChild('layout') contentChild : QueryList<ElementRef>;
@HostBinding('style.width') componentWidth = null;
@HostBinding('style.height') componentHeight = null;
@HostBinding('style.overflow') componentOverflow = null;
public state: string = null;

public getId() {
return this.id;
}

constructor() {
this.state = 'right';
}

public setInViewStyle(width: string, height: string, overflow: string): void {
this.componentWidth = width + '%';
this.componentHeight = height + '%';
this.componentOverflow = overflow;
this.state = 'inview';
}

public setDefault(): void {
this.state = 'right';
}

public moveOut(): void {
this.state = 'left';
}


public transitionDoneHide(): void {
if(this.state === 'right') {
console.log('hiding transition done');
this.componentWidth = '0' + '%';
this.componentHeight = '0' + '%';
this.componentOverflow = 'hidden';
}
}
}


As you see I have split the setStyle into two methods setInViewStyle and moveOut. The setInViewStyle sets the panel style and moves it into view. The moveOut method moves the panel out of view to the left. Because of this I have also changed the layout manager method panelTransformation.



Here is the changed code:



panelTransformation(transitions) {
if (transitions) {
let movement = null;
let panelsToRemove = ;
let panelsToAdd = ;
if (this.previousPanels) {
panelsToRemove = this.previousPanels.filter((panel) => transitions.panel.indexOf(panel) < 0);
panelsToAdd = transitions.panel.filter((panel) => this.previousPanels.indexOf(panel) < 0);
} else {
panelsToAdd = transitions.panel
}

if (panelsToRemove.length > 0) {
for (let panelToRemove of panelsToRemove) {
this.idPanelMap.get(panelToRemove).moveOut();
}
// wait for fade out to finish then start fade in
timer(PanelComponent.ANIMATION_DURATION + 100).subscribe(() => {
for (let panelToAdd of panelsToAdd) {
this.idPanelMap.get(panelToAdd).setInViewStyle(transitions.width[transitions.panel.indexOf(panelToAdd)], '100', 'initial');
}
for (let panelToRemove of panelsToRemove) {
this.idPanelMap.get(panelToRemove).setDefault();
}
});
} else { // first time so just fade in
for (let panelToAdd of panelsToAdd) {
this.idPanelMap.get(panelToAdd).setInViewStyle(transitions.width[transitions.panel.indexOf(panelToAdd)], '100', 'initial');
}
}

this.previousPanels = transitions.panel;
}
}


As you can see I have completely changed the logic so I first move out panels that have to be removed wait for the animation to finish and then move in the new panels.
Here is a link to my StackBlitz sample that implements all this so you can also see it working.



As requested in the comment I provide also another sample with moving in both directions. This makes things more complicated. I had to add one more transition for the move in the other direction. And added the possibility to set the direction in the moveOut method. In my opinion it does not look so good because it can have some flicker.
The new panel component code:



import { Component, ContentChild, QueryList,HostBinding,Input,ElementRef } from '@angular/core';
import {
trigger,
state,
style,
animate,
transition
} from '@angular/animations';
import { timer } from 'rxjs';

@Component({
selector: 'my-panel',
templateUrl: './panel.component.html',
styleUrls:['./panel.component.css'],
animations: [
trigger('transition', [
state('right', style({
transform: 'translateX(100%)',
opacity: 0
})),
state('inview', style({
})),
state('left', style({
transform: 'translateX(-100%)',
opacity: 0
})),
transition('right => inview', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-out`,style({
transform: 'translateX(0)',
opacity: 1 }))
]),
transition('inview => left', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-in`,style({
transform: 'translateX(-100%)',
opacity: 0 }))
]),
transition('inview => right', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-in`,style( {
transform: 'translateX(100%)',
opacity: 0
}))
]),
transition('left => inview', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-out`,style({
transform: 'translateX(0)',
opacity: 1 }))
])
])]
})
export class PanelComponent {
public static readonly ANIMATION_DURATION = 500;
public static readonly ANIMATION_DELAY = 100;
@Input() destroyOnHidden: boolean = false;
@Input() id : string = null;
@ContentChild('layout') contentChild : QueryList<ElementRef>;
@HostBinding('style.width') componentWidth = null;
@HostBinding('style.height') componentHeight = null;
@HostBinding('style.overflow') componentOverflow = null;
public state: string = null;
private lastDirection: 'left' | 'right';

public getId() {
return this.id;
}

constructor() {
this.state = 'right';
}

public setInViewStyle(width: string, height: string, overflow: string): void {
this.componentWidth = width + '%';
this.componentHeight = height + '%';
this.componentOverflow = overflow;
this.state = 'inview';
}

public setDefault(): void {
this.state = 'right';
}

public moveOut(direction: 'left' | 'right'): void {
this.lastDirection = direction;
this.state = direction;
}


public transitionDoneHide(): void {
if(this.state === this.lastDirection) {
if (this.lastDirection === 'right') {
timer(PanelComponent.ANIMATION_DELAY).subscribe(() => this.hide());
} else {
this.hide();
}
console.log('hiding transition done');

}
}

private hide() {
this.componentWidth = '0' + '%';
this.componentHeight = '0' + '%';
this.componentOverflow = 'hidden';
}
}


In the panelTransformation method I added the logic to set the direction for moving out to right if it is the first panel.
This is the updated code:



panelTransformation(transitions) {
if (transitions) {
let movement = null;
let panelsToRemove = ;
let panelsToAdd = ;
if (this.previousPanels) {
panelsToRemove = this.previousPanels.filter((panel) => transitions.panel.indexOf(panel) < 0);
panelsToAdd = transitions.panel.filter((panel) => this.previousPanels.indexOf(panel) < 0);
} else {
panelsToAdd = transitions.panel
}

if (panelsToRemove.length > 0) {
for (let panelToRemove of panelsToRemove) {
let direction: 'left' | 'right' = 'left';
// if it is the first panel we move out right
if (this.previousPanels.indexOf(panelToRemove) === 0) {
direction = 'right';
}
this.idPanelMap.get(panelToRemove).moveOut(direction);
}
// wait for fade out to finish then start fade in
timer(PanelComponent.ANIMATION_DURATION + PanelComponent.ANIMATION_DELAY).subscribe(() => {
for (let panelToAdd of panelsToAdd) {
this.idPanelMap.get(panelToAdd).setInViewStyle(transitions.width[transitions.panel.indexOf(panelToAdd)], '100', 'initial');
}
for (let panelToRemove of panelsToRemove) {
this.idPanelMap.get(panelToRemove).setDefault();
}
});
} else { // first time so just fade in
for (let panelToAdd of panelsToAdd) {
this.idPanelMap.get(panelToAdd).setInViewStyle(transitions.width[transitions.panel.indexOf(panelToAdd)], '100', 'initial');
}
}

this.previousPanels = transitions.panel;
}
}


And also the StackBlitz sample for this implementation.






share|improve this answer


























  • really thank you i guess you have nailed it but one slight thing i would ask on this . in the example when we given panel 1 and 2 and then go to panel 2 and 3 it works great but from that view when we move to panel 1 and 2 again panel 1 should come from left don't you thing it is coming from right . any pointers how we control the direction as the order of panel is fixed for us 1 -> 2 -> -> 3- >4

    – Rahul Singh
    Jan 11 at 7:44













  • Please let me know if we can give the direction of the transition here , it would look great right as the panels are in order. even if you are not able to give anything on this i will give it to you thanks a ton. looking forward for your reply

    – Rahul Singh
    Jan 11 at 7:45











  • I have added another implementation to the answer where you can specify the direction of the animation.

    – AlesD
    Jan 11 at 23:13











  • AlesD i get it there is some flicker i will try and refine the same thanks a ton, even 500 bounty was less for your answer i got some real insights on how we can achieve this thanks

    – Rahul Singh
    Jan 14 at 5:41


















5





+100









I have changed the PanelComponent in your StackBlitz sample to work in the way the provided animation is showing.



You need just three states. One when the component is initially outside on the right. From there it moves into view this is the second state. After that it moves out of view to the left the third state. Once it is out of view to the left you move it back to the right initial state so it can come back in when needed.



Here is the code for the changed panel component:



import { Component, ContentChild, QueryList,HostBinding,Input,ElementRef } from '@angular/core';
import {
trigger,
state,
style,
animate,
transition
} from '@angular/animations';

@Component({
selector: 'my-panel',
templateUrl: './panel.component.html',
styleUrls:['./panel.component.css'],
animations: [
trigger('transition', [
state('right', style({
transform: 'translateX(100%)',
opacity: 0
})),
state('inview', style({
})),
state('left', style({
transform: 'translateX(-100%)',
opacity: 0
})),
transition('right => inview', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-out`,style({
transform: 'translateX(0)',
opacity: 1 }))
]),
transition('inview => left', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-in`,style({
transform: 'translateX(-100%)',
opacity: 0 }))
])
])]
})
export class PanelComponent {
public static readonly ANIMATION_DURATION = 500;
@Input() destroyOnHidden: boolean = false;
@Input() id : string = null;
@ContentChild('layout') contentChild : QueryList<ElementRef>;
@HostBinding('style.width') componentWidth = null;
@HostBinding('style.height') componentHeight = null;
@HostBinding('style.overflow') componentOverflow = null;
public state: string = null;

public getId() {
return this.id;
}

constructor() {
this.state = 'right';
}

public setInViewStyle(width: string, height: string, overflow: string): void {
this.componentWidth = width + '%';
this.componentHeight = height + '%';
this.componentOverflow = overflow;
this.state = 'inview';
}

public setDefault(): void {
this.state = 'right';
}

public moveOut(): void {
this.state = 'left';
}


public transitionDoneHide(): void {
if(this.state === 'right') {
console.log('hiding transition done');
this.componentWidth = '0' + '%';
this.componentHeight = '0' + '%';
this.componentOverflow = 'hidden';
}
}
}


As you see I have split the setStyle into two methods setInViewStyle and moveOut. The setInViewStyle sets the panel style and moves it into view. The moveOut method moves the panel out of view to the left. Because of this I have also changed the layout manager method panelTransformation.



Here is the changed code:



panelTransformation(transitions) {
if (transitions) {
let movement = null;
let panelsToRemove = ;
let panelsToAdd = ;
if (this.previousPanels) {
panelsToRemove = this.previousPanels.filter((panel) => transitions.panel.indexOf(panel) < 0);
panelsToAdd = transitions.panel.filter((panel) => this.previousPanels.indexOf(panel) < 0);
} else {
panelsToAdd = transitions.panel
}

if (panelsToRemove.length > 0) {
for (let panelToRemove of panelsToRemove) {
this.idPanelMap.get(panelToRemove).moveOut();
}
// wait for fade out to finish then start fade in
timer(PanelComponent.ANIMATION_DURATION + 100).subscribe(() => {
for (let panelToAdd of panelsToAdd) {
this.idPanelMap.get(panelToAdd).setInViewStyle(transitions.width[transitions.panel.indexOf(panelToAdd)], '100', 'initial');
}
for (let panelToRemove of panelsToRemove) {
this.idPanelMap.get(panelToRemove).setDefault();
}
});
} else { // first time so just fade in
for (let panelToAdd of panelsToAdd) {
this.idPanelMap.get(panelToAdd).setInViewStyle(transitions.width[transitions.panel.indexOf(panelToAdd)], '100', 'initial');
}
}

this.previousPanels = transitions.panel;
}
}


As you can see I have completely changed the logic so I first move out panels that have to be removed wait for the animation to finish and then move in the new panels.
Here is a link to my StackBlitz sample that implements all this so you can also see it working.



As requested in the comment I provide also another sample with moving in both directions. This makes things more complicated. I had to add one more transition for the move in the other direction. And added the possibility to set the direction in the moveOut method. In my opinion it does not look so good because it can have some flicker.
The new panel component code:



import { Component, ContentChild, QueryList,HostBinding,Input,ElementRef } from '@angular/core';
import {
trigger,
state,
style,
animate,
transition
} from '@angular/animations';
import { timer } from 'rxjs';

@Component({
selector: 'my-panel',
templateUrl: './panel.component.html',
styleUrls:['./panel.component.css'],
animations: [
trigger('transition', [
state('right', style({
transform: 'translateX(100%)',
opacity: 0
})),
state('inview', style({
})),
state('left', style({
transform: 'translateX(-100%)',
opacity: 0
})),
transition('right => inview', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-out`,style({
transform: 'translateX(0)',
opacity: 1 }))
]),
transition('inview => left', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-in`,style({
transform: 'translateX(-100%)',
opacity: 0 }))
]),
transition('inview => right', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-in`,style( {
transform: 'translateX(100%)',
opacity: 0
}))
]),
transition('left => inview', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-out`,style({
transform: 'translateX(0)',
opacity: 1 }))
])
])]
})
export class PanelComponent {
public static readonly ANIMATION_DURATION = 500;
public static readonly ANIMATION_DELAY = 100;
@Input() destroyOnHidden: boolean = false;
@Input() id : string = null;
@ContentChild('layout') contentChild : QueryList<ElementRef>;
@HostBinding('style.width') componentWidth = null;
@HostBinding('style.height') componentHeight = null;
@HostBinding('style.overflow') componentOverflow = null;
public state: string = null;
private lastDirection: 'left' | 'right';

public getId() {
return this.id;
}

constructor() {
this.state = 'right';
}

public setInViewStyle(width: string, height: string, overflow: string): void {
this.componentWidth = width + '%';
this.componentHeight = height + '%';
this.componentOverflow = overflow;
this.state = 'inview';
}

public setDefault(): void {
this.state = 'right';
}

public moveOut(direction: 'left' | 'right'): void {
this.lastDirection = direction;
this.state = direction;
}


public transitionDoneHide(): void {
if(this.state === this.lastDirection) {
if (this.lastDirection === 'right') {
timer(PanelComponent.ANIMATION_DELAY).subscribe(() => this.hide());
} else {
this.hide();
}
console.log('hiding transition done');

}
}

private hide() {
this.componentWidth = '0' + '%';
this.componentHeight = '0' + '%';
this.componentOverflow = 'hidden';
}
}


In the panelTransformation method I added the logic to set the direction for moving out to right if it is the first panel.
This is the updated code:



panelTransformation(transitions) {
if (transitions) {
let movement = null;
let panelsToRemove = ;
let panelsToAdd = ;
if (this.previousPanels) {
panelsToRemove = this.previousPanels.filter((panel) => transitions.panel.indexOf(panel) < 0);
panelsToAdd = transitions.panel.filter((panel) => this.previousPanels.indexOf(panel) < 0);
} else {
panelsToAdd = transitions.panel
}

if (panelsToRemove.length > 0) {
for (let panelToRemove of panelsToRemove) {
let direction: 'left' | 'right' = 'left';
// if it is the first panel we move out right
if (this.previousPanels.indexOf(panelToRemove) === 0) {
direction = 'right';
}
this.idPanelMap.get(panelToRemove).moveOut(direction);
}
// wait for fade out to finish then start fade in
timer(PanelComponent.ANIMATION_DURATION + PanelComponent.ANIMATION_DELAY).subscribe(() => {
for (let panelToAdd of panelsToAdd) {
this.idPanelMap.get(panelToAdd).setInViewStyle(transitions.width[transitions.panel.indexOf(panelToAdd)], '100', 'initial');
}
for (let panelToRemove of panelsToRemove) {
this.idPanelMap.get(panelToRemove).setDefault();
}
});
} else { // first time so just fade in
for (let panelToAdd of panelsToAdd) {
this.idPanelMap.get(panelToAdd).setInViewStyle(transitions.width[transitions.panel.indexOf(panelToAdd)], '100', 'initial');
}
}

this.previousPanels = transitions.panel;
}
}


And also the StackBlitz sample for this implementation.






share|improve this answer


























  • really thank you i guess you have nailed it but one slight thing i would ask on this . in the example when we given panel 1 and 2 and then go to panel 2 and 3 it works great but from that view when we move to panel 1 and 2 again panel 1 should come from left don't you thing it is coming from right . any pointers how we control the direction as the order of panel is fixed for us 1 -> 2 -> -> 3- >4

    – Rahul Singh
    Jan 11 at 7:44













  • Please let me know if we can give the direction of the transition here , it would look great right as the panels are in order. even if you are not able to give anything on this i will give it to you thanks a ton. looking forward for your reply

    – Rahul Singh
    Jan 11 at 7:45











  • I have added another implementation to the answer where you can specify the direction of the animation.

    – AlesD
    Jan 11 at 23:13











  • AlesD i get it there is some flicker i will try and refine the same thanks a ton, even 500 bounty was less for your answer i got some real insights on how we can achieve this thanks

    – Rahul Singh
    Jan 14 at 5:41
















5





+100







5





+100



5




+100





I have changed the PanelComponent in your StackBlitz sample to work in the way the provided animation is showing.



You need just three states. One when the component is initially outside on the right. From there it moves into view this is the second state. After that it moves out of view to the left the third state. Once it is out of view to the left you move it back to the right initial state so it can come back in when needed.



Here is the code for the changed panel component:



import { Component, ContentChild, QueryList,HostBinding,Input,ElementRef } from '@angular/core';
import {
trigger,
state,
style,
animate,
transition
} from '@angular/animations';

@Component({
selector: 'my-panel',
templateUrl: './panel.component.html',
styleUrls:['./panel.component.css'],
animations: [
trigger('transition', [
state('right', style({
transform: 'translateX(100%)',
opacity: 0
})),
state('inview', style({
})),
state('left', style({
transform: 'translateX(-100%)',
opacity: 0
})),
transition('right => inview', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-out`,style({
transform: 'translateX(0)',
opacity: 1 }))
]),
transition('inview => left', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-in`,style({
transform: 'translateX(-100%)',
opacity: 0 }))
])
])]
})
export class PanelComponent {
public static readonly ANIMATION_DURATION = 500;
@Input() destroyOnHidden: boolean = false;
@Input() id : string = null;
@ContentChild('layout') contentChild : QueryList<ElementRef>;
@HostBinding('style.width') componentWidth = null;
@HostBinding('style.height') componentHeight = null;
@HostBinding('style.overflow') componentOverflow = null;
public state: string = null;

public getId() {
return this.id;
}

constructor() {
this.state = 'right';
}

public setInViewStyle(width: string, height: string, overflow: string): void {
this.componentWidth = width + '%';
this.componentHeight = height + '%';
this.componentOverflow = overflow;
this.state = 'inview';
}

public setDefault(): void {
this.state = 'right';
}

public moveOut(): void {
this.state = 'left';
}


public transitionDoneHide(): void {
if(this.state === 'right') {
console.log('hiding transition done');
this.componentWidth = '0' + '%';
this.componentHeight = '0' + '%';
this.componentOverflow = 'hidden';
}
}
}


As you see I have split the setStyle into two methods setInViewStyle and moveOut. The setInViewStyle sets the panel style and moves it into view. The moveOut method moves the panel out of view to the left. Because of this I have also changed the layout manager method panelTransformation.



Here is the changed code:



panelTransformation(transitions) {
if (transitions) {
let movement = null;
let panelsToRemove = ;
let panelsToAdd = ;
if (this.previousPanels) {
panelsToRemove = this.previousPanels.filter((panel) => transitions.panel.indexOf(panel) < 0);
panelsToAdd = transitions.panel.filter((panel) => this.previousPanels.indexOf(panel) < 0);
} else {
panelsToAdd = transitions.panel
}

if (panelsToRemove.length > 0) {
for (let panelToRemove of panelsToRemove) {
this.idPanelMap.get(panelToRemove).moveOut();
}
// wait for fade out to finish then start fade in
timer(PanelComponent.ANIMATION_DURATION + 100).subscribe(() => {
for (let panelToAdd of panelsToAdd) {
this.idPanelMap.get(panelToAdd).setInViewStyle(transitions.width[transitions.panel.indexOf(panelToAdd)], '100', 'initial');
}
for (let panelToRemove of panelsToRemove) {
this.idPanelMap.get(panelToRemove).setDefault();
}
});
} else { // first time so just fade in
for (let panelToAdd of panelsToAdd) {
this.idPanelMap.get(panelToAdd).setInViewStyle(transitions.width[transitions.panel.indexOf(panelToAdd)], '100', 'initial');
}
}

this.previousPanels = transitions.panel;
}
}


As you can see I have completely changed the logic so I first move out panels that have to be removed wait for the animation to finish and then move in the new panels.
Here is a link to my StackBlitz sample that implements all this so you can also see it working.



As requested in the comment I provide also another sample with moving in both directions. This makes things more complicated. I had to add one more transition for the move in the other direction. And added the possibility to set the direction in the moveOut method. In my opinion it does not look so good because it can have some flicker.
The new panel component code:



import { Component, ContentChild, QueryList,HostBinding,Input,ElementRef } from '@angular/core';
import {
trigger,
state,
style,
animate,
transition
} from '@angular/animations';
import { timer } from 'rxjs';

@Component({
selector: 'my-panel',
templateUrl: './panel.component.html',
styleUrls:['./panel.component.css'],
animations: [
trigger('transition', [
state('right', style({
transform: 'translateX(100%)',
opacity: 0
})),
state('inview', style({
})),
state('left', style({
transform: 'translateX(-100%)',
opacity: 0
})),
transition('right => inview', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-out`,style({
transform: 'translateX(0)',
opacity: 1 }))
]),
transition('inview => left', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-in`,style({
transform: 'translateX(-100%)',
opacity: 0 }))
]),
transition('inview => right', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-in`,style( {
transform: 'translateX(100%)',
opacity: 0
}))
]),
transition('left => inview', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-out`,style({
transform: 'translateX(0)',
opacity: 1 }))
])
])]
})
export class PanelComponent {
public static readonly ANIMATION_DURATION = 500;
public static readonly ANIMATION_DELAY = 100;
@Input() destroyOnHidden: boolean = false;
@Input() id : string = null;
@ContentChild('layout') contentChild : QueryList<ElementRef>;
@HostBinding('style.width') componentWidth = null;
@HostBinding('style.height') componentHeight = null;
@HostBinding('style.overflow') componentOverflow = null;
public state: string = null;
private lastDirection: 'left' | 'right';

public getId() {
return this.id;
}

constructor() {
this.state = 'right';
}

public setInViewStyle(width: string, height: string, overflow: string): void {
this.componentWidth = width + '%';
this.componentHeight = height + '%';
this.componentOverflow = overflow;
this.state = 'inview';
}

public setDefault(): void {
this.state = 'right';
}

public moveOut(direction: 'left' | 'right'): void {
this.lastDirection = direction;
this.state = direction;
}


public transitionDoneHide(): void {
if(this.state === this.lastDirection) {
if (this.lastDirection === 'right') {
timer(PanelComponent.ANIMATION_DELAY).subscribe(() => this.hide());
} else {
this.hide();
}
console.log('hiding transition done');

}
}

private hide() {
this.componentWidth = '0' + '%';
this.componentHeight = '0' + '%';
this.componentOverflow = 'hidden';
}
}


In the panelTransformation method I added the logic to set the direction for moving out to right if it is the first panel.
This is the updated code:



panelTransformation(transitions) {
if (transitions) {
let movement = null;
let panelsToRemove = ;
let panelsToAdd = ;
if (this.previousPanels) {
panelsToRemove = this.previousPanels.filter((panel) => transitions.panel.indexOf(panel) < 0);
panelsToAdd = transitions.panel.filter((panel) => this.previousPanels.indexOf(panel) < 0);
} else {
panelsToAdd = transitions.panel
}

if (panelsToRemove.length > 0) {
for (let panelToRemove of panelsToRemove) {
let direction: 'left' | 'right' = 'left';
// if it is the first panel we move out right
if (this.previousPanels.indexOf(panelToRemove) === 0) {
direction = 'right';
}
this.idPanelMap.get(panelToRemove).moveOut(direction);
}
// wait for fade out to finish then start fade in
timer(PanelComponent.ANIMATION_DURATION + PanelComponent.ANIMATION_DELAY).subscribe(() => {
for (let panelToAdd of panelsToAdd) {
this.idPanelMap.get(panelToAdd).setInViewStyle(transitions.width[transitions.panel.indexOf(panelToAdd)], '100', 'initial');
}
for (let panelToRemove of panelsToRemove) {
this.idPanelMap.get(panelToRemove).setDefault();
}
});
} else { // first time so just fade in
for (let panelToAdd of panelsToAdd) {
this.idPanelMap.get(panelToAdd).setInViewStyle(transitions.width[transitions.panel.indexOf(panelToAdd)], '100', 'initial');
}
}

this.previousPanels = transitions.panel;
}
}


And also the StackBlitz sample for this implementation.






share|improve this answer















I have changed the PanelComponent in your StackBlitz sample to work in the way the provided animation is showing.



You need just three states. One when the component is initially outside on the right. From there it moves into view this is the second state. After that it moves out of view to the left the third state. Once it is out of view to the left you move it back to the right initial state so it can come back in when needed.



Here is the code for the changed panel component:



import { Component, ContentChild, QueryList,HostBinding,Input,ElementRef } from '@angular/core';
import {
trigger,
state,
style,
animate,
transition
} from '@angular/animations';

@Component({
selector: 'my-panel',
templateUrl: './panel.component.html',
styleUrls:['./panel.component.css'],
animations: [
trigger('transition', [
state('right', style({
transform: 'translateX(100%)',
opacity: 0
})),
state('inview', style({
})),
state('left', style({
transform: 'translateX(-100%)',
opacity: 0
})),
transition('right => inview', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-out`,style({
transform: 'translateX(0)',
opacity: 1 }))
]),
transition('inview => left', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-in`,style({
transform: 'translateX(-100%)',
opacity: 0 }))
])
])]
})
export class PanelComponent {
public static readonly ANIMATION_DURATION = 500;
@Input() destroyOnHidden: boolean = false;
@Input() id : string = null;
@ContentChild('layout') contentChild : QueryList<ElementRef>;
@HostBinding('style.width') componentWidth = null;
@HostBinding('style.height') componentHeight = null;
@HostBinding('style.overflow') componentOverflow = null;
public state: string = null;

public getId() {
return this.id;
}

constructor() {
this.state = 'right';
}

public setInViewStyle(width: string, height: string, overflow: string): void {
this.componentWidth = width + '%';
this.componentHeight = height + '%';
this.componentOverflow = overflow;
this.state = 'inview';
}

public setDefault(): void {
this.state = 'right';
}

public moveOut(): void {
this.state = 'left';
}


public transitionDoneHide(): void {
if(this.state === 'right') {
console.log('hiding transition done');
this.componentWidth = '0' + '%';
this.componentHeight = '0' + '%';
this.componentOverflow = 'hidden';
}
}
}


As you see I have split the setStyle into two methods setInViewStyle and moveOut. The setInViewStyle sets the panel style and moves it into view. The moveOut method moves the panel out of view to the left. Because of this I have also changed the layout manager method panelTransformation.



Here is the changed code:



panelTransformation(transitions) {
if (transitions) {
let movement = null;
let panelsToRemove = ;
let panelsToAdd = ;
if (this.previousPanels) {
panelsToRemove = this.previousPanels.filter((panel) => transitions.panel.indexOf(panel) < 0);
panelsToAdd = transitions.panel.filter((panel) => this.previousPanels.indexOf(panel) < 0);
} else {
panelsToAdd = transitions.panel
}

if (panelsToRemove.length > 0) {
for (let panelToRemove of panelsToRemove) {
this.idPanelMap.get(panelToRemove).moveOut();
}
// wait for fade out to finish then start fade in
timer(PanelComponent.ANIMATION_DURATION + 100).subscribe(() => {
for (let panelToAdd of panelsToAdd) {
this.idPanelMap.get(panelToAdd).setInViewStyle(transitions.width[transitions.panel.indexOf(panelToAdd)], '100', 'initial');
}
for (let panelToRemove of panelsToRemove) {
this.idPanelMap.get(panelToRemove).setDefault();
}
});
} else { // first time so just fade in
for (let panelToAdd of panelsToAdd) {
this.idPanelMap.get(panelToAdd).setInViewStyle(transitions.width[transitions.panel.indexOf(panelToAdd)], '100', 'initial');
}
}

this.previousPanels = transitions.panel;
}
}


As you can see I have completely changed the logic so I first move out panels that have to be removed wait for the animation to finish and then move in the new panels.
Here is a link to my StackBlitz sample that implements all this so you can also see it working.



As requested in the comment I provide also another sample with moving in both directions. This makes things more complicated. I had to add one more transition for the move in the other direction. And added the possibility to set the direction in the moveOut method. In my opinion it does not look so good because it can have some flicker.
The new panel component code:



import { Component, ContentChild, QueryList,HostBinding,Input,ElementRef } from '@angular/core';
import {
trigger,
state,
style,
animate,
transition
} from '@angular/animations';
import { timer } from 'rxjs';

@Component({
selector: 'my-panel',
templateUrl: './panel.component.html',
styleUrls:['./panel.component.css'],
animations: [
trigger('transition', [
state('right', style({
transform: 'translateX(100%)',
opacity: 0
})),
state('inview', style({
})),
state('left', style({
transform: 'translateX(-100%)',
opacity: 0
})),
transition('right => inview', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-out`,style({
transform: 'translateX(0)',
opacity: 1 }))
]),
transition('inview => left', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-in`,style({
transform: 'translateX(-100%)',
opacity: 0 }))
]),
transition('inview => right', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-in`,style( {
transform: 'translateX(100%)',
opacity: 0
}))
]),
transition('left => inview', [
animate(`${PanelComponent.ANIMATION_DURATION}ms 0ms ease-out`,style({
transform: 'translateX(0)',
opacity: 1 }))
])
])]
})
export class PanelComponent {
public static readonly ANIMATION_DURATION = 500;
public static readonly ANIMATION_DELAY = 100;
@Input() destroyOnHidden: boolean = false;
@Input() id : string = null;
@ContentChild('layout') contentChild : QueryList<ElementRef>;
@HostBinding('style.width') componentWidth = null;
@HostBinding('style.height') componentHeight = null;
@HostBinding('style.overflow') componentOverflow = null;
public state: string = null;
private lastDirection: 'left' | 'right';

public getId() {
return this.id;
}

constructor() {
this.state = 'right';
}

public setInViewStyle(width: string, height: string, overflow: string): void {
this.componentWidth = width + '%';
this.componentHeight = height + '%';
this.componentOverflow = overflow;
this.state = 'inview';
}

public setDefault(): void {
this.state = 'right';
}

public moveOut(direction: 'left' | 'right'): void {
this.lastDirection = direction;
this.state = direction;
}


public transitionDoneHide(): void {
if(this.state === this.lastDirection) {
if (this.lastDirection === 'right') {
timer(PanelComponent.ANIMATION_DELAY).subscribe(() => this.hide());
} else {
this.hide();
}
console.log('hiding transition done');

}
}

private hide() {
this.componentWidth = '0' + '%';
this.componentHeight = '0' + '%';
this.componentOverflow = 'hidden';
}
}


In the panelTransformation method I added the logic to set the direction for moving out to right if it is the first panel.
This is the updated code:



panelTransformation(transitions) {
if (transitions) {
let movement = null;
let panelsToRemove = ;
let panelsToAdd = ;
if (this.previousPanels) {
panelsToRemove = this.previousPanels.filter((panel) => transitions.panel.indexOf(panel) < 0);
panelsToAdd = transitions.panel.filter((panel) => this.previousPanels.indexOf(panel) < 0);
} else {
panelsToAdd = transitions.panel
}

if (panelsToRemove.length > 0) {
for (let panelToRemove of panelsToRemove) {
let direction: 'left' | 'right' = 'left';
// if it is the first panel we move out right
if (this.previousPanels.indexOf(panelToRemove) === 0) {
direction = 'right';
}
this.idPanelMap.get(panelToRemove).moveOut(direction);
}
// wait for fade out to finish then start fade in
timer(PanelComponent.ANIMATION_DURATION + PanelComponent.ANIMATION_DELAY).subscribe(() => {
for (let panelToAdd of panelsToAdd) {
this.idPanelMap.get(panelToAdd).setInViewStyle(transitions.width[transitions.panel.indexOf(panelToAdd)], '100', 'initial');
}
for (let panelToRemove of panelsToRemove) {
this.idPanelMap.get(panelToRemove).setDefault();
}
});
} else { // first time so just fade in
for (let panelToAdd of panelsToAdd) {
this.idPanelMap.get(panelToAdd).setInViewStyle(transitions.width[transitions.panel.indexOf(panelToAdd)], '100', 'initial');
}
}

this.previousPanels = transitions.panel;
}
}


And also the StackBlitz sample for this implementation.







share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 11 at 23:10

























answered Jan 9 at 23:28









AlesDAlesD

2,886414




2,886414













  • really thank you i guess you have nailed it but one slight thing i would ask on this . in the example when we given panel 1 and 2 and then go to panel 2 and 3 it works great but from that view when we move to panel 1 and 2 again panel 1 should come from left don't you thing it is coming from right . any pointers how we control the direction as the order of panel is fixed for us 1 -> 2 -> -> 3- >4

    – Rahul Singh
    Jan 11 at 7:44













  • Please let me know if we can give the direction of the transition here , it would look great right as the panels are in order. even if you are not able to give anything on this i will give it to you thanks a ton. looking forward for your reply

    – Rahul Singh
    Jan 11 at 7:45











  • I have added another implementation to the answer where you can specify the direction of the animation.

    – AlesD
    Jan 11 at 23:13











  • AlesD i get it there is some flicker i will try and refine the same thanks a ton, even 500 bounty was less for your answer i got some real insights on how we can achieve this thanks

    – Rahul Singh
    Jan 14 at 5:41





















  • really thank you i guess you have nailed it but one slight thing i would ask on this . in the example when we given panel 1 and 2 and then go to panel 2 and 3 it works great but from that view when we move to panel 1 and 2 again panel 1 should come from left don't you thing it is coming from right . any pointers how we control the direction as the order of panel is fixed for us 1 -> 2 -> -> 3- >4

    – Rahul Singh
    Jan 11 at 7:44













  • Please let me know if we can give the direction of the transition here , it would look great right as the panels are in order. even if you are not able to give anything on this i will give it to you thanks a ton. looking forward for your reply

    – Rahul Singh
    Jan 11 at 7:45











  • I have added another implementation to the answer where you can specify the direction of the animation.

    – AlesD
    Jan 11 at 23:13











  • AlesD i get it there is some flicker i will try and refine the same thanks a ton, even 500 bounty was less for your answer i got some real insights on how we can achieve this thanks

    – Rahul Singh
    Jan 14 at 5:41



















really thank you i guess you have nailed it but one slight thing i would ask on this . in the example when we given panel 1 and 2 and then go to panel 2 and 3 it works great but from that view when we move to panel 1 and 2 again panel 1 should come from left don't you thing it is coming from right . any pointers how we control the direction as the order of panel is fixed for us 1 -> 2 -> -> 3- >4

– Rahul Singh
Jan 11 at 7:44







really thank you i guess you have nailed it but one slight thing i would ask on this . in the example when we given panel 1 and 2 and then go to panel 2 and 3 it works great but from that view when we move to panel 1 and 2 again panel 1 should come from left don't you thing it is coming from right . any pointers how we control the direction as the order of panel is fixed for us 1 -> 2 -> -> 3- >4

– Rahul Singh
Jan 11 at 7:44















Please let me know if we can give the direction of the transition here , it would look great right as the panels are in order. even if you are not able to give anything on this i will give it to you thanks a ton. looking forward for your reply

– Rahul Singh
Jan 11 at 7:45





Please let me know if we can give the direction of the transition here , it would look great right as the panels are in order. even if you are not able to give anything on this i will give it to you thanks a ton. looking forward for your reply

– Rahul Singh
Jan 11 at 7:45













I have added another implementation to the answer where you can specify the direction of the animation.

– AlesD
Jan 11 at 23:13





I have added another implementation to the answer where you can specify the direction of the animation.

– AlesD
Jan 11 at 23:13













AlesD i get it there is some flicker i will try and refine the same thanks a ton, even 500 bounty was less for your answer i got some real insights on how we can achieve this thanks

– Rahul Singh
Jan 14 at 5:41







AlesD i get it there is some flicker i will try and refine the same thanks a ton, even 500 bounty was less for your answer i got some real insights on how we can achieve this thanks

– Rahul Singh
Jan 14 at 5:41






















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53910367%2ftransitions-in-angular%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

A Topological Invariant for $pi_3(U(n))$