Angular2 анимации, медиа-запросы
Я играл с анимацией DSL Angular2, и я немного смущен тем, как ограничить анимацию конкретными размерами экрана мультимедиа.
например, скажем, у меня есть логотип, который на домашней странице имеет ширину 400px и сжимается до 200px, когда пользователь посещает любую другую страницу на мониторе компьютера.
...
animations: [
trigger('homeLogoState',[
state('inactive', style({
width: '200px',
transition: 'width'
})),
state('active', style({
width: '400px',
transition: 'width'
})),
transition('inactive <=> active', animate('300ms ease-in'))
])
]
...
но на мобильном устройстве он должен оставаться на 100px для каждой страницы.
Я понимаю, что могу управлять различными анимациями управление тем, что отображается в DOM, как показано ниже, но это может создать безумное количество дублирования кода для обработки каждого варианта анимации для каждого размера экрана.
<div class="hidden-under-1920px" @logoAnimationOne="page">
<img src="logo.png">
</div>
<div class="hidden-under-1280px" @logoAnimationTwo="page">
<img src="logo.png">
</div>
каков правильный способ ограничить различные анимации конкретными размерами селектора @media?
2 ответов
у меня есть решение, просто не знаю, является ли это лучшим. У меня была похожая проблема, но решена.
у меня есть переменная, которая говорит, что если она открыта или закрыта (menuOpen), только варьируется между true и false, а переменная с тремя состояниями: 0 или 1 или 2 (onOpen) У меня три состояния, вы видите это здесь
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'))
])
]....
вы можете сделать одну функцию для разрешения, я в том, что я не сделал
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;
}
}
}
в моем шаблоне у меня есть это
<div class="geral" [@visibilityChanged]="onOpen"></div>
Я думаю в вашему делу придется иметь дело с большим количеством Штатов.
существует более простой способ достичь этого с помощью обратных вызовов анимации. В шаблоне вы делаете:
...
<element [@triggerName]="state"
(@triggerName.start)="animationStarted($event)"
(@triggerName.done)="animationDone($event)">
...
затем в компоненте:
...
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);
}
...
а затем в css вы можете делать медиа-запросы, такие как:
.some-element{
// styles here
// some media query
@media ... {
&.class1 {
// class1 styles here
}
&.class2 {
// class2 styles here
}
...