vue写three.js例子-立方体-全景图

336 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情


昨天的例子是用球体显示全景,需要的素材是一张全景图片,而用立方体显示全景图需要六个面各自的图片。

sun_temple_stripe.jpg

下面是演示gif:

20220825_090705.gif

需要的资源可在threejs官方项目中找到

先写一个容器

<div class="item">
    <div id="THREE15"></div>
</div>

然后一个mounted方法

mounted() {
    this.initThreejs();
},

下面是three.js的代码

定义一些变量

camera - 相机

controls - 控制器

renderer - 渲染器

scene - 场景

let camera, controls;
let renderer;
let scene;

init();
animate();

下面是init的代码

获取容器

const container = document.getElementById("THREE15");

创建渲染器

renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth - 201, window.innerHeight);
container.appendChild(renderer.domElement);

创建场景

scene = new THREE.Scene();

创建相机

camera = new THREE.PerspectiveCamera(
  90,
  (window.innerWidth - 201) / window.innerHeight,
  0.1,
  100
);
camera.position.z = 0.01;

创建控制器

controls.enableZoom = false - 禁用相机的缩放

controls.enablePan = false - 禁用相机的平移

controls.enableDamping = true - 启用阻尼(惯性),这将给控制器带来重量感

rotateSpeed - 旋转的速度

controls = new OrbitControls(camera, renderer.domElement);
controls.enableZoom = false;
controls.enablePan = false;
controls.enableDamping = true;
controls.rotateSpeed = -0.25;

创建纹理贴图

new THREE.Texture() - 创建一个纹理贴图

ImageLoader() - 用来加载一个Image的加载器

document.createElement("canvas") - 创建一个canvas元素

canvas.getContext("2d") - 获取canvas画布的绘图环境

context.drawImage(要绘制的图像,要裁剪区域的x,要裁剪区域的y,要裁剪区域的w,要裁剪区域的h,裁剪后的x,裁剪后的y,裁剪后的w,裁剪后的h) - canvas绘制图片

needsUpdate = true - 下次使用纹理时触发一次更新

const textures = getTexturesFromAtlasFile(
  "textures/cube/sun_temple_stripe.jpg",
  6
);
  function getTexturesFromAtlasFile(atlasImgUrl, tilesNum) {
    const textures = [];

    for (let i = 0; i < tilesNum; i++) {
      textures[i] = new THREE.Texture();
    }

    new THREE.ImageLoader().load(atlasImgUrl, (image) => {
      let canvas, context;
      const tileWidth = image.height;

      for (let i = 0; i < textures.length; i++) {
        canvas = document.createElement("canvas");
        context = canvas.getContext("2d");
        canvas.height = tileWidth; // 因为是正方形图片
        canvas.width = tileWidth;
        context.drawImage(
          image,
          tileWidth * i,
          0,
          tileWidth,
          tileWidth,
          0,
          0,
          tileWidth,
          tileWidth
        );
        textures[i].image = canvas;
        textures[i].needsUpdate = true;
      }
    });

    return textures;
  }

创建材质

new THREE.MeshBasicMaterial - 创建一个基础网格材质,材质使用上面创建的纹理

const materials = [];

for (let i = 0; i < 6; i++) {
  materials.push(new THREE.MeshBasicMaterial({ map: textures[i] }));
}

创建模型

new THREE.Mesh - 创建一个网格模型

skyBox.geometry.scale(1, 1, -1) - 将模型向内翻转

const skyBox = new THREE.Mesh(
  new THREE.BoxGeometry(1, 1, 1),
  materials
);
skyBox.geometry.scale(1, 1, -1);
scene.add(skyBox);

animate方法

  function animate() {
    requestAnimationFrame(animate);

    controls.update(); // required when damping is enabled

    renderer.render(scene, camera);
  }