Uniapp + VUE3.0 实现双向滑块视频裁剪效果

 效果图

<template>
  <view v-if="info" class="all">
    <video
        :src="info.videoUrl"
        class="video" id="video" :controls="true" object-fit="fill" :show-fullscreen-btn="false"
        play-btn-position="center"
        :autoplay="true" @loadedmetadata="loadedMetadata"></video>
    <view class="slider">
      <view class="thumb-left" @touchmove="e=>handleTouchMove(e,0)" @touchend="e=>handleTouchEnd(e,0)"
            :style="` margin-left: ${thumbLeft}px;`">{{ start }}
      </view>
      <view class="slider-bg"></view>
      <view class="thumb-right" @touchmove="e=>handleTouchMove(e,1)" @touchend="e=>handleTouchEnd(e,1)"
            :style="` margin-right: ${thumbRight}px;`">{{ end }}
      </view>
    </view>
  </view>

</template>

<script lang="ts" setup>
const videoInfo = defineProps(["info"])
const emit = defineEmits(['onChange'])
import {ref, computed, onMounted, getCurrentInstance} from "vue";
import {
  onReady,
} from "@dcloudio/uni-app"

const min = ref(0)
const max = ref(0)
const minInterval = ref(15)//最小裁剪间隔
const thumbLeft = ref(0)
const thumbRight = ref(0)
const start = ref(computed(() => {
  return Math.round((thumbLeft.value) * rate.value)
}))
const end = ref(computed(() => {
  return Math.round((totalWidth.value - thumbRight.value) * rate.value)
}))

const rate = ref(computed(() => {
  return max.value / totalWidth.value
}))
const interval = ref(computed(() => {
  return minInterval.value / rate.value
}))


const instance = getCurrentInstance()
const thumbLeftSize = ref({
  width: 0,
  height: 0,
  left: 0,
  right: 0
})
const thumbRightSize = ref({
  width: 0,
  height: 0,
  left: 0,
  right: 0
})
let dxLeft = 0
let dxRight = 0
const totalWidth = ref(0)
const videoTotalDuration = ref(0)
let videoContext: UniApp.VideoContext = null
let windowWidth = 0
let timer: number = null

function loadedMetadata(e) {
  max.value = Math.floor(e.detail.duration)
  emit('onChange', {start: start.value, end: end.value})
}

onReady(() => {
  videoContext = uni.createVideoContext('video', instance);
  windowWidth = uni.getSystemInfoSync().windowWidth
})
onMounted(() => {
  uni.createSelectorQuery().in(instance).select('.thumb-left').boundingClientRect(data => {
    console.log(data)
    thumbLeftSize.value = data
    console.log(thumbLeftSize.value)
  }).exec();
  uni.createSelectorQuery().in(instance).select('.thumb-right').boundingClientRect(data => {
    console.log(data)
    thumbRightSize.value = data
    console.log(thumbRightSize.value)
    totalWidth.value = thumbRightSize.value.right - thumbLeftSize.value.left - 2 * thumbLeftSize.value.width
  }).exec();
});

function handleTouchMove(e, index: Number) {
  let pageX = e.touches[0].pageX
  if (index == 0) {
    //左边边view
    dxLeft = Math.max(pageX - thumbLeftSize.value.left, 0)
    //修正
    if (dxLeft + dxRight + interval.value > totalWidth.value) {
      dxLeft = totalWidth.value - dxRight
    }
    console.log("pageX:" + pageX, "dxRight:" + dxRight, "dxLeft:" + dxLeft, "thumbRight:" + thumbRight.value, "thumbLeft:" + thumbLeft.value, "width:" + thumbLeftSize.value.width, "windowWidth:" + windowWidth, thumbRightSize.value.right, "totalWidth:" + totalWidth.value)
    if (dxLeft <= interval.value) {
      //左边边界
      thumbLeft.value = 0
      return
    }
    if (dxRight + dxLeft + interval.value > totalWidth.value) {
      thumbLeft.value = windowWidth - thumbRight.value - 2 * thumbLeftSize.value.width - 2 * thumbLeftSize.value.left - interval.value
    } else {
      thumbLeft.value = dxLeft - interval.value
    }
  } else {
    //右边view
    dxRight = Math.max(windowWidth - pageX - thumbRightSize.value.width, 0)
    //修正
    if (dxRight + dxLeft + interval.value > totalWidth.value) {
      dxRight = totalWidth.value - dxLeft
    }
    console.log("pageX:" + pageX, "dxRight:" + dxRight, "dxLeft:" + dxLeft, "thumbRight:" + thumbRight.value, "thumbLeft:" + thumbLeft.value, "width:" + thumbLeftSize.value.width, "windowWidth:" + windowWidth, thumbRightSize.value.right, "totalWidth:" + totalWidth.value)
    if (dxRight <= interval.value) {
      //右边边界
      thumbRight.value = 0
      return
    }
    if (dxRight + dxLeft + interval.value > totalWidth.value) {
      //左边边界修正
      thumbRight.value = windowWidth - thumbLeft.value - 2 * thumbLeftSize.value.width - 2 * thumbLeftSize.value.left - interval.value
    } else {
      thumbRight.value = dxRight - interval.value
    }
  }

}

