国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

ThreeJS-3D教學三:平移縮放+物體沿軌跡運動

這篇具有很好參考價值的文章主要介紹了ThreeJS-3D教學三:平移縮放+物體沿軌跡運動。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

我們在項目中會有一些這樣的需求,我們可視化一個場景,需要俯視、平移、縮放,方便觀察場景中的數(shù)據(jù)或者模型,之所以把這個案例拿出來
1、這是個很實用的需求,我相信很多人會用到
2、我自己認為在實際案例中我們可以學習相關知識點更易吸收些
為了豐富本篇文章知識點,我還加入了一個物體沿軌跡運動的場景,下面代碼會介紹到,回到之前的問題three中可以利用對 OrbitControls 的設置很輕松的實現(xiàn)相關場景,代碼如下:

controls = new OrbitControls( camera, renderer.domElement );
  // 移動端控制平移 縮放
  // controls.touches = {
  //   ONE: THREE.TOUCH.PAN,
  //   TWO: THREE.TOUCH.DOLLY_PAN
  // };
  // PC 左平移,右旋轉(zhuǎn) 滾輪放大縮小   默認是右平移
  controls.mouseButtons = {
    LEFT: THREE.MOUSE.PAN,
    MIDDLE: THREE.MOUSE.DOLLY,
    RIGHT: THREE.MOUSE.ROTATE
  };
  // 設置最大最小視距
  controls.minDistance = 20;
  controls.maxDistance = 1000;
  controls.autoRotate = false;
  controls.enableRotate = false;
  controls.enablePan = true;

需要注意的是移動端和PC是不同的配置,minDistance和maxDistance按實際需求設置即可,到這一步只是對controls的操作,已經(jīng)有能力實現(xiàn)效果了,但是camera的設置也是不可或缺的,即camera必須是俯視的

先上下整體效果圖
threejs 模型平滑移動,three,3d,javascript,前端
看下代碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    body {
      width: 100%;
      height: 100%;
    }
    * {
      margin: 0;
      padding: 0;
    }
    .label {
      font-size: 20px;
      color: #000;
      font-weight: 700;
    }
  </style>
</head>
<body>
<div id="container"></div>
<script type="importmap">
  {
    "imports": {
      "three": "../three-155/build/three.module.js",
      "three/addons/": "../three-155/examples/jsm/"
    }
  }
</script>
<script type="module">
import * as THREE from 'three';
import Stats from 'three/addons/libs/stats.module.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';
let stats, labelRenderer, curve, movingObjects;
let camera, scene, renderer, mesBox, target, controls;
const group = new THREE.Group();
let progress = 0; // 物體運動時在運動路徑的初始位置,范圍0~1
const velocity = 0.0005; // 影響運動速率的一個值,范圍0~1,需要和渲染頻率結(jié)合計算才能得到真正的速率
let widthImg = 200;
let heightImg = 200;
init();
initHelp();
initLight();
axesHelperWord();
animate();
// 添加一個物體
mesBox = addGeometries();
// 添加平面
addPlane();
// 添加路徑
makeCurve();
// 添加一個運動的物體
movingObjects = addMovingObjects();


window.addEventListener('mousemove', mousemoveFun);

function addPlane() {
  // 創(chuàng)建一個平面 PlaneGeometry(width, height, widthSegments, heightSegments)
  const planeGeometry = new THREE.PlaneGeometry(widthImg, heightImg, 1, 1);
  // 創(chuàng)建 Lambert 材質(zhì):會對場景中的光源作出反應,但表現(xiàn)為暗淡,而不光亮。
  const planeMaterial = new THREE.MeshLambertMaterial({
    color: 0xffffff
  });
  const plane = new THREE.Mesh(planeGeometry, planeMaterial);
  // 以自身中心為旋轉(zhuǎn)軸,繞 x 軸順時針旋轉(zhuǎn) 45 度
  plane.rotation.x = -0.5 * Math.PI;
  plane.position.set(0, -4, 0);
  scene.add(plane);
}

function addGeometries() {
  let img = new THREE.TextureLoader().load('../materials/img/view4.jpg');
  img.repeat.x = img.repeat.y = 5;
  const geometry = new THREE.BoxGeometry( 10, 10, 10 );
  let material = new THREE.MeshPhongMaterial({
    map: img,
    flatShading: true,
    side: THREE.DoubleSide,
    transparent: 1
  });

  const mesh = new THREE.Mesh( geometry, material );
  mesh.position.x = 0;
  mesh.position.y = 0;
  mesh.position.z = -20;
  scene.add( mesh );
  return mesh;
}

