Three.js + Gsap ScrollTrigger

hi everyone, about Three.js + Gsap ScrollTrigger.
I want to make that when the mouse scrolls down, the model can rotate.
When I use **let tween = gsap.to(camera.position, {x: 0.1 })** the model can move, but the speed is too fast… and it is not so natural and smooth

thanks~~

my code:

//場景 相機 渲染器 (scene, camera, renderer)

let container;
let canvas;
let camera;
let renderer;
let scene;
let mountain;
let controls;

function init() {
  // container = document.querySelector(".app");

  //選擇容器 canvas
  canvas = document.querySelector(".app");

  //創建場景 Scene
  scene = new THREE.Scene();

  const fov = 10;
  const aspect = canvas.clientWidth / canvas.clientWidth;
  const near = 0.1;
  const far = 1500;

  //建立相機 Perspective Camera (透視相機)
  camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  // camera.position.set( <X> , <Y> , <Z> );
  // <X>,<Z> 是2D座標, <Y>是高度
  camera.position.set(-200, 0, 10);

  //光源燈 Light
  const ambient = new THREE.AmbientLight(0x212121, 10);
  scene.add(ambient);

  const light = new THREE.DirectionalLight(0xffffff, 2);
  light.position.set(50, 50, 100);
  scene.add(light);

  //選染器 Render
  renderer = new THREE.WebGLRenderer({
    canvas,

    antialias: true,

    alpha: true,
  });

  const manager = new THREE.LoadingManager();

  //載入模型
  const mtlLoader = new THREE.MTLLoader(manager);
  mtlLoader.setResourcePath("models/fishbottle/");
  mtlLoader.setPath("models/fishbottle/");
  mtlLoader.load("10_633.mtl", function (materials) {
    materials.preload();

    const objLoader = new THREE.OBJLoader(manager);
    objLoader.setMaterials(materials);
    objLoader.setPath("models/fishbottle/");
    objLoader.load(
      "10_633.obj",
      function (object) {
        mesh = object;
        scene.add(mesh);
      }
      // onProgress,
      // onError
    );
  });

  // xyz輔助工具
  let helper = new THREE.AxesHelper(50);
  // scene.add(helper);

  //OrbitControls 滑鼠拖曳旋轉控制器

  controls = new THREE.OrbitControls(camera, canvas);

  controls.enableDamping = true; //拖拉慣性

  controls.campingFactor = 0.25; //拖拉慣性阻尼參數搭配enableDamping使用

  controls.enableZoom = false; //相機變焦移動

  controls.enablePan = false; //相機平移

  controls.enableRotate = true;

  // controls.maxAzimuthAngle = 1;
  // controls.minAzimuthAngle = 1;

  //禁用垂直控制單軸
  controls.maxPolarAngle = 1;
  controls.minPolarAngle = 1;

  // maxAzimuthAngle

  controls.update();
}

//canvas 畫面自訂義

function resizeRendererToDisplaySize(renderer) {
  const canvas = renderer.domElement;

  const width = canvas.clientWidth;

  const height = canvas.clientHeight;

  const needResize = canvas.width !== width || canvas.height !== height;

  if (needResize) {
    renderer.setSize(width, height, false);
  }

  return needResize;
}

//動畫執行
function animate() {
  requestAnimationFrame(animate);

  if (mountain) {
    // mountain.rotation.z += 0.001;
  }

  if (resizeRendererToDisplaySize(renderer)) {
    const canvas = renderer.domElement;

    camera.aspect = canvas.clientWidth / canvas.clientHeight;

    camera.updateProjectionMatrix();
  }

  renderer.render(scene, camera);
}

init();

animate();

gsap.registerPlugin(ScrollTrigger);

let tween = gsap.to(camera.position, { x: 0.1 }),
  st = ScrollTrigger.create({
    trigger: ".app-wraper",
    start: "top 100px",
    end: "bottom 80%",
    markers: true,
    toggleActions: "restart pause resume pause",
    animation: tween,
  });

EX:

Live example: three.js dev template - module - JSFiddle - Code Playground

Notice that the animation depends on the kind of device you are using. With a magic mouse or touchpad, the animation is already smooth. But with a regular mouse, the scrolling feels bumpy. It seems you have to use the .scrollerProxy() method to fix this issue.

3 Likes

@Mugen87 Thanks u, I will try it