美文网首页
Three.js实现鼠标拖拽平移并根据阈值控制回弹和切换

Three.js实现鼠标拖拽平移并根据阈值控制回弹和切换

作者: zhuyx0304 | 来源:发表于2024-03-19 08:56 被阅读0次
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      html,
      body {
        margin: 0;
      }
    </style>
    <script src="./three.js/tweenjs.js"></script>
    <script type="importmap">
      {
        "imports": {
          "three": "../three.js/build/three.module.js",
          "three/addons/": "../three.js/examples/jsm/"
        }
      }
    </script>
  </head>
  <body>
    <script type="module">
      import * as THREE from "three";
      import { OrbitControls } from "three/addons/controls/OrbitControls.js";
      import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";

      const scene = new THREE.Scene();

      const camera = new THREE.PerspectiveCamera(
        75,
        window.innerWidth / window.innerHeight,
        0.1,
        1000
      );

      const renderer = new THREE.WebGLRenderer();
      renderer.setSize(window.innerWidth, window.innerHeight);
      document.body.appendChild(renderer.domElement);

      camera.position.x = -3;
      camera.position.y = 2;
      camera.position.z = 5;

      const axesHelper = new THREE.AxesHelper(150);
      scene.add(axesHelper);

      const light = new THREE.AmbientLight(0xffffff); // 柔和的白光
      scene.add(light);

      function render() {
        requestAnimationFrame(render);
        camera.updateProjectionMatrix();
        renderer.render(scene, camera);
      }
      render();

      window.addEventListener("resize", function () {
        renderer.setSize(window.innerWidth, window.innerHeight);
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
      });

      const loader = new GLTFLoader();
      loader.load("./model/low-poly-city-dio.glb", function (gltf) {
        scene.add(gltf.scene);
      });

      // 假设你已经初始化了Three.js的基本环境:scene, camera, renderer

      let isDragging = false;
      let lastMouseX = 0;
      let dragDistance = 0;
      const threshold = 100; // 阈值,可根据需求调整

      // 监听鼠标按下事件
      renderer.domElement.addEventListener(
        "mousedown",
        onDocumentMouseDown,
        false
      );

      function onDocumentMouseDown(event) {
        event.preventDefault();
        isDragging = true;
        lastMouseX = event.clientX;
      }

      // 监听鼠标移动事件
      document.addEventListener("mousemove", onDocumentMouseMove, false);

      function onDocumentMouseMove(event) {
        if (isDragging) {
          const mouseDeltaX = event.clientX - lastMouseX;

          // 更新相机位置或触发切换效果
          if (Math.abs(mouseDeltaX) > threshold) {
            // 超过阈值时执行切换或特殊操作
            // 在这里执行切换图片墙、场景或其他操作
            // ...
          } else {
            const delta = new THREE.Vector3(-mouseDeltaX * 0.1, 0, 0); // 控制速度,可调整
            camera.position.add(delta);
            dragDistance += Math.abs(mouseDeltaX); // 记录累积的拖动距离
          }

          // 更新上一次鼠标位置
          lastMouseX = event.clientX;
        }
      }

      // 监听鼠标抬起事件,添加回弹动画
      document.addEventListener("mouseup", onDocumentMouseUp, false);

      function onDocumentMouseUp(event) {
        isDragging = false;

        // 回弹动画
        if (dragDistance > 0) {
          const snapBack = () => {
            const bounceFactor = 0.9; // 回弹系数,可调整
            const deltaBack = camera.position.x * bounceFactor;

            camera.position.x -= deltaBack;

            // 当回弹接近停止时(比如距离小于1像素),结束动画
            if (Math.abs(deltaBack) < 1) {
              camera.position.x = Math.round(camera.position.x); // 可选,使位置整数化以避免小数点误差
              return;
            }

            requestAnimationFrame(snapBack);
          };

          requestAnimationFrame(snapBack);
        }

        dragDistance = 0; // 松开鼠标后重置拖动距离
      }
    </script>
  </body>
</html>

相关文章

网友评论

      本文标题:Three.js实现鼠标拖拽平移并根据阈值控制回弹和切换

      本文链接:https://www.haomeiwen.com/subject/qtnazdtx.html