Three.js中光线投射Raycaster的简单使用案例 与模型的交互,当鼠标移动到模型时出现信息框

这篇具有很好参考价值的文章主要介绍了Three.js中光线投射Raycaster的简单使用案例 与模型的交互,当鼠标移动到模型时出现信息框。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

说明 

 创建两个模型

基础代码 

基础代码效果图如下:

重点!!! 

 创建光线投射Raycaster实例步骤

1.准备一个盒子,用来展示模型的长宽高信息,初始化时先隐藏该盒子

2.创建光线投射Raycaster实例

        1.创建 Raycaster 实例 

          2.为窗口绑定事件 pointermove 想使用点击事件 click 的可以自行修改

        3.定义窗口触发 pointermove 事件所执行的回调函数 onPointerMove 

        4.通过摄像机和鼠标位置更新射线

完整代码如下:

效果图如下 :

 结尾


说明 

说明:该案例是基于Vue2创建,如果未使用Ve2请自行修改代码,另外由于使用的是已经下载的Three.js,所以运行前请确保已安装Three.js以方便引入,未安装可以使用 npm install three 进行安装

 创建两个模型

先创建两个基本模型为 光线投射Raycaster 做铺垫

下面是一个名为 model 组件的编写,读者可以自行挂载在Vue示例上  

另外如果有 model 命名带来的错误,可以在文件 vue.config.js 中添加配置 lintOnSave: false

基础代码 

<template>
    <div ref="container">
        
    </div>
</template>

<script>
import * as THREE from "three";
import {OrbitControls} from "three/addons/controls/OrbitControls.js";

export default {
    name: "model",
    data() {
        return {
            //场景
            scene: null,
            //摄影机
            camera: null,
            //渲染器
            renderer: null,
            //相机控件
            controls: null,
        }
    },
    mounted() {
        // 调用方法创建场景、相机、渲染器和相机控件
        this.createScene();
        this.createCamera();
        this.createRenderer();
        this.createControls();

        // 创建两个不同大小的立方体模型,材质使用不受光照影响的 MeshBasicMaterial 材质
        const cube1 = new THREE.Mesh(
            new THREE.BoxGeometry(3, 2, 1),
            new THREE.MeshBasicMaterial({color: 0xff0000})
        );
        const cube2 = new THREE.Mesh(
            new THREE.BoxGeometry(1, 2, 3),
            new THREE.MeshBasicMaterial({color: 0x00ff00})
        );
        cube1.position.set(-2, 0, 0);
        cube2.position.set(2, 0, 0);
        this.scene.add(cube1, cube2);

        const render = () => {
            //手动更改相机的变换后,必须调用controls.update()
            this.controls.update()
            this.renderer.render(this.scene, this.camera);
            requestAnimationFrame(render);
        };
        render();
    },
    methods: {
        //创建场景
        createScene() {
            this.scene = new THREE.Scene();
        },
        //创建相机
        createCamera() {
            this.camera = new THREE.PerspectiveCamera(
                45,
                window.innerWidth / window.innerHeight,
                1,
                1000
            );
            this.camera.position.set(0, 0, 5);
        },
        //创建渲染器
        createRenderer() {
            this.renderer = new THREE.WebGLRenderer({antialias: true}); //antialias:是否执行抗锯齿,默认为false.
            this.renderer.setSize(window.innerWidth, window.innerHeight);
            this.$refs.container.appendChild(this.renderer.domElement);
        },
        //创建相机控件
        createControls() {
            this.controls = new OrbitControls(this.camera, this.renderer.domElement);
        }
    }
};
</script>

<style scoped>

</style>

基础代码效果图如下:

raycaster,javascript,前端,vue.js,3d


重点!!! 

 创建光线投射Raycaster实例步骤

1.准备一个盒子,用来展示模型的长宽高信息,初始化时先隐藏该盒子

template>
    <div ref="container">
        <div id="infoBox"></div>
    </div>
</template>

