VUE3 创建可交互的3D世界,就是这么简单

1,130 阅读2分钟

祝福

母亲节将至,妈妈节日快乐,愿妈妈身体健康,青春永驻

自我介绍

大家好,网名:迷离,本名:宋帅,一枚喜欢折腾的前端工程师,设计师转职到前端工程师的世界,爱好写代码和听着音乐绘画,偶尔弹弹吉他(初学者),电子手工爱好者。

简介

组件库升级

五一期间,对组件库进行了升级,主要添加了事件系统和接触检测。这让我们可以很方便做出很多有意思的项目

事件系统

事件系统让我们,可以很方便的做出可以交互的3D世界

例子

鼠标点击会旋转的箱子

效果

boxrotat.gif

代码

<template>
    <SDWebglRenderer :width="720" :height="360" :backgroundColor="0x1f63d1">
        <SDPerspectiveCamera :positionY="0" :positionZ="3" />
        <SDScene>
            <SDMesh :rotationY="v" :scaleXYZ="1" :onClick="() => {
                v += 0.25;
            }">
                <SDBoxGeometry :width="1" />
                <SDMeshBasicMaterial>
                    <SDTextureLoader url="/sandi-ui/img/crate.gif" type="map" />
                </SDMeshBasicMaterial>
            </SDMesh>
        </SDScene>
    </SDWebglRenderer>
</template>
<script setup >
import { ref } from 'vue'
const v = ref(0)
</script>

我们只需要在 物体上绑上点击事件 就会执行回调,这里有一点很重要

物体事件是跟物体绑定的如果,鼠标不在物体上是不会触发默认事件,后面会详细介绍

事件的分类

  • 物体事件 和物体绑定 鼠标在物体上触发
  • 非物体事件 鼠标不在任何物体上触发
  • 全局事件 鼠标在canvas内都会触发

简单的例子

我们需要全局控制物体的移动,我们希望监听键盘的事件。 同时我们希望鼠标点击的物体也可以产生一些交互。

效果

boxrotat1.gif

可以看到,我们通过按键控制物体的左右移动, 同时鼠标点击物体控制物体旋转。你可以做出很多有意思的交互

代码

<template>
    <SDWebglRenderer :width="720" :height="360" :backgroundColor="0x1f63d1">
        <SDPerspectiveCamera :positionY="0" :positionZ="3" />
        <SDScene>
            <SDMesh :rotationY="v" :position="[x, 0, 0]" :scaleXYZ="1" :onClick="() => {
                v += 0.25;
            }" :onGLKeyDown="evevtHandle">
                <SDBoxGeometry :width="1" />
                <SDMeshBasicMaterial>
                    <SDTextureLoader url="/sandi-ui/img/crate.gif" type="map" />
                </SDMeshBasicMaterial>
            </SDMesh>
        </SDScene>
    </SDWebglRenderer>
</template>
<script setup >
import { ref } from 'vue'
const v = ref(0)
const x = ref(0)
const evevtHandle = (event) => {
    const { code } = event;
    switch (code) {
        case "KeyA":
            x.value -= 1
            break
        case "KeyD":
            x.value += 1
            break
    }
} 
</script>

回调参数

(event: 事件,{
    target: 检测到目标物体,
    objects: 检测物体列表,
    intersects:  [检测到物体列表,](https://threejs.org/docs/index.html#api/zh/core/Raycaster)
    type: 事件的类型,
  })=>{
  // do some thing
  }

丰富的事件支持

// 物体事件 鼠标需在物体上触发

  • "onClick"
  • "onPointerMove"
  • "onPointerDown"
  • "onPointerUp"
  • "onWheel"
  • "onDblClick"
  • "onKeyDown"
  • "onKeyup"
  • "onKeypress"
  • "onContextmenu"
  • "onPointerOut"
  • "onPointerOver" // 非物体事件 鼠标不在物体上时触发
  • "onPointerMissed"
  • "onKeyMissed" // 全局事件 在画布内出发
  • "onGLClick"
  • "onGLPointerMove"
  • "onGLPointerDown"
  • "onGLPointerUp"
  • "onGLWheel"
  • "onGLDblClick"
  • "onGLKeyDown"
  • "onGLKeyup"
  • "onGLKeypress"
  • "onGLContextmenu"
  • "onGLPointerOut"
  • "onGLPointerOver"
知识补充

指针事件

鼠标事件

键盘事件

事件冒泡

物体事件 默认会有冒泡行为

阻止冒泡

回调事件

(event,SdEvent)=>{
event.preventDefault(); //组织 dom 冒泡
// do something
return false // 阻止 SdEvent 冒泡
}

交个朋友&& 找工作

Slice 1.png

下一篇 我们将介绍 射线检测,物体间可以产生交互,更好玩的交互