记录react 视频和 预览拖动

news2024/12/28 9:11:10

一、react 视频

##1、循环播放

import React, { useEffect, useState, useRef } from "react";
const videoRef= useRef(null);
const showVideoClass = { display: "block", width: "100%", height: "100%" }
const hindVideoClass = { display: "none", width: "100%", height: "100%" }

//布局中使用: 主要是 loop 
<video
       style={showVideoClass}
       src={require("../../../static/video/0.mp4")}
       muted
       loop
       autoPlay
       ref={videoRef}
 />

##2、两个视频交替播放

import React, { useEffect, useState, useRef } from "react";

const oneVideo = "/static/video/1.mp4";
const twoVideo ="/static/video/2.mp4";

function VideoPlay() {
    const [vidIndex, setVidIndex] = useState(0);
    const oneRef = useRef(null);
    const twoRef = useRef(null);

    useEffect(() => {
        console.log("当前index",vidIndex)
        if (vidIndex === 0 && oneRef.current) {
            oneRef.current.play();
        }

        if (vidIndex === 1 && twoRef.current) {
            twoRef.current.play();
        }
    }, [oneRef,twoRef, vidIndex]);
    return (
        <div className="videoShowDiv">
            <video
                style={{ display: vidIndex === 1 ? "none" : "block", width: "100%", height: "100%" }}
                src={oneVideo }
                muted
                onEnded={() => setVidIndex((idx) => idx + 1)}
                ref={oneRef}
            />
            <video
                style={{ display: vidIndex === 0 ? "none" : "block", width: "100%", height: "100%" }}
                src={twoVideo}
                muted
                onEnded={() => setVidIndex((idx) => idx -1)}
                ref={twoRef}
            />
        </div>
    );
}

export default VideoPlay

 ##3、选择播放

import React, { useEffect, useState, useRef } from "react";


function VideoPlay(props) {
    const { menuClickIndex } = props;
    const [vidIndex, setVidIndex] = useState(0);
    const oneRef = useRef(null);
    const twoRef = useRef(null);

    useEffect(() => {
        console.log("当前index", vidIndex)
        console.log("当前menuClickIndex", menuClickIndex)

        //menuClickIndex 为指定数,视频就指定播放那个视频
        if (menuClickIndex != undefined) {
            if (menuClickIndex == 0) {
                if (oneRef.current) {
                    oneRef.current.play();
                }
            }

            if (menuClickIndex == 1) {
                if (twoRef.current) {
                    twoRef.current.play();
                }
            }
        }

        //menuClickIndex 为空,视频就循环切换
        else {
            if (vidIndex === 0 && oneRef.current) {
                oneRef.current.play();
            }

            if (vidIndex === 1 && twoRef.current) {
                twoRef.current.play();
            }
        }

    }, [oneRef, twoRef, vidIndex]);

    const showVideoClass = { display: "block", width: "100%", height: "100%" }
    const hindVideoClass = { display: "none", width: "100%", height: "100%" }

    return (
        <div>
            {
                menuClickIndex == undefined &&

                <div className="videoShowDiv">

                    <video
                        style={{ display: vidIndex === 1 ? "none" : "block", width: "100%", height: "100%" }}
                        src={require("../../../static/video/one.mp4")}
                        muted
                        onEnded={() => setVidIndex((idx) => idx + 1)}
                        ref={oneRef}
                    />

                    <video
                        style={{ display: vidIndex === 0 ? "none" : "block", width: "100%", height: "100%" }}
                        src={require("../../../static/video/two.mp4")}
                        muted
                        onEnded={() => setVidIndex((idx) => idx - 1)}
                        ref={twoRef}
                    />
                </div>
            }

            {menuClickIndex == 0 &&
                <div className="videoShowDiv">
                    <video
                        style={showVideoClass}
                        src={require("../../../static/video/one.mp4")}
                        muted
                        loop
                        autoPlay
                        ref={oneRef}
                    />
                </div>
            }

            {menuClickIndex == 1 &&
                <div className="videoShowDiv">
                    <video
                        style={showVideoClass}
                        src={require("../../../static/video/two.mp4")}
                        muted
                        loop
                        autoPlay
                        ref={oneRef}
                    />
                </div>
            }
        </div>

    );
}

