Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fade in and fade out component in Angular

I have a todo list app that I wrote in angular and I wanted to fade in each todo, when it is created and fade them out before they are deleted. I was only able to get the fade in effect to work, if I apply the effect in the todo-item component, however the fade out effect wouldn't work. I've tried adding the animation to the parent todos component however, that doesn't work for either the fade in or fade out.

todos.component.ts (parent container of todo-items)

animations: [
    trigger('fade', [      
      transition('void => *', [
        style({opacity: 0}),
        animate(1000, style({opacity: 1}))
      ]),
      transition('* => void', [
        animate(1000, style({opacity: 0}))
      ])
    ])

]
})
export class TodosComponent implements OnInit {
  todos:Todo[];
  constructor(private todoService:TodoService) {
   }

  ngOnInit() {
    this.todoService.getTodos().subscribe(todos=> { this.todos = todos});
  }
  deleteTodo(todo:Todo){
    this.todos.splice(this.todos.indexOf(todo), 1);
    this.todoService.deleteTodo(todo).subscribe();
  }
  addTodo(todo:Todo){
    this.todoService.addTodo(todo).subscribe(todo=>{
      this.todos.push(todo);

    })
  }
}

todos.component.html (parent container of todo-items)

<app-add-todo (addTodo)="addTodo($event)"></app-add-todo>
<app-todo-item 
@fade
*ngFor="let todo of todos" 
[todo] = "todo"
(deleteTodo)="deleteTodo($event)"
>
</app-todo-item>

todo-item.component.ts

export class TodoItemComponent implements OnInit {
  @Input() todo: Todo;
  @Output() deleteTodo: EventEmitter<Todo> = new EventEmitter();

  setClasses(){
    let classes = {
      todo: true,
      'is-complete': this.todo.completed
    }

    return classes
  }
  onToggle(todo) {
    todo.completed = !todo.completed;
    this.todoService.toggleCompleted(todo).subscribe( todo => console.log(todo));
  }
  onDelete(todo){
    this.deleteTodo.emit(todo);
  }
  constructor(private todoService:TodoService) { }

  ngOnInit() {
  }

}

todo-item.component.html

<div [ngClass] = "setClasses()">
    <p>
        <input (change)="onToggle(todo)" type="checkbox"/>
        {{todo.title}}
        <button (click)="onDelete(todo)" class="del">x</button>
    </p>   
</div>
like image 329
C. Downer Avatar asked Dec 22 '19 16:12

C. Downer


People also ask

What is fade in and fade out in animation?

In android, Fade In and Fade Out animations are used to change the appearance and behavior of the objects over a particular interval of time. The Fade In and Fade Out animations will provide a better look and feel for our applications.

What is Fade in Fade out effect?

The Fade In/Fade Out behavior lets you dissolve into and out of any object by ramping the opacity of the object from 0 percent to 100 percent at the start, and then back to 0 percent at the end. You can eliminate the fade-in or fade-out effect by setting the duration of the Fade In Time or Fade Out Time to 0 frames.

What is the use of fade out option?

Definition and Usage The fadeOut() method gradually changes the opacity, for selected elements, from visible to hidden (fading effect). Note: Hidden elements will not be displayed at all (no longer affects the layout of the page). Tip: This method is often used together with the fadeIn() method.

How do you fade in and out in CSS?

In the CSS, use the @keyframes rule paired with fadeIn. At 0%, set the opacity to 0. At 100%, set the opacity to 1. This creates the fade-in effect.


3 Answers

For Animations I often use https://animista.net/ they offer simple animations in css.

To use them, you then only need to add the class to fade int, when clicking delete, you need to set the class for fading out - after the animation finished you really delete the object with a timer.

When deleting you need to dynamically set it to another class something like that can work:

<div [className]="someValue"></div>

(from: https://malcoded.com/posts/angular-ngclass/)

When deleting you also need to create a timer, such that the element is only deleted after the animation finished. Example for a simple timer:

// repeat with the interval of 2 seconds
let timerId = setInterval(() => alert('tick'), 2000);

// after 5 seconds stop
setTimeout(() => { clearInterval(timerId); alert('stop'); }, 5000);

Hope it helps!

like image 101
Kennuel Avatar answered Sep 22 '22 22:09

Kennuel


I have added one more field to ToDo class, status of perticular todo-item.

Using this status, we can transition the animation state by binding the status property to @fade

Demo

Here, I am deleting any random item added in list.

todo-parent.component.ts

@Component({
  selector: 'app-todo-parent',
  templateUrl: './todo-parent.component.html',
  styleUrls: ['./todo-parent.component.css'],
  animations: [
    trigger('fade', [
      transition('void => active', [ // using status here for transition
        style({ opacity: 0 }),
        animate(1000, style({ opacity: 1 }))
      ]),
      transition('* => void', [
        animate(1000, style({ opacity: 0 }))
      ])
    ])
  ]
})
export class TodoParentComponent {

  todoList: {str: string, status: string}[] = [];

  addItem() {
    this.todoList.push({str: 'added :' + this.todoList.length, status: 'active'});
  }

  deleteRandom() {
    const num = Math.ceil(Math.random() * this.todoList.length);
    this.todoList.splice(num, 1);
  }
}

todo-parent.component.html

<div style="width: 250px">
  <div *ngFor="let todo of todoList" [@fade]="todo.status"> <!-- using status here for transition -->
    <app-todo-item [todoValue]="todo.str"></app-todo-item>
  </div>
</div>

There is no need to do anything in your todo-item component.

like image 30
Plochie Avatar answered Sep 22 '22 22:09

Plochie


So I figured out the answer to my problem. The fade effect won't apply to component tags. So in my todos.component.html (parent todo-item container) I created a div to wrap my todo-item tag in; and I applied the trigger name to it.

my modified todos.component.html

<app-add-todo (addTodo)="addTodo($event)"></app-add-todo>
<div @fade *ngFor="let todo of todos">
<app-todo-item [todo] = "todo" (deleteTodo)="deleteTodo($event)">
</app-todo-item>
</div>
like image 41
C. Downer Avatar answered Sep 25 '22 22:09

C. Downer