首页 > 其他分享 >three.js之动画

three.js之动画

时间:2024-05-23 16:57:06浏览次数:24  
标签:scene 动画 const THREE three add new js

动画

<canvas id="mainCanvas"></canvas>
<script type="importmap">
  {
    "imports": {
      "three": "./js/build/three.module.js",
      "three/addons/": "./js/jsm/"
    }
  }
</script>
<script type="module">
  import * as THREE from "three";
  import { TrackballControls } from "three/addons/controls/TrackballControls.js";
  import { GUI } from "three/addons/libs/lil-gui.module.min.js";
  import { initRenderer, initPerspectiveCamera, initAmbientLight, initSpotLight, addPlane, addBox, addSphere, addCylinder } from "./init.js";

  const gui = new GUI();

  function init() {
    window.addEventListener("resize", onResize, false);
    document.addEventListener("mousedown", onDocumentMouseDown, false);
    document.addEventListener("mousemove", onDocumentMouseMove, false);

    const renderer = initRenderer("mainCanvas");

    const scene = new THREE.Scene();

    const camera = initPerspectiveCamera();
    scene.add(camera);

    const ambientLight = initAmbientLight();
    scene.add(ambientLight);

    const spotLight = initSpotLight();
    scene.add(spotLight);

    const plane = addPlane();
    scene.add(plane);

    const cube = addBox({ color: 0xff0000, width: 4, height: 4, depth: 4 });
    cube.position.set(-10, 5, 0);
    scene.add(cube);

    const sphere = addSphere({ color: 0x7777ff, radius: 4 });
    sphere.position.set(20, 5, 0);
    scene.add(sphere);

    const cylinder = addCylinder({ color: 0x77ff77, tr: 2, br: 2, height: 20 });
    scene.add(cylinder);

    let step = 0;
    let scalingStep = 0;
    const controls = new (function () {
      this.rotationSpeed = 0.02;
      this.bouncingSpeed = 0.03;
      this.scalingSpeed = 0.03;
      this.showRay = false;
    })();
    gui.add(controls, "rotationSpeed", 0, 0.5);
    gui.add(controls, "bouncingSpeed", 0, 0.5);
    gui.add(controls, "scalingSpeed", 0, 0.5);
    gui.add(controls, "showRay").onChange(function (e) {
      if (tube) scene.remove(tube);
    });

    const trackballControls = new TrackballControls(camera, renderer.domElement);
    const clock = new THREE.Clock();
    let tube;

    render();

    function render() {
      trackballControls.update(clock.getDelta());

      cube.rotation.x += controls.rotationSpeed;
      cube.rotation.y += controls.rotationSpeed;
      cube.rotation.z += controls.rotationSpeed;

      step += controls.bouncingSpeed;
      sphere.position.x = 20 + 10 * Math.cos(step);
      sphere.position.y = 2 + 10 * Math.abs(Math.sin(step));

      scalingStep += controls.scalingSpeed;
      const scaleX = Math.abs(Math.sin(scalingStep / 4));
      const scaleY = Math.abs(Math.cos(scalingStep / 5));
      const scaleZ = Math.abs(Math.sin(scalingStep / 7));
      cylinder.scale.set(scaleX, scaleY, scaleZ);

      requestAnimationFrame(render);
      renderer.render(scene, camera);
    }

    function onResize() {
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
      renderer.setSize(window.innerWidth, window.innerHeight);
    }

    function onDocumentMouseDown(event) {
      let vector = new THREE.Vector3((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window.innerHeight) * 2 + 1, 0.5);
      vector = vector.unproject(camera); //将此向量(坐标)从相机的标准化设备坐标 (NDC) 空间投影到世界空间

      // 光线投射Raycaster 用于进行raycasting(光线投射)。光线投射用于进行鼠标拾取
      const raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
      const intersects = raycaster.intersectObjects([sphere, cylinder, cube]); //检测所有在射线与这些物体之间,包括或不包括后代的相交部分。
      if (intersects.length > 0) {
        console.log(intersects[0]);
        intersects[0].object.material.transparent = true; //未生效 ???
        intersects[0].object.material.opacity = 0.1;
      }
    }

    function onDocumentMouseMove(event) {
      if (controls.showRay) {
        let vector = new THREE.Vector3((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window.innerHeight) * 2 + 1, 0.5);
        vector = vector.unproject(camera);

        const raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
        const intersects = raycaster.intersectObjects([sphere, cylinder, cube]);
        if (intersects.length > 0) {
          const points = [];
          points.push(new THREE.Vector3(-30, 29.8, 30));
          points.push(intersects[0].point);

          const mat = new THREE.MeshBasicMaterial({ color: 0xff0000, transparent: true, opacity: 0.6 });
          const tubeGeometry = new THREE.TubeGeometry(new THREE.CatmullRomCurve3(points), 60, 0.001);

          if (tube) scene.remove(tube);

          if (controls.showRay) {
            tube = new THREE.Mesh(tubeGeometry, mat);
            scene.add(tube);
          }
        }
      }
    }
  }

  init();
