我正在尝试基于这个想法Wizdm Genesys实现 Animate On Scroll 库/助手
当元素与视口相交时,我有一个服务会发出IntersectionInfo
(IsIntersecting、Direction、IsEntering 等)对象。
我订阅它,如果元素正在进入视口,我会触发进入动画。
除非我ChangeDetection.OnPush
在包含该元素的任何组件或其任何父级上
使用它,否则它工作正常。detectChanges()
不修复它。
奇怪的是变量正在改变,我可以在开发者工具中看到它,但它没有触发动画。
使用滚动动画库 (HelloComponent.html) 的组件:
<button mat-button color="primary" (click)="_replay = !_replay" >Primary</button>
<ng-container *ngFor="let item of items; let idx = index">
<div class="item-container" myAos [animate]="_replay">
<div class="item">
{{item}}
</div>
</div>
</ng-container>
在我使用的 AosComponnentselector: '[myAos]'
中,它可以像指令一样使用。
这是 AosComponent
@Component({
selector: '[myAos]',
template: `
<!-- H5 is just for testing info -->
<h5>{{ trigger | json }}</h5>
<ng-content></ng-content>
`,
styleUrls: ['./aos.component.scss'],
animations: [
trigger('aosAnimate', [
state('idle-bumpIn', style({ opacity: 0 })),
transition(
'* => bumpIn',
[
style({ transform: 'scale(0.5)', opacity: 0 }),
animate(
'{{timing}} {{delay}} cubic-bezier(.8, -0.6, 0.2, 1.5)',
style({ transform: 'scale(1)', opacity: 1 })
)
],
{ params: { timing: '500ms', delay: '' } }
),
// None
state('none', style('*')),
state('idle-none', style('*'))
])
]
})
export class AosComponent implements OnInit {
@Input('debounce') _debounce = 0;
@Input('rootMargin') _rootMargin = '0px';
@Input('root') _root: HTMLElement | undefined = undefined;
@Input('threshold') _threshold: number = 0;
@Input('delaySecs') _delay: number = 0.25;
@Input('durationSecs') _duration: number = 0.5;
private destroy$ = new Subject();
@HostBinding('@aosAnimate')
public trigger: any = 'none';
@Input()
set animate(trgr: boolean) {
this.trigger = !trgr
? 'idle-bumpIn'
: {
value: 'bumpIn',
params: {
timing: `${this._duration}s`,
delay: `${this._delay}s`
}
};
this._cd.detectChanges();
console.log('animate Input', trgr, this.trigger);
}
//-----------------------------------------------------//
constructor(
private _element: ElementRef,
private renderer: Renderer2,
private _scroll: IntersectionService,
private _cd: ChangeDetectorRef
) {} //ctor
//-----------------------------------------------------//
ngOnInit(): void {
// const me = this
this._scroll
.observeIntersection(
this._element,
this._threshold,
this._root,
this._rootMargin
)
.pipe(takeUntil(this.destroy$))
.subscribe(info => {
this.animate = info.isEntering;
console.log('observeIntersection', info.isEntering);
this._cd.detectChanges();
});
} //ngOnInit
//-----------------------------------------------------//
ngOnDestroy() {
this.destroy$.next();
} //ngOnDestroy
//-----------------------------------------------------//
} //Cls
如果我@Input() animate
从内部设置为 true,HelloComponent
它总是有效的。如果我设置@Input() animate
为 true ,则它仅在我从中subscribe
删除时才有效changeDetection: ChangeDetectionStrategy.OnPush
HelloComponent
你好组件.ts
@Component({
selector: 'hello',
templateUrl: './hello.component.html',
styleUrls: ['./hello.component.scss']
// changeDetection: ChangeDetectionStrategy.OnPush <--- this is the problem
})
export class HelloComponent {
_replay = false;
items = ['item 1', 'item 2', 'item 3', 'item 4', 'item 5'];
}
StackBlitz 在这里:我的 Stackblitz
有任何想法吗???