{"version":3,"file":"ng-flyweight-gallery.mjs","sources":["../../../projects/ng-flyweight-gallery/src/lib/ng-flyweight-gallery.component.ts","../../../projects/ng-flyweight-gallery/src/lib/ng-flyweight-gallery.module.ts","../../../projects/ng-flyweight-gallery/src/public-api.ts","../../../projects/ng-flyweight-gallery/src/ng-flyweight-gallery.ts"],"sourcesContent":["import { Component, Input, SecurityContext } from '@angular/core';\r\nimport { DomSanitizer } from '@angular/platform-browser';\r\n\r\n\r\nexport interface MediaItem {\r\n  id?: number; // optional ID\r\n  type: 'image' | 'video'; // media type\r\n  thumbnail?: string; // optional thumbnail URL\r\n  source: string; // media source (URL)\r\n  title?: string; // optional title\r\n  autoplay?: boolean; // optional autoplay for videos\r\n  loop?: boolean; // optional loop for videos\r\n}\r\n\r\n@Component({\r\n  selector: 'ng-flyweight-gallery',\r\n  standalone: false,\r\n  template: `\r\n <div class=\"fwt-gallery-grid\">\r\n    <div class=\"fwt-gallery-item\" *ngFor=\"let item of mediaItems; index as i\" (click)=\"openLightbox(item, i)\">\r\n        <!-- Image thumbnail -->\r\n        <img (click)=\"openLightbox(item, i)\" *ngIf=\"item.type === 'image'\" [src]=\"item?.thumbnail || item.source\" [alt]=\"item.title\">\r\n\r\n        <!-- Video thumbnail -->\r\n            <video \r\n            (click)=\"openLightbox(item, i)\" \r\n            *ngIf=\"item.type === 'video' && !item?.thumbnail\" \r\n            [src]=\"item.source\" \r\n            (loadedmetadata)=\"captureVideoThumbnail($event, i)\" \r\n            muted \r\n           ></video>\r\n           \r\n           <img (click)=\"openLightbox(item, i)\" *ngIf=\"item.type === 'video' && item?.thumbnail\" [src]=\"item.thumbnail\" [alt]=\"item.title\">\r\n    </div>\r\n</div>\r\n\r\n<div class=\"fwt-lightbox\" *ngIf=\"lightboxOpen\">\r\n    <div class=\"fwt-lightbox-backdrop\"></div>\r\n    <button class=\"fwt-nav-btn fwt-prev\" (click)=\"prev()\">&#10094;</button>\r\n        <button class=\"fwt-nav-btn fwt-next\" (click)=\"next()\">&#10095;</button>\r\n    <div class=\"fwt-lightbox-content\">\r\n        <div class=\"fwt-media-container\" *ngIf=\"selectedItem\">\r\n            <img *ngIf=\"selectedItem.type === 'image'\" [src]=\"selectedItem.source\" [alt]=\"selectedItem.title\">\r\n            <video *ngIf=\"selectedItem.type === 'video'\" [src]=\"selectedItem.source\" [autoplay]=\"selectedItem.autoplay\"\r\n                [loop]=\"selectedItem.loop\" controls>\r\n            </video>\r\n        </div>\r\n    </div>\r\n    <button class=\"fwt-close-btn\" (click)=\"closeLightbox()\">&times;</button>\r\n</div>\r\n  `,\r\n  styles: `.fwt-gallery-grid {\r\n    background-color: transparent;\r\n    display: grid;\r\n    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));\r\n    gap: 10px;\r\n    max-height: 450px; /* Set max height */\r\n    overflow-y: auto; /* Enable vertical scroll if content exceeds max-height */\r\n    padding-right: 10px; /* Add padding to avoid overlap with scrollbar */\r\n    \r\n    /* Scrollbar styling for Webkit browsers */\r\n    ::-webkit-scrollbar {\r\n        width: 8px;\r\n    }\r\n    \r\n    ::-webkit-scrollbar-thumb {\r\n        background-color: #888;\r\n        border-radius: 4px;\r\n        border: 2px solid transparent;\r\n        background-clip: content-box;\r\n    }\r\n\r\n    ::-webkit-scrollbar-thumb:hover {\r\n        background-color: #555;\r\n    }\r\n\r\n    ::-webkit-scrollbar-track {\r\n        background-color: #f1f1f1;\r\n        border-radius: 4px;\r\n    }\r\n\r\n    /* Firefox scrollbar styling */\r\n    scrollbar-width: thin;\r\n    scrollbar-color: #888 #f1f1f1;\r\n\r\n    @media (max-width: 768px) {\r\n        grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));\r\n    }\r\n\r\n    @media (max-width: 480px) {\r\n        grid-template-columns: 1fr;\r\n    }\r\n}\r\n\r\n.fwt-gallery-item {\r\n    cursor: pointer;\r\n    transition: transform 0.3s;\r\n    border: 2px solid lightsteelblue;\r\n    border-radius: 5px;\r\n    object-fit: cover;\r\n\r\n    /* Fallback for browsers that don't support object-fit */\r\n    -webkit-object-fit: cover;\r\n    -moz-object-fit: cover;\r\n\r\n    &:hover {\r\n        transform: scale(1.05);\r\n        -webkit-transform: scale(1.05); /* Safari */\r\n        -ms-transform: scale(1.05); /* IE */\r\n    }\r\n\r\n    img, video {\r\n        width: 100%;\r\n        height: 100%;\r\n    }\r\n}\r\n\r\n.fwt-lightbox {\r\n    position: fixed;\r\n    top: 0;\r\n    left: 0;\r\n    width: 100%;\r\n    height: 100%;\r\n    display: flex;\r\n    justify-content: center;\r\n    align-items: center;\r\n    z-index: 1000;\r\n\r\n    .fwt-lightbox-backdrop {\r\n        position: absolute;\r\n        top: 0;\r\n        left: 0;\r\n        width: 100%;\r\n        height: 100%;\r\n        background: rgba(0, 0, 0, 0.8);\r\n        z-index: 999;\r\n    }\r\n\r\n    .fwt-lightbox-content {\r\n        position: relative;\r\n        max-width: 70%;\r\n        max-height: 70%;\r\n        display: flex;\r\n        justify-content: center;\r\n        align-items: center;\r\n        text-align: center;\r\n        z-index: 1001;\r\n\r\n        .fwt-media-container {\r\n            img,\r\n            video {\r\n                width: 100%;\r\n                height: auto;\r\n            }\r\n        }\r\n\r\n        @media (max-width: 768px) {\r\n            max-width: 90%;\r\n            max-height: 90%;\r\n        }\r\n\r\n        @media (max-width: 480px) {\r\n            max-width: 95%;\r\n            max-height: 95%;\r\n        }\r\n    }\r\n\r\n    .fwt-nav-btn,\r\n    .fwt-close-btn {\r\n        position: absolute;\r\n        top: 50%;\r\n        transform: translateY(-50%);\r\n        -webkit-transform: translateY(-50%); /* Safari */\r\n        -ms-transform: translateY(-50%); /* IE */\r\n        background: transparent;\r\n        border: none;\r\n        color: white;\r\n        font-size: 2rem;\r\n        cursor: pointer;\r\n        z-index: 1002;\r\n\r\n        &.fwt-prev {\r\n            left: 10px;\r\n        }\r\n\r\n        &.fwt-next {\r\n            right: 10px;\r\n        }\r\n\r\n        &.fwt-close-btn {\r\n            top: 10px;\r\n            right: 10px;\r\n            transform: none;\r\n        }\r\n\r\n        @media (max-width: 480px) {\r\n            font-size: 1.5rem;\r\n        }\r\n    }\r\n}\r\n`\r\n})\r\nexport class NgFlyweightGalleryComponent {\r\n  @Input() mediaItems: MediaItem[] = [];\r\n  selectedItem?: MediaItem;\r\n  lightboxOpen = false;\r\n  selectedIndex: number = 0;\r\n\r\n  constructor(private sanitizer: DomSanitizer) { }\r\n\r\n  ngOnInit() {\r\n    this.mediaItems.forEach((item, index) => {\r\n      item.source = this.sanitizeUrl(item.source);\r\n      if (!item.thumbnail) {\r\n        if (item.type === 'image') {\r\n          item.thumbnail = this.sanitizeUrl(item.source);\r\n        } else if (item.type === 'video') {\r\n          this.generateVideoThumbnail(item, index);\r\n        }\r\n      } else {\r\n        item.thumbnail = this.sanitizeUrl(item.thumbnail);\r\n      }\r\n    });\r\n  }\r\n\r\n  sanitizeUrl(url: string): string {\r\n    return this.sanitizer.sanitize(SecurityContext.RESOURCE_URL,url) as string;\r\n  }\r\n\r\n  generateVideoThumbnail(item: MediaItem, index: number) {\r\n    const video = document.createElement('video');\r\n    video.src = item.source as string;\r\n    video.crossOrigin = 'anonymous';\r\n    video.load();\r\n\r\n\r\n    video.addEventListener('loadeddata', () => {\r\n      video.currentTime = 2;\r\n    });\r\n\r\n\r\n    video.addEventListener('seeked', () => {\r\n      const canvas = document.createElement('canvas');\r\n      canvas.width = video.videoWidth / 4;\r\n      canvas.height = video.videoHeight / 4;\r\n      const ctx = canvas.getContext('2d');\r\n      if (ctx) {\r\n        ctx.drawImage(video, 0, 0, canvas.width, canvas.height);\r\n        item.thumbnail = this.sanitizeUrl(canvas.toDataURL('image/jpeg')) as string;\r\n      }\r\n    });\r\n  }\r\n\r\n  captureVideoThumbnail(event: Event, index: number) {\r\n    const videoElement = event.target as HTMLVideoElement;\r\n    const canvas = document.createElement('canvas');\r\n    const context = canvas.getContext('2d');\r\n\r\n    if (context) {\r\n      // Set canvas dimensions\r\n      canvas.width = videoElement.videoWidth;\r\n      canvas.height = videoElement.videoHeight;\r\n      videoElement.currentTime = 0;\r\n      videoElement.addEventListener('loadeddata', () => {\r\n        context.drawImage(videoElement, 0, 0, canvas.width, canvas.height);\r\n        const thumbnailDataUrl = canvas.toDataURL('image/jpeg');\r\n        this.mediaItems[index].thumbnail = thumbnailDataUrl;\r\n      });\r\n    }\r\n  }\r\n\r\n  openLightbox(item: MediaItem, index: number) {\r\n    this.selectedItem = item;\r\n    this.selectedIndex = index;\r\n    this.lightboxOpen = true;\r\n  }\r\n\r\n  closeLightbox(event?: any) {\r\n    if (event?.target === event?.currentTarget) {\r\n      this.lightboxOpen = false;\r\n      this.selectedItem = undefined;\r\n    }\r\n  }\r\n\r\n  // Navigation functions\r\n  prev() {\r\n    if (this.selectedIndex > 0) {\r\n      this.selectedIndex--;\r\n      this.selectedItem = this.mediaItems[this.selectedIndex];\r\n    }\r\n  }\r\n\r\n  next() {\r\n    if (this.selectedIndex < this.mediaItems.length - 1) {\r\n      this.selectedIndex++;\r\n      this.selectedItem = this.mediaItems[this.selectedIndex];\r\n    }\r\n  }\r\n}\r\n","import { NgModule } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { NgFlyweightGalleryComponent } from './ng-flyweight-gallery.component';\r\n\r\n\r\n@NgModule({\r\n  declarations: [NgFlyweightGalleryComponent],\r\n  imports: [CommonModule],\r\n  exports: [NgFlyweightGalleryComponent],\r\n})\r\nexport class NgFlyweightGalleryModule {}\r\n","/*\r\n * Public API Surface of ng-flyweight-gallery\r\n */\r\n\r\nexport * from './lib/ng-flyweight-gallery.module';\r\nexport * from './lib/ng-flyweight-gallery.component';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}