</script>

TWEEN

<canvas id="mainCanvas"></canvas>
<script type="importmap">
  {
    "imports": {
      "three": "./js/build/three.module.js",
      "three/addons/": "./js/jsm/"
    }
  }
</script>
<script type="module">
  import * as THREE from "three";
  import { TrackballControls } from "three/addons/controls/TrackballControls.js";
  import { GUI } from "three/addons/libs/lil-gui.module.min.js";
  import * as TWEEN from "three/addons/libs/tween.module.js";
  import { PLYLoader } from "three/addons/loaders/PLYLoader.js";
  import { initRenderer, initPerspectiveCamera, initAmbientLight, initSpotLight } from "./init.js";

  function init() {
    const renderer = initRenderer("mainCanvas");

    const scene = new THREE.Scene();

    const camera = initPerspectiveCamera();
    scene.add(camera);

    const ambientLight = initAmbientLight();
    scene.add(ambientLight);

    const spotLight = initSpotLight();
    scene.add(spotLight);

    const posSrc = { pos: 1 };
    const tween = new TWEEN.Tween(posSrc).to({ pos: 0 }, 2000);
    tween.easing(TWEEN.Easing.Bounce.InOut);
    const tweenBack = new TWEEN.Tween(posSrc).to({ pos: 1 }, 2000);
    tweenBack.easing(TWEEN.Easing.Bounce.InOut);
    tweenBack.chain(tween);
    tween.chain(tweenBack);
    tween.start();

    let group;
    const loader = new PLYLoader();
    loader.load("./models/ply/ascii/dolphins.ply", function (geometry) {
      const origPosition = geometry.attributes["position"].clone();
      geometry.origPosition = origPosition;

      const material = new THREE.PointsMaterial({
        color: 0xffffff,
        size: 1,
        opacity: 0.6,
        transparent: true,
        blending: THREE.AdditiveBlending,
        depthWrite: false,
        map: generateSprite(),
      });
      group = new THREE.Points(geometry, material);
      group.scale.set(0.05, 0.05, 0.05);
      scene.add(group);
    });

    const trackballControls = new TrackballControls(camera, renderer.domElement);
    const clock = new THREE.Clock();

    render();

    function render() {
      trackballControls.update(clock.getDelta());

      TWEEN.update();

      if (typeof group != "undefined") {
        const positionArray = group.geometry.attributes["position"];
        const origPosition = group.geometry.origPosition;
        for (let i = 0; i < positionArray.count; i++) {
          const oldPosX = origPosition.getX(i);
          const oldPosY = origPosition.getY(i);
          const oldPosZ = origPosition.getZ(i);
          positionArray.setX(i, oldPosX * posSrc.pos);
          positionArray.setY(i, oldPosY * posSrc.pos);
          positionArray.setZ(i, oldPosZ * posSrc.pos);
        }
        positionArray.needsUpdate = true;
      }

      requestAnimationFrame(render);
      renderer.render(scene, camera);
    }
  }

  function generateSprite() {
    const canvas = document.createElement("canvas");
    canvas.width = 16;
    canvas.height = 16;
    const context = canvas.getContext("2d");

    const gradient = context.createRadialGradient(canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2);
    gradient.addColorStop(0, "rgba(255,255,255,1)");
    gradient.addColorStop(0.2, "rgba(0,255,255,1)");
    gradient.addColorStop(0.4, "rgba(0,0,64,1)");
    gradient.addColorStop(1, "rgba(0,0,0,1)");
    context.fillStyle = gradient;
    context.fillRect(0, 0, canvas.width, canvas.height);

    const texture = new THREE.Texture(canvas);
    texture.needsUpdate = true;
    return texture;
  }

  init();
