Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 animations media queries

I have been playing around with Angular2's animation DSL and I'm a bit confused as to how restrict animations to specific media screen sizes.

For example, lets say I have a logo that on the home page is 400px wide and shrinks to 200px wide when the user visits any other page on a computer monitor.

...
animations: [
trigger('homeLogoState',[
    state('inactive', style({
      width: '200px',
      transition: 'width'
    })),
    state('active', style({
      width: '400px',
      transition: 'width'
    })),
    transition('inactive <=> active', animate('300ms ease-in'))
  ])
]
...

Yet on a mobile device it needs to remain at 100px for every page.

I understand I could control different animations by controlling what is displayed in the DOM, like below, but that could create an insane amount of code duplication to handle each animation variation for each screen size.

<div class="hidden-under-1920px" @logoAnimationOne="page">
  <img src="logo.png">
</div>
<div  class="hidden-under-1280px" @logoAnimationTwo="page">
  <img src="logo.png">
</div>

What's the proper way to constrain different animations to specific @media selector sizes?

like image 507
BrentShanahan Avatar asked Aug 05 '16 20:08

BrentShanahan


People also ask

When animations are disabled in Angular?

To disable all animations for an Angular app, place the @. disabled host binding on the topmost Angular component. NOTE: Disabling animations application-wide is useful during end-to-end (E2E) testing.

Which animation strategy would you use if there were multiple animations that had to occur at the same time?

A staggered animation consists of sequential or overlapping animations. To create a staggered animation, use multiple Animation objects.

What is @angular animations?

Angular animations ( @angular/animations) is a powerful module that comes with Angular which provides a DSL (domain specific language) for defining web animation sequences for HTML elements as multiple transformations over time which could occur sequentially or in parallel.

What are the benefits of media queries in angular components?

Media queries in Angular components allows to get following benefits Media queries in CSS helps to target the styles certain sizes - desktop,mobile, Tablet and hug sizes. Media queries need to write a different breakpoints for each device resolution Size of the different devices

What is browseranimationsmodule in angular?

Before animating, the BrowserAnimationsModule must include into the root module’s imports array. It is available from @angular/platform-browser/animations. This NgModule ensures animations work for the given platform. This article assumes the standard web browser for each example. Angular animations declare within the @Component metadata.

How do I animate embedded views in angular?

As per the Angular docs, this is done by defining a nested animation sequence in the top-level component that hosts the view and the components that host the embedded views. This could also be applied to nested router-outlet s in your application, the animation trigger just needs to be applied to the div that wraps the router-outlet.


2 Answers

I have a solution, just do not know if it's the best. I had a similar problem, but solved.

I have a variable that says if it is open or closed (menuOpen) only varies between true and false, and a variable with three states: 0 or 1 or 2 (onOpen) I have three states, you see it here

import { Component, trigger, state, animate, transition, style, HostListener} from '@angular/core'
        ....
        ....
        animations: [
                trigger('visibilityChanged', [
                    state('0', style({ width: '50px' })),
                    state('1', style({ width: '25%' })),
                    state('2', style({ width: '100%' })),
                    transition('* => *', animate('.3s'))
                ])
            ]....

You can make a single function to resolution, I is that I have not done

    export class AppComponent {
        wt;

        @HostListener('window:resize', ['$event'])
        sizeWindow(event) {
            this.wt = event.target.innerWidth;
            this.sizeMenu(this.wt);
            console.log('width =>', this.wt);
        }

        constructor() {
            this.wt = window.innerWidth;
        }

        sizeMenu(width) {
            if (this.menuOpen === true) {
                if (width >= 600) {
                    this.onTestOpen = 1;

                } else if (width < 600) {
                    this.onTestOpen = 2;
                }

            } else if (this.menuOpen === false) {
                this.onTestOpen = 0;

            }

          }

        openMenu() {
                let wwt = window.innerWidth;
                if (this.menuOpen === false) {
                    if (wwt >= 600) {
                        this.onTestOpen = 1;

                    } else if (wwt < 600) {
                        this.onTestOpen = 2;
                    }
                    this.menuOpen = true;

                } else if (this.menuOpen === true) {

                    this.onTestOpen = 0;
                    this.menuOpen = false;

                }

            }
    }

in my template I have it

<div class="geral" [@visibilityChanged]="onOpen"></div>

I think in your case will have to deal with more states.

like image 126
Ketty Miilher Avatar answered Oct 11 '22 14:10

Ketty Miilher


There is a simpler way to achieve this with animation callbacks. In template you do:

...
<element [@triggerName]="state"
       (@triggerName.start)="animationStarted($event)"
       (@triggerName.done)="animationDone($event)">
...

then in the component:

...
 animationStarted(event) {
    // remove all classes you use. E.g.:
    event.element.classList.remove('class1');
    event.element.classList.remove('class2');
  }

  animationDone(event) {
    // add class based on the state. E.g:
    const classToApply = this.state ? 'class1' : 'class2';
    event.element.classList.add(classToApply);
  }
...

and then in the css you can do media queries like:

.some-element{
  // styles here

  // some media query
  @media ... {

    &.class1 {
      // class1 styles here
    }

    &.class2 {
      // class2 styles here
    }
    ...
like image 37
jbojcic Avatar answered Oct 11 '22 13:10

jbojcic