export default VideoPlay

 


overAndOutMenu = (index) => {
  
    this.setState({
      menuClickIndex: index
    })
}

//在布局中 
<div
     onMouseOver={() => {
         this.overAndOutMenu(0)
     }}
 >
                   菜单0
</div>
 

<div
     onMouseOver={() => {
         this.overAndOutMenu(1)
     }}
 >
                   菜单1
</div>

二、预览拖动 

transform的使用 :CSS 变形(CSS3) transform_css transform_快乐de馒头的博客-CSDN博客

##1、缩放 

给图片 加  transform: scale(1.4)

onWheel={(e) => { if (isModelPreview) { handleWheelImage(e) } }} 

const handleWheelImage = (event) => {
    const bigger = event.deltaY > 0 ? -1 : 1;
    //向上为负,向下为正
    if (bigger > 0 && rate < 5) {
      const enlargeRate = rate + SCALE;
      setImgStyle({
        ...imgStyle,
        'transformOrigin': 'center',
        'transform': `scale( ${enlargeRate}) rotate(${oldRotate}deg)`
      });
      setRate(enlargeRate);
    } else if (bigger < 0 && rate > 1) {
      const shrinkRate = rate - SCALE;
      setImgStyle({
        ...imgStyle,
        'transformOrigin': 'center',
        'transform': `scale( ${shrinkRate}) rotate(${oldRotate}deg)`
      });
      setRate(shrinkRate);
    }
  }

加动画:

 

 ##2、旋转

给图片 加  transform: rotate(90deg)  90,180,270,360 为选择方向

const childHandleClickRotate = () => {

    if (rotate == 90) {
      setOldRotate(90)
      setRotate(90 * 2)
    }

    if (rotate == 180) {
      setOldRotate(180)
      setRotate(90 * 3)
    }

    if (rotate == 270) {
      setOldRotate(270)
      setRotate(90 * 4)
    }

    if (rotate == 360) {
      setOldRotate(360)
      setRotate(90)
    }

    setImgStyle({
      ...imgStyle,
      'transformOrigin': 'center',
      'transform': `scale(${rate}) rotate(${rotate}deg)`
    });
  }

 ##3、matrix 平移

给图片加 

transform: matrix(2.2, 0, 0, 2.2, -89, 186)

matrix(2.2, 0, 0, 2.2, -89, 186)的值 ,2,2为 缩放, -89 和 186 为移动的偏移位置

 拖动时,结合鼠标事件,结合matrix 做图片平移

onMouseDown={(e) => { if (isModelPreview) { handleMouseDown(e) } }}
onMouseMove={(e) => { if (isModelPreview) { handleMouseMove(e) } }}
onMouseUp={(e) => { if (isModelPreview) { handleMouseUp(e) } }}

 
const handleMouseDown = (event) => {
    event.preventDefault();
    event.stopPropagation();

    const { pageX, pageY } = event;
    setMouseDowmFlag(true); // 控制只有在鼠标按下后才会执行mousemove
    setMouseDowmPos({
      x: pageX,
      y: pageY,
    });
  }


  const handleMouseMove = (event) => {
    // console.log("获取的move对象:",event)
    event.preventDefault()
    event.stopPropagation()

    const { pageX, pageY } = event;
    const diffX = pageX - mouseDowmPos.x;
    const diffY = pageY - mouseDowmPos.y;
    if (!mouseDowmFlag || (diffX === 0 && diffY === 0)) return;
    const offsetX = parseInt(`${diffX}`);
    const offsetY = parseInt(`${diffY}`);
    
   //具体移动 偏移 x和y 可自行计算
    setImgStyle({
      ...imgStyle,
      'cursor': 'move',
      'transformOrigin': 'center',
      'transform': `matrix(${rate}, 0, 0, ${rate}, ${offsetX + matrixPos.x}, ${offsetY + matrixPos.y})  rotate(${oldRotate}deg)`
    });

    setMatrixPos({
      x: offsetX,
      y: offsetY,
    });

  }
  const handleMouseUp = (event) => {
    event.preventDefault();
    event.stopPropagation();

    setMouseDowmFlag(false);
  }


