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

news2024/11/25 11:30:30

 效果图

<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>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

极电电子WMS项目顺利验收,盘古信息助推新能源车企数字化转型

近年来&#xff0c;中国新能源汽车产销持续保持着较高增速&#xff0c;产销总量连续9年位居全球第一。 在产销高涨的背后&#xff0c;新能源汽车行业“内卷”现象也日益加剧&#xff0c;“配置战”、“价格战”等愈发激烈&#xff0c;驱动车企提高自身竞争力&#xff0c;以抢占…

基于AdaBoost算法的情感分析研究-微博情感分析-文本分类

基于AdaBoost算法的情感分析研究 摘 要 随着互联网的快速发展&#xff0c;各类社交媒体平台如微信、QQ等也与日俱增&#xff0c;而微博更是集成了传统网站、论坛、博客等的优点&#xff0c;并加上了人与人之间的互动性、关系亲密程度等多种智能算法&#xff0c;并以简练的形式…

华清远见嵌入式学习——驱动开发——day9

目录 作业要求&#xff1a; 作业答案&#xff1a; 代码效果&#xff1a; ​编辑 Platform总线驱动代码&#xff1a; 应用程序代码&#xff1a; 设备树配置&#xff1a; 作业要求&#xff1a; 通过platform总线驱动框架编写LED灯的驱动&#xff0c;编写应用程序测试&…

Docker容器故障排查与解决方案

Docker是一种相对使用较简单的容器&#xff0c;我们可以通过以下几种方式获取信息&#xff1a; 1、通过docker run执行命令&#xff0c;或许返回信息 2、通过docker logs 去获取日志&#xff0c;做有针对性的筛选 3、通过systemctl status docker查看docker服务状态 4、通过…

React学习——快速上手

文章目录 初步模块思维 初步 https://php.cn/faq/400956.html 1、可以手动使用npm来安装各种插件&#xff0c;来从头到尾自己搭建环境。 如&#xff1a; npm install react react-dom --save npm install babel babel-loader babel-core babel-preset-es2015 babel-preset-rea…

一休哥助手网页版如何使用

一休哥助手网页版可以使用GPT4提问了&#xff0c;具体操作流程如下&#xff1a; 1.登录网页版一休哥助手&#xff08;首次打开页面时&#xff0c;初始化久一点&#xff0c;请耐心等一下&#xff09; https://www.fudai.fun 2.登录后就可以使用GPT4了 3.你还可以自定义系统角色…

备战蓝桥杯---基础算法刷题1

最近在忙学校官网上的题&#xff0c;就借此记录分享一下有价值的题&#xff1a; 1.注意枚举角度 如果我们就对于不同的k常规的枚举&#xff0c;复杂度直接炸了。 于是我们考虑换一个角度&#xff0c;我们不妨从1开始枚举因子&#xff0c;我们记录下他的倍数的个数sum个&#…

c++笔记理解

1.封装 &#xff08;1&#xff09;构造函数不是必须在的 可以通过行为修改属性 &#xff08;2&#xff09;private和protected区别在于继承那里要学 &#xff08;3&#xff09;类默认是私有&#xff0c;struct是共有 私有的好处&#xff1a;控制数据的有效性&#xff0c;意…

如何快速提升Lazada和Shopee店铺订单量:自养号测评补单策略详解

Lazada和Shopee&#xff0c;作为东南亚地区领先的电商平台&#xff0c;汇聚了无数卖家和消费者。然而&#xff0c;随着市场竞争的日益激烈&#xff0c;如何有效地推广自己的店铺&#xff0c;成为卖家们亟待解决的问题。本文将深入探讨店铺推广的策略&#xff0c;并分享如何迅速…

百度百科词条在网络推广中的六大作用

