vue-cli three中 Sprite使用 (生成标题卡片)

效果图

效果图

注意:鼠标滚动 也跟着变化

1. 引入

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

2. Sprite 生成图标

先创建 canvas图标 => 在使用 Sprite 生成 图标

methods: {
     // Sprite 生成图标 (将canvas生成图标 放入 Sprite里面生成)
    pointImgs(obj) {
      let material = new THREE.SpriteMaterial({
        map: this.canvasIcon({
          text: obj.name,
        }),
      });
      let particle = new THREE.Sprite(material);
      particle.scale.set(70, 70, 2); // 图标大小
      particle.position.set(obj.scale.x, obj.scale.y, obj.scale.z);
      return particle;
    },
    // canvas生成图标
    canvasIcon(obj) {
      let canvas = document.createElement("canvas");
      canvas.width = 1000;
      canvas.height = 1000;
      let ctx = canvas.getContext("2d");
      // ctx.textAlign="center"
      ctx.fillStyle = "rgba(0,0,0,0)";
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      ctx.font = "bold 80px normal";

      // ctx.fillStyle = '#000';
      ctx.fillRect(1, 1, canvas.width, 100);
      // ctx.lineWidth = 1;
      ctx.fillStyle = "#05D2FF";
      ctx.textAlign = "center";
      ctx.fillText(obj.text, 500, 80);
      ctx.drawImage(imgIcon, 100, 100, 799, 799);
      // ctx.draw()
      let texture = new THREE.Texture(canvas);
      // texture.needsUpdate = true
      texture.wrapS = THREE.RepeatWrapping;
      texture.wrapT = THREE.RepeatWrapping;
      texture.needsUpdate = true;
      return texture;
    },
}

3. 完整示例代码

  <!-- 使用 three 中 Sprite 生成标题卡片  鼠标滚动 也跟着变化  -->
<template>
  <div>
    <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_Sprite"></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";

//---------------------- 引用 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 imgIcon = new Image();
imgIcon.src = require("@/assets/logo.png"); // 图片
let spriteTitle = new THREE.Group(); // 生成的标题图标数据  (用来控制开关的)
// ----------------------------------- 自定义属性 -----------------------
export default {
  name: "titleState",
  data() {
    return {
      stateData: [
        {
          name: "开",
        },
        {
          name: "关",
        },
      ],
      stateIndex: 0,
    };
  },
  mounted() {
    this.initial();
  },
  methods: {
    // 初始化加载
    initial() {
      let Sprite = document.querySelector("#title_Sprite");
      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); //设置背景颜色
      Sprite.appendChild(renderer.domElement); //body元素中插入canvas对象
      //执行渲染操作   指定场景、相机作为参数
      renderer.render(scene, camera);

      controls = new OrbitControls(camera, renderer.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;
        let data = {
        name: "这是一个标题",
        scale: { x: 0, y: 0, z: 0 },
      };
      let title = this.pointImgs(data); // 标题图片数据
      spriteTitle.add(title);
      scene.add(spriteTitle)
      this.animate();
    },
    // Sprite 生成图标 (将canvas生成图标 放入 Sprite里面生成)
    pointImgs(obj) {
      let material = new THREE.SpriteMaterial({
        map: this.canvasIcon({
          text: obj.name,
        }),
      });
      let particle = new THREE.Sprite(material);
      particle.scale.set(70, 70, 2); // 图标大小
      particle.position.set(obj.scale.x, obj.scale.y, obj.scale.z);
      return particle;
    },
    // canvas生成图标
    canvasIcon(obj) {
      let canvas = document.createElement("canvas");
      canvas.width = 1000;
      canvas.height = 1000;
      let ctx = canvas.getContext("2d");
      // ctx.textAlign="center"
      ctx.fillStyle = "rgba(0,0,0,0)";
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      ctx.font = "bold 80px normal";

      // ctx.fillStyle = '#000';
      ctx.fillRect(1, 1, canvas.width, 100);
      // ctx.lineWidth = 1;
      ctx.fillStyle = "#05D2FF";
      ctx.textAlign = "center";
      ctx.fillText(obj.text, 500, 80);
      ctx.drawImage(imgIcon, 100, 100, 799, 799);
      // ctx.draw()
      let texture = new THREE.Texture(canvas);
      // texture.needsUpdate = true
      texture.wrapS = THREE.RepeatWrapping;
      texture.wrapT = THREE.RepeatWrapping;
      texture.needsUpdate = true;
      return texture;
    },

    // 自动刷新
    animate() {
      TWEEN.update();
      controls.update();
      requestAnimationFrame(this.animate);
      renderer.render(scene, camera);
    },
    clickState(index){
         this.stateIndex = index;
        if(index === 0) {
            spriteTitle.visible =true;
        }else{
            spriteTitle.visible =false;
        }
    }
  },
};
</script>

<style lang="scss" scoped></style>

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容