学习文章:react移动端svg等图片拖拽缩放 - 灰信网(软件开发博客聚合) (freesion.com)

 学习文章:https://www.saoniuhuo.com/question/detail-2609566.htmlreact图片缩放、平移(position、transform实现) - React那点事儿 - SegmentFault 思否

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

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

相关文章

Zookeeper的应用场景

一、Zookeeper的应用场景包括&#xff1a; 配置中心&#xff1a;Zookeeper可以用来存储和管理配置信息&#xff0c;例如集群中的机器配置、服务地址配置等。通过Zookeeper&#xff0c;可以将配置信息统一管理&#xff0c;同时实现动态加载和更新。统一命名服务&#xff1a;Zoo…

Ubuntu 20.04.02 LTS安装virtualbox7.0

ubuntu22.04的软件仓库也有virtualbox&#xff0c;不过版本较老。 使用安装命令&#xff1a;sudo apt install virtualbox 如果想要安装最新版&#xff0c;那么需要去官网下载deb包或者使用官方的仓库。 这里采用安装Oracle官方仓库的方法。 执行如下命令&#xff1a; wge…

fastadmin 点击获取当前行数据

fastadmin 点击获取当前行数据 // 先获取当前id // 使用方法的语法&#xff1a;$(#table).bootstrapTable(method, parameter);$(document).on("click",".detailtips",function(){var ids$(this).attr("id");var rows$("#table").boo…

pytorch快速入门中文——04(训练图片分类器)

训练分类器 原文&#xff1a;https://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html#sphx-glr-beginner-blitz-cifar10-tutorial-py 就是这个。 您已经了解了如何定义神经网络&#xff0c;计算损失并更新网络的权重。 现在您可能在想&#xff0c; 数据呢&…

java小技能:分布式任务调度平台

文章目录 引言I 报表数据生成II 注意事项2.1 任务创建2.2 pom.xml 添加到maven项目 see also 引言 任务调度的应用场景&#xff1a; 生成日报、月报、定时处理任务&#xff08;定期清理文件、处理数据&#xff09; I 报表数据生成 https://kunnan.blog.csdn.net/article/deta…

你知道GPT-3带的即时学习能力是什么吗

你知道GPT-3带的即时学习能力是什么吗 在人工智能领域&#xff0c;GPT-3&#xff08;Generative Pre-trained Transformer 3&#xff09;是当前比较先进的自然语言处理模型之一。它采用了自监督学习的方式进行训练&#xff0c;并且拥有强大的“in-context learning”&#xff…

nginx-rewrite

目录 1.rewrite 2.应用场景 3.跳转实现及特点 4.格式 5.location分类 6.具体应用场景 1.基于域名跳转 2.基于客户端ip访问跳转 3.基于旧域名跳转新域名后加的目录 4.基于匹配的跳转 5.基于目录下所有php结尾文件跳转 6.基于最普通一条url请求的跳转 7.总结 1.rewrite 重…

星辰秘典:揭开Python项目的神秘密码——2048游戏

✨博主&#xff1a;命运之光 &#x1f338;专栏&#xff1a;Python星辰秘典 &#x1f433;专栏&#xff1a;web开发&#xff08;html css js&#xff09; ❤️专栏&#xff1a;Java经典程序设计 ☀️博主的其他文章&#xff1a;点击进入博主的主页 前言&#xff1a;你好&#x…

Docker 部署 jar 项目

文章目录 1、上传jar包2、新建 Dockerfile 文件3、新建 deploy.sh 脚本&#xff08;创建并运行&#xff09;4、新建 upgrade.sh 脚本&#xff08;更新&#xff09; 1、上传jar包 2、新建 Dockerfile 文件 添加jar包及修改端口 # 基础镜像 FROM java:8 # 添加jar包 ADD servic…

百度智能车竞赛丝绸之路智能车设计与编程实现控制

一、项目简介 本项目现已基于鲸鱼机器人开发套件对其整体外形进行设计&#xff0c;并且对应于实习内容——以“丝绸之路”为题&#xff0c;对机器人各个功能与机器人结构部分进行相关设计与调整。主要可以实现“车道线巡检”“音乐交际”、“城堡检测”、“翻山越岭”。 本项…