function handleTouchEnd(e, index: Number) {
  emit('onChange', {start: start.value, end: end.value})
  videoContext.seek(index == 0 ? start.value : end.value);
  videoContext.play();
}
</script>

<style lang="scss" scoped>
.all {
  margin-left: 25rpx;
  margin-right: 25rpx;

  .video {
    height: 400rpx;
    width: 100%;
  }

  .slider {
    display: flex;
    color: white;
    flex-direction: row;
    height: 100rpx;

    .thumb-left {
      width: 50rpx;
      height: 100%;
      color: black;
      display: flex;
      font-size: 12rpx;
      align-items: center;
      justify-content: center;
      background-color: #8EFB7C;
      border-top-left-radius: 20rpx;
      border-bottom-left-radius: 20rpx;
    }

    .slider-bg {
      display: flex;
      flex: 1;
      background-color: #F1FFF0
    }

    .thumb-right {
      width: 50rpx;
      height: 100%;
      color: black;
      display: flex;
      font-size: 12rpx;
      align-items: center;
      justify-content: center;
      background-color: #8EFB7C;
      border-top-right-radius: 20rpx;
      border-bottom-right-radius: 20rpx;
    }
  }
}


</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/410628.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

linux服务器vi文件中文乱码

服务器vi编辑中文乱码 cat 文本是中文 可以编辑 vi /etc/environment 文件修改为utf8中文字符集 LANGzh_CN.UTF-8 LANGUAGEen_US:en LC_CTYPE"zh_CN.UTF-8" LC_NUMERIC"zh_CN.UTF-8" LC_TIME"zh_CN.UTF-8" LC_COLLATE"zh_CN.UTF-8"…

springboot219基于SpringBoot的网络海鲜市场系统的设计与实现

网络海鲜市场系统的设计与实现 摘 要 计算机网络发展到现在已经好几十年了&#xff0c;在理论上面已经有了很丰富的基础&#xff0c;并且在现实生活中也到处都在使用&#xff0c;可以说&#xff0c;经过几十年的发展&#xff0c;互联网技术已经把地域信息的隔阂给消除了&…

Python实现DAS单点登录

❇️ 流程 进入登录页面 &#xff08;DAS验证的登录页面&#xff09; 获取验证码图像&#xff0c;百度OCR识别 登录 &#x1f3de;️ 环境 Windows 11 Python 3.12 PyCharm 2023 &#x1f9f5; 准备工作 安装必要依赖库 bs4 Jupyter 推荐安装 Jupyter&#xff08;Anaco…

*ctf 2019 oob

diff文件如下 diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index b027d36..ef1002f 100644 --- a/src/bootstrapper.ccb/src/bootstrapper.cc-1668,6 1668,8 void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,Builtins::kArrayProto…

【重温设计模式】原型模式及其Java示例

【重温设计模式】原型模式及其Java示例 原型模式的介绍 在编程的世界里&#xff0c;有一种神秘而强大的法宝&#xff0c;它就是设计模式。设计模式&#xff0c;就像是一种编程的哲学&#xff0c;是对软件工程中的一些经典问题的通用解决方案。它能够帮助我们更好地组织代码&am…

又现股东大额减持,东鹏饮料业绩预喜也难“救市”?

“醒着拼”的东鹏饮料(605499.SH)&#xff0c;市值“累了困了”&#xff1f; 1月27日&#xff0c;东鹏饮料公布了2023年的业绩预告显示&#xff1a;预计将达到110.57亿元-113.12亿元&#xff0c;同比增长30%-33%&#xff1b;净利润预计在19.89亿元-20.61亿元之间&#xff0c;同…

汇编语言与接口技术实践——秒表

1. 设计要求 基于 51 开发板,利用键盘作为按键输入,将数码管作为显示输出,实现电子秒表。 功能要求: (1)计时精度达到百分之一秒; (2)能按键记录下5次时间并通过按键回看 (3)设置时间,实现倒计时,时间到,数码管闪烁 10 次,并激发蜂鸣器,可通过按键解除。 2. 设计思…

数学建模【GM(1, 1)灰色预测】

一、GM(1, 1)灰色预测简介 乍一看&#xff0c;这个名字好奇怪&#xff0c;其实是有含义的 G&#xff1a;Grey&#xff08;灰色&#xff09;M&#xff1a;Model&#xff08;模型&#xff09;(1, 1)&#xff1a;只含有一个变量的一阶微分方程模型 提到灰色&#xff0c;就得先说…

基于InSAR、CNN的滑坡监测(一)

文献阅读记录&#xff0c;也是组会汇报材料收集&#xff0c;从中文文献开始学习。 开发一种快速、精确且自动化程度较高的滑坡定位或检测模型可以为地质灾害防治提供有效支撑,为研究滑坡分布规律及滑坡潜在风险等问题提供技术支持 ①《基于高分辨率遥感影像和改进 U-Net 模型的…

