vue-cli thiee中CSS2DRenderer使用 (生成标题卡片)

效果图

效果图

注意:鼠标滚动 标题卡片大小不变

1. 引入 CSS2DRenderer.js

import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { TWEEN } from "three/examples/jsm/libs/tween.module.min";
import {CSS2DObject,CSS2DRenderer} from "three/examples/jsm/renderers/CSS2DRenderer.js";

2. 在 初始渲染 three.js 中添加

let labelRenderer = new THREE.CSS2DRenderer();
labelRenderer.setSize(window.innerWidth, window.innerHeight);
labelRenderer.domElement.style.position = 'absolute';
labelRenderer.domElement.style.top = 0;
document.body.appendChild(labelRenderer.domElement);
controls = new OrbitControls(camera, labelRenderer.domElement);

2.1 屏幕发生变化可以添加

window.addEventListener('resize', function() {
    labelRenderer.setSize(window.innerWidth, window.innerHeight);
})

3. 在刷新three.js 函数中 (requestAnimationFrame)添加

labelRenderer.render(scene, camera);

4. 创建 标题 卡片 函数

 methods: {
  //初始渲染
   initial() {
      ......
     let data = {
        name: "这是一个标题",
        scale: { x: 0, y: 0, z: 0 },
      };
      let img = require("@/assets/logo.png");
      let title = this.titleCard(data, img);
      scene.add(title);
      this.animate();
  },

    // 生成 标题 卡片
    titleCard(text, imgs) {
      laberDiv = document.createElement("div"); //创建div容器
      laberDiv.className = "laber_name";
      laberDiv.innerHTML = `<div class='title_text'>${text.name}</div>
         <div class= 'laber_imgs'><img src="${imgs}" alt=""></div>`;

      let pointLabel = new CSS2DObject(laberDiv);
      pointLabel.position.set(text.scale.x, text.scale.y, text.scale.z);
      return pointLabel;
    },
}

5. css样式

  .laber_name{
        width: 100px;
        height: 120px;
        color: #05D2FF;
    }
    .laber_name .title_text{
        height: 20px;
        width: 100%;
        line-height: 20px;
        font-size: 12px;
        font-weight: 700;
        text-align: center;
    }
    .laber_name .laber_imgs{
        width: 100px;
        height: 100px;
        
    }
    .laber_name .laber_imgs img{
        width: 100%;
        height: 100%;
    }

6. 完整示例代码

  <!-- 使用 three 中 CSS2DRenderer 生成标题卡片  鼠标滚动 标题卡片不变 -->
<template>
  <div class="title_TEXT">
    <div class="title_state">
      <div
        class="title_state_li"
        @click="clickState(index)"
        :class="stateIndex == index ? 'title_state_li_te' : 'state_li'"
        v-for="(item, index) in stateData"
        :key="index"
      >
        {{ item.name }}
      </div>
    </div>
    <div id="title_CSS2DRenderer"></div>
  </div>
</template>

<script>
//---------------------- 引用 three 的属性 --------------------------------
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { TWEEN } from "three/examples/jsm/libs/tween.module.min";
import {
  CSS2DObject,
  CSS2DRenderer,
} from "three/examples/jsm/renderers/CSS2DRenderer.js";
//---------------------- 引用 three 的属性 --------------------------------