Java使用策略模式和工厂模式来消除冗余的if-else语句(UML类图+案例+提供Gitee源码)

前言&#xff1a;在最近的后端开发中&#xff0c;多多少少会发现有很多if-else语句&#xff0c;如果条件过多则会造成整体代码看起来非常臃肿&#xff0c;这边我就举一个我在实际开发中的例子&#xff0c;来进行阐述这两种模式在实际开发中我是如何运用的。 目录 一、工厂模式…

把Jar打包为Maven 把jar打包为maven 将java项目打包为maven 将Java项目打包为Maven

把Jar打包为Maven 把jar打包为maven 将java项目打包为maven 将Java项目打包为Maven 自己写了一个通用SDK Jar包&#xff0c;但是现在的项目都是Maven项目&#xff0c;需要把Jar打包为Maven格式&#xff0c;输出到本地Maven仓库&#xff0c;在项目中可以引用查看Maven是否安装打…

nginx进行反向代理

Nginx是一个开源的高性能Web服务器和反向代理服务器。它最初是由Igor Sysoev在2004年开发的&#xff0c;现在由一个全球性的社区维护和支持。 Nginx的主要特点包括&#xff1a; 高性能&#xff1a;Nginx使用事件驱动模型&#xff0c;可以处理高并发请求&#xff0c;具有出色的…

A* 算法研究(附 Python / C++ 实现)

A* 算法研究 参考 A*寻路算法详解 #A星 #启发式搜索 路径规划之 A* 算法 最短路搜索-从Dijkstra到Best-First再到A-Star 路径规划算法学习笔记&#xff08;一&#xff09;&#xff1a;A*算法 A*算法寻路&#xff08;C代码实现&#xff09; 《基于A*算法的自动泊车全局路径规划…

恒生电子联合恒生聚源发布数智金融新品,聚焦大模型技术金融业务应用

6月28日&#xff0c;恒生电子和旗下子公司恒生聚源正式发布基于大语言模型技术打造的数智金融新品&#xff0c;金融智能助手光子和全新升级的智能投研平台WarrenQ。此外&#xff0c;恒生电子金融行业大模型LightGPT也首次对外亮相&#xff0c;并公布最新研发进展。 恒生电子董…

升级Win10后多了个恢复分区,有什么用

很多用户从Win7/Win8/Win8.1升级到Win10之后发现电脑硬盘上多出了一个“恢复分区”&#xff0c;64位系统下这个分区大小在450MB左右。那么为什么会多出这样一个分区&#xff0c;这个分区又是干什么的&#xff0c;能不能删除呢&#xff1f;下面以MBR硬盘情况为例来说明。 1.全盘…

MySQL数据库 SQL语言命令总结 数据类型、运算符和聚合函数汇总

数据库&#xff1a;存储数据的仓库&#xff0c;有组织的进行存储数据。SQL&#xff1a;操作关系型数据库的编程语言&#xff0c;定义了一套操作关系型数据库统一标准。常用的关系型数据库管理系统&#xff1a;Oracle、MySQL、Microsoft SQL Server等。 Oracle是大型收费数据库&…

初识express/路由/中间件

路由的概念 模块化路由 中间件(要有输入输出) 简化版本 全局生效中间件 局部生效中间件 注意事项 中间件分类 内置中间件,解析请求体/url-encoded 自定义中间件 使用querystring模块解析请求体数据 编写接口 ​​​​​​​

x86_64(intel64、amd64)和ARM64的区别以及发展

文章目录 区别引用 区别 ARM64架构 ARM 公司研发的&#xff0c;用的是精简指令集&#xff08;追求节能&#xff0c;低功耗&#xff09;。通常用于手机、平板等CPU&#xff0c;目前笔记本电脑也会采用ARM64构架的CPU&#xff0c;比如mac m1就是arm64(查看命令&#xff1a;uname…

智能佳—LoCoBot WX250 6自由度

&#xff08;用于科研与教学的ROS智能车&#xff09; LoCoBot是用于映射、导航和操纵&#xff08;可选&#xff09;等ROS研究的智能车&#xff0c;研究人员、教育工作者和学生都可以使用LoCoBot专注于高级代码的开发&#xff0c;而不是专注硬件和构建低级代码。通过开放的源代码…