3D模型工具栏-旋转动画

简介: 3D模型工具栏-旋转动画

工具栏--旋转动画代码:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
    <title>工具栏-旋转动画</title>
    <script src="./js/three.js"></script>
    <script src="./js/OBJLoader.js"></script>
    <script src="./js/OrbitControls.js"></script>
    <style>
      /* 初始化页面 */
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      /* 设置渲染容器的大小 */
      #webgl {
        width: 100%;
        height: 100vh;
        overflow: hidden;
      }
      /* 设置最大元素宽高 */
      .content{
        width: 100%;
        height: 100vh;
        position: relative;
      }
      /* 将工具栏定位到页面右下角 */
      .tool{
        position: absolute;
        bottom: 0;
        right: 0;
        margin-right: 20px;
        display: flex;
        user-select: none;
      }
      /* 设置每一个块的大小 */
      .tool-item{
        width: 35px;
        height: 35px;
        padding: 5px;
        position: relative;
      }
      /* 设置小图标黑色背景 */
      .tool-img{
        display: flex;
        justify-content: center;
        align-items: center;
        width: 25px;
        height: 25px;
        border-radius: 100%;
        background-color: rgba(0,0,0,0.8);
      }
      /* 设置小图标大小 */
      .tool-img img{
        width: 13px;
        height: 13px;
      }
      /* 设置小图标的提示文本 */
      .tool-text{
        display: block;
        line-height: 20px;
        padding: 6px 0px;
        border-radius: 5px;
        background-color: #000000;
        font-size: 12px;
        text-align: center;
        color: #FFFFFF;
        position: absolute;
        bottom: 40px;
        left: 50%;
        display: none;
      }
      /* 设置提示文本下边的小三角 */
      .tool-item i{
        display: none;
        width: 10px;
        height: 10px;
        background-color: #000000;
        position: absolute;
        bottom: 36px;
        left: 50%;
        margin-left: -5px;
        transform: rotate(45deg);
      }
      /* 鼠标放到每一块上显示提示文本 */
      .tool-item:hover .tool-text{
        display: block;
      }
      /* 鼠标放到每一块上显示小三角 */
      .tool-item:hover i{
        display: block;
      }
      /* 设置查看弹窗大小和位置 */
      .popout{
        width: 160px;
        position: absolute;
        bottom: 40px;
        background-color: #000000;
        padding: 6px 0;
        border-radius: 10px;
        font-size: 12px;
        color: #FFFFFF;
        right: -30px;
        z-index: 100;
      }
      /* 设置查看弹窗下边的小三角 */
      .popout-arrow{
        display: block;
        width: 10px;
        height: 10px;
        background-color: #000000;
        position: absolute;
        bottom: 36px;
        left: 50%;
        margin-left: -5px;
        transform: rotate(45deg);
      }
      /* 设置弹窗中每行的大小 */
      .popout p{
        width: 90%;
        height: 30px;
        margin-left: 5%;
        display: flex;
        justify-content: space-between;
        line-height: 30px;
      }
      /* 设置弹窗中每行箭头的大小 */
      .popout>p img{
        width: 12px;
        height: 12px;
        margin: 9px 0px;
      }
      /* 设置弹窗中的分界线 */
      .popout em{
        display: block;
        width: 100%;
        height: 1px;
        background-color: #525252;
      }
      /* 设置弹窗中背景图的那一行 */
      .popout-list{
        width: 90%;
        height: 30px;
        margin-left: 5%;
        padding: 5px 0;
        display: flex;
        justify-content: space-between;
      }
      /* 设置背景图中左右按钮的大小 */
      .popout-list>img{
        width: 14px;
        height: 14px;
        margin: 3px;
      }
      /* 设置背景图列表 */
      .popout-pic{
        display: flex;
        justify-content: space-between;
        width: calc(100% - 40px);
      }
      /* 设置背景图大小 */
      .popout-pic img{
        width: 20px;
        height: 20px;
      }
    </style>
  </head>
  <body>
    <div class="content">
      <!-- 渲染容器 -->
      <div id="webgl"></div>
      <!-- 工具栏 -->
      <div class="tool">
        <div class="tool-item">
          <span class="tool-text" id="rotate-text" style="width: 70px;margin-left: -35px;">开启旋转</span>
          <i></i>
          <div class="tool-img" onclick="rotates()">
            <img src="./img/旋转.png" alt="">
          </div>
        </div>
        <div class="tool-item">
          <span class="tool-text" style="width: 70px;margin-left: -35px;">开启AR</span>
          <i></i>
          <div class="tool-img">
            <img src="./img/AR.png" alt="">
          </div>
        </div>
        <div class="tool-item">
          <span class="tool-text" style="width: 50px;margin-left: -25px;">帮助</span>
          <i></i>
          <div class="tool-img">
            <img src="./img/帮助.png" alt="">
          </div>
        </div>
        <div class="tool-item">
          <span class="tool-text" style="width: 70px;margin-left: -35px;">查看方式</span>
          <i></i>
          <div onclick="look()" class="tool-img">
            <img src="./img/查看.png" alt="">
          </div>
          <!-- 查看弹窗 -->
          <div class="popout" style="display: none;">
            <p onclick="unfold(event)"><span>展示模式</span><img src="img/展开.png" alt=""></p>
            <p style="padding-left: 10px;display: none;"><span>允许缩放</span><img src="./img/对.png" alt=""></p>
            <em></em>
            <p onclick="unfold(event)"><span>背景切换</span><img src="./img/展开.png" alt=""></p>
            <div class="popout-list" style="display: none;">
              <img onclick="picLeft()" src="./img/左箭头.png" alt="">
              <div class="popout-pic">
                <img src="./img/pic1.jpg" >
                <img src="./img/pic2.webp" >
                <img src="./img/pic3.webp" >
                <img src="./img/pic4.webp" >
              </div>
              <img onclick="picRight()" src="./img/右箭头.png" alt="">
            </div>
          </div>
          <b class="popout-arrow" style="display: none;"></b>
        </div>
        <div class="tool-item">
          <span class="tool-text" style="width: 70px;margin-left: -35px;">开启VR</span>
          <i></i>
          <div class="tool-img">
            <img src="./img/VR.png" alt="">
          </div>
        </div>
        <div class="tool-item">
          <span class="tool-text" style="width: 70px;margin-left: -35px;">开启全屏</span>
          <i></i>
          <div class="tool-img">
            <img src="./img/全屏.png" alt="">
          </div>
        </div>
      </div>
    </div>
    <script>
      // 获取渲染容器
      let webgl = document.getElementById("webgl");
      // 获取渲染容器的宽高
      let webglWidth = webgl.offsetWidth;
      let webglHeight = webgl.offsetHeight;
      // 创建场景
      let scene = new THREE.Scene();
      // 设置环境光(十六进制颜色)
      let ambient = new THREE.AmbientLight(0x444444);
      // 将环境光添加到场景中
      scene.add(ambient);
      // 设置点光源(十六进制颜色)
      let point = new THREE.PointLight(0xffffff);
      // 设置点光源的位置(x轴, y轴, z轴)
      point.position.set(400, 200, 300); 
      // 将点光源添加到场景中
      scene.add(point);
      // 创建透视相机(角度, 宽高比, 最近距离, 最远距离)
      let camera = new THREE.PerspectiveCamera(60,webglWidth/webglHeight,0.1,2000);
      // 设置相机的位置(x轴, y轴, z轴)
      camera.position.set(100, 100, 100); 
      // 将相机指向场景中心
      camera.lookAt(scene.position);
      // 创建渲染器
      let renderer = new THREE.WebGLRenderer();
      // 设置渲染器的初始颜色(十六进制颜色, 透明度)
      renderer.setClearColor(0xEEEEEE,1);
      // 设置渲染器大小(标签宽度, 标签高度)
      renderer.setSize(webglWidth,webglHeight);
      // 将渲染器添加到渲染容器中(渲染器元素)
      webgl.appendChild(renderer.domElement);
      // 创建旋转状态
      let rotateStatus = false;
      // 创建渲染函数
      function render(){
        // 渲染场景和相机(场景, 相机)
        renderer.render(scene,camera);
        // 判断旋转状态为 ture 则执行
        if(rotateStatus){
          // 设置场景旋转速度
          scene.rotation.y += 0.002;
        }
        // 重复执行渲染函数
        requestAnimationFrame(render);
      }
      // 调用渲染函数
      render();
      // 设置窗口变化自适应调整事件
      window.onresize = function(){
        // 重新获取渲染容器的宽高
        webglWidth = webgl.offsetWidth;
        webglHeight = webgl.offsetHeight;
        // 重置渲染器canvas画布大小
        renderer.setSize(webglWidth,webglHeight);
        // 重置相机显示范围的宽高比
        camera.aspect = webglWidth/webglHeight;
        // 更新相机的投影矩阵
        camera.updateProjectionMatrix();
        // 重新调用渲染函数
        render();
      };
      // 创建 OBJ 模型加载器
      let loader = new THREE.OBJLoader();
      // 加载 OBJ 文件
      loader.load('./img/鹤.OBJ', function(obj) {
        // 加载纹理贴图
        let texture = new THREE.TextureLoader().load('./img/he.png',function(){
          render(); // 加载成功后重新调用渲染函数
        });
        // 给 OBJ 模型设置纹理贴图
        obj.children[0].material = new THREE.MeshBasicMaterial({ map: texture });
        // 将 OBJ 模型添加到场景中
        scene.add(obj);
        // 设置 OBJ 模型居中
        obj.children[0].geometry.center();
        // 设置 OBJ 模型缩放大小
        obj.children[0].scale.set(100, 100, 100);
      })
      // 鼠标操作三维场景
      let controls = new THREE.OrbitControls(camera,renderer.domElement);
      // 查看弹窗显示隐藏事件
      function look(){
        // 获取查看弹窗
        let popout = document.getElementsByClassName("popout")[0];
        // 获取查看弹窗下边的小三角
        let arrow = document.getElementsByClassName("popout-arrow")[0];
        // 判断弹窗是否隐藏
        if(popout.style.display == "none"){
          // 如果隐藏,显示弹窗和小三角
          popout.style.display = "block";
          arrow.style.display = "block";
        }else{
          // 如果显示,则隐藏弹窗和小三角
          popout.style.display = "none";
          arrow.style.display = "none";
        }
      }
      // 查看弹窗功能展开事件
      function unfold(e){
        // 获取事件目标对象
        e = e || window.event;
        let targets = e.target || e.srcElement;
        // 创建变量用于存储下一个同级元素
        let nexts;
        // 创建变量用于存储当前 p 标签内的 img 标签
        let pImg;
        // 当前目标元素是否为 p 标签
        if(targets.nodeName == "P"){
          // 如果为p标签,存储当前目标元素的下一个同级元素
          nexts = targets.nextElementSibling;
          // 存储当前 p 标签内的 img 标签
          pImg = targets.getElementsByTagName("img")[0];
        }else{
          // 如果不是p标签,存储当前目标元素的父元素的下一个同级元素
          nexts = targets.parentElement.nextElementSibling;
          // 存储当前目标元素的父元素内的 img 标签
          pImg = targets.parentElement.getElementsByTagName("img")[0];
        }
        // 判断下一个同级元素是否隐藏
        if(nexts.style.display == "none"){
          // 如果隐藏则显示
          nexts.style.display = "flex";
          // 设置小图标箭头朝下
          pImg.style.transform = "rotate(90deg)";
        }else{
          // 如果显示则隐藏
          nexts.style.display = "none";
          // 设置小图标箭头朝右
          pImg.style.transform = "rotate(0deg)";
        }
      }
      // 模拟背景图片数据
      let arr = [
        "./img/pic1.jpg",
        "./img/pic2.webp",
        "./img/pic3.webp",
        "./img/pic4.webp",
        "./img/pic5.jpg"
      ];
      // 输出背景图数据
      // 创建起始值,表示从第几张图片开始输出
      let begin = 0;
      // 创建结束值,表示到第几张图片输出结束
      // 并且判断图片数量是否大于等于4,如果大于设置为 4,否则设置为图片的数量
      let record = arr.length >= 4 ? 4 : arr.length;
      // 创建背景图渲染函数
      function picRender(){
        // 创建变量,存储拼接的字符串
        let picStr = "";
        // 循环拼接数据,从 begin 开始,到 record 结束
        for(let i = begin; i < record; i++){
          picStr += `<img src="${arr[i]}" >`;
        }
        // 向页面输出数据
        document.getElementsByClassName("popout-pic")[0].innerHTML = picStr;
      }
      // 调用背景图渲染函数
      picRender();
      // 背景图切换-左按钮事件
      function picLeft(){
        // 判断起始值是否大于 0
        if(begin > 0){
          // 如果大于 0 让 起始值 和 结束值 都减一
          record--;
          begin--;
          // 重新调用背景图渲染函数
          picRender();
        }
      }
      // 背景图切换-右按钮事件
      function picRight(){
        // 判断图片数量减起始值是否大于 4
        if(arr.length - begin > 4){
          // 如果大于 4 让 起始值 和 结束值 都加一
          record++;
          begin++;
          // 重新调用背景图渲染函数
          picRender();
        }
      }
      // 创建模型旋转点击事件
      function rotates(){
        // 获取旋转提问文本
        let rotateText = document.getElementById("rotate-text");
        // 取反旋转状态
        rotateStatus = !rotateStatus;
        // 判断旋转状态是否为 true
        if(rotateStatus){
          // 如果为 true,设置提示文本为停止旋转
          rotateText.innerHTML = "停止旋转";
        }else{
          // 如果为 false,设置提示文本为开启旋转
          rotateText.innerHTML = "开启旋转";
        }
      }
    </script>
  </body>
