【发布时间】:2021-12-19 18:17:44
【问题描述】:
我想创建一个自定义图像滑块,我可以在其中动态加载图像,这是工作示例的链接:
https://stackblitz.com/edit/angular-ivy-rwuxjd?file=src/app/app.component.html
滑块正在工作,但有一个问题我想隐藏当前幻灯片并仅翻译传入的幻灯片。新幻灯片应该从最右边翻译。但在这段代码中,当前幻灯片也在翻译中。
【问题讨论】:
标签: angular
我想创建一个自定义图像滑块,我可以在其中动态加载图像,这是工作示例的链接:
https://stackblitz.com/edit/angular-ivy-rwuxjd?file=src/app/app.component.html
滑块正在工作,但有一个问题我想隐藏当前幻灯片并仅翻译传入的幻灯片。新幻灯片应该从最右边翻译。但在这段代码中,当前幻灯片也在翻译中。
【问题讨论】:
标签: angular
前段时间我在SO(第二次更新)中使用了 ngb-carousel 并动画到 left-rigth 和 rigth-left(是时候 ngb-carousel 没有动画了) 从 8.0.0 开始,您就有了动画。
我觉得你不能使用 :enter 和 :left 因为只有在输入时才会加载图像。所以,基于之前的SO,你可以定义一个动画像
const animation = [
state('outright', style({ transform: `translateX(100%)` })),
state('outleft', style({ transform: `translateX(-100%)` })),
transition('void=>inleft',[
style({transform:`translateX(0)`}),
]),
transition('void=>outleft',[
style({transform:`translateX(-100%)`}),
]),
transition('*=>inright',[
style({transform:`translateX(-100%)`}),
animate('260ms ease-in',style({ transform: `translateX(0)` }))
]),
transition('*=>inleft',[
style({transform:`translateX(100%)`}),
animate('260ms ease-in',style({ transform: `translateX(0)` }))
]),
transition('*=>outleft', [
animate('260ms ease-in', style({ transform: `translateX(-100%)` }))
]),
transition('*=>outright', [
animate('260ms ease-in',style({ transform: `translateX(100%)` }))
]),
]
查看滑块可以是外向、外向、向内还是向内
所以我定义了一个数组
slideControl: any[] = this.images.map((x,index)=>index ? 'outleft' : 'inleft')
当我们点击下一个或上一个时,我们会调用函数onSlide
onNext() {
if (this.counter != this.images.length - 1) {
this.counter++;
this.onSlide(this.counter,this.counter-1,'right')
}
}
onPrevious() {
if (this.counter > 0) {
this.counter--;
this.onSlide(this.counter,this.counter+1,'left')
}
}
onSlide(current,prev,direction) {
this.slideControl=this.slideControl.map((x, index) => {
return (index == current) ?'in' + direction :
(index == prev) ? 'out' + direction : x
})
}
最后一块拼图是.html
<div class="wrapper" >
<div *ngFor="let img of images; let i = index"
[@animImageSlider]="slideControl[i]">
<img #slide [src]="img" style="height:200px; width:200px" />
</div>
</div>
还有 .css,如果所有图像都放置在包装器的 top:0, left:0 位置,则此动画有效
.wrapper{
overflow: hidden;
width:200px;
}
.wrapper::after {
display: block;
clear: both;
content: "";
}
.wrapper div{
float:left;
margin-right: -100%;
}
更新 嗯,onSlide 函数可以很简单:
onSlide(current,prev,direction) {
this.slideControl[current]='in' + direction;
this.slideControl[prev]='out' + direction
}
还有一点我不喜欢它是包装器的“硬代码”。我们可以利用事件加载,顺便使用变量 with
width:number=0;
onLoad(el:any)
{
this.width=el.getBoundingClientRect().width
}
所以,我们的 .html 可以是这样的
<div class="wrapper" [style.width.px]="width" >
<div *ngFor="let img of images; let i = index"
[@animImageSlider]="slideControl[i]">
<img #slide (load)="i==0 && onLoad(slide)" [src]="img" />
</div>
</div>
看到函数“onLoad”只在第一张幻灯片中调用
注意:如果我们想要一个“无限轮播”,我们可以将函数替换为 next 和 prev by
change(direction:string)
{
const incr=direction=='right'?1:-1
const prev=this.counter
this.counter=(this.counter+this.images.length+incr)%this.images.length
this.slideControl[this.counter]='in' + direction;
this.slideControl[prev]='out' + direction
}
并使用
<button type="button" (click)="change('left')" >
Previous
</button>
<button type="button" (click)="change('right')">
Next
</button>
注意:我用这两个更改更新了 stackblitz
【讨论】: