拖动播放条

拖动播放条

hook.ts

import { clamp, round } from "lodash-es"; import { getScaleMultiplesNumber } from "@/components/Adapter/utils"; export interface callBackResponse { type: 'moving' | 'moveEnd', percent: number } export function useProgress<T extends ReturnType<typeof defineEmits>>(emits: T) { const container = ref<HTMLDivElement | null>(); const thumb = ref<HTMLDivElement | null>(); const defaultInitLeft = ref(6); const curLeftValue = ref(defaultInitLeft.value) // 点击后添加事件 const mousedown = () => { window.addEventListener("mousemove", handleChange); window.addEventListener("mouseup", mouseup); }; // 移动滑块 const handleChange = (e: MouseEvent) => { const containerDom: NonNullable<typeof container.value> = container.value!; const thumbDom: NonNullable<typeof thumb.value> = thumb.value!; if (!thumbDom) return; const defaultLeft = defaultInitLeft.value; const containerWidth = containerDom.offsetWidth; const thumbWidth = thumbDom.offsetWidth; const RANG_LEFT_VALUE = [defaultLeft, containerWidth - defaultLeft - thumbWidth]; function moveAt(pageX: number) { let leftValue = pageX - containerDom.getBoundingClientRect().left; // * 适配不同分辨率情况下解决拖动时的偏移 // * 缩放情况下鼠标的获取坐标会发生偏移现象(导致鼠标实际移动的距离 = dom元素移动的距离 / 缩放倍数), // * 所以这里需要对其的x坐标进行转化到偏移前。 const { restore } = getScaleMultiplesNumber(); leftValue = leftValue * restore.x; leftValue = clamp(leftValue, RANG_LEFT_VALUE[0], RANG_LEFT_VALUE[1]); curLeftValue.value = leftValue containerDom.style.setProperty("--cur-init-left", `${curLeftValue.value}px`); emits('move', { type: 'moving', percent: getPercent() }) } moveAt(e.pageX); }; // 鼠标放开后移除事件 const mouseup = () => { window.removeEventListener("mousemove", handleChange); window.removeEventListener("mouseup", mouseup); emits('move', { type: 'moveEnd', percent: getPercent() }) }; const resetValue = () => { const containerDom: NonNullable<typeof container.value> = container.value!; curLeftValue.value = defaultInitLeft.value; containerDom.style.setProperty("--cur-init-left", `${curLeftValue.value}px`); } const getPercent = () => { const containerDom: NonNullable<typeof container.value> = container.value!; const thumbDom: NonNullable<typeof thumb.value> = thumb.value!; const defaultLeft = defaultInitLeft.value; const containerWidth = containerDom.offsetWidth; const thumbWidth = thumbDom.offsetWidth; const RANG_LEFT_VALUE = [defaultLeft, containerWidth - defaultLeft - thumbWidth]; const result = (curLeftValue.value - RANG_LEFT_VALUE[0]) / (RANG_LEFT_VALUE[1] - RANG_LEFT_VALUE[0]) const percent = round(result * 100, 0) return percent } onMounted(() => { resetValue() }); return { mousedown, container, thumb, resetValue, getPercent } }

vue

<template> <div relative ref="container"> <div class="progress"></div> <div ref="thumb" class="progress-control--trangle progress-control--position" @mousedown="mousedown" ></div> </div> </template> <script setup lang="ts"> import { useProgress } from "./hook"; import type { callBackResponse } from "./hook"; const emits = defineEmits<{ (eventName: "move", callback: callBackResponse): void; }>(); const { mousedown, container, thumb, resetValue, getPercent } = useProgress<typeof emits>( emits ); defineExpose({ resetValue, getPercent, }); </script> <style lang="scss" scoped> $--cur-init-left: var(--cur-init-left); .progress { width: 100%; height: 0; border: 1px solid rgba(63, 155, 190, 1); &-control { &--trangle { width: 0; height: 0; border: 6px solid transparent; border-left-color: rgba(16, 195, 220, 1); transform: translateY(-50%); cursor: pointer; } &--position { position: absolute; top: 0; bottom: 0; left: $--cur-init-left; } } } </style>

__EOF__

本文作者damarkday知识库
本文链接https://www.cnblogs.com/GoodMemoryBlog/articles/18222408.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   DAmarkday  阅读(5)  评论(0编辑  收藏  举报
编辑推荐:
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示