1

I want to create a custom image slider, where i can load images dynamically, This is a link of working example:

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

Slider is working but there is one issue i want to hide current slide and translate incoming slide only. New slide should translate from extreme right. But in this code current slide is also translating.

1 Answer 1

1

Sometime ago I used the ngb-carousel and animate to left-rigth and rigth-left (it's time ngb-carousel has no animation) in this SO (the second update) Since 8.0.0 you has animation.

I feel you can not use :enter and :left because only when enter the imagen is loaded. So, based in the before SO, you can define an animation like

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%)` })) ]), ] 

see that a slider can be outleft,outrigth,inleft or inrigth

So I define an array like

slideControl: any[] = this.images.map((x,index)=>index ? 'outleft' : 'inleft') 

And when we click next or prev we call to the function 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 }) } 

The last piece of jigsaw are the .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> 

And the .css, See that this animation work if all the images are placed in the position top:0, left:0 of the wrapper

.wrapper{ overflow: hidden; width:200px; } .wrapper::after { display: block; clear: both; content: ""; } .wrapper div{ float:left; margin-right: -100%; } 

the stackblitz

Update Well, the function onSlide can be simply:

 onSlide(current,prev,direction) { this.slideControl[current]='in' + direction; this.slideControl[prev]='out' + direction } 

And there're a point I don't like that it's the "hardcode" with of wrapper. We can take advantage of the event load and use a variable with in the way

 width:number=0; onLoad(el:any) { this.width=el.getBoundingClientRect().width } 

So, our .html can be like

<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> 

See that the function "onLoad" it's only called for the first slide

NOTE: If we want a "infinite carousel" we can change reemplace the functions next and 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 } 

And use

<button type="button" (click)="change('left')" > Previous </button> <button type="button" (click)="change('right')"> Next </button> 

NOTE: I update the stackblitz with this two changes

Sign up to request clarification or add additional context in comments.

2 Comments

I have made an adaptation of the carousel, and I have the following problem, when I resize the screen, in some moments, the side border of the adjoining images is seen. I have even tried to copy the code as it is in stackblitz and the same thing happens to me. Do you know what could happen?
I have detected that the problem occurs when you put the carousel inside a div with a width by percentage: <div style="width:60%"><custom-carousel [images]="images" [height]="height"></custom-carousel></div>

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.