File
Implements
Metadata
selector |
lib-property-slide-show |
styleUrls |
./slide-show.component.scss |
templateUrl |
./slide-show.component.html |
Index
Properties
|
|
Methods
|
|
Inputs
|
|
Outputs
|
|
multimedia
|
Type : PFile[]
|
|
Outputs
currentIndex
|
Type : EventEmitter<number>
|
|
Methods
moveImage
|
moveImage(next?: boolean)
|
|
Parameters :
Name |
Type |
Optional |
next |
boolean
|
Yes
|
|
moveImageByIndex
|
moveImageByIndex(index: number)
|
|
Parameters :
Name |
Type |
Optional |
index |
number
|
No
|
|
ngAfterViewInit
|
ngAfterViewInit()
|
|
|
Private
validateHTTPS
|
validateHTTPS()
|
|
|
Private
_slider
|
Type : ElementRef
|
Decorators :
@ViewChild('slider', {static: true})
|
|
import {
AfterViewInit,
Component,
ElementRef,
EventEmitter,
Input,
OnChanges,
Output,
Renderer2,
SimpleChanges,
ViewChild
} from '@angular/core';
import {PFile} from '@maplander/types';
@Component({
selector: 'lib-property-slide-show',
templateUrl: './slide-show.component.html',
styleUrls: ['./slide-show.component.scss']
})
export class SlideShowComponent implements OnChanges, AfterViewInit {
@ViewChild('slider', {static: true}) private _slider: ElementRef;
@Input() multimedia: PFile[];
@Input() selectIndex: number;
@Input() initialIndex: number;
@Output() currentIndex: EventEmitter<number>;
public count: number;
public index: number;
constructor(
private _render: Renderer2
) {
this.currentIndex = new EventEmitter<number>();
this.index = this.initialIndex || 0;
this.multimedia = [];
}
ngAfterViewInit(): void {
this.currentIndex.emit(this.index);
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['selectIndex'] && (changes['selectIndex'].currentValue !== undefined && changes['selectIndex'].currentValue !== null)) {
this.moveImageByIndex(changes['selectIndex'].currentValue);
}
if (changes['multimedia'] && changes['multimedia'].currentValue) {
this.multimedia = changes['multimedia'].currentValue || [];
if (this.multimedia.length > 0) {
this.count = this.multimedia.length;
this.moveImageByIndex(this.initialIndex || 0);
this.validateHTTPS();
}
}
}
moveImage(next?: boolean): void {
this.index = next ? this.index + 1 : this.index - 1;
if (this.index === this.multimedia.length) {
this.index = 0;
}
this.currentIndex.emit(this.index);
this._render.setStyle(this._slider.nativeElement, 'margin-left', `-${this.index * 100}%`);
}
moveImageByIndex(index: number): void {
this.index = index;
if (this.index === this.multimedia.length) {
this.index = 0;
}
this.currentIndex.emit(this.index);
this._render.setStyle(this._slider.nativeElement, 'margin-left', `-${this.index * 100}%`);
}
private validateHTTPS(): void {
this.multimedia.forEach(item => {
if (item.fileCS.thumbnail.indexOf('https') === -1) {
item.fileCS.thumbnail = item.fileCS.thumbnail.replace('http', 'https');
}
});
}
}
<div class="slide-show">
<div class="count" *ngIf="multimedia && multimedia.length > 0">
{{index + 1}}/{{count}}
</div>
<button mat-button="" class="button-previous" [ngClass]="{'disabled':index===0}" [disabled]="index===0"
(click)="moveImage()">
<mat-icon>keyboard_arrow_left</mat-icon>
</button>
<ul class="images-list" #slider [ngStyle]="{'width':'calc(100% *' + count + ')'}">
<ng-template [ngIf]="multimedia && multimedia.length > 0">
<ng-container *ngFor="let m of multimedia">
<li class="images-item" [ngStyle]="{'width':'calc(100% /' + count + ')'}">
<ng-container [ngSwitch]="m.type">
<ng-container *ngSwitchCase="'IMAGE'">
<img class="images-item__img" [src]="m.fileCS.thumbnail" alt="Property image">
</ng-container>
<ng-container *ngSwitchCase="'SPHERIC'">
<lib-panorama-visor class="images-item__panorama" [url]="m.fileCS.thumbnail"></lib-panorama-visor>
</ng-container>
<ng-container *ngSwitchCase="'VIDEO'">
<iframe class="images-item__video"
[src]="'https://www.youtube.com/embed/' + m.fileCS.thumbnail | safeUrl"></iframe>
</ng-container>
</ng-container>
</li>
</ng-container>
</ng-template>
<ng-template [ngIf]="multimedia && multimedia.length === 0">
<div class="no-items"></div>
</ng-template>
</ul>
<button mat-button="" class="button-next" [disabled]="multimedia.length === 0" (click)="moveImage(true)">
<mat-icon>keyboard_arrow_right</mat-icon>
</button>
</div>
:host{
display: block;
position: relative;
width: 100%;
padding-bottom: calc(100% / 4 * 3);
}
.slide-show{
width: 100%;
height: 100%;
overflow: hidden;
position: absolute;
}
.count{
position: absolute;
bottom: 8px;
right: 8px;
color: white;
padding: 8px 24px;
font-size: 12px;
border-radius: 16px;
z-index: 2;
background: rgba(0, 0, 0, 0.5);
}
.images-list {
width: 100%;
height: 100%;
list-style: none;
padding: 0;
margin: 0;
display: flex;
overflow: hidden;
transition: all 250ms;
}
.images-item {
width: 100%;
height: 100%;
}
.images-item__img {
width: 100%;
height: 100%;
object-fit: contain;
border-radius: 8px;
}
.images-item__panorama, .images-item__video{
width: 100%;
height: 100%;
border: 0;
border-radius: 8px;
}
.button-previous, .button-next{
position: absolute;
min-width: 30px;
width: 30px;
height: 80px;
padding: 0;
z-index: 1;
color: white;
top: calc(50% - 40px);
background: rgba(0, 0, 0, .3);
mat-icon{
width: 30px;
height: 30px;
font-size: 30px;
}
}
.button-previous:hover, .button-next:hover{
color: black;
background: white;
}
.disabled{
color: lightgray;
}
.button-previous{
left: 0;
border-radius: 0 16px 16px 0;
}
.button-next{
right: 0;
border-radius: 16px 0 0 16px;
}
.no-items {
width: 100%;
height: 100%;
border-radius: 8px;
}
Legend
Html element with directive