Angular animate the whole page content on click of a button - html

I want to animate from bottom when I click on link. Below is the image what I want to achieve. On click of Link whole "Red" section should be animated and come from the bottom side. To achieve that What I did is:
What I tried is:
#Component({
selector: 'mypage',
templateUrl: './mypage.component.html',
styleUrls: ['./mypage.component.scss'],
animations: [
trigger('slideInOut', [
state('flyIn', style({
transform: 'translateX(0)'
})),
transition(':enter', [
style({
transform: 'translateX(-100%)'
}),
animate('0.5s 300ms ease-in')
]),
transition(':leave', [
animate('0.3s ease-out', style({
transform: 'translateX(100%)'
}))
])
])
],
});
animationState = "flyIn";
dataRefresh(id) {
this.animationState = 'flyIn';
}
<div [#slideInOut]="animationState">
<!-- Here is other page content, which I need to animate from bottom -->
<div class="col-lg-10 col-md-10 col-10" (click)="dataRefresh(id)">
<div class="row">
<div class="col-lg-12 col-md-12 col-12">
<div class="branch_row_padding">
<div class="">Name</div>
<div class="">Description</div>
</div>
</div>
</div>
</div>
</div>
By trying above, what happens only link div is animating from left side, I want to animate whole page.
What can be the possible solution for this?

Why not do it with just CSS?
relevant css:
.myAnimateClass{
border:1px solid red;display:block; animation: example 3s ease-in-out;
}
#keyframes example {
from {margin-left:-100%;}
to {margin-left:0;}
}
relevant TS:
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
name = 'Angular 6';
show: boolean = true;
myAnimateClass: string = '';
resetClass() {
console.log("check");
setTimeout(() => {
this.myAnimateClass = 'myAnimateClass';
},100);
}
animatePage() {
if(this.myAnimateClass == 'myAnimateClass') {
this.myAnimateClass = 'something';
this.resetClass();
} else{
this.myAnimateClass = 'myAnimateClass';
}
}
}
relevant HTML:
<div [ngClass]='myAnimateClass'>
<hello name="{{ name }}"></hello>
<p>
Start editing to see some magic happen :)
</p>
<button type="button" (click)='animatePage()'>Animation page</button>
<div >
<!-- Here is other page content, which I need to animate from bottom -->
<div class="col-lg-10 col-md-10 col-10" (click)="dataRefresh(id)">
<div class="row">
<div class="col-lg-12 col-md-12 col-12">
<div class="branch_row_padding">
<div class="">Name</div>
<div class="">Description</div>
</div>
</div>
</div>
</div>
</div>
</div>
check working stackblitz here

Related

Angular animate query returning zero elements

Using Angular, I wanted to make an animated display list. The problem is that I am getting this error:
Objects are in the array and show up on the screen, but are not animated.
This is what the HTML code looks like, where I iterate through the table and display the elements that I want to be slowly displayed (animation):
<section [#listAnimation]="articles.length">
<div *ngFor="let article of articles">
<div class="card border-0">
<div class="row no-gutters">
<div class="col-md-4 mt-3">
<div class="container-text-image">
<img [src]="article.mainImageSrc" onerror="this.onerror=null; this.src='..\..\..\assets\notFound.png';" class="card-img" [alt]="article.mainImageFullName">
<div class="label bottom-left">
<h3 class="label-text">
{{article.category}}
</h3>
</div>
</div>
</div>
<div class="col-md-8">
<div class="card-body">
<h5 class="card-title mt-0">{{article.title}}</h5>
<p *ngIf="article.description != null" class="card-text description-text">{{article.description}}</p>
</div>
</div>
</div>
</div>
</div>
</section>
This is what the animation code looks like in a component:
const listAnimation = trigger('listAnimation', [
transition('* <=> *', [
query(':enter',
[style({ opacity: 0 }), stagger('60ms', animate('600ms ease-out', style({ opacity: 1 })))],
),
query(':leave',
animate('200ms', style({ opacity: 0 })),
)
])
]);
#Component({
selector: 'app-articles',
templateUrl: './articles.component.html',
styleUrls: ['./articles.component.css'],
animations: [listAnimation]
})
Here's a snippet of code where I get my backend data into an array:
private fetchArticles = (): void => {
this.loaderService.show();
this.articlesService
.getPortalArticles(this.getArticlesParams())
.pipe(
finalize(() => {
this.setArticleMainImg();
this.loaderService.hide();
})
)
.subscribe(
(result) => {
this.articlesCount = result.totalItemsCount;
this.articles = result.items;
},
(error) => { }
);
}
Any ideas what might be causing the error? I realize that I can add {optional: true} to the animation code, but this will only get rid of the error and the animation will still not work.

Disable scrolling in typescript as soon as property is true

