首页 > 其他分享 >Three.js#04#Responsive Design&Scenegraph

Three.js#04#Responsive Design&Scenegraph

时间:2023-05-02 12:01:11浏览次数:40  
标签:bezierCurveTo const 04 THREE Three shape new js 2.5

参考https://threejs.org/manual/#en/responsive和https://threejs.org/manual/#en/scenegraph

前者主要是说怎样创建一个响应式的three.js应用,就是在变化屏幕大小的时候,画面不会畸形。后者是再说,怎么组合小的组件变成一个大的组件(依赖于一个空组件object3D)

下面是示例代码:

index.html

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8">
		<title>My first three.js app</title>
		<style>
			html, body {
			   margin: 0;
			   height: 100%;
			}
			#c {
			   width: 100%;
			   height: 100%;
			   display: block;
			}
		</style>
	</head>
	<body>
		<script type="module" src="/main.js"></script>
		<canvas id="c"></canvas>
		<div id="info"></div>
	</body>
</html>

main.js

import * as THREE from 'three';
import {FontLoader} from 'three/addons/loaders/FontLoader.js';
import {TextGeometry} from 'three/addons/geometries/TextGeometry.js';

function main() {
  const canvas = document.querySelector('#c');
  const renderer = new THREE.WebGLRenderer({antialias: true, canvas});

  const fov = 40;
  const aspect = 2;  // the canvas default
  const near = 0.1;
  const far = 1000;
  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  camera.position.z = 120;

  const scene = new THREE.Scene();
  scene.background = new THREE.Color('white');

  {
    const color = 0xFFFFFF;
    const intensity = 1;
    const light = new THREE.DirectionalLight(color, intensity);
    light.position.set(-1, 2, 4);
    scene.add(light);
  }
  {
    const color = 0xFFFFFF;
    const intensity = 1;
    const light = new THREE.DirectionalLight(color, intensity);
    light.position.set(1, -2, -4);
    scene.add(light);
  }

  const objects = [];
  const spread = 15;

  function addObject(x, y, obj) {
    obj.position.x = x * spread;
    obj.position.y = y * spread;

    scene.add(obj);
    objects.push(obj);
  }

  const myObjs = new Map();

  function addMyObj(x, y, obj, objName) {
    obj.position.x = x * spread;
    obj.position.y = y * spread;   
    
    // scene.add(obj);

    myObjs.set(objName, obj)
  }

  function makeObject3D(x, y, objName) {
    const obj3D = new THREE.Object3D();
    obj3D.position.x = x * spread;
    obj3D.position.y = y * spread;   

    myObjs.set(objName, obj3D)
    scene.add(obj3D);
  }

  function getObj(objName) {
    return myObjs.get(objName)
  }

  function createMaterial() {
    const material = new THREE.MeshPhongMaterial({
      side: THREE.DoubleSide,
    });

    const hue = Math.random();
    const saturation = 1;
    const luminance = .5;
    material.color.setHSL(hue, saturation, luminance);

    return material;
  }

  function addSolidGeometry(x, y, geometry) {
    const mesh = new THREE.Mesh(geometry, createMaterial());
    addObject(x, y, mesh);
  }

  function addMySolidGeometry(x, y, geometry, objName) {
    const mesh = new THREE.Mesh(geometry, createMaterial());
    addMyObj(x, y, mesh, objName);
  }

  function addLineGeometry(x, y, geometry) {
    const material = new THREE.LineBasicMaterial({color: 0x000000});
    const mesh = new THREE.LineSegments(geometry, material);
    addObject(x, y, mesh);
  }

  {
    const width = 9;
    const height = 9;
    const widthSegments = 2;
    const heightSegments = 2;
    addSolidGeometry(-5.5, 2, new THREE.PlaneGeometry(width, height, widthSegments, heightSegments));
  }
  {
    const shape = new THREE.Shape();
    const x = -2.5;
    const y = -5;
    shape.moveTo(x + 2.5, y + 2.5);
    shape.bezierCurveTo(x + 2.5, y + 2.5, x + 2, y, x, y);
    shape.bezierCurveTo(x - 3, y, x - 3, y + 3.5, x - 3, y + 3.5);
    shape.bezierCurveTo(x - 3, y + 5.5, x - 1.5, y + 7.7, x + 2.5, y + 9.5);
    shape.bezierCurveTo(x + 6, y + 7.7, x + 8, y + 4.5, x + 8, y + 3.5);
    shape.bezierCurveTo(x + 8, y + 3.5, x + 8, y, x + 5, y);
    shape.bezierCurveTo(x + 3.5, y, x + 2.5, y + 2.5, x + 2.5, y + 2.5);
    addSolidGeometry(-4.5, 2, new THREE.ShapeGeometry(shape));
  }
  {
    const radius = 7;
    const widthSegments = 12;
    const heightSegments = 8;
    addSolidGeometry(-3.5, 2, new THREE.SphereGeometry(radius, widthSegments, heightSegments));
  }
  {
    const loader = new FontLoader();
    // promisify font loading
    function loadFont(url) {
      return new Promise((resolve, reject) => {
        loader.load(url, resolve, undefined, reject);
      });
    }

    async function doit() {
      const font = await loadFont('helvetiker_regular.typeface.json');  
      const geometry = new TextGeometry('three.js', {
        font: font,
        size: 3.0,
        height: .2,
        curveSegments: 12,
        bevelEnabled: true,
        bevelThickness: 0.15,
        bevelSize: .3,
        bevelSegments: 5,
      });
      const mesh = new THREE.Mesh(geometry, createMaterial());
      geometry.computeBoundingBox();
      geometry.boundingBox.getCenter(mesh.position).multiplyScalar(-1);

      const parent = new THREE.Object3D();
      parent.add(mesh);

      addObject(-2.5, 2, parent);
    }
    doit();
  }
  {
    const radius = 3.5;
    const tube = 1.5;
    const radialSegments = 8;
    const tubularSegments = 64;
    const p = 2;
    const q = 3;
    addSolidGeometry(-1.5, 2, new THREE.TorusKnotGeometry(radius, tube, tubularSegments, radialSegments, p, q));
  }
  {
    const width = 8;
    const height = 8;
    const depth = 8;
    const thresholdAngle = 15;
    addLineGeometry(-0.5, 2, new THREE.EdgesGeometry(
        new THREE.BoxGeometry(width, height, depth),
        thresholdAngle));
  }
  {
    const width = 8;
    const height = 8;
    const depth = 8;
    addLineGeometry(0.5, 2, new THREE.WireframeGeometry(new THREE.BoxGeometry(width, height, depth)));
  }

  {
    makeObject3D(0, 0, 'system')
  }
  
  {
    const objName = 'ground'
    const width = 159;
    const height = 159;
    const widthSegments = 2;
    const heightSegments = 2;
    addMySolidGeometry(0, -1, new THREE.PlaneGeometry(width, height, widthSegments, heightSegments), objName);      

    const ground = getObj(objName)
    ground.rotation.x = Math.PI * -.5;
    const system = getObj('system')
    system.add(ground)
  }
  // const groundGeometry = new THREE.PlaneGeometry(50, 50);
  // const groundMaterial = new THREE.MeshPhongMaterial({color: 0xCC8866});
  // const groundMesh = new THREE.Mesh(groundGeometry, groundMaterial);
  // groundMesh.rotation.x = Math.PI * -.5;
  // groundMesh.receiveShadow = true;
  // scene.add(groundMesh);
  {
    const objName = 'player1'
    const shape = new THREE.Shape();
    const x = -2.5;
    const y = -5;
    shape.moveTo(x + 2.5, y + 2.5);
    shape.bezierCurveTo(x + 2.5, y + 2.5, x + 2, y, x, y);
    shape.bezierCurveTo(x - 3, y, x - 3, y + 3.5, x - 3, y + 3.5);
    shape.bezierCurveTo(x - 3, y + 5.5, x - 1.5, y + 7.7, x + 2.5, y + 9.5);
    shape.bezierCurveTo(x + 6, y + 7.7, x + 8, y + 4.5, x + 8, y + 3.5);
    shape.bezierCurveTo(x + 8, y + 3.5, x + 8, y, x + 5, y);
    shape.bezierCurveTo(x + 3.5, y, x + 2.5, y + 2.5, x + 2.5, y + 2.5);
    addMySolidGeometry(-5, -0.5, new THREE.ShapeGeometry(shape), objName);

    const player1 = getObj(objName)
    const system = getObj('system')
    system.add(player1)
  }

  {
    const objName = 'player2'
    const shape = new THREE.Shape();
    const x = -2.5;
    const y = -5;
    shape.moveTo(x + 2.5, y + 2.5);
    shape.bezierCurveTo(x + 2.5, y + 2.5, x + 2, y, x, y);
    shape.bezierCurveTo(x - 3, y, x - 3, y + 3.5, x - 3, y + 3.5);
    shape.bezierCurveTo(x - 3, y + 5.5, x - 1.5, y + 7.7, x + 2.5, y + 9.5);
    shape.bezierCurveTo(x + 6, y + 7.7, x + 8, y + 4.5, x + 8, y + 3.5);
    shape.bezierCurveTo(x + 8, y + 3.5, x + 8, y, x + 5, y);
    shape.bezierCurveTo(x + 3.5, y, x + 2.5, y + 2.5, x + 2.5, y + 2.5);
    addMySolidGeometry(5, -0.5, new THREE.ShapeGeometry(shape), objName);

    const player2 = getObj(objName)
    player2.rotation.x = Math.PI * -1;
    const system = getObj('system')
    system.add(player2)
  }

  function resizeRendererToDisplaySize(renderer) {
    const canvas = renderer.domElement;
    const width = canvas.clientWidth;
    const height = canvas.clientHeight;
    const needResize = canvas.width !== width || canvas.height !== height;
    if (needResize) {
      renderer.setSize(width, height, false);
    }
    return needResize;
  }

  function render(time) {
    time *= 0.001;

    if (resizeRendererToDisplaySize(renderer)) {
      const canvas = renderer.domElement;
      camera.aspect = canvas.clientWidth / canvas.clientHeight;
      camera.updateProjectionMatrix();
    }

    objects.forEach((obj, ndx) => {
      const speed = .1 + ndx * .05;
      const rot = time * speed;
      obj.rotation.x = rot;
      obj.rotation.y = rot;
    });

    const system = getObj('system')
    system.rotation.y = time * 0.05;

    const player1 = getObj('player1')
    player1.rotation.x = time * 0.5
    player1.rotation.y = time * 0.5
    player1.position.x += 0.01

    const player2 = getObj('player2')
    player2.rotation.x = time * 0.5
    player2.rotation.y = time * 0.5
    player2.position.x -= 0.01

    renderer.render(scene, camera);

    requestAnimationFrame(render);
  }

  requestAnimationFrame(render);
}

