美文网首页Angular
angular8+threejs 如何架构项目+分离模型+模型动

angular8+threejs 如何架构项目+分离模型+模型动

作者: 候鸟_ywh | 来源:发表于2019-08-02 15:40 被阅读0次

    原因:threejs在运用的时候因为是没有html全都是js,所以我想把每个模型都分成不同的service来处理,而且事件也分离到自己的service里面

    附加模型下载地址:传送门
    结构事例(有点乱没整理求不要骂)

    image.png

    下面直接上代码吧

    1、新建ng项目(不多说了);

    2、新建一个base.ts (angular8+threejs 入坑文中有详细说明),主要是用于存放一些threejs场景的基本元素:渲染器、场景、灯光、相机、网格、性能检测 和 主要画布的搭建

    image.png

    3、新建一个skeleton.service(这里面包括了骨骼、模型的动画调用)

    import { Injectable } from '@angular/core';
    import { SkeletonHelper, AnimationMixer, Clock, AnimationAction} from 'three';
    import { SCENE} from '../config/base';
    import { GLTFLoader } from 'three-full';
    @Injectable({
     providedIn: 'root'
    })
    export class SkeletonService {
     action: AnimationAction;  // 动画动作
     constructor() {
     }
    
     /**
      * @ name 控制动画开始和暂停
      * @ param e 回调开关
      */
     isPlay(e: boolean) {
       this.action.paused = e;
     }
    
     addSkeleton() {
       let mixer;
    
       const loader = new GLTFLoader();
       loader.load('assets/model/people/CesiumMan.glb', (gltf) => {
    
         // 把模型添加到场景中,SCENE是从base.ts导入的
         SCENE.add(gltf.scene);
    
         // 显示模型骨架
         const skeletonHelper = new SkeletonHelper(gltf.scene);
         skeletonHelper.material['linewidth'.toString()] = 2;
         SCENE.add(skeletonHelper);
    
         // 调用模型动画
         mixer = new AnimationMixer(gltf.scene);
         this.action = mixer.clipAction(gltf.animations[0]); //  gltf.animations[0]模型里面的第一个动作
         this.action.play(); //  必须要play()动画才会播放
    
         //  监听单个动画结束回调
         mixer.addEventListener('loop', (e) => {
           console.log(e);
           console.log('结束');
    
         });
       },
         undefined,
         (error) => {
           console.error(error);
         });
    
       //  定义时间,这个必须要写在const render 的外面,因为render是不停刷新的如果写在里面会不停重置
       const delta = new Clock();
    
       //  本模型的渲染事件可以分离到这里
       const render = () => {
         requestAnimationFrame(render);
    
         // RENDERER.render(SCENE, CAMERA);  这个 只需要写在canva.ts那边就可以了,这边不用写
    
         if (mixer) {
           mixer.update(delta.getDelta());
         }
    
       };
       render();
     }
    
    
    
    }
    
    image.png image.png

    4、回到canva的init() 直接调用 skeleton.service.ts 的 addSkeleton(); 就可以运行了

    5、给模型添加动作的暂停开始操作

    canva.html(可能会出现看不到按钮的情况,注意设置浮动)

     <input type="button" value="on/off" (click)="player()"></pre>
    

    canva.ts

    play = false;
    player() {
    this.play = !this.play;
    this.sk.isPlay(this.play); //  调用skeleton.service.ts 的方法
    }
    

    点击按钮就可以控制动画的继续和暂停了

    总结:这样就可以把事件和模型单独分离成多个ts了,不会导致代码混乱,如果有更好的方法欢迎大家留言讨论


    2019.08.19更改
    文中skeleton.service 里面有个地方写得不对


    image.png
    就是动画更新这块,这个不应该写在这里,应为在多个文件进行requestAnimationFrame的画性能会有影响,性能显示不平滑,出现锯齿状。 image.png
    解决办法:可以定义一个全局变量,然后去canvas那边统一进行更新。

    相关文章

      网友评论

        本文标题:angular8+threejs 如何架构项目+分离模型+模型动

        本文链接:https://www.haomeiwen.com/subject/oqjldctx.html