three.js初探

<!--创建了一个html文件-->
<!--事先将three项目拷入目录   https://github.com/mrdoob/three.js/  -->


<html>
<head>
  <title>My first Three.js app</title>
  <style>
    body {
      margin: 0;
    }

    canvas {
      display: block;
    }
  </style>
</head>
<body>
<!--以文件形式导入-->
<!--<script src="../src/js/Three.js"></script>-->
<!--<script src="../src/js/OrbitControls.js"></script> &lt;!&ndash;轨道控制器js引入&ndash;&gt;-->
<script type="module">

  // 以模块形式导入文件
  import * as THREE from '../src/js/three/build/three.module.js';
  import {OrbitControls} from '../src/js/three/examples/jsm/controls/OrbitControls.js';
  import {TWEEN} from "../src/js/three/examples/jsm/libs/tween.module.min.js";
  import { OBJLoader } from '../src/js/three/examples/jsm/loaders/OBJLoader.js';
  import { GLTFLoader } from '../src/js/three/examples/jsm/loaders/GLTFLoader.js'

  const scene = new THREE.Scene();      //创建场景
  const camera = new THREE.PerspectiveCamera      //创建相机
      (90, window.innerWidth / window.innerHeight, 0.1, 1000);

  const renderer = new THREE.WebGLRenderer({antialias: true});     //创建渲染器,antialias抗锯齿
  renderer.setSize(window.innerWidth, window.innerHeight);      //设置渲染器的尺寸
  renderer.setClearColor('#000000', 0.8);      //设置背景颜色
  document.body.appendChild(renderer.domElement);     //渲染器加入到dom中,这个元素是一个canvas
  // console.log(renderer.domElement)

  const pointLight = new THREE.PointLight(0xffffff);        //点光源
  pointLight.position.set(300, 400, 500);
  scene.add(pointLight);

  const light = new THREE.AmbientLight(0x404040); // soft white light
  scene.add(light);


  scene.add(new THREE.AxisHelper(20));// 加入坐标轴
  //      加入网格辅助线
  const gridHelper = new THREE.GridHelper( 100, 100, 0x888888, 0x444444 );
  gridHelper.position.y = 0;
  gridHelper.position.x = 0;
  gridHelper.name = "Grid";
  scene.add( gridHelper );


  const geometry = new THREE.BoxGeometry(1, 1, 1);
  const material = new THREE.MeshLambertMaterial({
    color: 0x00ff00,
    transparent: true,
    opacity: 0.5
  });
  const cube = new THREE.Mesh(geometry, material);
  scene.add(cube);

  const geometry1 = new THREE.SphereGeometry(0.4, 100, 100);
  const material1 = new THREE.MeshLambertMaterial({
    color: 0x7777FF,
    transparent: true,
    opacity: 0.4
  });
  const sphere = new THREE.Mesh(geometry1, material1);
  sphere.position.set(1.5, 1, 0.4)
  scene.add(sphere);

  const geometry2 = new THREE.TetrahedronBufferGeometry();
  const material2 = new THREE.MeshLambertMaterial({
    color: 0x7777FF,
  });
  const tetrahedron = new THREE.Mesh(geometry2, material2);
  tetrahedron.translateY(2)
  scene.add(tetrahedron);

  let geometry3 = new THREE.Geometry();
  geometry3.vertices.push(new THREE.Vector3(-1, 2, 1));
  geometry3.vertices.push(new THREE.Vector3(3, 1, 1));
  geometry3.vertices.push(new THREE.Vector3(3, 2, 0.5));
  let material3 = new THREE.LineBasicMaterial({color: '#523369'});
  let line = new THREE.Line(geometry3, material3);
  scene.add(line)


  //引入字体并创建文字
  let loader = new THREE.FontLoader();
  loader.load('../src/js/three/examples/fonts/helvetiker_regular.typeface.json', function (font) {

    let gem = new THREE.TextGeometry('THREE', {
      size: 0.5, //字号大小,一般为大写字母的高度
      height: 0.2, //文字的厚度
      weight: 'normal', //值为'normal'或'bold',表示是否加粗
      font: font, //字体,默认是'helvetiker',需对应引用的字体文件
      style: 'normal', //值为'normal'或'italics',表示是否斜体
      bevelEnabled: true, //布尔值,是否使用倒角,意为在边缘处斜切
      bevelThickness: 0.05, //倒角厚度
      bevelSize: 0.03, //倒角宽度
      curveSegments: 30,//弧线分段数,使得文字的曲线更加光滑
    });
    gem.center();
    let mat = new THREE.MeshPhongMaterial({
      color: 0xffe502,
      specular: 0x009900,
      shininess: 30,
      shading: THREE.FlatShading
    });
    let textObj = new THREE.Mesh(gem, mat);
    textObj.position.set(1, 1, 2)
    // textObj.castShadow = true;
    scene.add(textObj);
    // console.log(textObj.rotation)
    new TWEEN.Tween(textObj.rotation).to({y: Math.PI * 2}, 8000)
        .repeat(Infinity).yoyo(false).start();       //Tween动画,yoyo函数使表示是否存在逆向变化
  });


  // obj模型加载
  const loader1 = new OBJLoader();
  loader1.load( './WaltHead.obj', function ( obj ) {

    // console.log(obj)

    let material = new THREE.MeshLambertMaterial({color: '#ffffff'});

    // 加载完obj文件是一个场景组Group,遍历它的子元素,每一个元素是一个Mesh
    obj.children.forEach(function (child) {
      child.material = material;
      child.geometry.computeFaceNormals();
      child.geometry.computeVertexNormals();

      //模型缩小为0.05倍
      child.scale.set(0.05, 0.05, 0.05);
      child.translateX(5)
      // scene.add(child);
    });

    scene.add(obj);
  } );

  // 加载GLTF模型
  let mixers = [];
  const clock = new THREE.Clock();      // 创建时钟对象用于动画更新(在animate函数中)

  const loader2 = new GLTFLoader();
  loader2.load('./Bee.glb',function (obj) {
    // console.log(obj);
    obj.scene.scale.set(0.05, 0.05, 0.05)
    obj.scene.position.set(-2,0,-1);
    scene.add(obj.scene);

    let anims = obj.animations;       // 动画集合,每个元素都是一个AnimationClip对象
    console.log(anims)

    // 调用动画
    for (let anim of anims) {
      let mixer = new THREE.AnimationMixer( obj.scene.children[0] );      // 构造函数要传入Object3D对象
      mixer.clipAction( anim ).setDuration( anim.duration ).play();       //mixer.clipAction要传入AnimationClip对象     
      mixers.push( mixer );
    }
    console.log(mixers)

  });



  camera.position.z = 5;
  camera.translateX(0.5)
  camera.translateY(1)


  const controls = new OrbitControls(camera, renderer.domElement);     //引入控制器,更改相机对象
  // controls.update();


  // const animate = function () {
  //   requestAnimationFrame( animate );
  //
  //   cube.rotation.x += 0.01;
  //   cube.rotation.y += 0.01;
  //
  //   renderer.render( scene, camera );
  // };


  let T0 = new Date()

  function animate() {
    // //增加两帧之间的间隔
    // let n = 0
    // for (let i = 0; i <10000; i ++)
    //   for (let j = 0; j < 10000; j ++)
    //     n ++

    // let T1 = new Date()
    // let deltaT = T1 - T0
    // console.log('刷新频率为:  ' + Math.floor(1000 / deltaT))
    // T0 = T1
    renderer.render(scene, camera)
    cube.rotateX(0.01)
    cube.rotateY(0.01)
    TWEEN.update();       // TWEEN动画更新

    let delta = clock.getDelta();
    for (let mixer of mixers)     // 重复播放动画
      mixer.update( delta );


    requestAnimationFrame(animate)
  }


  animate();      //调用


  function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();

    renderer.setSize( window.innerWidth, window.innerHeight );
  }

  window.addEventListener('resize', onWindowResize);

</script>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值