Angular 使用动画时 smoothscroll 不起作用
Angular smoothscroll not working when using animation
我是 Angular 的新手,尝试设置 smoothScroll:https://github.com/kavil/ng2SmoothScroll
我的视图设置如下:
<piiick-one smoothScroll offset="10" [scrollIf]="step === 1"></piiick-one>
<piiick-two *ngIf="max >= 2" smoothScroll offset="10" [scrollIf]="step === 2"></piiick-two>
<piiick-three *ngIf="max >= 3" smoothScroll offset="10" [scrollIf]="step === 3"></piiick-three>
<piiick-results *ngIf="max >= 4" smoothScroll offset="10" [scrollIf]="step === 4"></piiick-results>
组件设置如下:
export class StepsComponent implements DoCheck {
step: number = 0;
max: number = 0;
private path: string;
constructor(
private route: ActivatedRoute
) {
this.route.params.subscribe(params => this.path = params.path)
}
ngDoCheck() {
switch (this.path) {
case 'one': this.changeStep(1); break;
case 'two': this.changeStep(2); break;
case 'three': this.changeStep(3); break;
case 'results': this.changeStep(4); break;
default: this.changeStep(0); break;
}
}
private changeStep(step) {
var current = this.step;
this.step = step;
if (step > current) {
this.max = step;
}
}
}
应该发生的是,当路由/steps/three
被调用时,它会smoothScroll到id等于[=30的div =]三个。
这一直有效,直到我打开页面转换动画。
我的 app.component
:
现在有了这个代码
import { Component } from '@angular/core';
import { query, style, animate, trigger, transition, group } from '@angular/animations';
const routerTransition = trigger('routerTransition', [
transition('* => home', [
query(':enter, :leave', style({ position: 'fixed', width:'100%' })
, { optional: true }),
group([
query(':enter', [
style({ transform: 'translateX(-100%)' }),
animate('0.5s ease-in-out', style({ transform: 'translateX(0%)' }))
], { optional: true }),
query(':leave', [
style({ transform: 'translateX(0%)' }),
animate('0.5s ease-in-out', style({ transform: 'translateX(100%)' }))
], { optional: true }),
])
]),
transition('* => steps', [
group([
query(':enter, :leave', style({ position: 'fixed', width:'100%' })
, { optional: true }),
query(':enter', [
style({ transform: 'translateX(100%)' }),
animate('0.5s ease-in-out', style({ transform: 'translateX(0%)' }))
], { optional: true }),
query(':leave', [
style({ transform: 'translateX(0%)' }),
animate('0.5s ease-in-out', style({ transform: 'translateX(-100%)' }))
], { optional: true }),
])
])
])
@Component({
selector: 'piiick-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
animations: [routerTransition]
})
export class AppComponent {
prepareRouteTransition(outlet) {
return outlet.activatedRouteData.state;
}
}
当animations
被注释掉时,smoothScroll起作用;但启用后,smoothScroll 不会触发。
有谁知道为什么?
我想我找到了这个问题的答案。
如果发现 post 有人在展示如何在动画完成后触发事件。
所以我创建了一个 AnimationService 这样的:
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class AnimationService {
private animatingSubject = new Subject<boolean>();
animating = this.animatingSubject.asObservable();
constructor() { }
loading(state: boolean) {
this.animatingSubject.next(state);
}
}
用于设置动画状态。
我创建了一个 Animations 组件,就像这样:
<div [@routerTransition]="prepareRouteTransition(outlet)" (@routerTransition.start)="handleStart()" (@routerTransition.done)="handleDone()">
<router-outlet #outlet="outlet"></router-outlet>
</div>
这是放在我的 App.Component 中的,如下所示:
<piiick-header></piiick-header>
<piiick-animations></piiick-animations>
<piiick-spinner></piiick-spinner>
组件代码如下所示:
import { Component } from '@angular/core';
import { query, style, animate, trigger, transition, group } from '@angular/animations';
import { AnimationService } from '../../core/services/animation.service';
const routerTransition = trigger('routerTransition', [
transition('* => home', [
query(':enter, :leave', style({ position: 'fixed', width:'100%' })
, { optional: true }),
group([
query(':enter', [
style({ transform: 'translateX(-100%)' }),
animate('0.5s ease-in-out', style({ transform: 'translateX(0%)' }))
], { optional: true }),
query(':leave', [
style({ transform: 'translateX(0%)' }),
animate('0.5s ease-in-out', style({ transform: 'translateX(100%)' }))
], { optional: true }),
])
]),
transition('* => steps', [
group([
query(':enter, :leave', style({ position: 'fixed', width:'100%' })
, { optional: true }),
query(':enter', [
style({ transform: 'translateX(100%)' }),
animate('0.5s ease-in-out', style({ transform: 'translateX(0%)' }))
], { optional: true }),
query(':leave', [
style({ transform: 'translateX(0%)' }),
animate('0.5s ease-in-out', style({ transform: 'translateX(-100%)' }))
], { optional: true }),
])
])
])
@Component({
selector: 'piiick-animations',
templateUrl: './animations.component.html',
styleUrls: ['./animations.component.scss'],
animations: [routerTransition]
})
export class AnimationsComponent {
constructor(private animationService: AnimationService) { }
prepareRouteTransition(outlet) {
return outlet.activatedRouteData.state;
}
handleStart(e) {
this.animationService.loading(true);
}
handleDone(e) {
this.animationService.loading(false);
}
}
如您所见,当动画开始时,它会更新 AnimationService 并将动画 属性 设置为 true,当它完成动画时,它只会更新再次服务并将 属性 设置为 false。
现在只是让它与 smoothScroll 一起工作。
起初我无法让它工作,然后我想这不仅仅是我必须等待的动画,还有内容;所以我在视图初始化后更新的 StepsComponent 添加了一个 属性。
我将 HTML 更新为:
<div *ngIf="scrollIf">
<piiick-one smoothScroll offset="10" [scrollIf]="step === 1"></piiick-one>
<piiick-two *ngIf="max >= 2" smoothScroll offset="10" [scrollIf]="step === 2"></piiick-two>
<piiick-three *ngIf="max >= 3" smoothScroll offset="10" [scrollIf]="step === 3"></piiick-three>
<piiick-results *ngIf="max >= 4" smoothScroll offset="10" [scrollIf]="step === 4"></piiick-results>
<piiick-navigation></piiick-navigation>
</div>
然后将代码更改为:
export class StepsComponent implements DoCheck, AfterViewInit {
step: number = 0;
max: number = 0;
scrollIf: boolean = false;
private path: string;
private afterViewInit: boolean;
private viewAnimating: boolean;
constructor(
private route: ActivatedRoute,
private animationService: AnimationService
) {
this.route.params.subscribe(params => this.path = params.path);
this.animationService.animating.subscribe(animating => this.viewAnimating = animating);
}
ngAfterViewInit() {
this.afterViewInit = true;
}
ngDoCheck() {
if (this.afterViewInit) {
switch (this.path) {
case 'one': this.changeStep(1); break;
case 'two': this.changeStep(2); break;
case 'three': this.changeStep(3); break;
case 'results': this.changeStep(4); break;
default: this.changeStep(0); break;
}
this.scrollIf = this.afterViewInit && !this.viewAnimating;
}
}
private changeStep(step) {
var current = this.step;
this.step = step;
if (step > current) {
this.max = step;
}
}
}
所以现在动画和 smoothScroll 工作了。我用这种方式遇到的唯一问题是视图在初始化之前不会显示。我不确定这是否是个问题。
我是 Angular 的新手,尝试设置 smoothScroll:https://github.com/kavil/ng2SmoothScroll
我的视图设置如下:
<piiick-one smoothScroll offset="10" [scrollIf]="step === 1"></piiick-one>
<piiick-two *ngIf="max >= 2" smoothScroll offset="10" [scrollIf]="step === 2"></piiick-two>
<piiick-three *ngIf="max >= 3" smoothScroll offset="10" [scrollIf]="step === 3"></piiick-three>
<piiick-results *ngIf="max >= 4" smoothScroll offset="10" [scrollIf]="step === 4"></piiick-results>
组件设置如下:
export class StepsComponent implements DoCheck {
step: number = 0;
max: number = 0;
private path: string;
constructor(
private route: ActivatedRoute
) {
this.route.params.subscribe(params => this.path = params.path)
}
ngDoCheck() {
switch (this.path) {
case 'one': this.changeStep(1); break;
case 'two': this.changeStep(2); break;
case 'three': this.changeStep(3); break;
case 'results': this.changeStep(4); break;
default: this.changeStep(0); break;
}
}
private changeStep(step) {
var current = this.step;
this.step = step;
if (step > current) {
this.max = step;
}
}
}
应该发生的是,当路由/steps/three
被调用时,它会smoothScroll到id等于[=30的div =]三个。
这一直有效,直到我打开页面转换动画。
我的 app.component
:
import { Component } from '@angular/core';
import { query, style, animate, trigger, transition, group } from '@angular/animations';
const routerTransition = trigger('routerTransition', [
transition('* => home', [
query(':enter, :leave', style({ position: 'fixed', width:'100%' })
, { optional: true }),
group([
query(':enter', [
style({ transform: 'translateX(-100%)' }),
animate('0.5s ease-in-out', style({ transform: 'translateX(0%)' }))
], { optional: true }),
query(':leave', [
style({ transform: 'translateX(0%)' }),
animate('0.5s ease-in-out', style({ transform: 'translateX(100%)' }))
], { optional: true }),
])
]),
transition('* => steps', [
group([
query(':enter, :leave', style({ position: 'fixed', width:'100%' })
, { optional: true }),
query(':enter', [
style({ transform: 'translateX(100%)' }),
animate('0.5s ease-in-out', style({ transform: 'translateX(0%)' }))
], { optional: true }),
query(':leave', [
style({ transform: 'translateX(0%)' }),
animate('0.5s ease-in-out', style({ transform: 'translateX(-100%)' }))
], { optional: true }),
])
])
])
@Component({
selector: 'piiick-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
animations: [routerTransition]
})
export class AppComponent {
prepareRouteTransition(outlet) {
return outlet.activatedRouteData.state;
}
}
当animations
被注释掉时,smoothScroll起作用;但启用后,smoothScroll 不会触发。
有谁知道为什么?
我想我找到了这个问题的答案。 如果发现 post 有人在展示如何在动画完成后触发事件。 所以我创建了一个 AnimationService 这样的:
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class AnimationService {
private animatingSubject = new Subject<boolean>();
animating = this.animatingSubject.asObservable();
constructor() { }
loading(state: boolean) {
this.animatingSubject.next(state);
}
}
用于设置动画状态。 我创建了一个 Animations 组件,就像这样:
<div [@routerTransition]="prepareRouteTransition(outlet)" (@routerTransition.start)="handleStart()" (@routerTransition.done)="handleDone()">
<router-outlet #outlet="outlet"></router-outlet>
</div>
这是放在我的 App.Component 中的,如下所示:
<piiick-header></piiick-header>
<piiick-animations></piiick-animations>
<piiick-spinner></piiick-spinner>
组件代码如下所示:
import { Component } from '@angular/core';
import { query, style, animate, trigger, transition, group } from '@angular/animations';
import { AnimationService } from '../../core/services/animation.service';
const routerTransition = trigger('routerTransition', [
transition('* => home', [
query(':enter, :leave', style({ position: 'fixed', width:'100%' })
, { optional: true }),
group([
query(':enter', [
style({ transform: 'translateX(-100%)' }),
animate('0.5s ease-in-out', style({ transform: 'translateX(0%)' }))
], { optional: true }),
query(':leave', [
style({ transform: 'translateX(0%)' }),
animate('0.5s ease-in-out', style({ transform: 'translateX(100%)' }))
], { optional: true }),
])
]),
transition('* => steps', [
group([
query(':enter, :leave', style({ position: 'fixed', width:'100%' })
, { optional: true }),
query(':enter', [
style({ transform: 'translateX(100%)' }),
animate('0.5s ease-in-out', style({ transform: 'translateX(0%)' }))
], { optional: true }),
query(':leave', [
style({ transform: 'translateX(0%)' }),
animate('0.5s ease-in-out', style({ transform: 'translateX(-100%)' }))
], { optional: true }),
])
])
])
@Component({
selector: 'piiick-animations',
templateUrl: './animations.component.html',
styleUrls: ['./animations.component.scss'],
animations: [routerTransition]
})
export class AnimationsComponent {
constructor(private animationService: AnimationService) { }
prepareRouteTransition(outlet) {
return outlet.activatedRouteData.state;
}
handleStart(e) {
this.animationService.loading(true);
}
handleDone(e) {
this.animationService.loading(false);
}
}
如您所见,当动画开始时,它会更新 AnimationService 并将动画 属性 设置为 true,当它完成动画时,它只会更新再次服务并将 属性 设置为 false。
现在只是让它与 smoothScroll 一起工作。 起初我无法让它工作,然后我想这不仅仅是我必须等待的动画,还有内容;所以我在视图初始化后更新的 StepsComponent 添加了一个 属性。
我将 HTML 更新为:
<div *ngIf="scrollIf">
<piiick-one smoothScroll offset="10" [scrollIf]="step === 1"></piiick-one>
<piiick-two *ngIf="max >= 2" smoothScroll offset="10" [scrollIf]="step === 2"></piiick-two>
<piiick-three *ngIf="max >= 3" smoothScroll offset="10" [scrollIf]="step === 3"></piiick-three>
<piiick-results *ngIf="max >= 4" smoothScroll offset="10" [scrollIf]="step === 4"></piiick-results>
<piiick-navigation></piiick-navigation>
</div>
然后将代码更改为:
export class StepsComponent implements DoCheck, AfterViewInit {
step: number = 0;
max: number = 0;
scrollIf: boolean = false;
private path: string;
private afterViewInit: boolean;
private viewAnimating: boolean;
constructor(
private route: ActivatedRoute,
private animationService: AnimationService
) {
this.route.params.subscribe(params => this.path = params.path);
this.animationService.animating.subscribe(animating => this.viewAnimating = animating);
}
ngAfterViewInit() {
this.afterViewInit = true;
}
ngDoCheck() {
if (this.afterViewInit) {
switch (this.path) {
case 'one': this.changeStep(1); break;
case 'two': this.changeStep(2); break;
case 'three': this.changeStep(3); break;
case 'results': this.changeStep(4); break;
default: this.changeStep(0); break;
}
this.scrollIf = this.afterViewInit && !this.viewAnimating;
}
}
private changeStep(step) {
var current = this.step;
this.step = step;
if (step > current) {
this.max = step;
}
}
}
所以现在动画和 smoothScroll 工作了。我用这种方式遇到的唯一问题是视图在初始化之前不会显示。我不确定这是否是个问题。