UNPKG

ng-cw-v12

Version:

Angular UI Component Library

704 lines 52.9 kB
import * as i0 from '@angular/core';
import { Component, Input, ViewChild, HostListener, NgModule } from '@angular/core';
import * as i1 from '@angular/common';
import { CommonModule } from '@angular/common';

class GalleriaComponent {
    constructor() {
        /** 图片数组 */
        this._images = [];
        /** 组件宽度 */
        this.ncWidth = '100%';
        /** 组件高度 */
        this.ncHeight = '100%';
        /** 缩略图宽度 */
        this.ncThumbnailWidth = 80;
        /** 缩略图高度 */
        this.ncThumbnailHeight = 60;
        /** 图片适应方式 */
        this.ncObjectFit = 'contain';
        /** 自动播放 */
        this._autoPlay = false;
        /** 自动播放间隔 */
        this.ncAutoPlayInterval = 3000;
        /** 显示缩略图 */
        this._showThumbnails = true;
        /** 显示指示器 */
        this._showIndicators = false;
        /** 指示器显示位置 */
        this.ncIndicatorsPosition = 'outside';
        /** 显示导航按钮 */
        this._showNavButtons = false;
        /** 导航按钮显示方式 */
        this.ncNavButtonsDisplay = 'always';
        /** 启用全屏预览 */
        this._enableFullscreen = false;
        /** 全屏按钮显示方式 */
        this.ncFullscreenButtonDisplay = 'always';
        /** 显示图片数目 */
        this._showIndex = false;
        /** 显示图片标题 */
        this._showTitle = false;
        /** 滚轮缩放 */
        this._wheelScale = false;
        this.currentIndex = 0;
        this.thumbnailStartIndex = 0;
        this.thumbnailTransform = 0; // 缩略图滚动偏移量
        this.isFullscreen = false; // 全屏状态
        this.isFullscreenAutoPlaying = false; // 全屏模式下的自动播放状态
        // 全屏缩放相关属性
        this.fullscreenScale = 1; // 当前缩放比例
        this.fullscreenTranslateX = 0; // X轴偏移
        this.fullscreenTranslateY = 0; // Y轴偏移
        this.minScale = 0.5; // 最小缩放比例
        this.maxScale = 3; // 最大缩放比例
        this.isDragging = false; // 是否正在拖拽
        this.lastMouseX = 0; // 上次鼠标X位置
        this.lastMouseY = 0; // 上次鼠标Y位置
        this.actualContainerWidth = 0;
    }
    set ncImages(value) {
        // 如果传入的是string[],转换为NcGalleriaImage[]
        if (value && value.length > 0 && typeof value[0] === 'string') {
            this._images = value.map(src => ({
                src: src,
                title: ''
            }));
        }
        else {
            this._images = value;
        }
    }
    get ncImages() {
        return this._images;
    }
    set ncAutoPlay(val) {
        this._autoPlay = val !== null && val !== undefined && val !== false && val !== 'false';
    }
    get ncAutoPlay() {
        return this._autoPlay;
    }
    set ncShowThumbnails(val) {
        this._showThumbnails = val !== null && val !== undefined && val !== false && val !== 'false';
    }
    get ncShowThumbnails() {
        return this._showThumbnails;
    }
    set ncShowIndicators(val) {
        this._showIndicators = val !== null && val !== undefined && val !== false && val !== 'false';
    }
    get ncShowIndicators() {
        return this._showIndicators;
    }
    set ncShowNavButtons(val) {
        this._showNavButtons = val !== null && val !== undefined && val !== false && val !== 'false';
    }
    get ncShowNavButtons() {
        return this._showNavButtons;
    }
    set ncEnableFullscreen(val) {
        this._enableFullscreen = val !== null && val !== undefined && val !== false && val !== 'false';
    }
    get ncEnableFullscreen() {
        return this._enableFullscreen;
    }
    set ncShowIndex(val) {
        this._showIndex = val !== null && val !== undefined && val !== false && val !== 'false';
    }
    get ncShowIndex() {
        return this._showIndex;
    }
    set ncShowTitle(val) {
        this._showTitle = val !== null && val !== undefined && val !== false && val !== 'false';
    }
    get ncShowTitle() {
        return this._showTitle;
    }
    set ncWheelScale(val) {
        this._wheelScale = val !== null && val !== undefined && val !== false && val !== 'false';
    }
    get ncWheelScale() {
        return this._wheelScale;
    }
    // 计算缩略图实际宽度(包含gap)
    get thumbnailActualWidth() {
        return this.ncThumbnailWidth + 8; // 8px gap
    }
    // 计算实际可显示的缩略图数量
    get actualVisibleThumbnailCount() {
        // 边界保护:如果没有图片,返回0
        if (!this.ncImages || this.ncImages.length === 0) {
            return 0;
        }
        let containerWidth = 0;
        if (this.ncWidth && this.ncWidth.includes('px')) {
            // 如果设置了具体像素宽度
            containerWidth = parseInt(this.ncWidth.replace('px', ''));
        }
        else if (this.actualContainerWidth > 0) {
            // 如果是百分比宽度,使用实际测量的宽度
            containerWidth = this.actualContainerWidth;
        }
        else {
            // 如果还没有测量到实际宽度,先返回图片数量(避免初始化时的问题)
            return this.ncImages.length;
        }
        // 边界保护:确保容器宽度和缩略图宽度都是正数
        if (containerWidth <= 0 || this.thumbnailActualWidth <= 0) {
            return 1;
        }
        // 减去左右滚动按钮的宽度(32px + 8px gap)× 2 = 80px,再减去容器padding
        const availableWidth = containerWidth - 80 - 32; // 额外减去32px的padding
        // 边界保护:确保可用宽度为正数
        if (availableWidth <= 0) {
            return 1;
        }
        const visibleCount = Math.floor(availableWidth / this.thumbnailActualWidth);
        // 确保至少显示1个,最多不超过图片总数
        return Math.max(1, Math.min(visibleCount, this.ncImages.length));
    }
    // 判断缩略图是否应该居中显示
    get shouldCenterThumbnails() {
        return this.ncImages.length <= this.actualVisibleThumbnailCount;
    }
    // 计算缩略图最大滚动距离
    getMaxThumbnailScroll() {
        const actualVisibleCount = this.actualVisibleThumbnailCount;
        if (this.ncImages.length <= actualVisibleCount) {
            return 0;
        }
        // 计算总宽度减去实际可见区域宽度
        const totalWidth = this.ncImages.length * this.thumbnailActualWidth;
        const visibleWidth = actualVisibleCount * this.thumbnailActualWidth;
        return -(totalWidth - visibleWidth);
    }
    ngAfterViewInit() {
        this.startInit();
    }
    ngOnChanges(changes) {
        if (changes['ncImages'] && !changes['ncImages'].firstChange) {
            this.startInit();
        }
    }
    startInit() {
        setTimeout(() => {
            this.updateActualContainerWidth();
            this.init();
        });
    }
    updateActualContainerWidth() {
        if (this.galleriaContainer && this.galleriaContainer.nativeElement) {
            const newWidth = this.galleriaContainer.nativeElement.offsetWidth;
            // 只有当宽度真正发生变化时才更新
            if (newWidth !== this.actualContainerWidth) {
                const oldVisibleCount = this.actualVisibleThumbnailCount;
                this.actualContainerWidth = newWidth;
                const newVisibleCount = this.actualVisibleThumbnailCount;
                // 如果可显示数量发生变化,重新调整缩略图视图
                if (oldVisibleCount !== newVisibleCount) {
                    this.updateThumbnailView();
                }
            }
        }
    }
    init() {
        //先删除autoPlayTimer定时器,防止ncImages更换时重复autoPlayTimer
        if (this.autoPlayTimer) {
            clearInterval(this.autoPlayTimer);
            this.autoPlayTimer = null;
        }
        if (this.ncAutoPlay && this.ncImages.length > 1) {
            this.startAutoPlay();
        }
    }
    ngOnDestroy() {
        this.stopAutoPlay();
        // 清理resize定时器
        if (this.resizeTimeout) {
            clearTimeout(this.resizeTimeout);
        }
        // 如果组件销毁时还在全屏状态,恢复页面滚动
        if (this.isFullscreen) {
            document.body.style.overflow = '';
        }
    }
    // 选择图片
    selectImage(index) {
        if (index >= 0 && index < this.ncImages.length) {
            this.currentIndex = index;
            this.updateThumbnailView();
            // 切换图片时重置缩放状态
            this.resetFullscreenZoom();
        }
    }
    // 重置全屏缩放状态
    resetFullscreenZoom() {
        this.fullscreenScale = 1;
        this.fullscreenTranslateX = 0;
        this.fullscreenTranslateY = 0;
    }
    // 上一张图片
    previousImage() {
        this.currentIndex = this.currentIndex > 0 ? this.currentIndex - 1 : this.ncImages.length - 1;
        this.updateThumbnailView();
        // 切换图片时重置缩放状态
        this.resetFullscreenZoom();
    }
    // 下一张图片
    nextImage() {
        this.currentIndex = this.currentIndex < this.ncImages.length - 1 ? this.currentIndex + 1 : 0;
        this.updateThumbnailView();
        // 切换图片时重置缩放状态
        this.resetFullscreenZoom();
    }
    // 更新缩略图视图
    updateThumbnailView() {
        const actualVisibleCount = this.actualVisibleThumbnailCount;
        if (this.ncImages.length <= actualVisibleCount) {
            this.thumbnailStartIndex = 0;
            this.thumbnailTransform = 0;
            return;
        }
        // 根据缩略图数量决定滚动策略
        const triggerIndex = Math.max(2, actualVisibleCount - 2);
        if (this.currentIndex < triggerIndex) {
            // 前面几张图片时,缩略图位置不变
            this.thumbnailStartIndex = 0;
        }
        else if (this.currentIndex >= this.ncImages.length - Math.floor(actualVisibleCount / 2)) {
            // 最后几张图片时,显示最后几张缩略图
            this.thumbnailStartIndex = this.ncImages.length - actualVisibleCount;
        }
        else {
            // 中间部分,让当前图片居中或接近居中显示
            const centerOffset = Math.floor(actualVisibleCount / 2);
            this.thumbnailStartIndex = this.currentIndex - centerOffset;
        }
        // 确保不超出边界
        this.thumbnailStartIndex = Math.max(0, Math.min(this.thumbnailStartIndex, this.ncImages.length - actualVisibleCount));
        // 计算transform偏移量
        this.thumbnailTransform = -this.thumbnailStartIndex * this.thumbnailActualWidth;
        // 确保不超出最大滚动范围
        const maxScroll = this.getMaxThumbnailScroll();
        this.thumbnailTransform = Math.max(maxScroll, this.thumbnailTransform);
    }
    // 缩略图向左滚动
    scrollThumbnailsLeft() {
        if (this.canScrollLeft()) {
            // 每次滚动一个缩略图的宽度
            this.thumbnailTransform += this.thumbnailActualWidth;
            // 确保不超出左边界
            this.thumbnailTransform = Math.min(0, this.thumbnailTransform);
            // 更新thumbnailStartIndex以保持一致性
            this.thumbnailStartIndex = Math.max(0, Math.round(-this.thumbnailTransform / this.thumbnailActualWidth));
        }
    }
    // 缩略图向右滚动
    scrollThumbnailsRight() {
        if (this.canScrollRight()) {
            // 每次滚动一个缩略图的宽度
            this.thumbnailTransform -= this.thumbnailActualWidth;
            // 确保不超出右边界
            const maxScroll = this.getMaxThumbnailScroll();
            this.thumbnailTransform = Math.max(maxScroll, this.thumbnailTransform);
            // 更新thumbnailStartIndex以保持一致性
            this.thumbnailStartIndex = Math.max(0, Math.round(-this.thumbnailTransform / this.thumbnailActualWidth));
        }
    }
    // 是否可以向左滚动缩略图
    canScrollLeft() {
        return this.thumbnailTransform < 0;
    }
    // 是否可以向右滚动缩略图
    canScrollRight() {
        if (this.ncImages.length <= this.actualVisibleThumbnailCount) {
            return false;
        }
        const maxScroll = this.getMaxThumbnailScroll();
        return this.thumbnailTransform > maxScroll;
    }
    // 开始自动播放
    startAutoPlay() {
        this.autoPlayTimer = setInterval(() => {
            this.nextImage();
        }, this.ncAutoPlayInterval);
    }
    // 停止自动播放
    stopAutoPlay() {
        if (this.autoPlayTimer) {
            clearInterval(this.autoPlayTimer);
            this.autoPlayTimer = null;
        }
    }
    // 鼠标进入时暂停自动播放
    onMouseEnter() {
        // 如果在全屏模式下,不要自动暂停播放,让用户手动控制
        if (this.isFullscreen) {
            return;
        }
        if (this.ncAutoPlay) {
            this.stopAutoPlay();
        }
    }
    // 鼠标离开时恢复自动播放
    onMouseLeave() {
        // 如果在全屏模式下,不要自动恢复播放,让用户手动控制
        if (this.isFullscreen) {
            return;
        }
        if (this.ncAutoPlay && this.ncImages.length > 1) {
            this.startAutoPlay();
        }
    }
    // 监听窗口大小变化
    onWindowResize(event) {
        // 使用防抖处理,避免频繁计算
        if (this.resizeTimeout) {
            clearTimeout(this.resizeTimeout);
        }
        this.resizeTimeout = setTimeout(() => {
            this.updateActualContainerWidth();
        }, 150); // 150ms防抖延迟
    }
    // 键盘导航支持
    onKeyDown(event) {
        if (!this.ncImages || this.ncImages.length <= 1) {
            return;
        }
        switch (event.key) {
            case 'ArrowLeft':
                event.preventDefault();
                this.previousImage();
                break;
            case 'ArrowRight':
                event.preventDefault();
                this.nextImage();
                break;
            case 'Home':
                event.preventDefault();
                this.selectImage(0);
                break;
            case 'End':
                event.preventDefault();
                this.selectImage(this.ncImages.length - 1);
                break;
        }
    }
    // 图片加载错误处理
    onImageError(event) {
        // 防止错误图片再次触发错误事件
        if (event.target.src.startsWith('data:image/svg+xml')) {
            return;
        }
        console.warn('图片加载失败:', event.target.src);
        // 使用SVG占位图
        const errorSvg = this.createErrorImageSvg(400, 300);
        event.target.src = errorSvg;
        event.target.style.objectFit = 'contain';
    }
    // 缩略图加载错误处理
    onThumbnailError(event) {
        // 防止错误图片再次触发错误事件
        if (event.target.src.startsWith('data:image/svg+xml')) {
            return;
        }
        console.warn('缩略图加载失败:', event.target.src);
        // 使用SVG占位图
        const errorSvg = this.createErrorImageSvg(this.ncThumbnailWidth, this.ncThumbnailHeight);
        event.target.src = errorSvg;
        event.target.style.objectFit = 'contain';
    }
    // 创建错误图片的SVG占位图
    createErrorImageSvg(width, height) {
        const svg = `
      <svg width="${width}" height="${height}" viewBox="0 0 ${width} ${height}" xmlns="http://www.w3.org/2000/svg">
        <rect width="100%" height="100%" fill="#f8f9fa" stroke="#dee2e6" stroke-width="2"/>
        <g transform="translate(${width / 2}, ${height / 2})">
          <!-- 破损图片图标 -->
          <g transform="translate(-24, -24)">
            <rect x="4" y="4" width="40" height="32" rx="2" fill="none" stroke="#6c757d" stroke-width="2"/>
            <circle cx="14" cy="14" r="2" fill="#6c757d"/>
            <path d="M44 28L36 20L24 32L16 24L4 36" stroke="#6c757d" stroke-width="2" fill="none"/>
            <!-- X 标记 -->
            <line x1="32" y1="8" x2="40" y2="16" stroke="#dc3545" stroke-width="2"/>
            <line x1="40" y1="8" x2="32" y2="16" stroke="#dc3545" stroke-width="2"/>
          </g>
          <!-- 错误文字 -->
          <text x="0" y="32" text-anchor="middle" fill="#6c757d" font-family="Arial, sans-serif" font-size="12">
            图片加载失败
          </text>
        </g>
      </svg>
    `;
        // 使用现代方法:直接URL编码,无需base64
        return 'data:image/svg+xml,' + encodeURIComponent(svg);
    }
    // 打开全屏预览
    openFullscreen() {
        if (this.ncEnableFullscreen) {
            this.isFullscreen = true;
            // 阻止页面滚动
            document.body.style.overflow = 'hidden';
            // 重置缩放状态
            this.resetFullscreenZoom();
            // 检查当前是否有自动播放在运行
            const wasAutoPlaying = !!this.autoPlayTimer;
            // console.log('打开全屏,当前自动播放状态:', wasAutoPlaying);
            // 如果原本有自动播放,在全屏模式下继续播放
            if (this.ncAutoPlay && this.ncImages.length > 1) {
                this.isFullscreenAutoPlaying = wasAutoPlaying;
                // 如果之前没有在播放,需要启动
                if (!wasAutoPlaying) {
                    this.startAutoPlay();
                    this.isFullscreenAutoPlaying = true;
                }
            }
        }
    }
    // 关闭全屏预览
    closeFullscreen() {
        this.isFullscreen = false;
        this.isFullscreenAutoPlaying = false;
        // 恢复页面滚动
        document.body.style.overflow = '';
        // 重置缩放状态
        this.resetFullscreenZoom();
        //先删除autoPlayTimer定时器,防止恢复自动播放时重复autoPlayTimer
        if (this.autoPlayTimer) {
            clearInterval(this.autoPlayTimer);
            this.autoPlayTimer = null;
        }
        // 退出全屏时恢复自动播放
        if (this.ncAutoPlay && this.ncImages.length > 1) {
            this.startAutoPlay();
        }
    }
    // 全屏模式下切换自动播放
    toggleFullscreenAutoPlay() {
        if (!this.isFullscreen || this.ncImages.length <= 1) {
            return;
        }
        // console.log('切换前状态:', this.isFullscreenAutoPlaying, '定时器:', !!this.autoPlayTimer);
        if (this.isFullscreenAutoPlaying) {
            this.stopAutoPlay();
            this.isFullscreenAutoPlaying = false;
            // console.log('已暂停自动播放');
        }
        else {
            this.startAutoPlay();
            this.isFullscreenAutoPlaying = true;
            // console.log('已开始自动播放');
        }
    }
    // 全屏模式下的键盘事件处理
    onFullscreenKeyDown(event) {
        if (!this.isFullscreen)
            return;
        switch (event.key) {
            case 'Escape':
                event.preventDefault();
                this.closeFullscreen();
                break;
            case 'ArrowLeft':
                event.preventDefault();
                this.previousImage();
                break;
            case 'ArrowRight':
                event.preventDefault();
                this.nextImage();
                break;
            case ' ': // 空格键
                event.preventDefault();
                if (this.ncAutoPlay) {
                    this.toggleFullscreenAutoPlay();
                }
                break;
        }
    }
    // 全屏模式下的滚轮缩放事件
    onFullscreenWheel(event) {
        if (!this.isFullscreen || !this.ncWheelScale) {
            return;
        }
        event.preventDefault();
        event.stopPropagation();
        const delta = event.deltaY;
        const scaleStep = 0.1;
        const rect = event.target.getBoundingClientRect();
        // 计算鼠标相对于图片的位置
        const mouseX = event.clientX - rect.left - rect.width / 2;
        const mouseY = event.clientY - rect.top - rect.height / 2;
        const oldScale = this.fullscreenScale;
        // 计算新的缩放比例
        if (delta < 0) {
            // 向上滚动,放大
            this.fullscreenScale = Math.min(this.maxScale, this.fullscreenScale + scaleStep);
        }
        else {
            // 向下滚动,缩小
            this.fullscreenScale = Math.max(this.minScale, this.fullscreenScale - scaleStep);
        }
        // 如果缩放比例发生了变化,调整偏移量以保持鼠标位置不变
        if (this.fullscreenScale !== oldScale) {
            const scaleRatio = this.fullscreenScale / oldScale;
            // 调整偏移量,使缩放以鼠标位置为中心
            this.fullscreenTranslateX = mouseX + (this.fullscreenTranslateX - mouseX) * scaleRatio;
            this.fullscreenTranslateY = mouseY + (this.fullscreenTranslateY - mouseY) * scaleRatio;
            // 限制偏移量范围
            this.constrainTranslation();
        }
    }
    // 全屏模式下的鼠标按下事件(开始拖拽)
    onFullscreenMouseDown(event) {
        if (!this.isFullscreen || !this.ncWheelScale || this.fullscreenScale <= 1) {
            return;
        }
        event.preventDefault();
        this.isDragging = true;
        this.lastMouseX = event.clientX;
        this.lastMouseY = event.clientY;
        // 改变鼠标样式
        document.body.style.cursor = 'grabbing';
    }
    // 全屏模式下的鼠标移动事件(拖拽中)
    onFullscreenMouseMove(event) {
        if (!this.isFullscreen || !this.ncWheelScale || !this.isDragging) {
            return;
        }
        event.preventDefault();
        const deltaX = event.clientX - this.lastMouseX;
        const deltaY = event.clientY - this.lastMouseY;
        this.fullscreenTranslateX += deltaX;
        this.fullscreenTranslateY += deltaY;
        // 限制偏移量范围
        this.constrainTranslation();
        this.lastMouseX = event.clientX;
        this.lastMouseY = event.clientY;
    }
    // 全屏模式下的鼠标松开事件(结束拖拽)
    onFullscreenMouseUp(event) {
        if (!this.isFullscreen || !this.ncWheelScale) {
            return;
        }
        this.isDragging = false;
        document.body.style.cursor = '';
    }
    // 限制图片偏移量范围
    constrainTranslation() {
        if (this.fullscreenScale <= 1) {
            this.fullscreenTranslateX = 0;
            this.fullscreenTranslateY = 0;
            return;
        }
        // 获取全屏图片的实际显示尺寸(考虑object-fit: contain)
        const viewportWidth = window.innerWidth * 0.9; // 90vw
        const viewportHeight = window.innerHeight * 0.9; // 90vh
        // 计算图片在当前缩放下超出视口的部分
        const scaledWidth = viewportWidth * this.fullscreenScale;
        const scaledHeight = viewportHeight * this.fullscreenScale;
        const maxTranslateX = Math.max(0, (scaledWidth - window.innerWidth) / 2);
        const maxTranslateY = Math.max(0, (scaledHeight - window.innerHeight) / 2);
        // 限制X轴偏移
        this.fullscreenTranslateX = Math.max(-maxTranslateX, Math.min(maxTranslateX, this.fullscreenTranslateX));
        // 限制Y轴偏移
        this.fullscreenTranslateY = Math.max(-maxTranslateY, Math.min(maxTranslateY, this.fullscreenTranslateY));
    }
    // 获取全屏图片的transform样式
    getFullscreenImageTransform() {
        // 先平移再缩放,这样平移的像素值不会被缩放影响
        return `translate(${this.fullscreenTranslateX}px, ${this.fullscreenTranslateY}px) scale(${this.fullscreenScale})`;
    }
    // 双击重置缩放
    onFullscreenDoubleClick(event) {
        if (!this.isFullscreen || !this.ncWheelScale) {
            return;
        }
        event.preventDefault();
        this.resetFullscreenZoom();
    }
}
GalleriaComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: GalleriaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
GalleriaComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.1.5", type: GalleriaComponent, selector: "nc-galleria", inputs: { ncImages: "ncImages", ncWidth: "ncWidth", ncHeight: "ncHeight", ncThumbnailWidth: "ncThumbnailWidth", ncThumbnailHeight: "ncThumbnailHeight", ncObjectFit: "ncObjectFit", ncAutoPlay: "ncAutoPlay", ncAutoPlayInterval: "ncAutoPlayInterval", ncShowThumbnails: "ncShowThumbnails", ncShowIndicators: "ncShowIndicators", ncIndicatorsPosition: "ncIndicatorsPosition", ncShowNavButtons: "ncShowNavButtons", ncNavButtonsDisplay: "ncNavButtonsDisplay", ncEnableFullscreen: "ncEnableFullscreen", ncFullscreenButtonDisplay: "ncFullscreenButtonDisplay", ncShowIndex: "ncShowIndex", ncShowTitle: "ncShowTitle", ncWheelScale: "ncWheelScale" }, host: { listeners: { "window:resize": "onWindowResize($event)", "keydown": "onKeyDown($event)" } }, viewQueries: [{ propertyName: "galleriaContainer", first: true, predicate: ["galleriaContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"nc-galleria\" #galleriaContainer [style.width]=\"ncWidth\" [style.height]=\"ncHeight\"\r\n    (mouseenter)=\"onMouseEnter()\" (mouseleave)=\"onMouseLeave()\" tabindex=\"0\" role=\"img\"\r\n    [attr.aria-label]=\"'\u56FE\u7247\u753B\u5ECA\uFF0C\u5F53\u524D\u7B2C' + (currentIndex + 1) + '\u5F20\uFF0C\u5171' + ncImages.length + '\u5F20'\"\r\n    *ngIf=\"ncImages && ncImages.length > 0\">\r\n\r\n    <!-- \u4E3B\u56FE\u663E\u793A\u533A\u57DF -->\r\n    <div class=\"galleria-main\">\r\n        <div class=\"main-image-container\" [class.nav-hover-mode]=\"ncNavButtonsDisplay === 'hover'\"\r\n            [class.full-hover-mode]=\"ncFullscreenButtonDisplay === 'hover'\">\r\n            <img [src]=\"ncImages[currentIndex].src\" [style.object-fit]=\"ncObjectFit\" [alt]=\"'\u56FE\u7247 ' + (currentIndex + 1)\"\r\n                [class.clickable]=\"ncEnableFullscreen\" (error)=\"onImageError($event)\"\r\n                (click)=\"ncEnableFullscreen && openFullscreen()\" class=\"main-image\">\r\n\r\n            <!-- \u6570\u76EE\u4FE1\u606F -->\r\n            <div class=\"index-container\" *ngIf=\"ncShowIndex && ncImages.length > 1\">\r\n                {{currentIndex + 1}} / {{ncImages.length}}\r\n            </div>\r\n\r\n            <!-- \u6807\u9898\u4FE1\u606F -->\r\n            <div class=\"title-container\" *ngIf=\"ncShowTitle && ncImages[currentIndex].title\">\r\n                {{ncImages[currentIndex].title}}\r\n            </div>\r\n\r\n            <!-- \u5168\u5C4F\u6309\u94AE -->\r\n            <button class=\"fullscreen-button\" *ngIf=\"ncEnableFullscreen && ncFullscreenButtonDisplay !== 'hidden'\"\r\n                (click)=\"openFullscreen()\" [attr.aria-label]=\"'\u5168\u5C4F\u9884\u89C8'\">\r\n                <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n                    <path\r\n                        d=\"M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3\"\r\n                        stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n                </svg>\r\n            </button>\r\n\r\n            <!-- \u5BFC\u822A\u6309\u94AE -->\r\n            <button class=\"nav-button nav-prev\" (click)=\"previousImage()\"\r\n                *ngIf=\"ncShowNavButtons && ncImages.length > 1\" [attr.aria-label]=\"'\u4E0A\u4E00\u5F20\u56FE\u7247'\">\r\n                <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n                    <path d=\"M15 18L9 12L15 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n                        stroke-linejoin=\"round\" />\r\n                </svg>\r\n            </button>\r\n\r\n            <button class=\"nav-button nav-next\" (click)=\"nextImage()\" *ngIf=\"ncShowNavButtons && ncImages.length > 1\"\r\n                [attr.aria-label]=\"'\u4E0B\u4E00\u5F20\u56FE\u7247'\">\r\n                <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n                    <path d=\"M9 18L15 12L9 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n                        stroke-linejoin=\"round\" />\r\n                </svg>\r\n            </button>\r\n\r\n            <!-- \u5185\u90E8\u6307\u793A\u5668 -->\r\n            <div class=\"indicators indicators-inside\"\r\n                *ngIf=\"ncShowIndicators && ncIndicatorsPosition === 'inside' && ncImages.length > 1\">\r\n                <span class=\"indicator\" *ngFor=\"let image of ncImages; let i = index\"\r\n                    [class.active]=\"i === currentIndex\" [attr.aria-label]=\"'\u8DF3\u8F6C\u5230\u7B2C' + (i + 1) + '\u5F20\u56FE\u7247'\" role=\"button\"\r\n                    tabindex=\"0\" (click)=\"selectImage(i)\" (keydown.enter)=\"selectImage(i)\"\r\n                    (keydown.space)=\"selectImage(i)\">\r\n                </span>\r\n            </div>\r\n        </div>\r\n    </div>\r\n\r\n    <!-- \u7F29\u7565\u56FE\u5BFC\u822A -->\r\n    <div class=\"galleria-thumbnails\" *ngIf=\"ncShowThumbnails && ncImages.length > 1\">\r\n        <div class=\"thumbnails-container\">\r\n            <!-- \u5DE6\u6EDA\u52A8\u6309\u94AE -->\r\n            <button class=\"scroll-button scroll-left\" (click)=\"scrollThumbnailsLeft()\"\r\n                *ngIf=\"!shouldCenterThumbnails && canScrollLeft()\" [attr.aria-label]=\"'\u5411\u5DE6\u6EDA\u52A8\u7F29\u7565\u56FE'\">\r\n                <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n                    <path d=\"M15 18L9 12L15 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n                        stroke-linejoin=\"round\" />\r\n                </svg>\r\n            </button>\r\n\r\n            <!-- \u7F29\u7565\u56FE\u5217\u8868 -->\r\n            <div class=\"thumbnails-list-container\">\r\n                <div class=\"thumbnails-list\" [class.center-thumbnails]=\"shouldCenterThumbnails\"\r\n                    [style.transform]=\"shouldCenterThumbnails ? 'none' : 'translateX(' + thumbnailTransform + 'px)'\">\r\n                    <div class=\"thumbnail-item\" *ngFor=\"let image of ncImages; let i = index\"\r\n                        [class.active]=\"i === currentIndex\" [style.width.px]=\"ncThumbnailWidth\"\r\n                        [style.height.px]=\"ncThumbnailHeight\" [attr.aria-label]=\"'\u7F29\u7565\u56FE ' + (i + 1)\" role=\"button\"\r\n                        tabindex=\"0\" (click)=\"selectImage(i)\" (keydown.enter)=\"selectImage(i)\"\r\n                        (keydown.space)=\"selectImage(i)\">\r\n                        <img [src]=\"image.src\" [alt]=\"'\u7F29\u7565\u56FE ' + (i + 1)\" (error)=\"onThumbnailError($event)\"\r\n                            class=\"thumbnail-image\">\r\n                    </div>\r\n                </div>\r\n            </div>\r\n\r\n            <!-- \u53F3\u6EDA\u52A8\u6309\u94AE -->\r\n            <button class=\"scroll-button scroll-right\" (click)=\"scrollThumbnailsRight()\"\r\n                *ngIf=\"!shouldCenterThumbnails && canScrollRight()\" [attr.aria-label]=\"'\u5411\u53F3\u6EDA\u52A8\u7F29\u7565\u56FE'\">\r\n                <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n                    <path d=\"M9 18L15 12L9 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n                        stroke-linejoin=\"round\" />\r\n                </svg>\r\n            </button>\r\n        </div>\r\n    </div>\r\n\r\n    <!-- \u5916\u90E8\u6307\u793A\u5668 -->\r\n    <div class=\"indicators indicators-outside\"\r\n        *ngIf=\"ncShowIndicators && ncIndicatorsPosition === 'outside' && ncImages.length > 1\"\r\n        [ngStyle]=\"{'margin-top': ncShowThumbnails ? '0' : '12px'}\">\r\n        <span class=\"indicator\" *ngFor=\"let image of ncImages; let i = index\" [class.active]=\"i === currentIndex\"\r\n            [attr.aria-label]=\"'\u8DF3\u8F6C\u5230\u7B2C' + (i + 1) + '\u5F20\u56FE\u7247'\" role=\"button\" tabindex=\"0\" (click)=\"selectImage(i)\"\r\n            (keydown.enter)=\"selectImage(i)\" (keydown.space)=\"selectImage(i)\">\r\n        </span>\r\n    </div>\r\n</div>\r\n\r\n<!-- \u7A7A\u72B6\u6001 -->\r\n<div class=\"galleria-empty\" [style.width]=\"ncWidth\" [style.height]=\"ncHeight\"\r\n    *ngIf=\"!ncImages || ncImages.length === 0\">\r\n    <div class=\"empty-content\">\r\n        <svg width=\"64\" height=\"64\" viewBox=\"0 0 24 24\" fill=\"none\" class=\"empty-icon\">\r\n            <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" stroke=\"currentColor\" stroke-width=\"2\" />\r\n            <circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\" stroke=\"currentColor\" stroke-width=\"2\" />\r\n            <polyline points=\"21,15 16,10 5,21\" stroke=\"currentColor\" stroke-width=\"2\" />\r\n        </svg>\r\n        <p>\u6682\u65E0\u56FE\u7247</p>\r\n    </div>\r\n</div>\r\n\r\n<!-- \u5168\u5C4F\u9884\u89C8\u6A21\u6001\u6846 -->\r\n<div class=\"fullscreen-modal\" *ngIf=\"isFullscreen\" (click)=\"closeFullscreen()\" (keydown)=\"onFullscreenKeyDown($event)\"\r\n    tabindex=\"0\">\r\n    <div class=\"fullscreen-content\" (click)=\"$event.stopPropagation()\">\r\n        <!-- \u5173\u95ED\u6309\u94AE -->\r\n        <button class=\"fullscreen-close\" (click)=\"closeFullscreen()\" [attr.aria-label]=\"'\u5173\u95ED\u5168\u5C4F'\">\r\n            <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n                <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" stroke=\"currentColor\" stroke-width=\"2\" />\r\n                <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" stroke=\"currentColor\" stroke-width=\"2\" />\r\n            </svg>\r\n        </button>\r\n\r\n        <!-- \u64AD\u653E/\u6682\u505C\u6309\u94AE -->\r\n        <button class=\"fullscreen-play-pause\" *ngIf=\"ncAutoPlay && ncImages.length > 1\"\r\n            (click)=\"toggleFullscreenAutoPlay()\" [attr.aria-label]=\"isFullscreenAutoPlaying ? '\u6682\u505C\u81EA\u52A8\u64AD\u653E' : '\u5F00\u59CB\u81EA\u52A8\u64AD\u653E'\">\r\n            <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\"\r\n                *ngIf=\"!isFullscreenAutoPlaying\">\r\n                <!-- \u64AD\u653E\u56FE\u6807 -->\r\n                <polygon points=\"5,3 19,12 5,21\" fill=\"currentColor\" />\r\n            </svg>\r\n            <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\"\r\n                *ngIf=\"isFullscreenAutoPlaying\">\r\n                <!-- \u6682\u505C\u56FE\u6807 -->\r\n                <rect x=\"6\" y=\"4\" width=\"4\" height=\"16\" fill=\"currentColor\" />\r\n                <rect x=\"14\" y=\"4\" width=\"4\" height=\"16\" fill=\"currentColor\" />\r\n            </svg>\r\n        </button>\r\n\r\n        <!-- \u7F29\u653E\u63D0\u793A -->\r\n        <div class=\"fullscreen-zoom-hint\" *ngIf=\"ncWheelScale\">\r\n            <div class=\"zoom-hint-content\">\r\n                <span>\u6EDA\u8F6E\u7F29\u653E \u2022 \u62D6\u62FD\u5E73\u79FB \u2022 \u53CC\u51FB\u91CD\u7F6E</span>\r\n            </div>\r\n        </div>\r\n\r\n        <!-- \u5168\u5C4F\u56FE\u7247 -->\r\n        <img [src]=\"ncImages[currentIndex].src\" [alt]=\"'\u5168\u5C4F\u9884\u89C8 - \u56FE\u7247 ' + (currentIndex + 1)\" (error)=\"onImageError($event)\"\r\n            class=\"fullscreen-image\" [class.scalable]=\"ncWheelScale\"\r\n            [style.transform]=\"ncWheelScale ? getFullscreenImageTransform() : ''\"\r\n            [style.cursor]=\"ncWheelScale && fullscreenScale > 1 ? 'grab' : (ncWheelScale ? 'zoom-in' : '')\"\r\n            (wheel)=\"onFullscreenWheel($event)\" (mousedown)=\"onFullscreenMouseDown($event)\"\r\n            (mousemove)=\"onFullscreenMouseMove($event)\" (mouseup)=\"onFullscreenMouseUp($event)\"\r\n            (mouseleave)=\"onFullscreenMouseUp($event)\" (dblclick)=\"onFullscreenDoubleClick($event)\">\r\n\r\n        <!-- \u5168\u5C4F\u5BFC\u822A\u6309\u94AE -->\r\n        <button class=\"fullscreen-nav fullscreen-nav-prev\" (click)=\"previousImage()\" *ngIf=\"ncImages.length > 1\"\r\n            [attr.aria-label]=\"'\u4E0A\u4E00\u5F20\u56FE\u7247'\">\r\n            <svg width=\"32\" height=\"32\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n                <path d=\"M15 18L9 12L15 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n                    stroke-linejoin=\"round\" />\r\n            </svg>\r\n        </button>\r\n\r\n        <button class=\"fullscreen-nav fullscreen-nav-next\" (click)=\"nextImage()\" *ngIf=\"ncImages.length > 1\"\r\n            [attr.aria-label]=\"'\u4E0B\u4E00\u5F20\u56FE\u7247'\">\r\n            <svg width=\"32\" height=\"32\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n                <path d=\"M9 18L15 12L9 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n                    stroke-linejoin=\"round\" />\r\n            </svg>\r\n        </button>\r\n\r\n        <!-- \u5168\u5C4F\u6307\u793A\u5668 -->\r\n        <div class=\"fullscreen-indicators\" *ngIf=\"ncImages.length > 1\">\r\n            <span class=\"fullscreen-indicator\" *ngFor=\"let image of ncImages; let i = index\"\r\n                [class.active]=\"i === currentIndex\" [attr.aria-label]=\"'\u8DF3\u8F6C\u5230\u7B2C' + (i + 1) + '\u5F20\u56FE\u7247'\" role=\"button\"\r\n                tabindex=\"0\" (click)=\"selectImage(i)\" (keydown.enter)=\"selectImage(i)\" (keydown.space)=\"selectImage(i)\">\r\n            </span>\r\n        </div>\r\n\r\n        <!-- \u56FE\u7247\u4FE1\u606F -->\r\n        <div class=\"fullscreen-info\">\r\n            <span>{{currentIndex + 1}} / {{ncImages.length}}</span>\r\n            <span *ngIf=\"ncWheelScale\" class=\"zoom-status\">\r\n                {{ (fullscreenScale * 100).toFixed(0) }}%\r\n            </span>\r\n            <span *ngIf=\"ncAutoPlay && ncImages.length > 1\" class=\"autoplay-status\">\r\n                {{ isFullscreenAutoPlaying ? '\u81EA\u52A8\u64AD\u653E\u4E2D' : '\u5DF2\u6682\u505C' }}\r\n            </span>\r\n        </div>\r\n    </div>\r\n</div>", styles: [".nc-galleria{display:flex;flex-direction:column;background:#fff;box-shadow:0 4px 12px #0000001a;overflow:hidden;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.nc-galleria .galleria-main{position:relative;background:#f8f9fa;flex:1;min-height:0}.nc-galleria .galleria-main .main-image-container{position:relative;width:100%;height:100%;overflow:hidden;display:flex;align-items:center;justify-content:center;background-color:#e5e5e5}.nc-galleria .galleria-main .main-image-container .main-image{width:100%;height:100%;transition:opacity .3s ease;-webkit-user-select:none;user-select:none;-webkit-user-drag:none}.nc-galleria .galleria-main .main-image-container .main-image.clickable{cursor:pointer}.nc-galleria .galleria-main .main-image-container .nav-button{position:absolute;top:50%;transform:translateY(-50%);width:40px;height:40px;border:none;border-radius:50%;background:rgba(0,0,0,.4);color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .3s ease;z-index:2;outline:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.nc-galleria .galleria-main .main-image-container .nav-button:hover{background:rgba(0,0,0,.6);transform:translateY(-50%) scale(1.1)}.nc-galleria .galleria-main .main-image-container .nav-button:focus{outline:none}.nc-galleria .galleria-main .main-image-container .nav-button:active{outline:none;background:rgba(0,0,0,.9)}.nc-galleria .galleria-main .main-image-container .nav-button.nav-prev{left:16px}.nc-galleria .galleria-main .main-image-container .nav-button.nav-next{right:16px}.nc-galleria .galleria-main .main-image-container .nav-button svg{width:24px;height:24px}.nc-galleria .galleria-main .main-image-container.nav-hover-mode .nav-button{opacity:0;visibility:hidden;transition:all .3s ease}.nc-galleria .galleria-main .main-image-container.nav-hover-mode:hover .nav-button{opacity:1;visibility:visible}.nc-galleria .galleria-main .main-image-container .indicators-inside{position:absolute;bottom:16px;left:50%;transform:translate(-50%);display:flex;justify-content:center;grid-gap:6px;gap:6px;z-index:3}.nc-galleria .galleria-main .main-image-container .indicators-inside .indicator{width:10px;height:10px;border-radius:50%;background:rgba(255,255,255,.6);cursor:pointer;transition:all .2s ease;border:1px solid rgba(0,0,0,.2)}.nc-galleria .galleria-main .main-image-container .indicators-inside .indicator:hover{background:rgba(255,255,255,.8)}.nc-galleria .galleria-main .main-image-container .indicators-inside .indicator.active{background:#007bff;box-shadow:0 0 4px #0000004d}.nc-galleria .galleria-main .main-image-container .fullscreen-button{position:absolute;top:16px;right:16px;width:36px;height:36px;border:none;border-radius:6px;background:rgba(0,0,0,.6);color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .3s ease;z-index:3;opacity:.8}.nc-galleria .galleria-main .main-image-container .fullscreen-button:hover{background:rgba(0,0,0,.8);opacity:1;transform:scale(1.05)}.nc-galleria .galleria-main .main-image-container.full-hover-mode .fullscreen-button{opacity:0;visibility:hidden;transition:all .3s ease}.nc-galleria .galleria-main .main-image-container.full-hover-mode:hover .fullscreen-button{opacity:1;visibility:visible}.nc-galleria .galleria-main .main-image-container .index-container{position:absolute;top:14px;left:50%;transform:translate(-50%);color:#fff;font-size:16px;background:rgba(0,0,0,.3);padding:2px 16px;border-radius:20px}.nc-galleria .galleria-main .main-image-container .title-container{position:absolute;bottom:10px;right:10px;color:#fff;font-size:16px;background:rgba(0,0,0,.5);padding:2px 16px;border-radius:20px}.nc-galleria .galleria-thumbnails{background:#fff;padding:16px;border-top:1px solid #e9ecef;flex-shrink:0}.nc-galleria .galleria-thumbnails .thumbnails-container{display:flex;align-items:center;grid-gap:8px;gap:8px;position:relative;width:100%}.nc-galleria .galleria-thumbnails .thumbnails-container .scroll-button{flex-shrink:0;width:32px;height:32px;border:1px solid #dee2e6;border-radius:4px;background:#fff;color:#6c757d;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s ease;outline:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.nc-galleria .galleria-thumbnails .thumbnails-container .scroll-button:hover{background:#f8f9fa;border-color:#adb5bd;color:#495057}.nc-galleria .galleria-thumbnails .thumbnails-container .scroll-button:focus{outline:none}.nc-galleria .galleria-thumbnails .thumbnails-container .scroll-button:active{outline:none;background:#e9ecef}.nc-galleria .galleria-thumbnails .thumbnails-container .scroll-button svg{width:16px;height:16px}.nc-galleria .galleria-thumbnails .thumbnails-container .thumbnails-list-container{overflow:hidden;position:relative;flex:1;min-width:0}.nc-galleria .galleria-thumbnails .thumbnails-container .thumbnails-list{display:flex;align-items:center;grid-gap:8px;gap:8px;justify-content:flex-start;transition:transform .4s cubic-bezier(.25,.46,.45,.94);will-change:transform}.nc-galleria .galleria-thumbnails .thumbnails-container .thumbnails-list.center-thumbnails{justify-content:center}.nc-galleria .galleria-thumbnails .thumbnails-container .thumbnails-list .thumbnail-item{flex-shrink:0;border:2px solid transparent;border-radius:4px;overflow:hidden;cursor:pointer;transition:all .2s ease;position:relative;opacity:.6}.nc-galleria .galleria-thumbnails .thumbnails-container .thumbnails-list .thumbnail-item:hover{opacity:1}.nc-galleria .galleria-thumbnails .thumbnails-container .thumbnails-list .thumbnail-item.active{border-color:#007bff91;box-shadow:0 0 0 2px #fffc;opacity:1}.nc-galleria .galleria-thumbnails .thumbnails-container .thumbnails-list .thumbnail-item .thumbnail-image{width:100%;height:100%;object-fit:cover;display:block;-webkit-user-select:none;user-select:none;-webkit-user-drag:none}.nc-galleria .indicators-outside{display:flex;justify-content:center;grid-gap:6px;gap:6px;margin-bottom:12px}.nc-galleria .indicators-outside .indicator{width:10px;height:10px;border-radius:50%;background:#dee2e6;cursor:pointer;transition:all .2s ease}.nc-galleria .indicators-outside .indicator:hover{background:#adb5bd}.nc-galleria .indicators-outside .indicator.active{background:#007bff}.galleria-empty{display:flex;align-items:center;justify-content:center;background:#f8f9fa;border-radius:8px;border:2px dashed #dee2e6;box-sizing:border-box}.galleria-empty .empty-content{text-align:center;color:#6c757d}.galleria-empty .empty-content .empty-icon{margin-bottom:16px;opacity:.5}.galleria-empty .empty-content p{margin:0;font-size:16px}.fullscreen-modal{position:fixed;top:0;left:0;width:100vw;height:100vh;background:rgba(0,0,0,.95);z-index:9999;display:flex;align-items:center;justify-content:center;animation:fadeIn .3s ease}.fullscreen-modal .fullscreen-content{position:relative;width:100%;height:100%;display:flex;align-items:center;justify-content:center}.fullscreen-modal .fullscreen-close{position:absolute;top:20px;right:20px;width:44px;height:44px;border:none;border-radius:50%;background:rgba(255,255,255,.2);color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .3s ease;z-index:10}.fullscreen-modal .fullscreen-close:hover{background:rgba(255,255,255,.3);transform:scale(1.1)}.fullscreen-modal .fullscreen-play-pause{position:absolute;top:20px;right:80px;width:44px;height:44px;border:none;border-radius:50%;background:rgba(255,255,255,.2);color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .3s ease;z-index:10}.fullscreen-modal .fullscreen-play-pause:hover{background:rgba(255,255,255,.3);transform:scale(1.1)}.fullscreen-modal .fullscreen-zoom-hint{position:absolute;top:20px;left:20px;z-index:10;opacity:.7;animation:fadeInOut 4s ease-in-out}.fullscreen-modal .fullscreen-zoom-hint .zoom-hint-content{background:rgba(0,0,0,.6);color:#fff;padding:8px 16px;border-radius:20px;font-size:14px;white-space:nowrap}.fullscreen-modal .fullscreen-image{max-width:90vw;max-height:90vh;object-fit:contain;-webkit-user-select:none;user-select:none;-webkit-user-drag:none;transition:transform .1s ease-out;transform-origin:center center}.fullscreen-modal .fullscreen-nav{position:absolute;top:50%;transform:translateY(-50%);width:60px;height:60px;border:none;border-radius:50%;background:rgba(255,255,255,.2);color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .3s ease;z-index:10}.fullscreen-modal .fullscreen-nav:hover{background:rgba(255,255,255,.3);transform:translateY(-50%) scale(1.1)}.fullscreen-modal .fullscreen-nav.fullscreen-nav-prev{left:30px}.fullscreen-modal .fullscreen-nav.fullscreen-nav-next{right:30px}.fullscreen-modal .fullscreen-indicators{position:absolute;bottom:30px;left:50%;transform:translate(-50%);display:flex;grid-gap:8px;gap:8px;z-index:10}.fullscreen-modal .fullscreen-indicators .fullscreen-indicator{width:12px;height:12px;border-radius:50%;background:rgba(255,255,255,.5);cursor:pointer;transition:all .3s ease}.fullscreen-modal .fullscreen-indicators .fullscreen-indicator:hover{background:rgba(255,255,255,.8);transform:scale(1.2)}.fullscreen-modal .fullscreen-indicators .fullscreen-indicator.active{background:white;transform:scale(1.3)}.fullscreen-modal .fullscreen-info{position:absolute;bottom:20px;right:20px;color:#fff;font-size:16px;background:rgba(0,0,0,.5);padding:8px 16px;border-radius:20px;z-index:10}.fullscreen-modal .fullscreen-info .zoom-status{margin-left:12px;font-size:14px;opacity:.8}.fullscreen-modal .fullscreen-info .zoom-status:before{content:\"\\2022\";margin-right:6px}.fullscreen-modal .fullscreen-info .autoplay-status{margin-left:12px;font-size:14px;opacity:.8}.fullscreen-modal .fullscreen-info .autoplay-status:before{content:\"\\2022\";margin-right:6px}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeInOut{0%{opacity:0}10%{opacity:.7}90%{opacity:.7}to{opacity:0}}\n"], directives: [{ type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: GalleriaComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'nc-galleria',
                    templateUrl: './galleria.component.html',
                    styleUrls: ['./galleria.component.less']
                }]
        }], ctorParameters: function () { return []; }, propDecorators: { ncImages: [{
                type: Input
            }], ncWidth: [{
                type: Input
            }], ncHeight: [{
                type: Input
            }], ncThumbnailWidth: [{
                type: Input
            }], ncThumbnailHeight: [{
                type: Input
            }], ncObjectFit: [{
                type: Input
            }], ncAutoPlay: [{
                type: Input
            }], ncAutoPlayInterval: [{
                type: Input
            }], ncShowThumbnails: [{
                type: Input
            }], ncShowIndicators: [{
                type: Input
            }], ncIndicatorsPosition: [{
                type: Input
            }], ncShowNavButtons: [{
                type: Input
            }], ncNavButtonsDisplay: [{
                type: Input
            }], ncEnableFullscreen: [{
                type: Input
            }], ncFullscreenButtonDisplay: [{
                type: Input
            }], ncShowIndex: [{
                type: Input
            }], ncShowTitle: [{
                type: Input
            }], ncWheelScale: [{
                type: Input
            }], galleriaContainer: [{
                type: ViewChild,
                args: ['galleriaContainer', { static: false }]
            }], onWindowResize: [{
                type: HostListener,
                args: ['window:resize', ['$event']]
            }], onKeyDown: [{
                type: HostListener,
                args: ['keydown', ['$event']]
            }] } });

class NcGalleriaModule {
}
NcGalleriaModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcGalleriaModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
NcGalleriaModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcGalleriaModule, declarations: [GalleriaComponent], imports: [CommonModule], exports: [GalleriaComponent] });
NcGalleriaModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcGalleriaModule, imports: [[
            CommonModule
        ]] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcGalleriaModule, decorators: [{
            type: NgModule,
            args: [{
                    declarations: [
                        GalleriaComponent
                    ],
                    imports: [
                        CommonModule
                    ],
                    exports: [
                        GalleriaComponent
                    ]
                }]
        }] });

/**
 * Generated bundle index. Do not edit.
 */

export { GalleriaComponent, NcGalleriaModule };
//# sourceMappingURL=ng-cw-v12-galleria.js.map