threejs 360房间的学习

2023-03-29  本文已影响0人  squidbrother

操作流程学习

准备的基本知识

  1. 360房间的制作

立方体屋子的具体操作:

const textures = cubeTextureLoader.load([
  '/textures/px.jpg',
  '/textures/nx.jpg',
  '/textures/py.jpg',
  '/textures/ny.jpg',
  '/textures/pz.jpg',
  '/textures/nz.jpg'
]);

const materials = [];
for ( let i = 0; i < 6; i ++ ) {
  materials.push( new THREE.MeshBasicMaterial( { map: textures[ i ] } ) );
}
const skyBox = new THREE.Mesh( new THREE.BoxGeometry( 1, 1, 1 ), materials );
skyBox.geometry.scale( 1, 1, - 1 );
scene.add( skyBox );

球体360屋子的具体操作:

const geometry = new THREE.SphereGeometry(16, 256, 256);
const material = new THREE.MeshBasicMaterial({
  map: textLoader.load('全景图片地址'),
  //-- 球体内外均显示
  side: THREE.DoubleSide,
});
//-- 放大球体,让摄像机进入球体内部
geometry.scale(1, 1, -1);
const room = new THREE.Mesh(geometry, material);
  1. 房间展示的信息点,使用Sprite来实现
  1. 三维房间信息点,与鼠标实现交互
let raycaster = new THREE.Raycaster();
let mouse = new THREE.Vector2();
mouse.x = (e.clientX / element.clientWidth) * 2 - 1;
mouse.y = -(e.clientY / element.clientHeight) * 2 + 1;
raycaster.setFromCamera(mouse, this.camera);
//-- 鼠标与照相机连线去穿透的对象集合,有几个穿透几个
let intersects = raycaster.intersectObjects(创建信息点的对象数组, true);
if (intersects.length > 0) {
    //--- 第1个被穿透,也就是纵深方向上,离你鼠标最近的对象
        console.log(intersects[0].object);
}

实现方式的不同

同一个房间,换肤切换房间

学习帖子地址 - https://juejin.cn/post/7047709128600322056#heading-1

  1. 创建一个场景,添加一个mash作为房间,仅通过更换mash的材质贴图来模拟房间的切换;
//-- 替换场景360材质图 - 开始
let texture = new THREE.TextureLoader().load('360图片链接');
let sphereMaterial = new THREE.MeshBasicMaterial({
    map: texture,
    transparent: true,
    //设置默认透明 -- 为后续切换房间场景过渡做准备,防止黑屏生硬
    opacity: 0,
});
//-- 修改房屋mash的材质
this.sphere.material = sphereMaterial;
  1. 房间场景切的换过渡
import gsap from "gsap";
...
//-- 针对房间新的360材质图,缓动透明从0 到 1
gsap.to(sphereMaterial, { transparent: true, opacity: 1, duration: 2 });
  1. 标记点的添加与移除
this.scene.children = this.scene.children.filter(
        (item) => String(item.type) !== "Sprite"
);
//-- 创建标记点材质
let tipTexture = new THREE.TextureLoader().load(
    require("@/assets/image/tip.png")
);
let material = new THREE.SpriteMaterial({ map: tipTexture });
//-- 添加一个带材质的
let sprite = new THREE.Sprite(material);
sprite.scale.set(xx, xx, xx);
sprite.position.set(坐标x, 坐标y, 坐标z);
sprite.content = xxxx;
this.scene.add(sprite)
  1. 鼠标滑过移除信息点,显示隐藏信息的方式
真不同房间切换

学习帖子地址 - https://juejin.cn/post/7215268204062490679

  1. 创建一个场景,添加多个mash作为房间,有各自贴图,在不同的sence坐标位置,各自看不见;
const createRoom = (name, position, map) => {
  const geometry = new THREE.SphereGeometry(16, 256, 256);
  geometry.scale(1, 1, -1);
  const material = new THREE.MeshBasicMaterial({
    map: textLoader.load(map),
    side: THREE.DoubleSide,
  });
  const room = new THREE.Mesh(geometry, material);
  room.name = name;
  room.position.set(position.x, position.y, position.z);
  room.rotation.y = Math.PI / 2;
  scene.add(room);
  return room;
};

// 批量创建
rooms.map((item) => {
  const room = createRoom(item.key, item.position, item.map);
  return room;
});
  1. 房间场景切的换过渡,通过操作摄像机移动实现,移动过程中使用了tween库
// 点击切换场景
const handleSwitchButtonClick = async (key) => {
  const room = rooms.filter((item) => item.key === key)[0];
  if (data.camera) {
    const x = room.position.x;
    const y = room.position.y;
    const z = room.position.z;
    //-- 获取房间坐标信息,移动摄像机(缓动方式)
    Animations.animateCamera(data.camera, data.controls, { x, y, z: data.cameraZAxis }, { x, y, z }, 1600, () => {});
    data.controls.update();
  }
}
  1. 缓动库 - 缓动动画修改摄像机位置,更新摄像机,更新轨道控制器
import { TWEEN } from 'three/examples/jsm/libs/tween.module.min.js';

const Animations = {
  // 相机移动实现漫游等动画
  animateCamera: (camera, controls, newP, newT, time = 2000, callBack) => {
    const tween = new TWEEN.Tween({
      x1: camera.position.x, // 相机x
      y1: camera.position.y, // 相机y
      z1: camera.position.z, // 相机z
      x2: controls.target.x, // 控制点的中心点x
      y2: controls.target.y, // 控制点的中心点y
      z2: controls.target.z, // 控制点的中心点z
    });
    tween.to(
      {
        x1: newP.x,
        y1: newP.y,
        z1: newP.z,
        x2: newT.x,
        y2: newT.y,
        z2: newT.z,
      },
      time,
    );
    tween.onUpdate(function (object) {
      camera.position.x = object.x1;
      camera.position.y = object.y1;
      camera.position.z = object.z1;
      controls.target.x = object.x2;
      controls.target.y = object.y2;
      controls.target.z = object.z2;
      controls.update();
    });
    tween.onComplete(function () {
      controls.enabled = true;
      controls.update();
      callBack();
    });
    tween.easing(TWEEN.Easing.Cubic.InOut);
    tween.start();
  },
};
export default Animations;
上一篇 下一篇

猜你喜欢

热点阅读