I am creating a simple, single page site (mostly to learn Angular), and cant seem to figure out how to use a single animation to affect different DOM elements. I could define the animation for each element, but that seems extremely ineffective.
Is there a way to animate the image within the clicked button without defining a separate animation block for each element?
Thank you, Terry
<!-- HTML: -->
<button mat-flat-button (click)="finishedChore()">
<img
[@openClose]="isOpen ? 'open' : 'closed'"
src="assets/images/morning.png"
/>
</button>
<button mat-flat-button (click)="finishedChore()">
<img
[@openClose]="isOpen ? 'open' : 'closed'"
src="assets/images/poop.png"
/>
</button>
<button mat-flat-button (click)="finishedChore()">
<img
[@openClose]="isOpen ? 'open' : 'closed'"
src="assets/images/cleanRoom.png"
/>
</button>
<button mat-flat-button (click)="finishedChore()">
<img
[@openClose]="isOpen ? 'open' : 'closed'"
src="assets/images/cleanSinks.png"
/>
</button>
<button mat-flat-button (click)="finishedChore()">
<img
[@openClose]="isOpen ? 'open' : 'closed'"
src="assets/images/evening.png"
/>
</button>
// .ts file
import { Component, OnInit } from '@angular/core';
import {
trigger,
state,
style,
animate,
transition,
} from '@angular/animations';
@Component({
selector: 'app-chore-list',
templateUrl: './chore-list.component.html',
styleUrls: ['./chore-list.component.scss'],
animations: [
trigger('openClose', [
state('closed', style({ backgroundColor: '' })),
state('open', style({ backgroundColor: 'blue' })),
transition('closed<=>open', [animate('0.3s 0.0s ease-in')]),
]),
],
})
export class ChoreListComponent implements OnInit {
isOpen = false;
constructor() {}
ngOnInit(): void {}
finishedChore() {
this.isOpen = !this.isOpen;
}
}
yes it is possible to use a single animation block
here the issue is you are using single isOpen
variable and single finishedChore()
function that affects this variable so when one of the buttons is clicked it will change for all of them so my suggestion would be look like this
<button mat-flat-button (click)="finishedChore('morning')">
<img [@openClose]="ismorning" src="assets/images/morning.png" />
</button>
<button mat-flat-button (click)="finishedChore('poop')">
<img [@openClose]="ispoop" src="assets/images/poop.png" />
</button>
<button mat-flat-button (click)="finishedChore('cleanRoom')">
<img [@openClose]="iscleanRoom" src="assets/images/cleanRoom.png" />
</button>
<button mat-flat-button (click)="finishedChore('cleanSinks')">
<img [@openClose]="iscleanSinks" src="assets/images/cleanSinks.png" />
</button>
<button mat-flat-button (click)="finishedChore('evening')">
<img [@openClose]="isevening" src="assets/images/evening.png" />
</button>
the .ts file
import { Component, OnInit } from "@angular/core";
import {
trigger,
state,
style,
animate,
transition
} from "@angular/animations";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
animations: [
trigger("openClose", [
state("false", style({ backgroundColor: "" })),
state("true", style({ backgroundColor: "blue" })),
transition("false<=>true", [animate("0.3s 0.0s ease-in")])
])
]
})
export class ChoreListComponent implements OnInit {
//flower list can be done dynamically
isevening = false;
iscleanSinks = false;
ismorning = false;
ispoop = false;
iscleanRoom = false;
flowerList = ["morning", "poop", "cleanSinks", "cleanRoom", "evening"];
ngOnInit(): void {}
finishedChore(flowerClicked) {
this.flowerList.forEach((flowername) => {
let varName = "is" + flowername; // assume this as "is"+'noop'=>isnoop
console.log(varName);
if (flowerClicked == flowername) {
this[varName] = !this[varName];
} else {
this[varName] = false;
}
});
}
}