function addMovingObjects() {
  let img = new THREE.TextureLoader().load('../materials/img/view3.jpg');
  const geometry = new THREE.BoxGeometry( 10, 10, 10 );
  const material = new THREE.MeshPhongMaterial({
    map: img,
    flatShading: true,
    side: THREE.DoubleSide,
    transparent: 1
  });
  const mesh = new THREE.Mesh( geometry, material );
  scene.add( mesh );
  return mesh;
}

function makeCurve() {
  // 創(chuàng)建一個環(huán)形路徑
  curve = new THREE.CatmullRomCurve3([
    new THREE.Vector3(80, 0, 80),
    new THREE.Vector3(80, 0, -80),
    new THREE.Vector3(-80, 0, -80),
    new THREE.Vector3(-80, 0, 80)
  ]);
  curve.curveType = "catmullrom";
  curve.closed = true;//設置是否閉環(huán)
  curve.tension = 0; //設置線的張力,0為無弧度折線

  // 為曲線添加材質(zhì)在場景中顯示出來,不顯示也不會影響運動軌跡,相當于一個Helper
  const points = curve.getPoints(20);
  const geometry = new THREE.BufferGeometry().setFromPoints(points);
  const material = new THREE.LineBasicMaterial({
    color: '#f00',
    linewidth: 1
  });

  // Create the final object to add to the scene
  const curveObject = new THREE.Line(geometry, material);
  curveObject.position.y = 1;
  curveObject.visible = false;
  scene.add(curveObject);
}

function mousemoveFun() {
  let width = widthImg;
  let height = heightImg;
  let newPo;
  let newPoHeight;

  const prevPos = camera.position.clone();

  if (camera.position['x'] > width / 2) {
    newPo = width / 2 - 0.01;
    camera.position.set(newPo, prevPos.y, prevPos.z);
    controls.target = new THREE.Vector3(newPo, 0, prevPos.z);
    controls.enablePan = false;
  } else if (camera.position['x'] < -width / 2) {
    newPo = -width / 2 + 0.01;
    camera.position.set(newPo, prevPos.y, prevPos.z);
    controls.target = new THREE.Vector3(newPo, 0, prevPos.z);
    controls.enablePan = false;
  } else if (camera.position['z'] > height / 2) {
    // 因為我們的坐標系 y軸在上 所以平移時 height 即是 z
    newPoHeight = height / 2 - 0.01;
    camera.position.set(prevPos.x, prevPos.y, newPoHeight);
    controls.target = new THREE.Vector3(prevPos.x, 0, newPoHeight);
    controls.enablePan = false;
  } else if (camera.position['z'] < -height / 2) {
    newPoHeight = -height / 2 + 0.01;
    camera.position.set(prevPos.x, prevPos.y, newPoHeight);
    controls.target = new THREE.Vector3(prevPos.x, 0, newPoHeight);
    controls.enablePan = false;
  } else {
    controls.enablePan = true;
  }
}

function init() {

  camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 10, 2000 );
  camera.up.set(0, 1, 0);
  camera.position.set(0, 100, 0);
  camera.lookAt(0, 0, 0);

  scene = new THREE.Scene();
  // scene.background = new THREE.Color( '#ccc' );

  renderer = new THREE.WebGLRenderer( { antialias: true } );
  renderer.setPixelRatio( window.devicePixelRatio );
  renderer.setSize( window.innerWidth, window.innerHeight );
  document.body.appendChild( renderer.domElement );

  labelRenderer = new CSS2DRenderer();
  labelRenderer.setSize( window.innerWidth, window.innerHeight );
  labelRenderer.domElement.style.position = 'absolute';
  labelRenderer.domElement.style.top = '0px';
  labelRenderer.domElement.style.pointerEvents = 'none';
  document.getElementById( 'container' ).appendChild( labelRenderer.domElement );

  controls = new OrbitControls( camera, renderer.domElement );
  // 移動端控制平移 縮放
  // controls.touches = {
  //   ONE: THREE.TOUCH.PAN,
  //   TWO: THREE.TOUCH.DOLLY_PAN
  // };
  // PC 左平移,右旋轉(zhuǎn) 滾輪放大縮小   默認是右平移
  controls.mouseButtons = {
    LEFT: THREE.MOUSE.PAN,
    MIDDLE: THREE.MOUSE.DOLLY,
    RIGHT: THREE.MOUSE.ROTATE
  };
  // 設置最大最小視距
  controls.minDistance = 20;
  controls.maxDistance = 1000;
  controls.autoRotate = false;
  controls.enableRotate = false;
  controls.enablePan = true;

  window.addEventListener( 'resize', onWindowResize );

  stats = new Stats();
  stats.setMode(1); // 0: fps, 1: ms
  document.body.appendChild( stats.dom );

  scene.add( group );
}

