main.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. import * as THREE from 'https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js';
  2. import {FBXLoader} from 'https://cdn.jsdelivr.net/npm/[email protected]/examples/jsm/loaders/FBXLoader.js';
  3. import {OrbitControls} from 'https://cdn.jsdelivr.net/npm/[email protected]/examples/jsm/controls/OrbitControls.js';
  4. class Website3DDemo {
  5. constructor() {
  6. this._Initialize();
  7. }
  8. _Initialize() {
  9. this._threejs = new THREE.WebGLRenderer({
  10. antialias: true,
  11. alpha: true,
  12. });
  13. this._threejs.shadowMap.enabled = true;
  14. this._threejs.shadowMap.type = THREE.PCFSoftShadowMap;
  15. this._threejs.physicallyCorrectLights = true;
  16. this._threejs.toneMapping = THREE.ACESFilmicToneMapping;
  17. this._threejs.outputEncoding = THREE.sRGBEncoding;
  18. const modelDiv = document.getElementById('model');
  19. modelDiv.appendChild(this._threejs.domElement);
  20. this._threejs.setSize(modelDiv.offsetWidth, modelDiv.offsetHeight);
  21. window.addEventListener('resize', () => {
  22. this._OnWindowResize();
  23. }, false);
  24. const fov = 60;
  25. const aspect = modelDiv.offsetWidth / modelDiv.offsetHeight;
  26. const near = 1.0;
  27. const far = 1000.0;
  28. this._camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  29. this._camera.position.set(15, 15, 20);
  30. this._scene = new THREE.Scene();
  31. let light = new THREE.DirectionalLight(0xFFFFFF);
  32. light.position.set(20, 100, 10);
  33. light.target.position.set(0, 0, 0);
  34. light.castShadow = true;
  35. light.shadow.bias = -0.001;
  36. light.shadow.mapSize.width = 2048;
  37. light.shadow.mapSize.height = 2048;
  38. light.shadow.camera.near = 0.1;
  39. light.shadow.camera.far = 500.0;
  40. light.shadow.camera.near = 0.5;
  41. light.shadow.camera.far = 500.0;
  42. light.shadow.camera.left = 100;
  43. light.shadow.camera.right = -100;
  44. light.shadow.camera.top = 100;
  45. light.shadow.camera.bottom = -100;
  46. this._scene.add(light);
  47. light = new THREE.AmbientLight(0xFFFFFF);
  48. this._scene.add(light);
  49. this._controls = new OrbitControls(
  50. this._camera, this._threejs.domElement);
  51. this._controls.target.set(0, 10, 0);
  52. this._controls.update();
  53. this._LoadAnimatedModelAndPlay(
  54. './resources/zombie/', 'mremireh_o_desbiens.fbx',
  55. 'Silly Dancing.fbx', new THREE.Vector3(0, 0, 0));
  56. this._LoadAnimatedModelAndPlay(
  57. './resources/zombie/', 'mremireh_o_desbiens.fbx',
  58. 'Silly Dancing.fbx', new THREE.Vector3(-20, 0, -20));
  59. this._LoadAnimatedModelAndPlay(
  60. './resources/zombie/', 'mremireh_o_desbiens.fbx',
  61. 'Silly Dancing.fbx', new THREE.Vector3(20, 0, -20));
  62. this._mixers = [];
  63. this._previousRAF = null;
  64. this._scrollAmount = 0.0;
  65. this._RAF();
  66. }
  67. _LoadAnimatedModelAndPlay(path, modelFile, animFile, offset) {
  68. const loader = new FBXLoader();
  69. loader.setPath(path);
  70. loader.load(modelFile, (fbx) => {
  71. fbx.scale.setScalar(0.1);
  72. fbx.traverse(c => {
  73. c.castShadow = true;
  74. });
  75. fbx.position.copy(offset);
  76. const anim = new FBXLoader();
  77. anim.setPath(path);
  78. anim.load(animFile, (anim) => {
  79. const m = new THREE.AnimationMixer(fbx);
  80. this._mixers.push(m);
  81. const idle = m.clipAction(anim.animations[0]);
  82. idle.play();
  83. });
  84. this._scene.add(fbx);
  85. });
  86. }
  87. OnScroll(pos) {
  88. const a = 15;
  89. const b = -15;
  90. const amount = Math.min(pos / 500.0, 1.0);
  91. this._camera.position.set(a + amount * (b - a), 15, 20);
  92. this._controls.update();
  93. }
  94. _OnWindowResize() {
  95. this._camera.aspect = window.innerWidth / window.innerHeight;
  96. this._camera.updateProjectionMatrix();
  97. this._threejs.setSize(window.innerWidth, window.innerHeight);
  98. }
  99. _Step(timeElapsed) {
  100. const timeElapsedS = timeElapsed * 0.001;
  101. if (this._mixers) {
  102. this._mixers.map(m => m.update(timeElapsedS));
  103. }
  104. }
  105. _RAF() {
  106. requestAnimationFrame((t) => {
  107. if (this._previousRAF === null) {
  108. this._previousRAF = t;
  109. }
  110. this._RAF();
  111. this._threejs.render(this._scene, this._camera);
  112. this._Step(t - this._previousRAF);
  113. this._previousRAF = t;
  114. });
  115. }
  116. }
  117. let _APP = null;
  118. window.addEventListener('DOMContentLoaded', () => {
  119. _APP = new Website3DDemo();
  120. });
  121. window.addEventListener('scroll', (e) => {
  122. _APP.OnScroll(window.scrollY);
  123. });