@furman1331/page-scroller
Version:
Amazing plugin for creating smooth scroll on your website
138 lines (84 loc) • 4.45 kB
text/typescript
import { state } from '../state/state'
import { ClassName, SlideClassName } from '../utils/class.enum'
import { EmitterEvents, emitter } from '../emitter'
import type { TScrollingDirectionVertically, TScrollingDirectionHorizontally } from '@/types'
export function changeSectionOrSlideByDirection(direction: TScrollingDirectionVertically) {
if (isAllowToChangeSlide(direction)) {
changeSlideByDirection(direction === 'down' ? 'right' : 'left')
return
}
changeSectionByDirection(direction)
}
export function changeSlideByDirection(direction: TScrollingDirectionHorizontally) {
if (state.isScrolling) return
state.isScrolling = true
const currentSlideIndex = state.activeSlide
state.activeSlide = direction === 'right' ? currentSlideIndex + 1 : currentSlideIndex - 1
changeSlide(currentSlideIndex, state.activeSlide)
}
export function changeSectionByDirection(direction: TScrollingDirectionVertically) {
if (state.isScrolling) return
state.isScrolling = true
const currentSectionIndex = state.activeSection
if (!isAllowToChangeSection(direction)) return (state.isScrolling = false)
state.activeSection = direction === 'down' ? currentSectionIndex + 1 : currentSectionIndex - 1
changeSection(currentSectionIndex, state.activeSection)
}
export function changeSectionBySpecificIndex(index: number) {
if (state.isScrolling) return
state.isScrolling = true
const currentSectionIndex = state.activeSection
if (!isAllowToChangeByIndex(index)) return (state.isScrolling = false)
state.sections[currentSectionIndex].element.classList.remove(ClassName.activeSection)
state.activeSection = index
changeSection(currentSectionIndex, state.activeSection)
}
export function reAdjustCurrentSection() {
if (state.scrollMode === 'manual') return
const sectionOffset = state.sections[state.activeSection].element.offsetTop
const transform = `translate3d(0px, -${sectionOffset}px, 0px)`
state.container.style.transform = transform
state.container.style.webkitTransform = transform
}
export function changeSection(previousIndex: number, nextIndex: number) {
emitter.emit(EmitterEvents.onBeforeSectionChange, { beforeIndex: previousIndex, afterIndex: nextIndex })
state.sections[previousIndex].element.classList.remove(ClassName.activeSection)
const sectionOffset = state.sections[nextIndex].element.offsetTop
const transform = `translate3d(0px, -${sectionOffset}px, 0px)`
state.container.style.transform = transform
state.container.style.webkitTransform = transform
state.sections[nextIndex].element.classList.add(ClassName.activeSection)
setTimeout(() => {
state.isScrolling = false
emitter.emit(EmitterEvents.onSectionChange, { beforeIndex: previousIndex, afterIndex: nextIndex })
}, 700)
}
export function changeSlide(previousIndex: number, nextIndex: number) {
emitter.emit(EmitterEvents.onBeforeSlideChange, { beforeIndex: previousIndex, afterIndex: nextIndex })
const activeSection = state.sections[state.activeSection]
activeSection.slides.elements[previousIndex]?.classList.remove(SlideClassName.active)
const slideOffset = activeSection.slides.elements[nextIndex].offsetLeft
const transform = `translate3d(-${slideOffset}px, 0px, 0px)`
activeSection.slides.container.style.transform = transform
activeSection.slides.container.style.webkitTransform = transform
state.sections[state.activeSection].slides.elements[nextIndex].classList.add(SlideClassName.active)
setTimeout(() => {
state.isScrolling = false
emitter.emit(EmitterEvents.onSlideChange, { beforeIndex: previousIndex, afterIndex: nextIndex })
}, state.scrollingSpeed)
}
export function isAllowToChangeSection(direction: TScrollingDirectionVertically) {
return direction === 'down' ? state.sections.length != state.activeSection + 1 : state.activeSection - 1 !== -1
}
export function isAllowToChangeSlide(direction: TScrollingDirectionVertically): boolean {
if (!state.isAllowToScrollThroughSlides) return false
const isCurrentSectionHasSlides = state.sections[state.activeSection].slides?.elements.length > 0
if (!isCurrentSectionHasSlides) return false
const slides = state.sections[state.activeSection].slides
const isEdgeSlide = direction === 'down' ? state.activeSlide + 1 === slides.elements.length : state.activeSlide - 1 === -1
if (isEdgeSlide) return false
return true
}
export function isAllowToChangeByIndex(index: number) {
return index >= 0 && index < state.sections.length
}