//盒子样式如下: (要是觉得盒子丑大家可以自己修改,哈哈)
#infoBox{
    display: none;
    position: absolute;
    top: 0;
    left: 0;
    background-color: #fff;
    border:1px solid #ccc;
    padding: 5px;
}

2.创建光线投射Raycaster实例

为了大家方便对照官方文档学习,所以我直接引用了官文文档的源码,大家可以对照官文修改代码进行实验加深理解 

官网地址:https://threejs.org/docs/index.html#api/zh/core/Raycaster

        1.创建 Raycaster 实例 

const raycaster = new THREE.Raycaster();
 //创建一个二维向量为后面 Raycaster 实例调用 .setFromCamera 方法做准备
const pointer = new THREE.Vector2();

         2.为窗口绑定事件 pointermove 想使用点击事件 click 的可以自行修改

window.addEventListener('pointermove', onPointerMove);

        3.定义窗口触发 pointermove 事件所执行的回调函数 onPointerMove 

const infoBox = document.querySelector('#infoBox') //获取Dom元素
const onPointerMove = (event) => {  //如果不使用箭头函数需要注意this指向问题
    // 修改 pointer 的值:将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)
    pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
    pointer.y = -(event.clientY / window.innerHeight) * 2 + 1;
    //计算物体和射线的焦点
    // 方法 .intersectObjects ( objects : Array, recursive : Boolean, optionalTarget : Array ) : Array
    // 作用:检测所有在射线与这些物体之间,包括或不包括后代的相交部分。返回结果时,相交部分将按距离进行排序,最近的位于第一个),
    //      相交部分和.intersectObject所返回的格式是相同的。
    const intersects = raycaster.intersectObjects(this.scene.children);//返回和射线相交的一组物体,值为数组
    //没有相交物体时
    if (intersects.length === 0) {
        console.log('隐藏');
        infoBox.style.display = "none";
        return;
    }
    //有相交物体时
    if (intersects.length > 0) { //其中数组第一个值的 object属性值就是鼠标放在屏幕上离我们最近的模型
        console.log('显示');
        //设置信息
        infoBox.innerHTML = `长:${intersects[0].object.geometry.parameters.depth}
        <br>宽:${intersects[0].object.geometry.parameters.width}<br>
        高:${intersects[0].object.geometry.parameters.height}`;
        infoBox.style.display = "block";
        console.log(event.clientX);
        infoBox.style.left = event.clientX + "px"; //记得一定要拼接 px 我就是开始忘记了,导致信息框不移动
        infoBox.style.top = event.clientY + "px"
    }
}

        4.通过摄像机和鼠标位置更新射线

raycaster.setFromCamera(pointer, this.camera);

以上就是 光线投射Raycaster 的使用步骤


完整代码如下:

<template>
    <div ref="container">
        <div id="infoBox"></div>
    </div>
</template>

<script>
import * as THREE from "three";
import {OrbitControls} from "three/addons/controls/OrbitControls.js";