I have a hamburger inside of my header - as soon as it is clicked, I wan't to disable scroll - since the hamburger is moving on scroll.
I tried to set the hamburger to position: fixed. But this one changed the position of its neighbour, which looked weird.
Is there a way to realize this in typescript - so that as soon clicked is true, scrolling is disabled. Or is there a better approach?
https://stackblitz.com/edit/angular-beiajz
export class HeaderComponent implements OnInit {
clicked = false;
onClick(): void {
this.clicked = !this.clicked;
}
constructor() { }
ngOnInit(): void {
}
}
<div class="container-fluid mobile position-absolute">
<div class="row m-0 w-100">
<div class="col-6 offset-3 justify-content-center d-flex">
<a class="align-self-center" routerLink="">
<h1>NØREBRO STUDIOS</h1>
</a>
</div>
<div class="col-3">
<button class="hamburger hamburger--collapse" (click)="onClick()" [class.is-active]="clicked" type="button">
<span class="hamburger-box">
<span class="hamburger-inner"></span>
</span>
</button>
</div>
<div class="container-fluid position-fixed min-vh-100 px-0 slide-in" [class.get-active]="clicked">
</div>
</div>
</div>
One of the way is passing a event from the child to parent whenever click is made on the hamburger menu and changing the parent class CSS
in app.component.html
<app-test (hamburgerClick)="hamburgerClickEvent($event)"></app-test>
<div [ngClass]="{
'container-fluid-overlay': overlayFlag === true,
'container-fluid': overlayFlag === false }">
</div>
in app.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
overlayFlag = false; // overlay flag..onload overlay is hidden
public hamburgerClickEvent(e:boolean):void{
this.overlayFlag= e;
}
}
in app.component.css
.container-fluid {
min-height: 200vh;
}
.container-fluid-overlay {
height: auto;
}
in test.component.ts
import { Component, OnInit , Output, EventEmitter} from '#angular/core';
#Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.css']
})
export class TestComponent implements OnInit {
#Output() hamburgerClick = new EventEmitter();//emitter
clicked = false;
onClick(): void {
this.clicked = !this.clicked;
this.hamburgerClick.emit(this.clicked); //emitting clicked event to parent
}
constructor() { }
ngOnInit(): void {
}
}
Hope it helps :)

How to show a Form on Click with some delay on Angular 7?

