• 基于typescript开发的threejs3D动画项目


    资源下载地址:https://download.csdn.net/download/sheziqiong/85721248

    前言

    我们前面使用的是自己编写的ts,以及自己手动引入的jquery,由于第三方库采用的是直接引入js,没有d.ts声明文件,开发起来很累,所以一般情况下我们使用npm引入第三方的库,本文记录使用npm,typescript开发threejs3D项目,搭建基础实例,为以后开发具体业务做准备。

    项目结构

    在这里插入图片描述

    依旧是熟悉的SpringBoot项目,不同以往的是使用了npm管理工具来下载依赖js库,类似maven,同时为了解决typescript编译后引入npm库的路径有问题,导致浏览器报错的问题,我们采用的webpack打包工具来打包 PS:webpack依赖的文件真的是多,全都安装完后,好几百M

    下面简单说一下如何初始化npm、webpack,以及下载jquery、three等js库

    npm的使用

    初始化

    cmd先打开到项目的 threejs\src\main\resources\static 路径,使用npm init命令,回答一系列问题(当然也可以全部按照默认值),初始化成npm项目

    得到node_modules目录以及package.json文件

    当我们使用打包命令,会提示我们还缺少那些依赖,这时候我们按照提示去下载就可以了

    有一点要注意,package.json文件的name值不能用typescript,我们改成

      "name": "typescript-threejs",
    
    • 1

    脚本命令

      "scripts": {
        "tsc": "tsc -w",//监控文件,有改动时实时编译ts
        "build": "webpack",//打包
        "dev": "webpack -w"//监控文件,有改动时实时打包
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5

    webpack.config.js配置

    const path = require('path');
    module.exports = {
        entry : {
            main : './src/controller/Main.ts'
        },
        devtool : 'inline-source-map',
        mode : 'development',
        module : {
            rules : [ {
                test : /\.ts$/,
                use : 'ts-loader',
                exclude : /node_modules/
            } ]
        },
        resolve : {
            extensions : [ '.ts', '.js' ]
        },
        output : {
            filename : '[name].js',
            path : path.resolve(__dirname, './dist/')
        },
        plugins : [
        ],
        optimization: {
            splitChunks: {
                chunks: "all",
                minSize: 30000,
                minChunks: 1,
                maxAsyncRequests: 5,
                maxInitialRequests: 3,
                automaticNameDelimiter: '-',
                name: true,
                cacheGroups: {
                    vendors: {
                        test: /[\\/]node_modules[\\/]/,
                        priority: -10
                    },
                    default: {
                        minChunks: 2,
                        priority: -20,
                        reuseExistingChunk: true
                    }
                }
            }
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    使用 npm install 命令就可以下载第三方插件

    下载jquery的声明文件

    在node_modules目录下面j就可以看到npm下载下来的库

    如何引入

    使用typescript编译成js,路径不正确,浏览器报错

    使用webpack编译、打包成js,路径正确

    threejs

    threejs,是一个JavaScript编写的WebGL第三方库

    官网:https://threejs.org/

    官方文档:https://threejs.org/docs/index.html#manual/zh/introduction/Creating-a-scene

    官方提供的各种例子:https://threejs.org/examples/

    官方GitHub:https://github.com/mrdoob/three.js

    网友克隆的官网,gitee国内镜像,网速较快:http://break_egg.gitee.io/three.js/

    这里还有一个大神的博客,有比较丰富的例子可以参考:https://www.wjceo.com/

    通过查阅官网文档、以及参考大量的例子进行学习,我们开始three.js之旅,采用的是npm引入的方式引入three

    路径结构介绍

    渲染器有三个WebGLRenderer、CSS2DRenderer、CSS3DRenderer,后面这两个是为了能够使用CSS2DObject、CSS3DObject对象作为Label,注意,使用了多个渲染器后,我们的控制器要控制的是CSS3DRenderer.domElement,控制它可以同时控制到WebGLRenderer的对象

    同时,3D的渲染器DOM要加绝对定位,要不然DOM的东西显示不出来(为了统一,2D的我也加了),然后webGL的canvas也加样式,position: absolute;

    在这里插入图片描述

    然后在初始化场景时,不停的渲染,注意,有一个地方不停的渲染就可以了,多了影响性能

    封装原生发射射线的方式监听对象的鼠标事件,有个地方要注意,射线只能检测到Mesh对象,Group组对象是检测不到了

    更新监听事件方法:

        /**
         * 添加cSS3DRenderer.domElement监听对象事件,利用原生射线原理,被射线检测到自身节点或者子节点则触发监听事件
         */
        public addEventListener(listenerObj: THREE.Object3D, even: string, callback: (object: THREE.Object3D) => void): void {
            let thid = this;
    
            //把具体的事件添加到对象,然后再绑定到dom,这样做的目的是为了方便后期移除
            listenerObj[even] = function (event) {
                //阻止冒泡
                event.preventDefault();
    
                //光线投射
                let raycaster = new THREE.Raycaster();
                let mouse = new THREE.Vector2();
    
                mouse.x = (event["clientX"] / thid.cSS3DRenderer.domElement.clientWidth) * 2 - 1;
                mouse.y = -(event["clientY"] / thid.cSS3DRenderer.domElement.clientHeight) * 2 + 1;
    
                raycaster.setFromCamera(mouse, thid.camera);
                // 需要被监听的对象要存储在intersectObjects中,对象本身就是一个group,所以不能直接检测射线(三维世界中点击事件需要检测射线),
                // 其下children里面有许多mesh,才是要被检测的目标。
                let intersects;
                if (listenerObj.type == "Mesh") {
                    intersects = raycaster.intersectObjects([listenerObj], false);
                } else {
                    intersects = raycaster.intersectObjects(listenerObj.children, true);
                }
                if (intersects.length > 0) {
                    // 回调函数,返回被监听对象本身
                    if (callback) callback(listenerObj);
                }
            };
    
            //threejs原生事件监听 mousedown
            this.cSS3DRenderer.domElement.addEventListener(even, listenerObj[even], false);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
        /**
         * 移除cSS3DRenderer.domElement监听对象事件
         */
        public removeEventListener(listenerObj: THREE.Object3D, even: string,): void {
            this.cSS3DRenderer.domElement.removeEventListener(even, listenerObj[even]);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    同时还封装了一个动画效果,按屏幕刷新率调用,每次调用++一定的值,每次回调函数返回,从0到1递增,等于1的时候结束递归调用

    在这里插入图片描述

    还有一个是镜头的巡检

    在这里插入图片描述

    其他地方就不一一介绍了,大家自己看代码

    效果演示

    地球模仿的是:https://wa.qq.com/xplan/earth/index.html?_wv=1

    地球外部有一层漂浮的云层(大气层),效果比较逼真

    云层模仿的是: http://www.sucai58.com/plus/demo.php?aid=132

    云海又八千多个PlaneGeometry对象组成,推动镜头营造穿越云层的效果,作为地球场景到园区场景的过渡动画

    在这里插入图片描述

    园区是加载了官方例子的obj模型(站立的男人)以及fbx模型(跳舞的女人),跳舞的动画是模型自带的,中间那两个是普通的BoxGeometry对象(录GIF的软件录带绿色的东西效果好难看啊,我就不放上来了…)

    在这里插入图片描述

    在这里插入图片描述

    更多效果自己运行查看

    补充

    1、npm install 包的时候报错

    在这里插入图片描述

    解决:给npm降级或者升级

    降级 : npm install -g npm@5.4.0 //@后面是具体版本号

    升级 : npm install -g npm //升级到最新版本

    如果还不行就清除缓存再次安装

    npm cache clean -f

    2、threejs移动的时候老是报错

    在three.module.js做一下小调整,非空才调用.call方法

    资源下载地址:https://download.csdn.net/download/sheziqiong/85721248
    资源下载地址:https://download.csdn.net/download/sheziqiong/85721248

  • 相关阅读:
    Linux友人帐之日志与备份
    vim的使用介绍以及命令大全
    【单元测试】--高级主题
    BLE蓝牙模块NRF518/NRF281/NRF528/NRF284芯片方案对比
    C++学习笔记(Ⅳ):C++提高编程
    前端项目边界处理
    【行为识别】差影法三维人体姿态行为识别【含Matlab源码 277期】
    Springboot毕设项目绿色生鲜5954z(java+VUE+Mybatis+Maven+Mysql)
    【Java面试】Mysql事务的实现原理
    最新版手机软件App下载排行网站源码/App应用商店源码
  • 原文地址:https://blog.csdn.net/sheziqiong/article/details/125388044