export default {
    name: "model",
    data() {
        return {
            //场景
            scene: null,
            //摄影机
            camera: null,
            //渲染器
            renderer: null,
            //相机控件
            controls: null,
        }
    },
    mounted() {
        // 调用方法创建场景、相机、渲染器和相机控件
        this.createScene();
        this.createCamera();
        this.createRenderer();
        this.createControls();

        // 创建两个不同大小的立方体模型,材质使用不受光照影响的 MeshBasicMaterial 材质
        const cube1 = new THREE.Mesh(
            new THREE.BoxGeometry(3, 2, 1),
            new THREE.MeshBasicMaterial({color: 0xff0000})
        );
        const cube2 = new THREE.Mesh(
            new THREE.BoxGeometry(1, 2, 3),
            new THREE.MeshBasicMaterial({color: 0x00ff00})
        );
        cube1.position.set(-2, 0, 0);
        cube2.position.set(2, 0, 0);
        this.scene.add(cube1, cube2);

        //1.创建 Raycaster 实例
        const raycaster = new THREE.Raycaster();
        const pointer = new THREE.Vector2(); //创建一个二维向量为后面 Raycaster 实例调用 .setFromCamera 方法做准备
        //3.定义窗口触发 pointermove 事件所执行的回调函数 onPointerMove
        const infoBox = document.querySelector('#infoBox') //获取Dom元素
        const onPointerMove = (event) => {  //如果不使用箭头函数需要注意this指向问题
            // 修改 pointer 的值:将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)
            pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
            pointer.y = -(event.clientY / window.innerHeight) * 2 + 1;
            //计算物体和射线的焦点
            // 方法 .intersectObjects ( objects : Array, recursive : Boolean, optionalTarget : Array ) : Array
            // 作用:检测所有在射线与这些物体之间,包括或不包括后代的相交部分。返回结果时,相交部分将按距离进行排序,最近的位于第一个),
            //      相交部分和.intersectObject所返回的格式是相同的。
            const intersects = raycaster.intersectObjects(this.scene.children);//返回和射线相交的一组物体,值为数组
            //没有相交物体时
            if (intersects.length === 0) {
                console.log('隐藏');
                infoBox.style.display = "none";
                return;
            }
            //有相交物体时
            if (intersects.length > 0) { //其中数组第一个值的 object属性值就是鼠标放在屏幕上离我们最近的模型
                console.log('显示');
                //设置信息
                infoBox.innerHTML = `长:${intersects[0].object.geometry.parameters.depth}
        <br>宽:${intersects[0].object.geometry.parameters.width}<br>
        高:${intersects[0].object.geometry.parameters.height}`;
                infoBox.style.display = "block";
                console.log(event.clientX);
                infoBox.style.left = event.clientX + "px"; //记得一定要拼接 px 我就是开始忘记了,导致信息框不移动
                infoBox.style.top = event.clientY + "px"
            }
        }
        //2.为窗口绑定事件 pointermove 想使用点击事件 click 的可以自行修改
        window.addEventListener('pointermove', onPointerMove);

        const render = () => {
            // 4.通过摄像机和鼠标位置更新射线
            raycaster.setFromCamera(pointer, this.camera);
            //手动更改相机的变换后,必须调用controls.update()
            this.controls.update()
            this.renderer.render(this.scene, this.camera);
            requestAnimationFrame(render);
        };
        render();
    },
    methods: {
        //创建场景
        createScene() {
            this.scene = new THREE.Scene();
        },
        //创建相机
        createCamera() {
            this.camera = new THREE.PerspectiveCamera(
                45,
                window.innerWidth / window.innerHeight,
                1,
                1000
            );
            this.camera.position.set(0, 0, 5);
        },
        //创建渲染器
        createRenderer() {
            this.renderer = new THREE.WebGLRenderer({antialias: true}); //antialias:是否执行抗锯齿,默认为false.
            this.renderer.setSize(window.innerWidth, window.innerHeight);
            this.$refs.container.appendChild(this.renderer.domElement);
        },
        //创建相机控件
        createControls() {
            this.controls = new OrbitControls(this.camera, this.renderer.domElement);
        }
    }
};
</script>

<style scoped>
#infoBox {
    display: none;
    position: absolute;
    top: 0;
    left: 0;
    background-color: #fff;
    border: 1px solid #ccc;
    padding: 5px;
}
</style>

效果图如下 :

raycaster,javascript,前端,vue.js,3d


 结尾

要是读者觉得帮到你们了,麻烦点个赞鼓励一下,以便鼓舞我这个新手小白,谢谢大家

另外大家要有什么疑问或者是指教都可以在评论区发出来,作者看到一定回复,谢谢大家文章来源地址https://www.toymoban.com/news/detail-753955.html