main();

下一步应该是,怎样面向对象开发three.js应用,如何去模块化。

 

标签:bezierCurveTo,const,04,THREE,Three,shape,new,js,2.5
From: https://www.cnblogs.com/xkxf/p/17367512.html

相关文章

  • 04 BTC-实现
    《区块链技术与应用》课程链接:https://www.bilibili.com/video/BV1Vt411X7JF/?spm_id_from=333.337.search-card.all.click04BTC-实现目录04BTC-实现比特币系统是transaction-basedledgerUTXO:UpsentTransactionOutputUTXO中的元素需要给出它所在交易的哈希值,以及它是......
  • ngxin 配置 二级目录使用nodejs处理
    ngxin配置location/napi{proxy_passhttp://127.0.0.1:7018;proxy_set_headerHost$host:$server_port;proxy_set_headerX-Real-IP$remote_addr;proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;proxy_set_h......
  • 04 Docker内容补充
    第四章Docker内容补充目录第四章Docker内容补充0总结1迁移与备份1.0总结1.1容器保存为镜像1.2把镜像打包成压缩包1.3把压缩包恢复为镜像2Dockerfile【重要】2.1Dockerflie是什么?2.2Dockerfile指令:2.3写一个Dockerfile3docker-compose0总结1介绍docker -docker......
  • COM3504/COM6504 智能网络
    COM3504COM3504/COM6504TheIntelligentWebAssignment2022-2023Deadline:Fri,19May20233pmHandin:zipfileviaBlackboard(seeSection8-Submissions).1.IntroductionThisassignmentwilltestyourabilitytocreateawebapplicationusingthemet......
  • 将ansible的输出转换为JSON格式
    第一步找到ansible.cfg我的ansible.cfg的文件在/etc/ansible文件夹的下面。可以使用Linux命令行进行切换到这个文件夹下面。cd/etc/ansible第二步,修改ansible.cfg文件,在配置文件中添加以下的配置。[defaults]stdout_callback=jsonbin_ansible_callbacks=True ......
  • js 复制/转换 window对象的全部属性内容 为字符串
    控制台copy(window)不行,只得到[objectWindow]copy(object) copiesastringrepresentation至于具体是怎么实现的嘛,猜测类似于.toString() ofthespecifiedobjecttotheclipboard.(参考https://developer.chrome.com/docs/devtools/console/utilities/#copy-function) co......
  • Ubuntu18.04 VMwareTools安装方法
    一、VMwareTools的一些实用性安装后用户可以从物理主机直接往虚拟机里面拖文件。安装后鼠标进入虚拟机后可以直接出来,不安装的话要按CTRL+ALT才可以释放鼠标。安装后可以解决Ubuntu主窗口分辨率不适应问题,用户可以随意改变虚拟机窗口大小,vmtools会自动帮你改成适当的分辨率。二、......
  • Vue.js 简介与入门指南
    Vue.js是一个轻量级的JavaScript框架,用于构建交互式的用户界面。Vue.js的核心是一个用于构建组件化应用的视图层库,它易于上手,且能够快速地构建出高效、灵活、易于维护的应用程序。Vue.js受到了许多开发者的欢迎,因为它允许使用简单的HTML模板来创建可重用的组件,这些组件可以......
  • JSX语法介绍
    title:02-JSX语法介绍publish:trueJSX介绍JSX的引入如果直接让用户通过JS代码手动创建DOM元素,肯定是非常麻烦的。于是,React官方就提出了一套JSX语法规范,能够让我们在JS文件中,书写类似于HTML那样的代码,快速定义虚拟DOM结构。JSX的全称JSX:JavaScriptXML,一种类......
  • json字符串的解析和遍历
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><metahttp-equiv="X-UA-Compati......