mirror of
https://github.com/Sped0n/bridget.git
synced 2026-04-21 13:39:30 -07:00
refactor: refactor the pile of crap I wrote before 🤡 (#259)
* feat: refactor file structure and imports in mobile and desktop components - Removed the import of `scrollable` from `assets/ts/mobile/scroll.ts` - Renamed `assets/ts/mobile/mounted.ts` to `assets/ts/mobile/state.ts` - Changed the import of `active` from `./stage` to `./state` in `assets/ts/desktop/customCursor.ts` - Changed the import of `active` from `../state` to `../globalState` in `assets/ts/desktop/stage.ts` - Changed the import of `active` from `./stage` to `./state` in `assets/ts/desktop/stageNav.ts` - Renamed `assets/ts/state.ts` to `assets/ts/globalState.ts` - Created a new file `assets/ts/desktop/state.ts` - Added the interface `HistoryItem` to `assets/ts/desktop/state.ts` - Added the variables `cordHist`, `isOpen`, `active`, and `isLoading` to `assets/ts/desktop/state.ts` - Deleted the function `loader` from `assets/ts/desktop/stage.ts` and replaced it with `setLoaderForImage` - Deleted the import of `./stage` from `assets/ts/desktop/stageNav.ts` - Added the import of `minimizeImage` from `./stage` in `assets/ts/desktop/stageNav.ts` - Deleted the import of `./mounted` from `assets/ts/mobile/collection.ts` - Changed the import of `mounted` from `./mounted` to `./state` in ` * refactor: refactor the `onVisible` function to improve performance - Modify the type of the `onVisible` function parameter `T` to extend `HTMLElement` - Change the `entries.forEach` loop in the `onVisible` function to `entries.every` * feat: add new function for detecting opacity changes in element - Add a new function `onOpacityOne` in `assets/ts/utils.ts` - The function uses a `MutationObserver` to check for opacity changes on an element - When the element's opacity reaches `1`, the provided callback function is called - The `MutationObserver` is disconnected after the callback is executed * refactor: refactor function names and parameters in intersection and mutation observers - Change the function name `onVisible` to `onIntersection` - Modify the `callback` parameter in the `onIntersection` function to accept `IntersectionObserverEntry[]` and `IntersectionObserver` parameters - Remove the code block that checks for intersection ratio and immediately calls the `callback` function in the `onIntersection` function - Modify the function name `onOpacityOne` to `onMutation` - Modify the `callback` parameter in the `onMutation` function to accept `MutationRecord[]` and `MutationObserver` parameters - Add a default value for the `observeOptions` parameter in the `onMutation` function * refactor: refine preload logic on both mobile and desktop * refactor: refactor import statements and add new files - The import statement for `Watchable` in `assets/ts/globalState.ts` has been changed from `../utils` to `../globalUtils` - The import statement for `Watchable` in `assets/ts/desktop/state.ts` has been changed from `../utils` to `../globalUtils` - The import statement for `decrement` and `increment` in `assets/ts/desktop/stageNav.ts` has been changed from `../utils` to `../globalUtils` - A new file `utils.ts` has been added in the `assets/ts/desktop` directory - The import statements for `getRandom`, `onIntersection`, and `type MobileImage` in `assets/ts/mobile/collection.ts` have been changed from `../utils` to `./utils` - The `imgs` array in `assets/ts/mobile/collection.ts` has been changed from an array of `HTMLImageElement` to an array of `MobileImage` - The import statements for `expand`, `loadGsap`, `loadSwiper`, and `removeDuplicates` in `assets/ts/mobile/gallery.ts` have been changed from `../utils` to `../globalUtils` - The import statement for `type MobileImage` in `assets/ts/mobile/gallery.ts` has been changed from `./utils` to `../mobile/utils` - The `galleryLoadImages` function in `assets/ts/mobile/gallery.ts` has been removed - A new file `utils.ts` * refactor: refactor swiper import and functions in mobile and global utils * refactor: refactor navigation and image loading logic in desktop and mobile * refactor: remove print function and optimize removeDuplicates return * refactor: update text variable assignments and attributes * refactor: update variable types in galleryImages and collectionImages in mobile/gallery.ts * refactor: refactor variable types for consistency with naming conventions * refactor: update animation durations and types in gallery functions * refactor: refactor image loading logic and add console logs * refactor: refactor sass hierarchy * refactor: remove console logs in multiple files
This commit is contained in:
@@ -1,16 +1,17 @@
|
||||
import { container } from '../container'
|
||||
import { setIndex } from '../globalState'
|
||||
import { type ImageJSON } from '../resources'
|
||||
import { setIndex } from '../state'
|
||||
import { getRandom, onVisible } from '../utils'
|
||||
|
||||
import { slideUp } from './gallery'
|
||||
import { mounted } from './mounted'
|
||||
import { mounted } from './state'
|
||||
// eslint-disable-next-line sort-imports
|
||||
import { getRandom, onIntersection, type MobileImage } from './utils'
|
||||
|
||||
/**
|
||||
* variables
|
||||
*/
|
||||
|
||||
export let imgs: HTMLImageElement[] = []
|
||||
export let imgs: MobileImage[] = []
|
||||
|
||||
/**
|
||||
* main functions
|
||||
@@ -40,9 +41,14 @@ export function initCollection(ijs: ImageJSON[]): void {
|
||||
}
|
||||
})
|
||||
// get image elements
|
||||
imgs = Array.from(collection.getElementsByTagName('img'))
|
||||
imgs = Array.from(collection.getElementsByTagName('img')) as MobileImage[]
|
||||
// add event listeners
|
||||
imgs.forEach((img, i) => {
|
||||
// preload first 5 images on page load
|
||||
if (i < 5) {
|
||||
img.src = img.dataset.src
|
||||
}
|
||||
// event listeners
|
||||
img.addEventListener(
|
||||
'click',
|
||||
() => {
|
||||
@@ -58,12 +64,18 @@ export function initCollection(ijs: ImageJSON[]): void {
|
||||
{ passive: true }
|
||||
)
|
||||
// preload
|
||||
onVisible(img, () => {
|
||||
for (let _i = 0; _i < 5; _i++) {
|
||||
const n = i + _i
|
||||
if (n < 0 || n > imgs.length - 1) continue
|
||||
imgs[n].src = imgs[n].dataset.src as string
|
||||
}
|
||||
onIntersection(img, (entries, observer) => {
|
||||
entries.every((entry) => {
|
||||
// no intersection, skip
|
||||
if (entry.intersectionRatio <= 0) return true
|
||||
// preload the i + 5th image
|
||||
if (i + 5 < imgs.length) {
|
||||
imgs[i + 5].src = imgs[i + 5].dataset.src
|
||||
}
|
||||
// disconnect observer and return false to break the loop
|
||||
observer.disconnect()
|
||||
return false
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -82,7 +94,7 @@ function createCollection(ijs: ImageJSON[]): void {
|
||||
const x = i !== 0 ? getRandom(-25, 25) : 0
|
||||
const y = i !== 0 ? getRandom(-30, 30) : 0
|
||||
// element
|
||||
const e = document.createElement('img')
|
||||
const e = document.createElement('img') as MobileImage
|
||||
e.dataset.src = ij.loUrl
|
||||
e.height = ij.loImgH
|
||||
e.width = ij.loImgW
|
||||
|
||||
@@ -1,19 +1,14 @@
|
||||
import { type Power3, type gsap } from 'gsap'
|
||||
import { type Swiper } from 'swiper'
|
||||
|
||||
import { container } from '../container'
|
||||
import { container, scrollable } from '../container'
|
||||
import { isAnimating, navigateVector, setIndex, state } from '../globalState'
|
||||
import { expand, loadGsap, removeDuplicates } from '../globalUtils'
|
||||
import { type ImageJSON } from '../resources'
|
||||
import { setIndex, state } from '../state'
|
||||
import {
|
||||
Watchable,
|
||||
capitalizeFirstLetter,
|
||||
expand,
|
||||
loadGsap,
|
||||
loadSwiper
|
||||
} from '../utils'
|
||||
|
||||
import { mounted } from './mounted'
|
||||
import { scrollable } from './scroll'
|
||||
import { mounted } from './state'
|
||||
// eslint-disable-next-line sort-imports
|
||||
import { capitalizeFirstLetter, loadSwiper, type MobileImage } from './utils'
|
||||
|
||||
/**
|
||||
* variables
|
||||
@@ -23,11 +18,10 @@ let swiperNode: HTMLDivElement
|
||||
let gallery: HTMLDivElement
|
||||
let curtain: HTMLDivElement
|
||||
let swiper: Swiper
|
||||
const isAnimating = new Watchable<boolean>(false)
|
||||
let lastIndex = -1
|
||||
let indexDispNums: HTMLSpanElement[] = []
|
||||
let galleryImages: HTMLImageElement[] = []
|
||||
let collectionImages: HTMLImageElement[] = []
|
||||
let galleryImages: MobileImage[] = []
|
||||
let collectionImages: MobileImage[] = []
|
||||
|
||||
let _Swiper: typeof Swiper
|
||||
let _gsap: typeof gsap
|
||||
@@ -44,7 +38,7 @@ export function slideUp(): void {
|
||||
isAnimating.set(true)
|
||||
|
||||
// load active image
|
||||
loadImages()
|
||||
galleryLoadImages()
|
||||
|
||||
_gsap.to(curtain, {
|
||||
opacity: 1,
|
||||
@@ -61,11 +55,12 @@ export function slideUp(): void {
|
||||
setTimeout(() => {
|
||||
scrollable.set(false)
|
||||
isAnimating.set(false)
|
||||
}, 1200)
|
||||
}, 1400)
|
||||
}
|
||||
|
||||
function slideDown(): void {
|
||||
scrollable.set(true)
|
||||
if (isAnimating.get()) return
|
||||
isAnimating.set(true)
|
||||
scrollToActive()
|
||||
|
||||
_gsap.to(gallery, {
|
||||
@@ -79,6 +74,11 @@ function slideDown(): void {
|
||||
duration: 1.2,
|
||||
delay: 0.4
|
||||
})
|
||||
|
||||
setTimeout(() => {
|
||||
scrollable.set(true)
|
||||
isAnimating.set(false)
|
||||
}, 1600)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,18 +95,22 @@ export function initGallery(ijs: ImageJSON[]): void {
|
||||
swiperNode = document.getElementsByClassName('galleryInner').item(0) as HTMLDivElement
|
||||
gallery = document.getElementsByClassName('gallery').item(0) as HTMLDivElement
|
||||
curtain = document.getElementsByClassName('curtain').item(0) as HTMLDivElement
|
||||
galleryImages = Array.from(gallery.getElementsByTagName('img'))
|
||||
galleryImages = Array.from(gallery.getElementsByTagName('img')) as MobileImage[]
|
||||
collectionImages = Array.from(
|
||||
document
|
||||
.getElementsByClassName('collection')
|
||||
.item(0)
|
||||
?.getElementsByTagName('img') ?? []
|
||||
)
|
||||
) as MobileImage[]
|
||||
// state watcher
|
||||
state.addWatcher(() => {
|
||||
const s = state.get()
|
||||
// change slide only when index is changed
|
||||
if (s.index === lastIndex) return
|
||||
else if (lastIndex === -1)
|
||||
navigateVector.set('none') // lastIndex before first set
|
||||
else if (s.index < lastIndex) navigateVector.set('prev')
|
||||
else navigateVector.set('next')
|
||||
changeSlide(s.index)
|
||||
updateIndexText()
|
||||
lastIndex = s.index
|
||||
@@ -152,7 +156,7 @@ export function initGallery(ijs: ImageJSON[]): void {
|
||||
*/
|
||||
|
||||
function changeSlide(slide: number): void {
|
||||
loadImages()
|
||||
galleryLoadImages()
|
||||
swiper.slideTo(slide, 0)
|
||||
}
|
||||
|
||||
@@ -175,6 +179,29 @@ function updateIndexText(): void {
|
||||
})
|
||||
}
|
||||
|
||||
function galleryLoadImages(): void {
|
||||
let activeImagesIndex: number[] = []
|
||||
const currentIndex = state.get().index
|
||||
const nextIndex = Math.min(currentIndex + 1, state.get().length - 1)
|
||||
const prevIndex = Math.max(currentIndex - 1, 0)
|
||||
switch (navigateVector.get()) {
|
||||
case 'next':
|
||||
activeImagesIndex = [nextIndex]
|
||||
break
|
||||
case 'prev':
|
||||
activeImagesIndex = [prevIndex]
|
||||
break
|
||||
case 'none':
|
||||
activeImagesIndex = [currentIndex, nextIndex, prevIndex]
|
||||
break
|
||||
}
|
||||
removeDuplicates(activeImagesIndex).forEach((i) => {
|
||||
const e = galleryImages[i]
|
||||
if (e.src === e.dataset.src) return // already loaded
|
||||
e.src = e.dataset.src
|
||||
})
|
||||
}
|
||||
|
||||
function createGallery(ijs: ImageJSON[]): void {
|
||||
/**
|
||||
* gallery
|
||||
@@ -192,17 +219,18 @@ function createGallery(ijs: ImageJSON[]): void {
|
||||
// swiper wrapper
|
||||
const _swiperWrapper = document.createElement('div')
|
||||
_swiperWrapper.className = 'swiper-wrapper'
|
||||
// swiper slide
|
||||
// loading text
|
||||
const loadingText = container.dataset.loading
|
||||
for (const ij of ijs) {
|
||||
// swiper slide
|
||||
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) + '...'
|
||||
l.innerText = loadingText
|
||||
// img
|
||||
const e = document.createElement('img')
|
||||
const e = document.createElement('img') as MobileImage
|
||||
e.dataset.src = ij.hiUrl
|
||||
e.height = ij.hiImgH
|
||||
e.width = ij.hiImgW
|
||||
@@ -281,16 +309,3 @@ function createGallery(ijs: ImageJSON[]): void {
|
||||
*/
|
||||
container.append(_gallery, _curtain)
|
||||
}
|
||||
|
||||
function loadImages(): void {
|
||||
const activeImages: HTMLImageElement[] = []
|
||||
// load current, next, prev image
|
||||
activeImages.push(galleryImages[swiper.activeIndex])
|
||||
activeImages.push(
|
||||
galleryImages[Math.min(swiper.activeIndex + 1, swiper.slides.length - 1)]
|
||||
)
|
||||
activeImages.push(galleryImages[Math.max(swiper.activeIndex - 1, 0)])
|
||||
for (const e of activeImages) {
|
||||
e.src = e.dataset.src as string
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
import { Watchable } from '../utils'
|
||||
|
||||
export const scrollable = new Watchable<boolean>(true)
|
||||
@@ -1,3 +1,3 @@
|
||||
import { Watchable } from '../utils'
|
||||
import { Watchable } from '../globalUtils'
|
||||
|
||||
export const mounted = new Watchable<boolean>(false)
|
||||
37
assets/ts/mobile/utils.ts
Normal file
37
assets/ts/mobile/utils.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { type Swiper } from 'swiper'
|
||||
|
||||
/**
|
||||
* interfaces
|
||||
*/
|
||||
|
||||
export interface MobileImage extends HTMLImageElement {
|
||||
dataset: {
|
||||
src: string
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* utils
|
||||
*/
|
||||
|
||||
export function getRandom(min: number, max: number): number {
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min
|
||||
}
|
||||
|
||||
export function onIntersection<T extends HTMLElement>(
|
||||
element: T,
|
||||
callback: (arg0: IntersectionObserverEntry[], arg1: IntersectionObserver) => void
|
||||
): void {
|
||||
new IntersectionObserver((entries, observer) => {
|
||||
callback(entries, observer)
|
||||
}).observe(element)
|
||||
}
|
||||
|
||||
export function capitalizeFirstLetter(str: string): string {
|
||||
return str.charAt(0).toUpperCase() + str.slice(1)
|
||||
}
|
||||
|
||||
export async function loadSwiper(): Promise<typeof Swiper> {
|
||||
const s = await import('swiper')
|
||||
return s.Swiper
|
||||
}
|
||||
Reference in New Issue
Block a user