</html>

工具栏-旋转动画效果:

原创作者:吴小糖

创作时间:2022.11.3

相关文章
|
1月前
ThreeJs添加拖动辅助线
这篇文章介绍了在Three.js中使用TransformControls组件来添加拖动辅助线,实现对3D模型在不同轴向上进行直观的拖动和平移操作。
59 0
|
1月前
|
监控
ThreeJs限制模型拖动的范围
这篇文章讲解了在Three.js中如何限制模型拖动的范围,确保模型在特定边界内移动,提供了实现拖动限制的代码示例和技术细节。
48 1
ThreeJs限制模型拖动的范围
|
6月前
滑动工具条
滑动工具条
42 0
|
11月前
水波纹按钮动画
水波纹按钮动画
46 0
水波纹按钮动画
|
前端开发
【30天30个小项目】菜单悬停动画
【30天30个小项目】菜单悬停动画
67 0
【30天30个小项目】菜单悬停动画
Qt无边框窗口拖拽和阴影
无边框窗口的实现
426 0
Qt无边框窗口拖拽和阴影
QT软件开发: 点击鼠标在窗口里绘制矩形(窗口透明背景)
QT软件开发: 点击鼠标在窗口里绘制矩形(窗口透明背景)
531 0
QT软件开发: 点击鼠标在窗口里绘制矩形(窗口透明背景)
|
Android开发
Android 自定义控件之SlidingMenuVertical顶部悬浮(垂直折叠抽屉,有滑动渐变回调,可自行添加渐变动画)
顶部悬浮(垂直折叠抽屉,有滑动渐变回调,可自行添加渐变动画)
2067 0
|
C# 索引 容器
WPF ListView控件设置奇偶行背景色交替变换以及ListViewItem鼠标悬停动画
原文:WPF ListView控件设置奇偶行背景色交替变换以及ListViewItem鼠标悬停动画 利用WPF的ListView控件实现类似于Winform中DataGrid行背景色交替变换的效果,同时增加鼠标的悬停效果。
1830 0