vue使用three.js实现盒子上下左右开关门的效果(进一步优化)

本文介绍如何在vue项目中结合three.js库创建一个盒子模型,并实现开关门的功能。通过按钮控制门的开启和关闭,利用场景、相机、渲染器以及光照创建3D模型。详细阐述了开门和关门的实现逻辑,包括旋转角度的计算。同时,文章展示了子组件和父组件的封装及数据传递,以实现组件的复用。
摘要由CSDN通过智能技术生成

一、vue使用three.js实现开关门

1、实现效果

使用button按钮来控制开关门。

默认是关门状态,当点击“向左/向右/向上/向下开门”按钮时实现某个方向的开门效果,点击“关门按钮”实现关门的效果。开门后必须先进行上门操作,才能进行其他方向的开门操作,否则将提示:请先点击“关门按钮”。
在这里插入图片描述
当在http://localhost:8080/#/onoffnew?a=80&b=80 中修改参数a和参数b的大小可以改变模型宽高,此时不影响开关门效果。
在这里插入图片描述

2、实现思路

2.1、建立一个盒子模型。

(1)定义一个Scene、PerspectiveCamera、WebGLRenderer以及包含AmbientLight和DirectionalLight的混合光。
(2)设置六个不同的面,给每个面的外层贴上不同的纹理材质,里层贴上相同的纹理材质。
(3)外层中六个不同的mesh通过position和rotation属性组合成一个盒子模型,设置好后先不添加到scene中。
(4)内层中六个cube主要旋转Math.PI,使其翻转(cube中Material.side默认是THREE.FrontSide),然后将其添加到mesh里,最后将mesh添加到scene中。
(5) 最后将六个面通过group.add()方法组合成一个盒子,并将其添加到scene中。

2.2、开关门的实现

(1)为了更好地适应页面的风格,我们通过5个button按钮的v-on:click = ' '方法来实现关门和向左、向右、向上、向下开门。

    <el-row>
        <el-button type="primary" v-on:click = 'closeDoor'>关门按钮</el-button>
        <el-button type="success" v-on:click = 'openLeft'>向左开门</el-button>
        <el-button type="success" v-on:click = 'openRight'>向右开门</el-button>
        <el-button type="success" v-on:click = 'openUp'>向上开门</el-button>
        <el-button type="success" v-on:click = 'openDown'>向下开门</el-button>
    </el-row>

(2)开门效果的实现:

door_state和direction的初始设置为true。当door_state为true时,可进行开门操作。
将要旋转的一个面绕着其某一边缘进行一定角度的旋转,如同打开门一样。然后根据旋转角度计算得到旋转后该面中心位置的x、y、z的位置坐标,并将其设置为该面的位置坐标即可实现开门效果。
最后设置door_state和direction的布尔类型。

其中旋转后位置核心计算方法如下:

假设旋转的是模型加载那一刻看到的面,该面在左右开门的情况下,其在y轴上的坐标位置是未发生变化,所以只需要计算在x轴和z轴的坐标位置。下图是在不考虑y轴下,转化为二维坐标计算。(上下开门时同理,只是此时未发生变化的是x轴上位置坐标。)

假设在开门时面的中心位置从A移动到B点,旋转过程中面的大小是不变的,只是位置发生了改变,所以我们可以把旋转的过程轨迹看成是一小段扇形区域。

设扇形半径为r,旋转角度为θ。建立如下坐标轴。那么问题就转化为如何计算B点坐标即可,下图中B点坐标为*(-(r-rcosθ),-rsinθ)。

当然,计算的思路提供了。但最终的位置坐标需要根据开门方向以及在坐标系中位置灵活应用。
在这里插入图片描述

    openLeft() {
        if(this.door_state){                   
            let angle = -Math.PI/4;
            this.mesh1.rotation.y = angle;
            let a = 0 - (this.width * 0.5 *(1-Math.cos(angle)));
            let b = 0;
            let c = this.depth/2 + this.width *0.5 *Math.sin(Math.abs(angle));
            this.mesh1.position.set(a, b,c);
            this.door_state = false;
            this.direction = true;
        }
        else{
            alert('请先点击“关门按钮”!')
        }
    },
    openRight(){
       if(this.door_state){                   
            this.mesh1.position.set(0,0,this.depth/2);
            this.mesh1.rotation.y =0 ;                       
            let angle = Math.PI/4;
            this.mesh1.rotation.y = angle;
            let a = 0 + (this.width * 0.5 *(1-Math.cos(angle)));
            let b = 0;
            
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值