// ----------------------------------- 自定义属性 -----------------------
// 创建场景对象Scene
let scene = new THREE.Scene();
//点光源
let point = new THREE.PointLight(0xffffff);
//环境光
let ambient = new THREE.AmbientLight(0x444444);
//创建相机对象 属性
let camera = null;
// 创建渲染器对象
let renderer = new THREE.WebGLRenderer({
  //增加下面两个属性,可以抗锯齿
  antialias: true,
  alpha: true,
});
let controls = null;
let labelRenderer = new CSS2DRenderer(); // 使用 CSS2DRenderer
let laberDiv = null; //  DoM属性
// ----------------------------------- 自定义属性 -----------------------
export default {
  name: "titleCSS2DRenderer",
  data() {
    return {
      stateData: [
        {
          name: "开",
        },
        {
          name: "关",
        },
      ],
      stateIndex: 0,
    };
  },
  mounted() {
    this.initial();
  },
  methods: {
    // 初始 加载
    initial() {
      let CSS2D = document.querySelector("#title_CSS2DRenderer");
      let gridHelper = new THREE.GridHelper(400, 10, 0x2c2c2c, 0x666666);
      scene.add(gridHelper); // 网格辅助线
      /**
       * 光源设置
       */
      point.position.set(400, 200, 300); //点光源位置
      scene.add(point); //点光源添加到场景中

      scene.add(ambient); //环境光添加到场景中
      /**
       * 相机设置
       */
      let width = window.innerWidth; //窗口宽度
      let height = window.innerHeight; //窗口高度
      let k = width / height; //窗口宽高比
      let s = 200; //三维场景显示范围控制系数,系数越大,显示的范围越大
      //创建相机对象
      camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
      camera.position.set(200, 300, 200); //设置相机位置
      camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
      /**
       * 创建渲染器对象
       */
      renderer.setSize(width, height); //设置渲染区域尺寸
      renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
      CSS2D.appendChild(renderer.domElement); //body元素中插入canvas对象

      labelRenderer.setSize(window.innerWidth, window.innerHeight);
      labelRenderer.domElement.style.position = "absolute";
      labelRenderer.domElement.style.top = 0;
      CSS2D.appendChild(labelRenderer.domElement);

      //执行渲染操作   指定场景、相机作为参数
      renderer.render(scene, camera);

      controls = new OrbitControls(camera, labelRenderer.domElement);
      // 如果使用animate方法时,将此函数删除
      //controls.addEventListener( 'change', render );
      // 使动画循环使用时阻尼或自转 意思是否有惯性
      controls.enableDamping = true;
      //动态阻尼系数 就是鼠标拖拽旋转灵敏度
      controls.dampingFactor = 0.25;
      //是否可以缩放
      controls.enableZoom = true;
      //是否自动旋转
      controls.autoRotate = true;
      controls.autoRotateSpeed = 0.3;
      //设置相机距离原点的最近距离
      controls.minDistance = 1;
      //设置相机距离原点的最远距离
      controls.maxDistance = 300;
      //是否开启右键拖拽
      controls.enablePan = true;
      //上下翻转的最大角度
      controls.maxPolarAngle = 1.5;
      //上下翻转的最小角度
      controls.minPolarAngle = 0.3;
      // 使用 CSS2DRenderer.js

      let data = {
        name: "这是一个标题",
        scale: { x: 0, y: 0, z: 0 },
      };
      let img = require("@/assets/logo.png");
      let title = this.titleCard(data, img);
      scene.add(title);
      this.animate();
    },
    // 生成 标题 卡片
    titleCard(text, imgs) {
      laberDiv = document.createElement("div"); //创建div容器
      laberDiv.className = "laber_name";
      laberDiv.innerHTML = `<div class='title_text'>${text.name}</div>
         <div class= 'laber_imgs'><img src="${imgs}" alt=""></div>`;

      let pointLabel = new CSS2DObject(laberDiv);
      pointLabel.position.set(text.scale.x, text.scale.y, text.scale.z);
      return pointLabel;
    },
    // 自动刷新
    animate() {
      TWEEN.update();
      controls.update();
      labelRenderer.render(scene, camera);
      requestAnimationFrame(this.animate);
      renderer.render(scene, camera);
    },
    // 切换状态
    clickState(index) {
      this.stateIndex = index;
      if (index === 0) {
        laberDiv.className = "laber_name";
      } else {
        laberDiv.className = "laber_name_te";
      }
    },
  },
};
</script>
<style lang="scss">
#title_CSS2DRenderer {
  .laber_name {
    width: 100px;
    height: 120px;
    color: #05d2ff;
  }
  .laber_name_te {
    display: none;
  }
  .laber_name .title_text {
    height: 20px;
    width: 100%;
    line-height: 20px;
    font-size: 12px;
    font-weight: 700;
    text-align: center;
  }
  .laber_name .laber_imgs {
    width: 100px;
    height: 100px;
  }
  .laber_name .laber_imgs img {
    width: 100%;
    height: 100%;
  }
}
</style>
<style lang="scss" scoped>
.title_state {
  position: fixed;
  top: 20px;
  left: 20px;
  z-index: 100;
  display: flex;
  border-radius: 4px;
  overflow: hidden;
  .title_state_li {
    width: 50px;
    height: 30px;
    background-color: #fff;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 14px;
    cursor: pointer;
  }
  .state_li:hover {
    background-color: #f1f1f1;
  }
  .title_state_li_te {
    font-weight: 700;
    color: #fff;
    background-color: #00a6ff;
  }
}
#title_CSS2DRenderer {
  width: 100%;
  height: 100%;
}
</style>
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容