首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >移动设备上onMouseWheel的触摸行为-- three.js

移动设备上onMouseWheel的触摸行为-- three.js
EN

Stack Overflow用户
提问于 2020-02-06 17:22:58
回答 1查看 270关注 0票数 1

如何在移动触摸设备上实现前后滚动,或者具有与桌面(onMouseWheel)相同的行为?示例:

JS Fiddle:https://jsfiddle.net/xzwve647/

桌面(桌面上的动画工作正常)

移动(动画不向后工作-只向前工作):

代码语言:javascript
复制
function onTouchStart(event) {
        startY = event.touches[0].pageY;
    }
    function onTouchMove(event) {
        var delta = event.deltaY;
        if (event.deltaY > 0) {
            for (var i = 0; i < mixers.length; i++) {
                mixers[i].update(clock.getDelta() * 5);
            }
        } else {
            for (var i = 0; i < mixers.length; i++) {
                mixers[i].update(clock.getDelta() * -5);
            }
        }
    }

事件侦听器:

代码语言:javascript
复制
 window.addEventListener( 'mousewheel', onMouseWheel, false );
 window.addEventListener( 'touchstart', onTouchStart, false );
 window.addEventListener( 'touchmove', onTouchMove, false );

代码语言:javascript
复制
var container, stats, controls;
var camera, scene, renderer, light;
var clock = new THREE.Clock();

var mixer = [];

var mixers = [];

init();

animate();

function init() {

  container = document.createElement('div');
  document.body.appendChild(container);

  camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
  camera.position.set(0, 100, 100);

  scene = new THREE.Scene();

  light = new THREE.HemisphereLight(0xffffff, 0x444444);
  light.position.set(0, 200, 0);
  scene.add(light);

  light = new THREE.DirectionalLight(0xffffff);
  light.position.set(0, 200, 100);
  light.castShadow = true;
  light.shadow.camera.top = 180;
  light.shadow.camera.bottom = -100;
  light.shadow.camera.left = -120;
  light.shadow.camera.right = 120;
  scene.add(light);

  // scene.add( new THREE.CameraHelper( light.shadow.camera ) );

  var grid = new THREE.GridHelper(2000, 20, 0x000000, 0x000000);
  grid.material.opacity = 0.2;
  grid.material.transparent = true;
  scene.add(grid);

  // model
  var loader = new THREE.FBXLoader();
  loader.load('https://threejs.org/examples/models/fbx/Samba Dancing.fbx', function(object) {

    object.mixer = new THREE.AnimationMixer(object);
    mixers.push(object.mixer);


    var action = object.mixer.clipAction(object.animations[0]);
    action.play();


    object.traverse(function(child) {

      if (child.isMesh) {

        child.castShadow = true;
        child.receiveShadow = true;

      }

    });
    object.position.y = 85;

    scene.add(object);

  });


  renderer = new THREE.WebGLRenderer({
    alpha: true,
    antialias: true
  });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.shadowMap.enabled = true;
  container.appendChild(renderer.domElement);

  window.addEventListener('mousewheel', onMouseWheel, false);
  window.addEventListener('touchstart', onTouchStart, false);
  window.addEventListener('touchmove', onTouchMove, false);

  window.addEventListener('resize', onResize, false);

  // stats
  stats = new Stats();
  container.appendChild(stats.dom);

}


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


function onMouseWheel(event) {


  if (event.deltaY > 0) {
    for (var i = 0; i < mixers.length; i++) {
      mixers[i].update(clock.getDelta() * 5);
    }
  } else {
    for (var i = 0; i < mixers.length; i++) {
      mixers[i].update(clock.getDelta() * -5);

    }
  }
}


function onTouchStart(event) {

  startY = event.touches[0].pageY;


}

function onTouchMove(event) {

  var delta = event.deltaY;

  if (event.deltaY > 0) {
    for (var i = 0; i < mixers.length; i++) {
      mixers[i].update(clock.getDelta() * 5);
    }
  } else {
    for (var i = 0; i < mixers.length; i++) {
      mixers[i].update(clock.getDelta() * -5);

    }
  }


}


function animate() {

  delta = clock.getDelta();

  requestAnimationFrame(animate);

  renderer.render(scene, camera);

  stats.update();

}
代码语言:javascript
复制
body {
  margin: 0px;
  overflow: hidden;
}
代码语言:javascript
复制
<script src="https://threejs.org/build/three.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://threejs.org/examples/js/libs/inflate.min.js"></script>
<script src="https://threejs.org/examples/js/loaders/FBXLoader.js"></script>
<script src="https://threejs.org/examples/js/WebGL.js"></script>
<script src="https://threejs.org/examples/js/libs/stats.min.js"></script>

EN

回答 1

Stack Overflow用户

发布于 2020-02-07 02:49:55

我不知道你的代码会发生什么。

您可能需要wheel事件,而不是mousewheel事件。火狐上不存在mousewheel

触摸事件上没有event.deltaY。将数据放在event.touches数组上的触摸事件,每个手指对应一个

如果您曾经尝试在页面的某个地方打印event.deltaY,或者在调试器(远程运行)中逐步执行代码,那么很明显,有些地方是不正确的。

代码可以通过使用函数来简化。不需要重复循环4次。

代码语言:javascript
复制
function adjustMixers(deltaY) {
  const speed = deltaY > 0 ? 5 : -5;
  const amount = clock.getDelta() * speed;
  for (let i = 0; i < mixers.length; i++) {
    mixers[i].update(amount);
}

function onMouseWheel(event) {
  adjustMixers(event.deltaY);
}

let lastY;
function onTouchStart(event) {
  lastY = event.touches[0].pageY;
}

function onTouchMove(event) {
  const currentY = event.touches[0].pageY;
  const deltaY = currentY - lastY;
  lastY = currentY;
  adjustMixers(deltaY);
}

最后,通过使事件监听器不是被动的并调用event.preventDefault,可以防止浏览器执行其默认操作(移动页面)。

代码语言:javascript
复制
function onMouseWheel(event) {
  event.preventDefault();
  ...
}

function onTouchStart(event) {
  event.preventDefault();
  ...
}

function onTouchMove(event) {
  event.preventDefault();
  ...
}

window.addEventListener('wheel', onMouseWheel, {passive: false});
window.addEventListener('touchstart', onTouchStart, {passive: false});
window.addEventListener('touchmove', onTouchMove, {passive: false});
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60100436

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档