【Spring Cloud】高并发带来的问题及常见容错方案

文章目录 高并发带来的问题编写代码修改配置压力测试修改配置&#xff0c;并启动软件添加线程组配置线程并发数添加Http取样配置取样&#xff0c;并启动测试访问message方法观察效果 服务雪崩效应常见容错方案常见的容错思路常见的容错组件 总结 欢迎来到阿Q社区 https://bbs.c…

YOLOv5改进 | SPPF篇 | 利用YOLOv9最新的SPPELAN模块改进SPPF(全网独家创新,附手撕结构图)

一、本文介绍 本文给大家带来的改进机制是利用2024/02/21号最新发布的YOLOv9其中提出的SPPELAN模块来改进SPPF,其中YOLOv9针对于这个模块并没有介绍,只是在其项目文件中用到了,我将其整理出来用于我们的YOLOv5的项目,同时空间金字塔池化作为我们YOLOv5中的一个比较独特的存…

算法学习(十三)多路归并

多路归并 1. 概念 一、多路归并算法的由来 假定现在有一包含大量整数的文本文件存放于磁盘中&#xff0c;其文件大小为10GB&#xff0c;而本机内存只有4GB。此时若我们要对该文件中的所有整数进行升序排序&#xff0c;肯定不能直接将文件中的所有数据一次性读入内存中&#x…

《Docker 简易速速上手小册》第7章 高级容器管理(2024 最新版)

文章目录 7.1 容器监控与日志7.1.1 重点基础知识7.1.2 重点案例&#xff1a;监控 Flask 应用7.1.3 拓展案例 1&#xff1a;使用 ELK Stack 收集和分析日志7.1.4 拓展案例 2&#xff1a;使用集成监控工具 7.2 性能调优与资源限制7.2.1 重点基础知识7.2.2 重点案例&#xff1a;Fl…

边缘计算网关与边缘计算的融合之道-天拓四方

随着物联网、大数据和人工智能的飞速发展&#xff0c;数据处理和分析的需求呈现出爆炸式增长。传统的中心化数据处理模式已难以满足实时性、低延迟和高带宽的需求&#xff0c;边缘计算应运而生&#xff0c;成为解决这一难题的关键技术。而边缘计算网关&#xff0c;作为连接边缘…

护眼台灯哪个品牌质量比较好?五大优质护眼台灯推荐!

护眼台灯作为近年来最受欢迎的灯具之一&#xff0c;它不仅可以提供充足明亮的光照&#xff0c;光线环境&#xff0c;从而减少眼睛的负担和疲劳&#xff0c;还能够实现预防近视的效果&#xff0c;所以很多家长都会给孩子准备护眼台灯。但也有不少朋友觉得护眼台灯是名副其实的智…

爆火的Sora,动了谁的奶酪?

北京时间2月16日凌晨&#xff0c;当我们还沉浸在春节假期的喜庆和欢乐中时&#xff0c;Open AI 官宣推出首个文生视频模型 Sora。一年多前&#xff0c;Chat GPT 的横空出世&#xff0c;引起了全球广泛关注。如今 Sora 的出现&#xff0c;再次掀起千层浪。 只需要一段文本描述&a…

校招失败后,在小公司熬了 2 年终于进了字节跳动,竭尽全力....

其实两年前校招的时候就往字节投了一次简历&#xff0c;结果很明显凉了&#xff0c;随后这个理想就被暂时放下了&#xff0c;但是这个种子一直埋在心里这两年除了工作以外&#xff0c;也会坚持写博客&#xff0c;也因此结识了很多优秀的小伙伴&#xff0c;从他们身上学到了特别…

SMTP和IMAP是什么?SMTP的定义及工作模式?

SMTP是什么邮件的协议&#xff1f;如何开启网站邮箱SMTP服务&#xff1f; 随着互联网的普及和电子邮件的广泛使用&#xff0c;SMTP和IMAP这两个名词逐渐进入了我们的视野。它们是什么&#xff1f;它们在我们的日常生活中扮演着怎样的角色呢&#xff1f;下面&#xff0c;蜂邮ED…

C语言--贪吃蛇

目录 1. 实现目标2. 需掌握的技术3. Win32 API介绍控制台程序控制台屏幕上的坐标COORDGetStdHandleGetConsoleCursorinfoCONSOLE_CURSOR_INFOSetConsoleCursorInfoSetConsoleCursorPositionGetAsyncKeyState 4. 贪吃蛇游戏设计与分析地图<locale.h>本地化类项setlocale函…

uniapp微信小程序解决上方刘海屏遮挡

问题 在有刘海屏的手机上&#xff0c;我们的文字和按钮等可能会被遮挡 应该避免这种情况 解决 const SYSTEM_INFO uni.getSystemInfoSync();export const getStatusBarHeight ()> SYSTEM_INFO.statusBarHeight || 15;export const getTitleBarHeight ()>{if(uni.get…