惯性垂直拖动滚动

发布于 2025-01-15 11:36:55 字数 1420 浏览 5 评论 0原文

我通过用鼠标向上/向下拖动来在我的网页上工作来实现垂直滚动。然而,问题是它感觉很突然,因为当你停止拖动时滚动会立即停止。我想添加一些惯性,以便在停止拖动后它会继续滚动一段时间,直到停止。

这实施起来有点复杂,所以我需要一些帮助。这是我当前的所有代码:

let newScrollY = 0
let element = null

const dragScroll = (enabled) => {
        element?.removeEventListener("mousedown", element?.mouseDownFunc, false)
        window.removeEventListener("mouseup", element?.mouseUpFunc, false)
        window.removeEventListener("mousemove", element?.mouseMoveFunc, false)

        element = document.querySelector(".drag")
        if (!element || !enabled) return
        let lastClientY = 0
        let mouseDown = false

        element.addEventListener("mousedown", element.mouseDownFunc = (event) => {
                event.preventDefault()
                mouseDown = true
                lastClientY = event.clientY
        }, false)

        window.addEventListener("mouseup", element.mouseUpFunc = (event) => {
            mouseDown = false
        }, false)

        window.addEventListener("mousemove", element.mouseMoveFunc = (event) => {
            if (!mouseDown) return
            let scrollElement = element
            if (element == document.body) scrollElement = document.documentElement
            newScrollY = event.clientY - lastClientY
            lastClientY = event.clientY
            scrollElement.scrollTop -= newScrollY
        }, false)
}

I have gotten vertical scrolling by dragging up/down with the mouse to work on my webpage. However, the problem is that it feels pretty abrupt because the scrolling stops instantly when you stop dragging. I would like to add some inertia so that it continues to scroll for a bit after you stop dragging until it comes to a stop.

This is somewhat complicated to implement so I would like some help. This is my all of my current code:

let newScrollY = 0
let element = null

const dragScroll = (enabled) => {
        element?.removeEventListener("mousedown", element?.mouseDownFunc, false)
        window.removeEventListener("mouseup", element?.mouseUpFunc, false)
        window.removeEventListener("mousemove", element?.mouseMoveFunc, false)

        element = document.querySelector(".drag")
        if (!element || !enabled) return
        let lastClientY = 0
        let mouseDown = false

        element.addEventListener("mousedown", element.mouseDownFunc = (event) => {
                event.preventDefault()
                mouseDown = true
                lastClientY = event.clientY
        }, false)

        window.addEventListener("mouseup", element.mouseUpFunc = (event) => {
            mouseDown = false
        }, false)

        window.addEventListener("mousemove", element.mouseMoveFunc = (event) => {
            if (!mouseDown) return
            let scrollElement = element
            if (element == document.body) scrollElement = document.documentElement
            newScrollY = event.clientY - lastClientY
            lastClientY = event.clientY
            scrollElement.scrollTop -= newScrollY
        }, false)
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

绮筵 2025-01-22 11:36:56

我已经想出了一个解决办法。关键是使用速度的绝对值,并根据速度的符号(指示它们是向上还是向下滚动)对scrollTop 进行加/减。

let newScrollY = 0
let lastScrollTop = 0
let element = null as any
let inertia = false
let mouseDown = false

const dragScroll = (enabled) => {
        if (inertia || mouseDown) return
        element?.removeEventListener("mousedown", element?.mouseDownFunc, false)
        window.removeEventListener("mouseup", element?.mouseUpFunc, false)
        window.removeEventListener("mousemove", element?.mouseMoveFunc, false)

        element = document.querySelector(".drag")
        if (!element || !enabled) return
        let lastClientY = 0
        mouseDown = false
        let time = null
        let id = 0

        element.addEventListener("mousedown", element.mouseDownFunc = (event) => {
                event.preventDefault()
                mouseDown = true
                inertia = false
                time = new Date()
                lastClientY = event.clientY
                let scrollElement = element
                if (element == document.body) scrollElement = document.documentElement
                lastScrollTop = scrollElement.scrollTop
                cancelAnimationFrame(id)
        }, false)

        window.addEventListener("mouseup", element.mouseUpFunc = (event) => {
            mouseDown = false
            const timeDiff = (new Date() as any - time)
            let scrollElement = element
            if (element == document.body) scrollElement = document.documentElement
            let speedY = (scrollElement.scrollTop - lastScrollTop) / timeDiff * 20
            let speedYAbsolute = Math.abs(speedY)

            const draw = () => {
                let scrollElement = element
                if (element == document.body) scrollElement = document.documentElement
                if (speedYAbsolute > 0) {
                    if (speedY > 0) {
                        scrollElement.scrollTop += speedYAbsolute--
                    } else {
                        scrollElement.scrollTop -= speedYAbsolute--
                    }
                } else {
                    inertia = false
                }
                id = requestAnimationFrame(draw)
            }
            inertia = true
            draw()
        }, false)

        window.addEventListener("mousemove", element.mouseMoveFunc = (event) => {
            if (!mouseDown) return
            let scrollElement = element
            if (element == document.body) scrollElement = document.documentElement
            newScrollY = event.clientY - lastClientY
            lastClientY = event.clientY
            scrollElement.scrollTop -= newScrollY
        }, false)
    }

I have figured out a solution. The key was to use the absolute value of the speed and either add/subtract to the scrollTop depending on the sign of the speed (indicating whether they were scrolling up or down).

let newScrollY = 0
let lastScrollTop = 0
let element = null as any
let inertia = false
let mouseDown = false

const dragScroll = (enabled) => {
        if (inertia || mouseDown) return
        element?.removeEventListener("mousedown", element?.mouseDownFunc, false)
        window.removeEventListener("mouseup", element?.mouseUpFunc, false)
        window.removeEventListener("mousemove", element?.mouseMoveFunc, false)

        element = document.querySelector(".drag")
        if (!element || !enabled) return
        let lastClientY = 0
        mouseDown = false
        let time = null
        let id = 0

        element.addEventListener("mousedown", element.mouseDownFunc = (event) => {
                event.preventDefault()
                mouseDown = true
                inertia = false
                time = new Date()
                lastClientY = event.clientY
                let scrollElement = element
                if (element == document.body) scrollElement = document.documentElement
                lastScrollTop = scrollElement.scrollTop
                cancelAnimationFrame(id)
        }, false)

        window.addEventListener("mouseup", element.mouseUpFunc = (event) => {
            mouseDown = false
            const timeDiff = (new Date() as any - time)
            let scrollElement = element
            if (element == document.body) scrollElement = document.documentElement
            let speedY = (scrollElement.scrollTop - lastScrollTop) / timeDiff * 20
            let speedYAbsolute = Math.abs(speedY)

            const draw = () => {
                let scrollElement = element
                if (element == document.body) scrollElement = document.documentElement
                if (speedYAbsolute > 0) {
                    if (speedY > 0) {
                        scrollElement.scrollTop += speedYAbsolute--
                    } else {
                        scrollElement.scrollTop -= speedYAbsolute--
                    }
                } else {
                    inertia = false
                }
                id = requestAnimationFrame(draw)
            }
            inertia = true
            draw()
        }, false)

        window.addEventListener("mousemove", element.mouseMoveFunc = (event) => {
            if (!mouseDown) return
            let scrollElement = element
            if (element == document.body) scrollElement = document.documentElement
            newScrollY = event.clientY - lastClientY
            lastClientY = event.clientY
            scrollElement.scrollTop -= newScrollY
        }, false)
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文