Skip to content

Commit

Permalink
fix: use ScrollTo method to replace back-top animation
Browse files Browse the repository at this point in the history
  • Loading branch information
BeADre committed May 21, 2021
1 parent 3e96046 commit 88b6577
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 27 deletions.
36 changes: 13 additions & 23 deletions packages/varlet-ui/src/back-top/BackTop.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import Button from '../button'
import Icon from '../icon'
import { props } from './props'
import { isString, easeInOutCubic, throttle, toNumber } from '../utils/shared'
import { getScrollTop, getScrollLeft, requestAnimationFrame } from '../utils/elements'
import { getScrollTop, getScrollLeft, scrollTo } from '../utils/elements'
export default defineComponent({
name: 'VarBackTop',
Expand All @@ -23,47 +23,37 @@ export default defineComponent({
},
props,
setup(props) {
let element: Element | Window = window
let element: HTMLElement | Window = window
const show: Ref<boolean> = ref(false)
const click = () => {
props.onClick?.()
const top = getScrollTop(element as Element)
const left = getScrollLeft(element as Element)
const left = getScrollLeft(element as HTMLElement)
const startTime = Date.now()
const frameFunc = () => {
const progress = (Date.now() - startTime) / props.duration
if (progress < 1) {
const nextTop = top * (1 - easeInOutCubic(progress))
;(element as Element).scrollTo(left, nextTop)
requestAnimationFrame(frameFunc)
} else {
;(element as Element).scrollTo(left, 0)
}
}
requestAnimationFrame(frameFunc)
scrollTo(element, {
left,
duration: props.duration,
animation: easeInOutCubic
})
}
const scroll = () => {
show.value = getScrollTop(element as Element) >= toNumber(props.visibilityHeight)
show.value = getScrollTop(element as HTMLElement) >= toNumber(props.visibilityHeight)
}
const throttleScroll = throttle(scroll, 200)
const getElement = () => {
const getHTMLElement = () => {
if (!isString(props.target)) throw Error('[Varlet] BackTop: type of prop "target" should be a string')
const el = document.querySelector(props.target)
if (!el) throw Error('[Varlet] BackTop: "target" should be a selector')
return el
return el as HTMLElement
}
onMounted(() => {
if (props.target) element = getElement()
if (props.target) element = getHTMLElement()
element.addEventListener('scroll', throttleScroll)
})
Expand Down
2 changes: 1 addition & 1 deletion packages/varlet-ui/src/tabs/Tabs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import {
import { props } from './props'
import { TabsProvider, useTabList } from './provide'
import { TabProvider } from '../tab/provide'
import { easeInOutCubic, isNumber, linear } from '../utils/shared'
import { isNumber, linear } from '../utils/shared'
import { toSizeUnit, scrollTo } from '../utils/elements'
export default defineComponent({
Expand Down
8 changes: 5 additions & 3 deletions packages/varlet-ui/src/utils/elements.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { easeInOutCubic, isNumber, isString, toNumber } from './shared'
import { isNumber, isString, toNumber } from './shared'

export function getTop(element: HTMLElement): number {
const { top } = element.getBoundingClientRect()
Expand Down Expand Up @@ -136,9 +136,11 @@ interface ScrollToOptions {
animation: (progress: number) => number
}

export function scrollTo(element: HTMLElement, { top = 0, left = 0, duration = 300, animation }: ScrollToOptions) {
export function scrollTo(element: HTMLElement | Window, { top = 0, left = 0, duration = 300, animation }: ScrollToOptions) {
const startTime = Date.now()
const { scrollTop, scrollLeft } = element

const scrollTop = getScrollTop(element)
const scrollLeft = getScrollLeft(element)

const frame = () => {
const progress = (Date.now() - startTime) / duration
Expand Down

0 comments on commit 88b6577

Please sign in to comment.