到了这里,关于Three.js中光线投射Raycaster的简单使用案例 与模型的交互,当鼠标移动到模型时出现信息框的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • three.js——模型对象的使用材质和方法

    BufferGeometry通过.scale()、.translate()、.rotateX()、.rotateY()等方法可以对几何体本身进行缩放、平移、旋转,这些方法本质上都是改变几何体的顶点数据。 官网的模型和材质使用 线条模式渲染,查看几何体三角形结构

    2024年02月07日
    浏览(32)
  • 【案例】3D地球(vue+three.js)

    需要下载插件 有人找不到合适的地球平面图的话,可直接地球平面图

    2024年02月06日
    浏览(29)
  • 小程序集成Three.js框架(演示案例)

    Three.js作为非常好用的3D前端开发框架,受到很多前端开发者的追捧,而要在微信小程序中运用则需要使用适配小程序的Three.js库。 下面是集成Three.js后的微信小程序演示示例。包括常规的创建模型,应用材质,raycastor选择器等大部分Three.js使用案例。 扫码查看Three.js集成到小

    2024年02月13日
    浏览(30)
  • VUE使用Three.js实现模型,点击交互,相机旋转视角跟随移动(Threejs中使用Tweenjs,含demo源码)

    目录 一、Three.js是什么? 二、VUE简单使用Three.js步骤 1.npm安装 2.template模板 3.引入库 4.定义全局变量 5.初始化场景 6.初始化相机 7.初始化灯光 8.初始化渲染器 9.创建模型(这里我搭建的模型是一个简单双面货架模型) 10.根据浏览器窗口自适应 11.初始化函数,页面加载完成时调用

    2024年02月03日
    浏览(43)
  • 微信小程序3D,使用Three.js在微信小程序中展示gltf模型,使用VisionKit展示AR能力

    本仓库只开源gltf模型展示技术,技术好的朋友有这些代码就能帮助你解决很多问题了 如需要完整项目(基于若依框架开发的后端,AR能力前端)需另外付费赞助, 联系方式:QQ 790002517 微信公众号:时不待我 https://github.com/zzy-life/Wechat3D Three.js Three.js is a JavaScript 3D library. thr

    2024年02月09日
    浏览(36)
  • 3D沉浸式旅游网站开发案例复盘【Three.js】

    Plongez dans Lyon网站终于上线了。 我们与 Danka 团队和 Nico Icecream 共同努力,打造了一个令我们特别自豪的流畅的沉浸式网站。 这个网站是专为 ONLYON Tourism 和会议而建,旨在展示里昂最具标志性的活动场所。观看简短的介绍视频后,用户可以进入城市的交互式风景如画的地图,

    2024年02月12日
    浏览(29)
  • three.js 基础认识与简单应用

    学习总结初衷:          1. 公司项目需要。         2. 做一下笔记,方便以后学习查看,好记性不如烂笔头;也能筑固基础,加深印象。         3. 现在国内关于Three.js的学习资料很少,总结一下多多少少也能给有需要的小伙伴一些帮助。 1. 什么是three.js?你将它理解成

    2024年02月03日
    浏览(33)
  • three js模型旋转

    如何让立方体模型旋转到指定的面 父页面 效果:

    2024年02月15日
    浏览(29)
  • Three 之 three.js (webgl)鼠标/手指通过射线移动物体的简单整理封装

    目录 Three 之 three.js (webgl)鼠标/手指通过射线移动物体的简单整理封装 一、简单介绍 二、实现原理 三、注意事项 四、效果预览 五、案例实现步骤 六、关键代码 Three js 开发的一些知识整理,方便后期遇到类似的问题,能够及时查阅使用。 本节介绍, three.js (webgl) 中,

    2024年02月16日
    浏览(35)
  • Three.js 三维模型(一)

    今天主要给搭建介绍下three.js的基本使用,本篇是基于笔者在16年给做的一个项目的demo版进行讲解的,笔者当时采用Html5和JS进行编写的。可能大家会问有没有vue、React 、angular版的。这些笔者后面有时间的时候一定会给大家介绍。 其实编程的本源在于提炼属于自己的哲学思想

    2024年02月16日
    浏览(25)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包