Transitions in Angular
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 .
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
|
show 8 more comments
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 .
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
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
|
show 8 more comments
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 .
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
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 .
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
angular css-transitions angular-animations
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
|
show 8 more comments
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
|
show 8 more comments
1 Answer
1
active
oldest
votes
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.
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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