【问题标题】:Custom animated image slider in AngularAngular中的自定义动画图像滑块
【发布时间】:2021-12-19 18:17:44
【问题描述】:

我想创建一个自定义图像滑块,我可以在其中动态加载图像,这是工作示例的链接:

https://stackblitz.com/edit/angular-ivy-rwuxjd?file=src/app/app.component.html

滑块正在工作,但有一个问题我想隐藏当前幻灯片并仅翻译传入的幻灯片。新幻灯片应该从最右边翻译。但在这段代码中,当前幻灯片也在翻译中。

【问题讨论】:

    标签: angular


    【解决方案1】:

    前段时间我在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%;
    }
    

    stackblitz

    更新 嗯,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

    【讨论】:

      猜你喜欢
      • 2015-07-14
      • 2016-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-28
      • 1970-01-01
      • 1970-01-01
      • 2017-06-06
      相关资源
      最近更新 更多