用threejs实现掘金红包封面-3D旋转文字环(1)

1,591 阅读2分钟

「这是我参与2022首次更文挑战的第22天,活动详情查看:2022首次更文挑战

背景

本人前几天写了一个教你用3步代码实现360度全景图,超简单的文章,浏览量和点赞的人很多,而且有人留言想看更多的threejs文章,于是我又写了一篇教你实现超级炫酷的粒子光,超级简单的文章,但是浏览量就不高,本人觉得可能是不够实用,于是本人决定用threejs实现一个3D效果的掘金红包封面,并一步一步详细讲解,并实现如下效果:

image.png

技术

知识点

  1. 场景(Scene)
  2. 文本几何体(TextGeometry)
  3. 字体加载器(FontLoader)
  4. 轨道控制器(OrbitControls)

准备

  1. threejs
  2. vue-cli
  3. helvetiker_bold.typeface.json(字体)

红色背景实现

因为红包是红的,所以我们需要一个红色的背景。如下

image.png

1. 原理

场景(Scene)的属性有background。文档描述如下:

若不为空,在渲染场景的时候将设置背景,且背景总是首先被渲染的。 可以设置一个用于的“clear”的Color(颜色)、一个覆盖canvas的Texture(纹理), 或是 a cubemap as a CubeTexture or an equirectangular as a Texture。默认值为null。

2. 代码

this.scene = new THREE.Scene();
this.scene.background = new THREE.Color(0xe55439);

文字环实现

1. 加载字体

const loader = new FontLoader();
loader.load("/assets/fonts/helvetiker_bold.typeface.json", (res) => {
...
});

2. 创建文字

const text = "2022@JUEJIN@HAPPYNEWYEAR2022@JUEJIN@HAPPYNEWYEAR";
    for (let i = 0; i < text.length; i++) {
      const x = Math.floor(Math.cos((Math.PI / 24) * i) * -30);
      const y = 0;
      const z = Math.floor(Math.sin((Math.PI / 24) * i) * 30);
      const font = new TextGeometry(text[i], {
        font: res,
        size: 4, //字体大小
        height: 1, // 挤出文本的厚度
        curveSegments: 12, // 曲线上点的数量。默认值为12
        bevelEnabled: true, // 是否开启斜角,默认为false
        bevelThickness: 0.5, // 文本上斜角的深度,默认值为20
        bevelSize: 0.03, //斜角与原始文本轮廓之间的延伸距离。默认值为8
        bevelSegments: 3, // 斜角的分段数。默认值为3
      });
      font.center();
      const material = new THREE.MeshBasicMaterial({
        color: 0xffcea3,
      });
      const textMesh = new THREE.Mesh(font, material);
      textMesh.position.set(x, y, z);
      textMesh.rotateY((Math.PI / 24) * i - Math.PI / 2);
    }

3. 文字编组

this.textGroup = new THREE.Group();
this.textGroup && this.textGroup.add(textMesh);
this.scene.add(this.textGroup);

效果如下:

image.png

4.增加切斜角度

this.textGroup.rotateY(Math.PI * -0.2);
this.textGroup.rotateZ(Math.PI * -0.1);

效果如下: image.png

5.增加旋转动画

if (this.textGroup) {
  const axis = new THREE.Vector3(0, 1, 0); //向量axis
  this.textGroup.rotateOnAxis(axis, -Math.PI / 200); //绕axis轴旋转π / 200
}

完整代码

setText(): void {
    const loader = new FontLoader();
    loader.load("/assets/fonts/helvetiker_bold.typeface.json", (res) => {
      if (this.scene) {
        this.textGroup = new THREE.Group();
        const text = "2022@JUEJIN@HAPPYNEWYEAR2022@JUEJIN@HAPPYNEWYEAR";
        for (let i = 0; i < text.length; i++) {
          const x = Math.floor(Math.cos((Math.PI / 24) * i) * -30);
          const y = 0;
          const z = Math.floor(Math.sin((Math.PI / 24) * i) * 30);
          const font = new TextGeometry(text[i], {
            font: res,
            size: 4, //字体大小
            height: 1, // 挤出文本的厚度
            curveSegments: 12, // 曲线上点的数量。默认值为12
            bevelEnabled: true, // 是否开启斜角,默认为false
            bevelThickness: 0.5, // 文本上斜角的深度,默认值为20
            bevelSize: 0.03, //斜角与原始文本轮廓之间的延伸距离。默认值为8
            bevelSegments: 3, // 斜角的分段数。默认值为3
          });
          font.center();
          const material = new THREE.MeshBasicMaterial({
            color: 0xffcea3,
          });
          const textMesh = new THREE.Mesh(font, material);
          textMesh.position.set(x, y, z);
          textMesh.rotateY((Math.PI / 24) * i - Math.PI / 2);
          this.textGroup && this.textGroup.add(textMesh);
        }
        this.textGroup.rotateY(Math.PI * -0.2);
        this.textGroup.rotateZ(Math.PI * -0.1);
        this.scene.add(this.textGroup);
      }
    });
  }

效果

动画.gif

总结

因为红包结构比较复杂,本人也是业余创作,所以一次很难完成,我将会分几期分开来实现掘金红包,大家也可以关注我以后的文章,谢谢大家。

56fbe5154105202c842ed0e43a9cd87.jpg

相关文章

教你用3步代码实现360度全景图,超简单

vue3.0 + ts + threejs 实现3D 文字(hello juejin)和demo详解

用 threejs 实现旋转的掘金logo

vue3.0 + ts + threejs 实现简单的demo