</script>

 

标签:scene,动画,const,THREE,three,add,new,js
From: https://www.cnblogs.com/caroline2016/p/18208941

相关文章

  • three.js基础之Material
    MeshBasicMaterial<canvasid="mainCanvas"></canvas><scripttype="importmap">{"imports":{"three":"./js/build/three.module.js","three/addons/":"./js......
  • three.js之加载模型
    加载各种模型<canvasid="mainCanvas"></canvas><scripttype="importmap">{"imports":{"three":"./js/build/three.module.js","three/addons/":"./js/jsm/"......
  • three.js之Group
    Group<canvasid="mainCanvas"></canvas><scripttype="importmap">{"imports":{"three":"./js/build/three.module.js","three/addons/":"./js/jsm/"......
  • NodeJS-高性能编程-全-
    NodeJS高性能编程(全)原文:zh.annas-archive.org/md5/DF276329F6BD35B176ABE023A386AF47译者:飞龙协议:CCBY-NC-SA4.0前言在像Node.js这样的平台上实现高性能意味着要了解如何充分利用硬件的各个方面,并帮助内存管理发挥最佳作用,并正确决定如何设计复杂的应用程序。如果您的......
  • nodejs + express + mysql + redis 基础功能实现
    nodejs+express+mysql+redis基础功能实现yeyue  9人赞同了该文章本文大体介绍了nodejs项目的创建、express框架的使用、mysql数据库的连接、以及redis的数据交互等方法,并举例了些简单的例子进行说明,代码都是亲自重头跑了一遍的,拿来可用。 一、......
  • Meteor-JS-框架入门指南-全-
    MeteorJS框架入门指南(全)原文:zh.annas-archive.org/md5/A6A998711E02B953FECB90E097CD1168译者:飞龙协议:CCBY-NC-SA4.0序言我们生活在一个惊人的时代。医学、通信、物理以及所有其他科学领域的进步为我们提供了创建一些在短短一段时间前简直是无法创造的事物的机会。然......
  • IDocList/IDocDict JSON for Delphi and FPC
    IDocList/IDocDictJSONforDelphiandFPC【英文原文】多年来,我们的开源mORMot框架提供了多种方式,以处理在运行时定义的任何数组/对象文档组合,例如通过JSON,它具备许多功能,并且非常高的性能。我们的TDocVariant自定义变体类型是处理这类无模式数据的一种强大方式,但一些用户......
  • FullCalendar插件js原生用法
    1.先看下要实现的效果图,左侧栏为当日时间,顶部为部门所有人员,表格内容是人员事件,要求数据多的时候,左侧栏和顶部固定,支持横竖滚动条,如图:  2.这里用的js原生写法:<html><head><title>工作记录详情</title><metaname="decorator"content="default"/><s......
  • JSP九大内置对象详解
    *JSP九大内置对象详解*JSP内置对象(9个内置对象):1.PageContextjavax.servlet.jsp.PageContextJSP的页面容器2.requestjavax.servlet.http.HttpServletrequest获取用户的请求信息3.responsejavax.servlet.http.HttpServletResponse服务器向客户端的回应信息4.sessionj......
  • JSP九大内置对象
    JSP九大内置对象JSP提供了由容器实现和管理的内置对象,也可以称之为隐含对象,由于JSP使用Java作为脚本语言,所以JSP将具有强大的对象处理能力,并且可以动态创建Web页面内容。但Java语法在使用一个对象前,需要先实例化这个对象,这其实是一件比较烦琐的事情。JSP为了简化开发,提供了一些内......