File

projects/maplander/components/src/lib/components/property/components/slideshow/slide-show.component.ts

Implements

OnChanges AfterViewInit

Metadata

selector lib-property-slide-show
styleUrls ./slide-show.component.scss
templateUrl ./slide-show.component.html

Index

Properties
Methods
Inputs
Outputs

Constructor

constructor(_render: Renderer2)
Parameters :
Name Type Optional
_render Renderer2 No

Inputs

initialIndex
Type : number
multimedia
Type : PFile[]
selectIndex
Type : number

Outputs

currentIndex
Type : EventEmitter<number>

Methods

moveImage
moveImage(next?: boolean)
Parameters :
Name Type Optional
next boolean Yes
Returns : void
moveImageByIndex
moveImageByIndex(index: number)
Parameters :
Name Type Optional
index number No
Returns : void
ngAfterViewInit
ngAfterViewInit()
Returns : void
ngOnChanges
ngOnChanges(changes: SimpleChanges)
Parameters :
Name Type Optional
changes SimpleChanges No
Returns : void
Private validateHTTPS
validateHTTPS()
Returns : void

Properties

Private _slider
Type : ElementRef
Decorators :
@ViewChild('slider', {static: true})
Public count
Type : number
Public index
Type : number
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>

./slide-show.component.scss

: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
Component
Html element with directive

result-matching ""

    No results matching ""