You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React-three-map中使用Gsap控制相机与缩放的问题求助

用GSAP实现React-three-map的平滑缩放控制

不用找额外GSAP插件,直接操作Three.js相机或者React-three-map的控制实例就能实现,给你两个可行方案:

方案1:直接驱动相机的zoom属性

React-three-map底层基于Three.js相机,你可以通过组件的回调拿到相机实例,然后用GSAP过渡它的zoom属性,记得每次更新后调用updateProjectionMatrix()刷新投影才能生效:

import { useRef } from 'react';
import { gsap } from 'gsap';
import { Map } from 'react-three-map';

export default function ZoomableMap() {
  const cameraRef = useRef(null);

  // 获取初始化完成的相机实例
  const onCameraReady = (camera) => {
    cameraRef.current = camera;
  };

  // 平滑放大
  const zoomIn = () => {
    if (!cameraRef.current) return;
    gsap.to(cameraRef.current, {
      zoom: cameraRef.current.zoom * 1.5,
      duration: 0.5,
      onUpdate: () => cameraRef.current.updateProjectionMatrix()
    });
  };

  // 平滑缩小
  const zoomOut = () => {
    if (!cameraRef.current) return;
    gsap.to(cameraRef.current, {
      zoom: cameraRef.current.zoom / 1.5,
      duration: 0.5,
      onUpdate: () => cameraRef.current.updateProjectionMatrix()
    });
  };

  return (
    <>
      <div style={{ position: 'fixed', top: 10, left: 10, zIndex: 100 }}>
        <button onClick={zoomIn}>放大</button>
        <button onClick={zoomOut} style={{ marginLeft: 8 }}>缩小</button>
      </div>
      <Map onCameraReady={onCameraReady} />
    </>
  );
}

方案2:控制内置缩放控制器(如果有)

如果你的项目用到了React-three-map的内置控制器(类似Three.js的OrbitControls),可以直接用GSAP控制控制器的目标缩放值,无需直接操作相机:

import { useRef } from 'react';
import { gsap } from 'gsap';
import { Map, Controls } from 'react-three-map';

export default function ControlledZoomMap() {
  const controlsRef = useRef(null);

  const onControlsReady = (controls) => {
    controlsRef.current = controls;
  };

  // 平滑缩放到指定倍数
  const zoomTo = (targetZoom) => {
    if (!controlsRef.current) return;
    gsap.to(controlsRef.current, {
      targetZoom: targetZoom,
      duration: 0.8,
      ease: 'power2.inOut'
    });
  };

  return (
    <>
      <div style={{ position: 'fixed', top: 10, left: 10, zIndex: 100 }}>
        <button onClick={() => zoomTo(2)}>缩放到2倍</button>
        <button onClick={() => zoomTo(1)} style={{ marginLeft: 8 }}>恢复默认</button>
      </div>
      <Map>
        <Controls onReady={onControlsReady} />
      </Map>
    </>
  );
}

额外优化:绑定鼠标滚轮的平滑缩放

如果要替换原生滚轮缩放为GSAP平滑版本,可以监听滚轮事件,用GSAP实现过渡效果:

import { useRef, useEffect } from 'react';
import { gsap } from 'gsap';
import { Map } from 'react-three-map';

export default function WheelZoomMap() {
  const cameraRef = useRef(null);

  const onCameraReady = (camera) => {
    cameraRef.current = camera;
  };

  useEffect(() => {
    const handleWheel = (e) => {
      e.preventDefault();
      if (!cameraRef.current) return;
      // 根据滚轮方向计算目标缩放值
      const newZoom = cameraRef.current.zoom * (e.deltaY > 0 ? 1.1 : 0.9);
      gsap.to(cameraRef.current, {
        zoom: newZoom,
        duration: 0.2,
        onUpdate: () => cameraRef.current.updateProjectionMatrix()
      });
    };

    window.addEventListener('wheel', handleWheel);
    return () => window.removeEventListener('wheel', handleWheel);
  }, []);

  return <Map onCameraReady={onCameraReady} />;
}

内容的提问来源于stack exchange,提问作者Randy Kevin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 19:42:45