I have to change some angularJS code in Angular 7.
I've got a function that onClick shows me a new form bottom the principal one.
HTML
<img [hidden]= "!skillsToDelete"
(click)="showFormDelete(skill)" title="Delete"
class="cross"
src="../../../assets/icon/deletex.png">
TypeScript
this.showCompDelete = false;
showFormDelete(skill) {
this.showCompDelete = !this.showCompDelete;
this.skillsToDelete.push(skill);
}
HTML DELETE COMPONENT
<div class="col-md-12 col-sm-12 newForm" id="deleteSkill" *ngIf="showCompDelete">
CSS
.newForm{
padding-left: 0;
height: auto;
opacity: 1;
transition: height ease 0.3s, opacity ease 0.3s, margin-bottom ease 0.3s, padding-top ease 0.3s
}
This transition doesn't work, I also tried -webkit but nothing happens.
This was the old one:
HTML
<div class="col-md-12 col-sm-12 newForm" id="deleteSkill" style="display: block;">
JS
$scope.showDeleteForm = function () {
$('#formSkill').hide(300);
$('#formExp').hide(300);
$('#initSkills').hide(300);
$('#certifiedSkill').hide(300);
if($scope.skillToDelete.length){
$('#deleteSkill').show(300);
setTimeout(function () {
$('.yesno').show(200);
}, 300);
}
else{
$('#deleteSkill').hide(300);
$('.yesno').hide(0);
}
};
I would like to avoid css, and add something like "show(300)" in my TS, but if you have ideas also in css I would appreciate it.
As you ask for not using css you can use angular-animation
See working example code
Import animation for ts and use code as below
In animate('1000ms 3000ms' set the time for animation(in this example 1 second) and the time for delay(in this example 3 second)
import { Component } from '#angular/core';
import sdk from '#stackblitz/sdk';
import { animate, state, style, transition, trigger } from '#angular/animations';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ],
animations: [
trigger('showAnimation', [
transition(':enter', [
style({opacity: 0}),
animate('1000ms 3000ms', style({opacity: 1}))
]),
transition(':leave', [
state('invisible', style({opacity: 0})),
style({opacity: 1}),
animate('1000ms 3000ms', style({opacity: 0}))
])
])
],
})
export class AppComponent {
skillsToDelete=false;
showCompDelete=false;
animationState="leave";
showFormDelete(skill) {
this.showCompDelete = !this.showCompDelete;
this.animationState=this.animationState=="enter"?'leave':'enter';
// this.skillsToDelete.push(skill);
}
}
In html use *ngIf and use code as below:
<img *ngIf= "!skillsToDelete"
(click)="showFormDelete(skill)" title="Delete"
class="cross"
src="https://i.stack.imgur.com/B4Ha4.jpg">
<div class="col-md-12 col-sm-12 newForm" id="deleteSkill" *ngIf="showCompDelete" [#showAnimation]="animationState">
form with animation
</div>

Expansion effect in navbar

I'm trying to make an expansion effect in my navbar using angular.
I need when I click in "mostrar informações" the content must ride up.
The problem is that the superior part of my footer is not following the effect.
I try something like:
<footer class="page-footer font-small footer-fundo-cinza">
<div class="container">
<div class="row pt-3">
<div class="col-md-4">
<img src="../../../assets/estilomotocar-rodape.png" class="img-responsive img-fluid">
</div>
</div>
</div>
<div [#fadeInUpDown]="mostrar_informacoes" [#statusDisplay]="mostrar_informacoes" class="row">
<div class="container">
<div class="row">
<div class="col-md-12">
<hr>
</div>
</div>
</div>
</footer>
My animations:
export const statusDisplay =
trigger('statusDisplay', [
state('aberto', style({ display: 'block' })),
state('fechado', style({ display: 'none' })),
transition('fechado => aberto', animate('0ms ease')),
transition('aberto => fechado', animate('0ms 200ms ease'))
])
export const fadeInUpDown =
trigger('fadeInUpDown', [
state('fechado', style({
transform: 'translate3d(0,100%,0)'
})),
state('aberto', style({
transform: 'translate3d(0,0,0)'
})),
transition('fechado <=> aberto', animate('400ms ease'))
])
If I put my animation direct in my footer the effect work but the translate3d make my nav go out the page, making a scroll.
My CSS:
footer{
position: absolute;
bottom: 0;
width: 100%;
}
Your code is not enough to evaluate your problem . Generally in Angular and any other web language you would need to explain your css very good . In that case I would propose a wrapper element :
<div class="wrapper">
<div class="ride-up">
<div class="ride-up-element"> Some text here </div>
</div>
</div
And then the CSS :
.wrapper {
display : flex ;
flex-direction : row/column ;
width : you choose it ;
height : as well :
other-options : also you choose;
}
.ride-up {
width : you choose it ;
height : as well :
}
.ride-up:hover {
some css goes here ....
}
.ride-up-element {
some other css goes here....
}

How to ovveride the css class of root component in its child component - Angular 2?

I have 3 components in angular 2 application.The class="container-fluid content" is css class in app.component.html. This class="container-fluid content" is default css for other components. Now I want to set background-color:blue in the detail component. I tried to set in detail.component.ts like this styles:['.container-fluid content{background-color: blue;}'] It did not work. If I set in app.component.html like this <div class="container-fluid content" style="background-color: blue;"> It applies to both the components. How to override this class="container-fluid content" in detail component?
//my project structure
app
- app.component.html
-app.component.ts
- welcome
-welcome.component.html
-welcome.component.ts
- detail
-detail.component.html
-detail.component.ts
//app.component.html
<div class="container-fluid content">
<router-outlet></router-outlet>
</div>
<app-footer></app-footer>
</div>
//welcome.component.html
<h1>welcome page heading</h1>
<div fxLayout="row" fxLayoutWrap style="padding-bottom: 25px;
padding-top: 25px; margin: auto;justify-content: center" >
<md-card>
<md-card-content>
<h1></h1>
<h2></h2>
<h2>
</h2>
</md-card-content>
</md-card>
</div>
//detail.component.html
<h1>Details page heading</h1>
<div fxLayout="row" fxLayoutWrap style="padding-bottom: 25px;
padding-top: 25px; margin: auto;justify-content: center" >
<md-card>
<md-card-content>
<h1></h1>
<h2></h2>
<h2>
</h2>
</md-card-content>
</md-card>
</div>
//detail.component.ts
import { OnInit, Component } from '#angular/core';
import { DetailService } from '../detail/detail.service';
import { HostBinding} from '#angular/core';
#Component({
providers: [DetailService ]
templateUrl: './detail.component.html',
styles: ['h3 {margin:5px}']
})
export class DetailComponent implements OnInit {
#HostBinding('class.blueClass') blue: boolean = false;
constructor( private _detailService: DetailService ) { }
ngOnInit() {
this.blue = true;
}
}
In child component, you can add this param to #Component.
// child-component.component.ts
#Component({
selector: 'child-component',
templateUrl: 'child-component.component.html',
styleUrls: ['child-component.component.css']
encapsulation: ViewEncapsulation.None
})
// child-component.component.css
.container-fluid content{background-color: blue;}
You can ref this side for more infomartion :
https://blog.thoughtram.io/angular/2015/06/29/shadow-dom-strategies-in-angular2.html
Have you tried with the hostbinding and adding a new class there?
#HostBinding('class.blueClass') blue: boolean = false;
And in the second component just switch that on onInit?
ngOnInit() {
this.blue = true;
}
The other way could be in the component definition, you can add the following line :
host: {'class': 'blueClass'}
and you do the rest of the css work in css instead.