,

ThreeJS全景看房相关封装

房间几何体 位置Sprite 信息提示Sprite

房间几何体

import * as THREE from "three";

export class Room { 
  constructor(
    public name: string,
    public roomPrefix: string,
    public textureUrl: string,
    public scene: THREE.Scene = new THREE.Scene(),
    public position: THREE.Vector3 = new THREE.Vector3(0, 0, 0),
    public euler: THREE.Euler = new THREE.Euler(0, 0, 0),
  ) { 

    // 创建立方体
    const geometry = new THREE.BoxGeometry(10, 10, 10);
    geometry.scale(1, 1, -1);

    const arr = [
      `${roomPrefix}_r`,
      `${roomPrefix}_l`,
      `${roomPrefix}_u`,
      `${roomPrefix}_d`,
      `${roomPrefix}_f`,
      `${roomPrefix}_b`,
    ];
    const boxMaterials: THREE.MeshBasicMaterial[] = [];

    arr.forEach((item) => { 
      const texture = new THREE.TextureLoader().load(
        textureUrl + item + ".jpg"
      );
      boxMaterials.push(new THREE.MeshBasicMaterial({ map: texture }));
    })

    const box = new THREE.Mesh(geometry, boxMaterials);
    box.position.copy(position);
    box.rotation.copy(euler);
    scene.add(box);
  }
}

位置Sprite

import * as THREE from "three";

export class PositionSprite {
  sprite: THREE.Sprite;
  callbacks: any[];
  constructor(
    text: string,
    position: THREE.Vector3,
    scene: THREE.Scene,
    camera: THREE.Camera
  ) {
    this.callbacks = [];

    // 定义canvas
    const canvas = document.createElement("canvas");
    canvas.width = 1024;
    canvas.height = 1024;
    const context = canvas.getContext("2d")!;
    context.fillStyle = "rgba(100,100,100,.7)";
    context.fillRect(0, 256, canvas.width, canvas.height / 2);
    context.textAlign = "center";
    context.textBaseline = "middle";
    context.font = "bold 200px Arial";
    context.fillStyle = "white";
    context.fillText(text, canvas.width / 2, canvas.height / 2);

    const texture = new THREE.CanvasTexture(canvas);
    const material = new THREE.SpriteMaterial({
      map: texture,
      transparent: true,
    })

    const sprite = new THREE.Sprite(material);
    sprite.position.copy(position);
    this.sprite = sprite;
    scene.add(sprite);

    let pointer = new THREE.Vector2();
    let raycaster = new THREE.Raycaster();
    window.addEventListener('click', (event: MouseEvent) => { 
      pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
      pointer.y = -(event.clientY / window.innerHeight) * 2 + 1;
      raycaster.setFromCamera(pointer, camera);
      const intersects = raycaster.intersectObject(sprite);
      if (intersects.length > 0) { 
        // 触发回调
        this.callbacks.forEach((callback) => {
          callback();
        })
      }
    })
  }
  onClick(callback: () => void) {
    this.callbacks.push(callback);
  }
}

信息提示Sprite

import * as THREE from "three";

export class TooltipSprite { 
  sprite: THREE.Sprite;
  constructor(
    public url: string,
    public position: THREE.Vector3,
    public scene: THREE.Scene,
    public camera: THREE.Camera,
    public userData: Record<string, any> = {}
  ) { 
    const tooltipTexture = new THREE.TextureLoader().load(url);
    const tooltipMaterial = new THREE.SpriteMaterial({
      map: tooltipTexture,
      transparent: true,
    });

    const tooltipSprite = new THREE.Sprite(tooltipMaterial);
    tooltipSprite.position.copy(position);
    tooltipSprite.scale.set(0.2, 0.2, 0.2);
    tooltipSprite.userData = userData;
    this.sprite = tooltipSprite;
    scene.add(tooltipSprite);
  }
}

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

About the Author

每个人都有自己得时区,在自己得时区里,一切都是准时的。

BlockSpare — News, Magazine and Blog Addons for (Gutenberg) Block Editor