function initLight() {
  let spotLight;
  spotLight = new THREE.SpotLight( 0xffffff, 500 );
  spotLight.name = 'Spot Light';
  spotLight.angle = Math.PI / 5;
  spotLight.penumbra = 0.1;
  spotLight.position.set( 0, 5, 10 );
  spotLight.castShadow = true;
  spotLight.shadow.camera.near = 2;
  spotLight.shadow.camera.far = 100;
  spotLight.shadow.mapSize.width = 1024;
  spotLight.shadow.mapSize.height = 1024;
  scene.add( spotLight );

  const AmbientLight = new THREE.AmbientLight(0xCCCCCC, 2);
  scene.add( AmbientLight );
}

function initHelp() {
  // const size = 100;
  // const divisions = 5;
  // const gridHelper = new THREE.GridHelper( size, divisions );
  // scene.add( gridHelper );

  // The X axis is red. The Y axis is green. The Z axis is blue.
  const axesHelper = new THREE.AxesHelper( 100 );
  scene.add( axesHelper );
}

function axesHelperWord() {
  let xP = addWord('X軸');
  let yP = addWord('Y軸');
  let zP = addWord('Z軸');
  xP.position.set(50, 0, 0);
  yP.position.set(0, 50, 0);
  zP.position.set(0, 0, 50);
}

function addWord(word) {
  let name = `<span>${word}</span>`;
  let moonDiv = document.createElement( 'div' );
  moonDiv.className = 'label';
  // moonDiv.textContent = 'Moon';
  // moonDiv.style.marginTop = '-1em';
  moonDiv.innerHTML = name;
  const label = new CSS2DObject( moonDiv );
  group.add( label );
  return label;
}

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

function animate() {
  requestAnimationFrame( animate );

  // mesh繞自身中心的 y 軸自轉(zhuǎn)
  if (mesBox) {
    mesBox.rotation.y += 0.01;
  }

  if (curve && movingObjects) {
    if (progress <= 1 - velocity) {
      // 獲取樣條曲線指定點坐標
      const point = curve.getPointAt(progress);
      movingObjects.position.set(point.x, point.y, point.z);
      progress += velocity;
    } else {
      progress = 0;
    }
  }

  stats.update();
  controls.update();
  labelRenderer.render( scene, camera );
  renderer.render( scene, camera );
}
</script>
</body>
</html>

這里是全部代碼,可以看出 three用的是 155版本,大家從官網(wǎng)上下載到本地改下路徑即可。圖片url你可以換成本地圖片,項目就能跑起來了。

中間立方體在做了一個環(huán)繞自身y軸旋轉(zhuǎn),外面的立方體通過獲取curve上的坐標點,沿著curve的軌跡運動。

這里有一些新的知識點:

new THREE.TextureLoader().load(‘…/materials/img/view3.jpg’);
TextureLoader是three加載圖片的方法,我們還可以這樣用
let loader = new THREE.TextureLoader();
loader.load(‘url’, (img) => {
// img 這個img就是加載完成后的圖片
});

這時就一個疑問了,同步還是異步,我們來看源碼
threejs 模型平滑移動,three,3d,javascript,前端
其實還是異步,拿到圖片后我們發(fā)現(xiàn)material有一個map參數(shù),可以接收圖片作為材質(zhì),這樣material就可以做的很豐富了,side是指物體的正反兩面,THREE.DoubleSide即兩面都要渲染,如果我們只看外面,不要設置這里,這樣也能節(jié)省一些性能

 let material = new THREE.MeshPhongMaterial({
    map: img,
    flatShading: true,
    side: THREE.DoubleSide,
    transparent: 1
  });

最后一個知識點,即物體沿著軌跡運動,我們把這一行代碼
curveObject.visible = false; 改為 true 大家就可以看到這個軌跡了。
邏輯代碼中已經(jīng)寫的很詳細了,大家也可以思考下還有哪些方法可以作為curve使用。
如果感覺有用,點個贊不過分吧?。?!文章來源地址http://www.zghlxwxcb.cn/news/detail-771650.html