也许很多网友都发现了&#xff0c;在网上查资料&#xff0c;百科词条往往是优先展示的。一方面因为百科是搜索引擎自身的平台&#xff0c;另一方面就是因为百科信息权威&#xff0c;网友认可度高。所以企业开展网络营销&#xff0c;百科营销是一块重要阵地。 也有的企业认为百科…

Feign远程调用(学习笔记)

先来看我们以前利用RestTemplate发起远程调用的代码&#xff1a; 存在下面的问题&#xff1a; ●代码可读性差&#xff0c;编程体验不统一 ●参数复杂URL难以维护 Feign是一个声明式的http客户端&#xff0c;官方地址&#xff1a;https://github.com/OpenFeign/feign 其作用…

代理IP为什么会有延迟?

在当今信息高速发展的时代&#xff0c;随着代理IP在数据采集、网络安全和匿名浏览等领域的应用&#xff0c;已成为网络技术中不可或缺的一环。然而&#xff0c;用户在使用代理IP时经常会遇到一个问题——延迟。 那我们要如何解决这个问题呢&#xff1f; 这需要从代理IP的原理说…

【MATLAB源码-第143期】基于matlab的蝴蝶优化算法(BOA)机器人栅格路径规划,输出做短路径图和适应度曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 蝴蝶优化算法&#xff08;Butterfly Optimization Algorithm, BOA&#xff09;是基于蝴蝶觅食行为的一种新颖的群体智能算法。它通过模拟蝴蝶个体在寻找食物过程中的嗅觉导向行为以及随机飞行行为&#xff0c;来探索解空间&a…

R语言数据分析(五)

R语言数据分析&#xff08;五&#xff09; 文章目录 R语言数据分析&#xff08;五&#xff09;前言一、什么是整洁的数据二、延长数据2.1 列名中的数据值2.2 pivot_longer()的处理原理2.3 列名中包含许多变量的情况2.4 列名同时包含数据和变量 三、扩宽数据3.1 pivot_wider的处…

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

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

k8s(2)

目录 一.二进制部署k8s 常见的K8S安装部署方式&#xff1a; k8s部署 二进制与高可用的区别 二.部署k8s 初始化操作&#xff1a; 每台node安装docker&#xff1a; 在 master01 节点上操作; 准备cfssl证书生成工具:&#xff1a; 执行脚本文件&#xff1a; 拉入etcd压缩包…

Spring Boot应用集成Actuator端点自定义Filter解决未授权访问的漏洞

一、前言 我们知道想要实时监控我们的应用程序的运行状态&#xff0c;比如实时显示一些指标数据&#xff0c;观察每时每刻访问的流量&#xff0c;或者是我们数据库的访问状态等等&#xff0c;需要使用到Actuator组件&#xff0c;但是Actuator有一个访问未授权问题&#xff0c;…

2023全新UI千月影视APP源码 | 前后端完美匹配、后端基于ThinkPHP框架

应用介绍 本文来自&#xff1a;2023全新UI千月影视APP源码 | 前后端完美匹配、后端基于ThinkPHP框架 - 源码1688 简介&#xff1a; 2023全新UI千月影视APP源码 | 前后端完美匹配、后端基于thinkphp框架 图片&#xff1a;

索引大战:探秘InnoDB数据库中B树和Hash索引的优劣

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 索引大战&#xff1a;探秘InnoDB数据库中B树和Hash索引的优劣 前言B树索引的深度解析Hash索引的奥秘揭晓性能对比分析 前言 在当今软件开发的世界中&#xff0c;数据库扮演着至关重要的角色。而InnoD…

怎么用sora赚第一桶金?

&#x1f31f;解锁文字变视频的强大功能&#xff01;&#x1f31f; ✨欢迎来到 Sora Cand&#xff0c;一个革命性的网站&#xff0c;利用 OpenAI 的 Sora 模型帮你把文字变成酷炫的视频&#xff01;✨ 想象一下&#xff0c;你的文字从纸上跳出来&#xff0c;变成引人入胜的视觉…