Reputation: 33
I just created my first angular project, and am trying to use Angular Animations to animate my content on scroll (I want content to appear as I scroll through the page) and also add a staggering animation.
for some reason its not working with me, and given that angular 17 is new and came with a lot of changes I couldn't find enough resources for examples.
Component HTML File:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
@defer (on viewport;){
<div class="grid grid-items" [@staggerAnimation]="projects.length">
@for (project of projects; track project.id;) {
<div class="container">
<h4>{{project.name}}</h4>
<p>
{{project.description}}
</p>
<a class="explore-btn" href="{{project.link}}" target="_blank">Explore</a>
</div>
}
</div>
} @placeholder {
<div>Loading Projects...</div>
}
</body>
</html>
Component TS File:
import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';
import { provideAnimations } from '@angular/platform-browser/animations';
import {
trigger,
transition,
query,
stagger,
animate,
keyframes,
style,
} from '@angular/animations';
@Component({
selector: 'app-project-card',
standalone: true,
imports: [],
templateUrl: './project-card.component.html',
styleUrl: './project-card.component.css',
providers: [],
animations: [
trigger('staggerAnimation', [
transition('* => *', [
query(':enter', style({opacity: 0}), {optional: true}),
query(':enter', stagger('300ms', [
animate('1s ease-in', keyframes([
style({opacity: 0, transform: 'translateY(-75px)', offset: 0}),
style({opacity: 0.5, transform: 'translateY(35px)', offset: 0.3}),
style({opacity: 1, transform: 'translateY(0)', offset: 1}),
]))
]))
])
])
],
})
export class ProjectCardComponent {
projects = [ PROJECT OBJECTS HERE]
bootstrapApplication(ProjectCardComponent, {
providers: [provideAnimations()],
});
*Am using a standalone project in angular 17 so there is no need for NgModule file
I tried placing the trigger at the div with "container" and still didn't work.
I also tried removing the @defer which still lead to nothing.
Not sure if it's relevant but this component is a child component.
Upvotes: 3
Views: 1030
Reputation: 56420
First problem was that the animation was not added in the html, it was done with [@staggerAnimation]="projects.length"
After that, please move the defer up to the main div, this was causing the animations to not work, please find below a working example!
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';
import { provideAnimations } from '@angular/platform-browser/animations';
import {
trigger,
transition,
query,
stagger,
animate,
keyframes,
style,
} from '@angular/animations';
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule],
providers: [],
template: `
@defer (on viewport;){
<div class="grid grid-items" [@staggerAnimation]="projects.length">
@for (project of projects; track project.id;) {
<div class="container">
<h4>{{project.name}}</h4>
<p>
{{project.description}}
</p>
<a class="explore-btn" href="{{project.link}}" target="_blank">Explore</a>
</div>
}
</div>
} @placeholder {
<div>Loading Projects...</div>
}
<button (click)="add()">add</button>
`,
animations: [
trigger('staggerAnimation', [
transition('* => *', [
query(':enter', style({ opacity: 0 }), { optional: true }),
query(
':enter',
stagger('300ms', [
animate(
'1s ease-in',
keyframes([
style({
opacity: 0,
transform: 'translateY(-75px)',
offset: 0,
}),
style({
opacity: 0.5,
transform: 'translateY(35px)',
offset: 0.3,
}),
style({ opacity: 1, transform: 'translateY(0)', offset: 1 }),
])
),
])
),
]),
]),
],
})
export class App {
name = 'Angular';
id = 5;
projects = [
{ name: 'test', description: 'test', link: 'https://google.com', id: 1 },
{ name: 'test', description: 'test', link: 'https://google.com', id: 2 },
{ name: 'test', description: 'test', link: 'https://google.com', id: 3 },
{ name: 'test', description: 'test', link: 'https://google.com', id: 4 },
{ name: 'test', description: 'test', link: 'https://google.com', id: 5 },
];
add() {
this.id = this.id++;
this.projects.push({
name: 'test',
description: 'test',
link: 'https://google.com',
id: this.id,
});
}
}
bootstrapApplication(App, {
providers: [provideAnimations()],
});
Upvotes: 4