From 9fa1b718b85ef1eb6d9dbc16f8b4b4ea55c758e8 Mon Sep 17 00:00:00 2001 From: Spedon <70063177+Sped0n@users.noreply.github.com> Date: Sat, 20 Jan 2024 23:34:13 +0800 Subject: [PATCH] feat: add loading indicator for desktop and mobile (#244) * feat: add new CSS rule for hiding elements - Add a new CSS rule for the class "hide" with a display property set to "none". * feat: refactor image loading and navigation logic on desktop - Add a line of code in `assets/ts/desktop/stage.ts` to reset the `src` of `elc` and add a class `hide` to it - Add a line of code in `assets/ts/desktop/stage.ts` to call the `loader` function with `elc` as an argument - Add a function `loader` in `assets/ts/desktop/stage.ts` to handle image loading and error events - Modify the `initStageNav` function in `assets/ts/desktop/stageNav.ts` to watch the `isLoading` state and set custom cursor accordingly - Modify the `initStageNav` function in `assets/ts/desktop/stageNav.ts` to handle close click events by calling the `handleClick` function and setting `isLoading` state to false - Modify the `initStageNav` function in `assets/ts/desktop/stageNav.ts` to handle previous/next click events by calling the `handleClick` function only if `isLoading` is false - Modify the `initStageNav` function in `assets/ts/desktop/stageNav.ts` to handle previous/next hover events by setting `loadedText` and updating custom cursor depending on `isLoading` state * feat: refactor createGallery function and enhance loading functionality on mobile - Add a loading text element to the gallery.scss file - Add a loading indicator to the createGallery function in gallery.ts - Modify the createGallery function in gallery.ts to hide the loading text element on image load - Move the image element append logic to the parent container in the createGallery function in gallery.ts * feat: update translations and add new loading translation in i18n files * chore: remove css source map * chore: modify build command to ignore css source map * refactor: remove unnecessary style * fix: fix desktop cursor text transition bug --- assets/scss/_core/_base.scss | 4 + assets/scss/_partial/_gallery.scss | 12 +++ assets/ts/desktop/stage.ts | 39 ++++++++- assets/ts/desktop/stageNav.ts | 130 ++++++++++++++++++++++------- assets/ts/mobile/gallery.ts | 22 ++++- i18n/de.toml | 2 + i18n/en.toml | 2 + i18n/es.toml | 2 + i18n/fr.toml | 2 + i18n/it.toml | 2 + i18n/ja.toml | 2 + i18n/ko.toml | 2 + i18n/zh-cn.toml | 2 + i18n/zh-hk.toml | 2 + i18n/zh-mo.toml | 2 + i18n/zh-sg.toml | 2 + i18n/zh-tw.toml | 2 + layouts/_default/single.html | 1 + package.json | 4 +- static/bundled/css/style.css.map | 29 ------- 20 files changed, 200 insertions(+), 65 deletions(-) delete mode 100644 static/bundled/css/style.css.map diff --git a/assets/scss/_core/_base.scss b/assets/scss/_core/_base.scss index eb48cd7..d8e8a82 100644 --- a/assets/scss/_core/_base.scss +++ b/assets/scss/_core/_base.scss @@ -17,3 +17,7 @@ a, button { cursor: pointer; } + +.hide { + display: none; +} diff --git a/assets/scss/_partial/_gallery.scss b/assets/scss/_partial/_gallery.scss index 1d82815..a161edc 100644 --- a/assets/scss/_partial/_gallery.scss +++ b/assets/scss/_partial/_gallery.scss @@ -27,6 +27,18 @@ height: 100%; object-fit: contain; } + + .loadingText { + position: absolute; + top: 50%; + left: 50%; + transform: translate3d(-50%, -50%, 0); + } + + .slideContainer { + position: relative; + display: inline-block; + } } } diff --git a/assets/ts/desktop/stage.ts b/assets/ts/desktop/stage.ts index e5ff098..c8efe54 100644 --- a/assets/ts/desktop/stage.ts +++ b/assets/ts/desktop/stage.ts @@ -25,6 +25,7 @@ export const cordHist = new Watchable([]) export const isOpen = new Watchable(false) export const isAnimating = new Watchable(false) export const active = new Watchable(false) +export const isLoading = new Watchable(false) let _gsap: typeof gsap let _Power3: typeof Power3 @@ -114,9 +115,13 @@ function setPositions(): void { if (isOpen.get()) { lores(getElTrail()) - hires([getElCurrent(), getElPrev(), getElNext()]) + const elc = getElCurrent() + elc.src = '' // reset src to ensure we only display hires images + elc.classList.add('hide') + hires([elc, getElPrev(), getElNext()]) _gsap.set(imgs, { opacity: 0 }) - _gsap.set(getElCurrent(), { opacity: 1, x: 0, y: 0, scale: 1 }) + _gsap.set(elc, { opacity: 1, x: 0, y: 0, scale: 1 }) + loader(elc) } } @@ -127,7 +132,11 @@ function expandImage(): void { isOpen.set(true) isAnimating.set(true) - hires([getElCurrent(), getElPrev(), getElNext()]) + const elc = getElCurrent() + // don't clear src here because we want a better transition + + hires([elc, getElPrev(), getElNext()]) + loader(elc) const tl = _gsap.timeline() // move down and hide trail inactive @@ -292,3 +301,27 @@ function lores(imgs: HTMLImageElement[]): void { img.width = parseInt(img.dataset.loImgW as string) }) } + +function loader(e: HTMLImageElement): void { + if (!e.complete) { + isLoading.set(true) + e.addEventListener( + 'load', + () => { + isLoading.set(false) + e.classList.remove('hide') + }, + { once: true, passive: true } + ) + e.addEventListener( + 'error', + () => { + isLoading.set(false) + }, + { once: true, passive: true } + ) + } else { + e.classList.remove('hide') + isLoading.set(false) + } +} diff --git a/assets/ts/desktop/stageNav.ts b/assets/ts/desktop/stageNav.ts index 931becb..ab5676d 100644 --- a/assets/ts/desktop/stageNav.ts +++ b/assets/ts/desktop/stageNav.ts @@ -3,7 +3,14 @@ import { decIndex, incIndex, state } from '../state' import { decrement, increment } from '../utils' import { setCustomCursor } from './customCursor' -import { active, cordHist, isAnimating, isOpen, minimizeImage } from './stage' +import { + active, + cordHist, + isAnimating, + isLoading, + isOpen, + minimizeImage +} from './stage' /** * types @@ -21,6 +28,8 @@ const navItems = [ mainDiv.getAttribute('closeText') as string, mainDiv.getAttribute('nextText') as string ] as const +const loadingText = (mainDiv.getAttribute('loadingText') as string) + '...' +let loadedText = '' /** * main functions @@ -56,39 +65,80 @@ function handleKey(e: KeyboardEvent): void { */ export function initStageNav(): void { + // isLoading + isLoading.addWatcher((o) => { + if (o) setCustomCursor(loadingText) + else setCustomCursor(loadedText) + }) + // navOverlay const navOverlay = document.createElement('div') navOverlay.className = 'navOverlay' - for (const navItem of navItems) { + for (const [index, navItem] of navItems.entries()) { const overlay = document.createElement('div') overlay.className = 'overlay' - overlay.addEventListener( - 'click', - () => { - handleClick(navItem) - }, - { passive: true } - ) - overlay.addEventListener( - 'keydown', - () => { - handleClick(navItem) - }, - { passive: true } - ) - overlay.addEventListener( - 'mouseover', - () => { - setCustomCursor(navItem) - }, - { passive: true } - ) - overlay.addEventListener( - 'focus', - () => { - setCustomCursor(navItem) - }, - { passive: true } - ) + const isClose = index === 1 + // close + if (isClose) { + overlay.addEventListener( + 'click', + () => { + handleCloseClick(navItem) + }, + { passive: true } + ) + overlay.addEventListener( + 'keydown', + () => { + handleCloseClick(navItem) + }, + { passive: true } + ) + overlay.addEventListener( + 'mouseover', + () => { + handleCloseHover(navItem) + }, + { passive: true } + ) + overlay.addEventListener( + 'focus', + () => { + handleCloseHover(navItem) + }, + { passive: true } + ) + } + // prev and next + else { + overlay.addEventListener( + 'click', + () => { + handlePNClick(navItem) + }, + { passive: true } + ) + overlay.addEventListener( + 'keydown', + () => { + handlePNClick(navItem) + }, + { passive: true } + ) + overlay.addEventListener( + 'mouseover', + () => { + handlePNHover(navItem) + }, + { passive: true } + ) + overlay.addEventListener( + 'focus', + () => { + handlePNHover(navItem) + }, + { passive: true } + ) + } navOverlay.append(overlay) } active.addWatcher(() => { @@ -127,3 +177,23 @@ function prevImage(): void { decIndex() } + +function handleCloseClick(navItem: NavItem): void { + handleClick(navItem) + isLoading.set(false) +} + +function handleCloseHover(navItem: NavItem): void { + loadedText = navItem + setCustomCursor(navItem) +} + +function handlePNClick(navItem: NavItem): void { + if (!isLoading.get()) handleClick(navItem) +} + +function handlePNHover(navItem: NavItem): void { + loadedText = navItem + if (isLoading.get()) setCustomCursor(loadingText) + else setCustomCursor(navItem) +} diff --git a/assets/ts/mobile/gallery.ts b/assets/ts/mobile/gallery.ts index 8deb762..86d28ad 100644 --- a/assets/ts/mobile/gallery.ts +++ b/assets/ts/mobile/gallery.ts @@ -196,14 +196,34 @@ function createGallery(ijs: ImageJSON[]): void { for (const ij of ijs) { const _swiperSlide = document.createElement('div') _swiperSlide.className = 'swiper-slide' + // loading indicator + const l = document.createElement('div') + l.className = 'loadingText' + l.innerText = + (document.getElementById('main')?.getAttribute('loadingText') as string) + '...' // img const e = document.createElement('img') e.dataset.src = ij.hiUrl e.height = ij.hiImgH e.width = ij.hiImgW e.alt = ij.alt + e.classList.add('hide') + // load event + e.addEventListener( + 'load', + () => { + e.classList.remove('hide') + l.classList.add('hide') + }, + { once: true, passive: true } + ) + // parent container + const p = document.createElement('div') + p.className = 'slideContainer' // append - _swiperSlide.append(e) + p.append(e) + p.append(l) + _swiperSlide.append(p) _swiperWrapper.append(_swiperSlide) } // swiper node diff --git a/i18n/de.toml b/i18n/de.toml index d002021..784433c 100644 --- a/i18n/de.toml +++ b/i18n/de.toml @@ -8,3 +8,5 @@ other = "schließen" other = "schwelle" [404] other = "seite nicht gefunden" +[loading] +other = "lade" diff --git a/i18n/en.toml b/i18n/en.toml index 3e68700..d3b3154 100644 --- a/i18n/en.toml +++ b/i18n/en.toml @@ -8,3 +8,5 @@ other = "close" other = "threshold" [404] other = "page not found" +[loading] +other = "loading" diff --git a/i18n/es.toml b/i18n/es.toml index 492e36c..2a56bf7 100644 --- a/i18n/es.toml +++ b/i18n/es.toml @@ -8,3 +8,5 @@ other = "cerrar" other = "umbral" [404] other = "página no encontrada" +[loading] +other = "cargando" diff --git a/i18n/fr.toml b/i18n/fr.toml index 1e8cded..047d1e0 100644 --- a/i18n/fr.toml +++ b/i18n/fr.toml @@ -8,3 +8,5 @@ other = "fermer" other = "seuil" [404] other = "page non trouvée" +[loading] +other = "chargement" diff --git a/i18n/it.toml b/i18n/it.toml index 8c5c330..36134c5 100644 --- a/i18n/it.toml +++ b/i18n/it.toml @@ -8,3 +8,5 @@ other = "chiudi" other = "soglia" [404] other = "pagina non trovata" +[loading] +other = "caricamento" diff --git a/i18n/ja.toml b/i18n/ja.toml index 02e803b..3a4ee4a 100644 --- a/i18n/ja.toml +++ b/i18n/ja.toml @@ -8,3 +8,5 @@ other = "閉じる" other = "しきい値" [404] other = "ページが見つかりません" +[loading] +other = "読み込み中" diff --git a/i18n/ko.toml b/i18n/ko.toml index f3149e1..6cfb67b 100644 --- a/i18n/ko.toml +++ b/i18n/ko.toml @@ -8,3 +8,5 @@ other = "닫기" other = "임계값" [404] other = "페이지를 찾을 수 없습니다" +[loading] +other = "로딩중" diff --git a/i18n/zh-cn.toml b/i18n/zh-cn.toml index 31fcbb9..bb58da0 100644 --- a/i18n/zh-cn.toml +++ b/i18n/zh-cn.toml @@ -8,3 +8,5 @@ other = "关闭" other = "阈值" [404] other = "页面不存在" +[loading] +other = "加载中" diff --git a/i18n/zh-hk.toml b/i18n/zh-hk.toml index 9de5480..c81da28 100644 --- a/i18n/zh-hk.toml +++ b/i18n/zh-hk.toml @@ -8,3 +8,5 @@ other = "關閉" other = "閾值" [404] other = "找不到頁面" +[loading] +other = "載入中" diff --git a/i18n/zh-mo.toml b/i18n/zh-mo.toml index 9de5480..c81da28 100644 --- a/i18n/zh-mo.toml +++ b/i18n/zh-mo.toml @@ -8,3 +8,5 @@ other = "關閉" other = "閾值" [404] other = "找不到頁面" +[loading] +other = "載入中" diff --git a/i18n/zh-sg.toml b/i18n/zh-sg.toml index 31fcbb9..bb58da0 100644 --- a/i18n/zh-sg.toml +++ b/i18n/zh-sg.toml @@ -8,3 +8,5 @@ other = "关闭" other = "阈值" [404] other = "页面不存在" +[loading] +other = "加载中" diff --git a/i18n/zh-tw.toml b/i18n/zh-tw.toml index 9de5480..c81da28 100644 --- a/i18n/zh-tw.toml +++ b/i18n/zh-tw.toml @@ -8,3 +8,5 @@ other = "關閉" other = "閾值" [404] other = "找不到頁面" +[loading] +other = "載入中" diff --git a/layouts/_default/single.html b/layouts/_default/single.html index a4f0a73..b5407f1 100644 --- a/layouts/_default/single.html +++ b/layouts/_default/single.html @@ -3,6 +3,7 @@ document.getElementById("main").setAttribute("nextText", "{{- i18n "next" -}}") document.getElementById("main").setAttribute("prevText", "{{- i18n "prev" -}}") document.getElementById("main").setAttribute("closeText", "{{- i18n "close" -}}") + document.getElementById("main").setAttribute("loadingText", "{{- i18n "loading" -}}")
{{- partial "nav.html" . -}} diff --git a/package.json b/package.json index b4b66d7..4b23902 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bridget", - "version": "v0.0.4", + "version": "v1.0.0", "description": "bridget theme source file", "packageManager": "pnpm@8.10.2", "private": true, @@ -9,7 +9,7 @@ "lint": "eslint . --fix && prettier --write .", "lint:check": "eslint . && prettier . --check", "dev": "run-p rollup:dev hugo:dev", - "build": "rm -f ./static/bundled/js/* && run-s rollup:build hugo:build && yes | cp -rf ./exampleSite/public/css/* ./static/bundled/css", + "build": "rm -f ./static/bundled/js/* && run-s rollup:build hugo:build && yes | cp -rf ./exampleSite/public/css/*.css ./static/bundled/css", "server": "run-p rollup:server hugo:server", "rollup:build": "rollup -c --environment BUILD:production", "rollup:server": "rollup -c --watch --environment BUILD:production", diff --git a/static/bundled/css/style.css.map b/static/bundled/css/style.css.map deleted file mode 100644 index 64eccff..0000000 --- a/static/bundled/css/style.css.map +++ /dev/null @@ -1,29 +0,0 @@ -{ - "version": 3, - "file": "style.css", - "sourceRoot": "/home/runner/work/bridget/bridget/exampleSite", - "sources": [ - "/home/runner/work/bridget/bridget/assets/scss/style.scss", - "assets/scss/_partial/_customCursor.scss", - "assets/scss/_partial/_stage.scss", - "assets/scss/_partial/_stageNav.scss", - "assets/scss/_partial/_collection.scss", - "assets/scss/_partial/_gallery.scss", - "assets/scss/_partial/_container.scss", - "node_modules/swiper/swiper.scss", - "node_modules/swiper/swiper-vars.scss" - ], - "sourcesContent": [ - "@charset \"utf-8\";\n\n@import '_partial/customCursor';\n@import '_partial/stage';\n@import '_partial/stageNav';\n\n@import '_partial/collection';\n@import '_partial/gallery';\n@import '_partial/container';\n\n@import 'node_modules/swiper/swiper.scss';\n", - ".cursor {\n position: fixed;\n z-index: var(--z-cursor);\n top: 0;\n left: 0;\n\n display: none;\n cursor: none;\n pointer-events: none;\n\n color: white;\n mix-blend-mode: difference;\n\n .cursorInner {\n transform: translate3d(-50%, -50%, 0);\n }\n}\n\n.active {\n display: block;\n}\n", - ".stage {\n position: relative;\n overflow: hidden;\n width: 100vw;\n height: calc(var(--window-height) - var(--nav-height));\n\n cursor: pointer;\n\n img {\n position: absolute;\n top: 0;\n left: 0;\n\n width: 100vw;\n height: var(--window-height);\n object-fit: contain;\n\n transform: scale(0.6);\n opacity: 0;\n pointer-events: none;\n }\n}\n", - ".navOverlay {\n position: fixed;\n top: 0;\n left: 0;\n z-index: var(--z-nav-gallery);\n\n width: 100vw;\n height: calc(var(--window-height) - var(--nav-height));\n\n display: flex;\n cursor: none;\n\n &:not(.active) {\n pointer-events: none;\n display: none;\n }\n\n .overlay {\n flex: 1;\n }\n}\n", - ".collection {\n display: flex;\n flex-direction: column;\n gap: 20vh;\n\n padding-top: 50vh;\n margin-top: calc(var(--nav-height) * -1);\n\n img {\n position: sticky;\n top: 50vh;\n\n width: 60vw;\n height: 20vh;\n\n object-fit: contain;\n\n transform: translate3d(0, -50%, 0);\n align-self: center;\n\n &:last-child {\n margin-bottom: 20vh;\n }\n }\n}\n\n.hidden {\n display: none;\n}\n", - ".gallery {\n pointer-events: all;\n\n position: fixed;\n top: var(--nav-height);\n z-index: var(--z-nav-gallery);\n\n display: flex;\n flex-direction: column;\n\n width: 100vw;\n height: calc(var(--window-height) - var(--nav-height));\n background: white;\n transform: translate3d(0, 100%, 0);\n\n .galleryInner {\n flex: 1;\n height: 0;\n\n .swiper-slide {\n display: flex;\n align-items: center;\n justify-content: center;\n\n img {\n width: 100%;\n height: 100%;\n object-fit: contain;\n }\n }\n }\n\n .nav {\n height: var(--nav-height);\n padding: var(--space-standard);\n\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n}\n\n.curtain {\n position: fixed;\n top: 0;\n left: 0;\n z-index: var(--z-curtain);\n\n width: 100vw;\n height: var(--window-height);\n\n background: rgba(0, 0, 0, 0.5);\n opacity: 0;\n\n pointer-events: none;\n}\n", - ".container {\n position: fixed;\n top: 0;\n z-index: 0;\n\n width: 100vw;\n height: var(--window-height);\n\n overflow-y: scroll;\n overflow-x: hidden;\n background: white;\n\n overscroll-behavior: none;\n -webkit-overflow-scrolling: none;\n}\n\n.disableScroll {\n pointer-events: none;\n}\n", - "/**\n * Swiper 11.0.5\n * Most modern mobile touch slider and framework with hardware accelerated transitions\n * https://swiperjs.com\n *\n * Copyright 2014-2023 Vladimir Kharlampidi\n *\n * Released under the MIT License\n *\n * Released on: November 22, 2023\n */\n\n@import 'swiper-vars.scss';\n@at-root {\n @font-face {\n font-family: 'swiper-icons';\n src: url('data:application/font-woff;charset=utf-8;base64, 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')\n format('woff');\n font-weight: 400;\n font-style: normal;\n }\n}\n@at-root {\n :root {\n --swiper-theme-color: #{$themeColor};\n /*\n --swiper-preloader-color: var(--swiper-theme-color);\n --swiper-wrapper-transition-timing-function: initial;\n */\n }\n}\n:host {\n position: relative;\n display: block;\n margin-left: auto;\n margin-right: auto;\n z-index: 1;\n}\n.swiper {\n margin-left: auto;\n margin-right: auto;\n position: relative;\n overflow: hidden;\n list-style: none;\n padding: 0;\n /* Fix of Webkit flickering */\n z-index: 1;\n display: block;\n}\n.swiper-vertical > .swiper-wrapper {\n flex-direction: column;\n}\n.swiper-wrapper {\n position: relative;\n width: 100%;\n height: 100%;\n z-index: 1;\n display: flex;\n transition-property: transform;\n transition-timing-function: var(--swiper-wrapper-transition-timing-function, initial);\n box-sizing: content-box;\n}\n.swiper-android .swiper-slide,\n.swiper-ios .swiper-slide,\n.swiper-wrapper {\n transform: translate3d(0px, 0, 0);\n}\n.swiper-horizontal {\n touch-action: pan-y;\n}\n.swiper-vertical {\n touch-action: pan-x;\n}\n.swiper-slide {\n flex-shrink: 0;\n width: 100%;\n height: 100%;\n position: relative;\n transition-property: transform;\n display: block;\n}\n.swiper-slide-invisible-blank {\n visibility: hidden;\n}\n/* Auto Height */\n.swiper-autoheight,\n.swiper-autoheight .swiper-slide {\n height: auto;\n}\n.swiper-autoheight .swiper-wrapper {\n align-items: flex-start;\n transition-property: transform, height;\n}\n.swiper-backface-hidden .swiper-slide {\n transform: translateZ(0);\n backface-visibility: hidden;\n}\n/* 3D Effects */\n.swiper-3d.swiper-css-mode .swiper-wrapper {\n perspective: 1200px;\n}\n.swiper-3d .swiper-wrapper {\n transform-style: preserve-3d;\n}\n.swiper-3d {\n perspective: 1200px;\n .swiper-slide,\n .swiper-cube-shadow {\n transform-style: preserve-3d;\n }\n}\n\n/* CSS Mode */\n.swiper-css-mode {\n > .swiper-wrapper {\n overflow: auto;\n scrollbar-width: none; /* For Firefox */\n -ms-overflow-style: none; /* For Internet Explorer and Edge */\n &::-webkit-scrollbar {\n display: none;\n }\n }\n > .swiper-wrapper > .swiper-slide {\n scroll-snap-align: start start;\n }\n &.swiper-horizontal {\n > .swiper-wrapper {\n scroll-snap-type: x mandatory;\n }\n }\n &.swiper-vertical {\n > .swiper-wrapper {\n scroll-snap-type: y mandatory;\n }\n }\n &.swiper-free-mode {\n > .swiper-wrapper {\n scroll-snap-type: none;\n }\n > .swiper-wrapper > .swiper-slide {\n scroll-snap-align: none;\n }\n }\n &.swiper-centered {\n > .swiper-wrapper::before {\n content: '';\n flex-shrink: 0;\n order: 9999;\n }\n > .swiper-wrapper > .swiper-slide {\n scroll-snap-align: center center;\n scroll-snap-stop: always;\n }\n }\n &.swiper-centered.swiper-horizontal {\n > .swiper-wrapper > .swiper-slide:first-child {\n margin-inline-start: var(--swiper-centered-offset-before);\n }\n > .swiper-wrapper::before {\n height: 100%;\n min-height: 1px;\n width: var(--swiper-centered-offset-after);\n }\n }\n &.swiper-centered.swiper-vertical {\n > .swiper-wrapper > .swiper-slide:first-child {\n margin-block-start: var(--swiper-centered-offset-before);\n }\n > .swiper-wrapper::before {\n width: 100%;\n min-width: 1px;\n height: var(--swiper-centered-offset-after);\n }\n }\n}\n\n/* Slide styles start */\n/* 3D Shadows */\n.swiper-3d {\n .swiper-slide-shadow,\n .swiper-slide-shadow-left,\n .swiper-slide-shadow-right,\n .swiper-slide-shadow-top,\n .swiper-slide-shadow-bottom,\n .swiper-slide-shadow,\n .swiper-slide-shadow-left,\n .swiper-slide-shadow-right,\n .swiper-slide-shadow-top,\n .swiper-slide-shadow-bottom {\n position: absolute;\n left: 0;\n top: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n z-index: 10;\n }\n .swiper-slide-shadow {\n background: rgba(0, 0, 0, 0.15);\n }\n .swiper-slide-shadow-left {\n background-image: linear-gradient(to left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n }\n .swiper-slide-shadow-right {\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n }\n .swiper-slide-shadow-top {\n background-image: linear-gradient(to top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n }\n .swiper-slide-shadow-bottom {\n background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n }\n}\n.swiper-lazy-preloader {\n width: 42px;\n height: 42px;\n position: absolute;\n left: 50%;\n top: 50%;\n margin-left: -21px;\n margin-top: -21px;\n z-index: 10;\n transform-origin: 50%;\n box-sizing: border-box;\n border: 4px solid var(--swiper-preloader-color, var(--swiper-theme-color));\n border-radius: 50%;\n border-top-color: transparent;\n}\n.swiper:not(.swiper-watch-progress),\n.swiper-watch-progress .swiper-slide-visible {\n .swiper-lazy-preloader {\n animation: swiper-preloader-spin 1s infinite linear;\n }\n}\n.swiper-lazy-preloader-white {\n --swiper-preloader-color: #fff;\n}\n.swiper-lazy-preloader-black {\n --swiper-preloader-color: #000;\n}\n@keyframes swiper-preloader-spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n/* Slide styles end */\n\n\n\n", - "$themeColor: #007aff !default;\n" - ], - "names": [], - "mappings": "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" -} \ No newline at end of file