UNPKG

ng-cw-v12

Version:

Angular UI Component Library

673 lines 127 kB
import { Component, Input, ViewChild, HostListener } from '@angular/core'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; export 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']] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2FsbGVyaWEuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvY29tcG9uZW50cy9nYWxsZXJpYS9nYWxsZXJpYS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL2dhbGxlcmlhL2dhbGxlcmlhLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQWEsS0FBSyxFQUFFLFNBQVMsRUFBNkIsWUFBWSxFQUE0QixNQUFNLGVBQWUsQ0FBQzs7O0FBaUIxSSxNQUFNLE9BQU8saUJBQWlCO0lBZ001QjtRQS9MQSxXQUFXO1FBQ0gsWUFBTyxHQUFzQixFQUFFLENBQUM7UUFnQnhDLFdBQVc7UUFDRixZQUFPLEdBQVcsTUFBTSxDQUFDO1FBQ2xDLFdBQVc7UUFDRixhQUFRLEdBQVcsTUFBTSxDQUFDO1FBQ25DLFlBQVk7UUFDSCxxQkFBZ0IsR0FBVyxFQUFFLENBQUM7UUFDdkMsWUFBWTtRQUNILHNCQUFpQixHQUFXLEVBQUUsQ0FBQztRQUN4QyxhQUFhO1FBQ0osZ0JBQVcsR0FBb0IsU0FBUyxDQUFDO1FBQ2xELFdBQVc7UUFDSCxjQUFTLEdBQVksS0FBSyxDQUFDO1FBUW5DLGFBQWE7UUFDSix1QkFBa0IsR0FBVyxJQUFJLENBQUM7UUFDM0MsWUFBWTtRQUNKLG9CQUFlLEdBQVksSUFBSSxDQUFDO1FBUXhDLFlBQVk7UUFDSixvQkFBZSxHQUFZLEtBQUssQ0FBQztRQVF6QyxjQUFjO1FBQ0wseUJBQW9CLEdBQTZCLFNBQVMsQ0FBQztRQUNwRSxhQUFhO1FBQ0wsb0JBQWUsR0FBWSxLQUFLLENBQUM7UUFRekMsZUFBZTtRQUNOLHdCQUFtQixHQUE0QixRQUFRLENBQUM7UUFDakUsYUFBYTtRQUNMLHNCQUFpQixHQUFZLEtBQUssQ