How to disable Angular animations using dynamic providers?

Viewed 281

I want to disable all Angular Material animations on my page at runtime based on user preferences (button click). I know that I can do it by importing NoopAnimationsModule, but I can't do it dynamically (after user interaction in application).

I'm using Angular Material 8.2 - generally my idea was to import BrowserAnimationsModule normally in my AppModule, but to change providers. At first I did it manually:

{ provide: AnimationDriver, useClass: NoopAnimationDriver },
{ provide: ANIMATION_MODULE_TYPE, useValue: 'NoopAnimations' }

It worked, so then I wanted to take advantage of 'useFactory' to do it more dynamically:

{ provide: ANIMATION_MODULE_TYPE, useValue: 'NoopAnimations' },
{ provide: AnimationDriver,
  deps: [SomeService],
  useFactory: (someService) => someService.getDriver()
}

import { ɵNoopAnimationDriver as NoopAnimationDriver } from '@angular/animations/browser';

@Injectable({
  providedIn: 'root'
})
export class SomeService {
  animationsDisabled: boolean = true;

  constructor() {
  }

  getDriver(): any {
    if (this.animationsDisabled) {
      return new NoopAnimationDriver();
    }
  }
}

It worked, but when I wanted to return AnimationDriver (from BrowserAnimationsModule) based on function instantiateSupportedAnimationDriver() implementation from here there was a problem. Both new WebAnimationsDriver() and new CssKeyframesDriver() set manually are working, but only in some part. Can't really say why - 70% animations work as expected, 30% not.

import { ɵNoopAnimationDriver as NoopAnimationDriver } from '@angular/animations/browser';

@Injectable({
  providedIn: 'root'
})
export class SomeService {
  animationsDisabled: boolean = false;

  constructor() {
  }

  getDriver(): any {
    if (this.animationsDisabled) {
      return new NoopAnimationDriver();
    } else {
      return new WebAnimationsDriver();
      // or return new CssKeyframesDriver()}
  }
}

Next problem/question is - does changing field animationsDisabled dynamically (using for example Subject) can reload useFactory and change AnimationDriver? Maybe there is some other way to do it?

My another try was to use * selector in CSS and set all transitions, transform and other animation properties, but it breaks some other stuff like placeholders:

enter image description here

Is there any way to accomplish this dynamically at runtime?

0 Answers
Related