到了這里,關于ThreeJS-3D教學三:平移縮放+物體沿軌跡運動的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • ThreeJS-3D教學一:基礎場景創(chuàng)建

    ThreeJS-3D教學一:基礎場景創(chuàng)建

    Three.js 是一個開源的 JS 3D 圖形庫,用于創(chuàng)建和展示高性能、交互式的 3D 圖形場景。它建立在 WebGL 技術之上,并提供了豐富的功能和工具,使開發(fā)者可以輕松地構建令人驚嘆的 3D 可視化效果。 Three.js 提供了一套完整的工具和 API,用于創(chuàng)建和管理 3D 場景、幾何體、紋理、光照

    2024年02月07日
    瀏覽(24)
  • ThreeJS-3D教學十-有寬度的line

    ThreeJS-3D教學十-有寬度的line

    webgl中線是沒有寬度的,現(xiàn)實的應用中一般做法都是將線拓寬成面來繪制。默認threejs的線寬是無法調(diào)節(jié)的,需要用有厚度的線 THREE.Line2。 先看效果圖: 看下代碼:

    2024年02月07日
    瀏覽(23)
  • ThreeJS-3D教學八-OBJLoader模型加載+動畫

    ThreeJS-3D教學八-OBJLoader模型加載+動畫

    先看效果圖: 本篇給大家介紹下模型加載的知識,用到了OBJLoader對應的模型,為了增加趣味性,花了些時間,利用new THREE.Points獲取到模型上的點,做了一個動畫效果,其實就是操作 Y軸上的點,先降低上0,然后再還原,代碼如下: 如果有同學從我第一篇文章開始學到現(xiàn)在,

    2024年04月24日
    瀏覽(21)
  • ThreeJS-3D教學十一:屏幕坐標和世界坐標轉(zhuǎn)換

    ThreeJS-3D教學十一:屏幕坐標和世界坐標轉(zhuǎn)換

    直接復制上面的代碼,將three資源路徑修改后,啟動即可看到效果 上面是代碼實現(xiàn),以下我們看下一些理論知識點: 坐標系之間的轉(zhuǎn)換關系大致為: 因此坐標轉(zhuǎn)換過程就變成了: 原本世界坐標轉(zhuǎn)換到觀察空間坐標需要乘上視圖矩陣 CameraMatrixWorldInverse(ViewMatrix) 隨后,觀察空

    2024年01月17日
    瀏覽(20)
  • Unity3D根據(jù)物體運動畫出實體軌跡線

    Unity3D根據(jù)物體運動畫出實體軌跡線

    在Unity3D根據(jù)物體運動畫出實體軌跡線 在Inspector里面添加組件LineRender,線條圓滑設置如下, 顏色可以新建材質(zhì)直接拖上該物體上就行。 添加腳本LineMark 將上面的Line放在OBS里面,對應需要畫出的物體直接拖入右側(cè)的 — 小技巧:想畫出對應階段的軌跡曲線可以通過啟用和不啟

    2024年02月12日
    瀏覽(97)
  • ThreeJS-縮放、旋轉(zhuǎn)(四)

    ThreeJS-縮放、旋轉(zhuǎn)(四)

    代碼: template ? div id=\\\"three_div\\\" ? /div /template ? script import * as THREE from \\\"three\\\"; import {OrbitControls } from \\\'three/examples/jsm/controls/OrbitControls\\\' export default { ? name: \\\"HOME\\\", ? components: { ? ? // vueQr, ? ? // glHome, ? }, ? data() { ? ? return { ? ? }; ? }, ? mounted() { ? ? //使用控制器控制3D拖動旋轉(zhuǎn)

    2024年02月08日
    瀏覽(27)
  • threejs(6)-操控物體實現(xiàn)家居編輯器
  • Threejs入門之三:讓物體跟隨鼠標動起來

    Threejs入門之三:讓物體跟隨鼠標動起來

    上一節(jié)我們創(chuàng)建了一個三維的立方體,將其放在了瀏覽器窗口中,但是目前來講它只是一個靜態(tài)的圖片,我們并不能通過鼠標控制其旋轉(zhuǎn)、縮放和移動,這一節(jié)我們來實現(xiàn)用鼠標控制物體的運動。 首先我們要了解一個概念,在三維場景中,我們要控制物體旋轉(zhuǎn),實際上不是物

    2024年02月11日
    瀏覽(42)
  • Threejs開發(fā)3D展館 | 大帥老猿threejs特訓

    Threejs開發(fā)3D展館 | 大帥老猿threejs特訓

    本文將介紹如果使用Threejs開發(fā)制作一個3D展館,效果如圖: ?首先,我們需要一個展館模型。我是通過Blender做出來的,在Blender中將模型導出為glb格式。 接下來,我們通過代碼將模型加載到網(wǎng)頁中。 在3D圖形開發(fā)中,最基本的概念就是場景、相機和光源。這三個是構成3D世界

    2024年02月11日
    瀏覽(17)
  • Threejs 3D模型居中

    項目開發(fā)中難免會遇到客戶導出的3D模型中心點并不在坐標中心,這時候直接渲染這個模型會發(fā)現(xiàn)模型位置會有所偏移 引用:Three.js模型居中

    2024年02月13日
    瀏覽(17)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包