实现Web 播放器上触摸滑动, 鼠标拖拽改变播放seek的即时反馈

背景

最近项目要求在播放器上实现触摸滑动或者鼠标按下滑动松开时改变播放seek, 要显示播放时间点的变化.

事件

查了一下相关事件,

触摸主要是touchstart, touchemove, touchend.

鼠标按下滑动松开是mousedown, mousemove, mouseleave, mouseup.

实现效果

开始时出现半透明黑色浮层, 中间显示时间的数字变化, 包括固定不变的片长和随着滑动变化的播放时间点, 当滑动动作完成时, 浮层在1秒内渐渐消失.

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
    <style>
        #flashbox {
            position: absolute;
            left: 0px;
            top: 0px;
            width: 100vw;
            height: 100vh;
            background-color: black;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        @keyframes fadeOut0 {
            0% { opacity: 1; }
            50% { opacity: 1; }
            100% { opacity: 0; }
        }
        @keyframes fadeOut1 {
            0% { opacity: 1; }
            50% { opacity: 1; }
            100% { opacity: 0; }
        }
        .tipsBox {
            position: absolute;
            left: 0px; top: 0px;
            width: 100%; height: 100%;
            background-color: #0000007F;
            display: flex;
            justify-content: center;
            align-items: center;
            opacity: 0;
        }
        .animateFadeOut0 {
            animation: fadeOut0 2s;
	        animation-fill-mode: forwards;
        }
        .animateFadeOut1 {
            animation: fadeOut1 2s;
	        animation-fill-mode: forwards;
        }
        .playTimeLeft {
            color: #0CCC4C;
            font-size: 20px;
            padding-right: 10px;
        }
        .playTimeSplit {
            color: #ffffff;
            font-size: 20px;
            padding-right: 10px;
        }
        .playTimeRight {
            color: #ffffff;
            font-size: 20px;
        }
    </style>
    <script>
        window.onload = function () {
            let obj = document.getElementById('flashbox');
            var downX = 0, downY = 0;
            var minOffset = 5;
            obj.onmousedown = function(event){
                if (event) {
                    downX = parseInt(event.offsetX);
                    downY = parseInt(event.offsetY);
                    console.log(`onmousedown, ox: ${downX}, oy: ${downY}`);
                    obj.onmousemove = onMouseMove;
                    obj.onmouseup = onMouseUp;
                    obj.onmouseleave = onMouseUp;
                }
            }
            obj.addEventListener("touchstart", (event)=>{
                if (event) {
                    try {
                        downX = parseInt(event.touches[0].clientX);
                        downY = parseInt(event.touches[0].clientY);                    
                    } catch (error) { }
                    console.log(`ontouchstart, ox: ${downX}, oy: ${downY}`);
                }
            }, false);
            obj.addEventListener("touchmove", onTouchMove, false);
            function onTouchMove(event) {
                if (event) {
                    var moveX = 0, moveY = 0;
                    try {
                        moveX = parseInt(event.touches[0].clientX);
                        moveY = parseInt(event.touches[0].clientY);                    
                    } catch (error) { }
                    console.log(`ontouchmove, ox: ${moveX}, oy: ${moveY}`);
                    if (isValidNum(moveX) && isValidNum(moveY) && 
                        isValidNum(downX) && isValidNum(downY)) {
                        parseTouchEvent(moveX - downX, moveY - downY);
                    }
                    downX = moveX;
                    downY = moveY;
                }
            }
            obj.addEventListener("touchend", onTouchEnd, false);
            function onTouchEnd(event) {
                if (event) {
                    var upX = 0, upY = 0;
                    try {
                        upX = parseInt(event.touches[0].clientX);
                        upY = parseInt(event.touches[0].clientY);                    
                    } catch (error) { }
                    console.log(`ontouchend, ox: ${upX}, oy: ${upY}`);
                    if (isValidNum(upX) && isValidNum(upY) && 
                        isValidNum(downX) && isValidNum(downY)) {
                        parseTouchEvent(upX - downX, upY - downY);
                    }
                    downX = 0;
                    downY = 0;
                }
            }
            function isValidNum(num) {
                return typeof num === "number" && !isNaN(num);
            }
            function onMouseMove(event) {
                if (event) {
                    var moveX = parseInt(event.offsetX);
                    var moveY = parseInt(event.offsetY);
                    if (isValidNum(moveX) && isValidNum(moveY) && 
                        isValidNum(downX) && isValidNum(downY)) {
                        parseTouchEvent(moveX - downX, moveY - downY);
                    }
                    downX = moveX;
                    downY = moveY;
                    console.log(`onmousemove, ox: ${moveX}, oy: ${moveY}`);
                }
            }
            function onMouseUp(event) {
                if (event) {
                    var upX = parseInt(event.offsetX);
                    var upY = parseInt(event.offsetY);
                    if (isValidNum(upX) && isValidNum(upY) && 
                        isValidNum(downX) && isValidNum(downY)) {
                        parseTouchEvent(upX - downX, upY - downY);
                    }
                    console.log(`onmouseup, ox: ${upX}, oy: ${upY}`);
                    document.onmouseup = null;
                    obj.onmousemove = null;
                    downX = 0;
                    downY = 0;
                }
            }
            function parseTouchEvent(offsetX, offsetY) {
                if (Math.abs(offsetX) > Math.abs(offsetY)) {
                    if (offsetX >= 0) {
                        onTouchEvent("move-right", offsetX);
                    } else {
                        onTouchEvent("move-left", -offsetX);
                    }
                } else {
                    if (offsetY >= 0) {
                        onTouchEvent("move-down", offsetY);
                    } else {
                        onTouchEvent("move-up", -offsetY);
                    }
                }
            }
            var curPlayPos = 0;
            var videoDuration = 600;
            function onTouchEvent(touchName, touchOffset) {
                if (touchOffset > minOffset) {
                    console.log(`${touchName} ${touchOffset}`);
                    if (touchName === "move-right") {
                        let prePos = curPlayPos;
                        curPlayPos += touchOffset;
                        if (curPlayPos > videoDuration) {
                            curPlayPos = videoDuration;
                        }
                        showTips(prePos, curPlayPos);
                    } else if (touchName === "move-left") {
                        let prePos = curPlayPos;
                        curPlayPos -= touchOffset;
                        if (curPlayPos < 0) {
                            curPlayPos = 0;
                        }
                        showTips(prePos, curPlayPos);
                    }
                }
            }
            var task = null;
            let animateIndex = 0;
            var inter = null;
            function updateTextByInterval(dom, curPos, dstPos) {
                if (curPos === dstPos) return;
                task = {
                    curPos, dstPos, 
                    asend: dstPos > curPos
                };
                clearInterval(inter);
                inter = setInterval(()=>{
                    if (task) {
                        if (task.asend) {
                            task.curPos+=5;
                            if (task.curPos > task.dstPos) task.curPos = task.dstPos;
                        } else {
                            task.curPos-=5;
                            if (task.curPos < task.dstPos) task.curPos = task.dstPos;
                        }
                        dom.innerText = toTimeSpan(task.curPos);
                        if (task.curPos === task.dstPos) {
                            clearInterval(inter);
                            inter = null;
                            task = null;
                        }
                    } else {
                        clearInterval(inter);
                        inter = null;
                        task = null;
                    }
                });
            }
            function showAnimation(tipsBox) {
                animateIndex = (animateIndex + 1) % 2;
                tipsBox.setAttribute("class", `tipsBox animateFadeOut${animateIndex}`);
            }
            function showTips(curPos, dstPos) {
                let tipsBox = document.querySelector('.tipsBox');
                if (!tipsBox) return;
                showAnimation(tipsBox);

                let spanLeft = document.querySelector('.playTimeLeft');
                spanLeft.innerText = toTimeSpan(curPos);
                updateTextByInterval(spanLeft, curPos, dstPos);

                let spanRight = document.querySelector('.playTimeRight');
                spanRight.innerText = toTimeSpan(videoDuration);
            }
            function toTimeSpan(seconds) {
                var value = Math.round(seconds);
                var s = value % 60;
                value = Math.floor(value / 60);
                var m = value % 60;
                value = Math.floor(value / 60);
                var h = value;

                var strHour = h.toString().padStart(2, '0');
                var strMinute = m.toString().padStart(2, '0');
                var strSecond = s.toString().padStart(2, '0');
                return `${strHour}:${strMinute}:${strSecond}`;
            }
        }
    </script>
</head>
<body >
    <div id="flashbox" ondragstart="return false;" onselectstart="return false">
        <div class="tipsBox" >
            <span class="playTimeLeft"></span>
            <span class="playTimeSplit">/</span>
            <span class="playTimeRight"></span>
        </div>
    </div>
</body>
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值