Skip to content

事件传递

由于 three 各种 Controls 监听的都是 PointerEvent , 而小程序内部的事件类似于 web 环境的 TouchEvent ,需要经过一道转换才能正常使用。

所以 adapter 下的 useCanvas 方法返回了 eventHandler 属性,只需将在画布上触发的的 touch 事件传递给 eventHandler, 即会自动转换为控制器需要的 PoinitEvent

正常使用

基于 创建一个场景 的例子,进行如下改动:

vue

<script setup>
  import * as THREE from 'three';
  import { ref } from 'vue';  
  import { adapter } from '@minisheep/three-platform-adapter';

  const canvasEventHandler = ref(() => {
  }); 

  adapter
      .useCanvas('#canvas')
      .then(({
               canvas,
               requestAnimationFrame,
               eventHandler, 
             }) => {
        canvasEventHandler.value = eventHandler; 

        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(75, canvas.clientWidth / canvas.clientHeight, 0.1, 1000);

        const renderer = new THREE.WebGLRenderer({ canvas });
        renderer.setSize(canvas.clientWidth, canvas.clientHeight);

        const geometry = new THREE.BoxGeometry(1, 1, 1);
        const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
        const cube = new THREE.Mesh(geometry, material);
        scene.add(cube);

        camera.position.z = 5;

        function animate() {
          requestAnimationFrame(animate);

          cube.rotation.x += 0.01;
          cube.rotation.y += 0.01;

          renderer.render(scene, camera);
        }

        animate();
      });
</script>
vue
<template>
  <canvas 
      type="webgl2"
      id="canvas"
      @touchstart="canvasEventHandler"
      @touchmove="canvasEventHandler"
      @touchcancel="canvasEventHandler"
      @touchend="canvasEventHandler"
      @tap="canvasEventHandler"
  />
</template>
vue

<style>
  canvas {
    width: 100vw;
    height: 100vh;
  }
</style>

其他应用

调用 eventHandler 不仅仅会在画布上触发对应的 PointerEvent 事件, 还会在 adapterTHREEGlobals 对象下的 document / window 属性上触发,以支持一些不仅仅在画布元素监听事件的控制器。

当然,也可以通过传递第二个参数禁用这个事件冒泡逻辑, 例如 (ev)=>eventHandler(ev, false)