用threejs实现掘金红包封面-3D旋转星光(4)

335 阅读2分钟

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

背景

上一篇文章(用threejs实现掘金红包封面-实现中文和SVG)我们实现了中文和SVG,本篇文章我准备实现3D旋转星光,接下来我就来实现它吧!

image.png

技术

threejs知识点

  1. CylinderGeometry
  2. MeshLambertMaterial
  3. Group

实现 3D旋转星光

1. 创建一个光束

const geometry = new THREE.CylinderGeometry(0.2, 0.2, 2.5, 32);
const material = new THREE.MeshLambertMaterial({ color: 0xffcea3 });
const cylinder = new THREE.Mesh(geometry, material);

实现后的效果,如下:

image.png

2. 组合星光

有了一束星光,我们可以通过旋转偏移组合成一朵星光。因为一朵星光是有七束星光组合而成的,所以我们可以创建七束星光。

setStarGroup(): THREE.Group {
    const starLeftGroup = new THREE.Group();
    for (let i = 0; i < 1; i++) {
      const geometry = new THREE.CylinderGeometry(0.2, 0.2, 2.5, 32);
      const material = new THREE.MeshLambertMaterial({ color: 0xffcea3 });
      const cylinder = new THREE.Mesh(geometry, material);
      // const mesh = this.setPivot(0, 3, 0, cylinder);
      cylinder.rotateZ((Math.PI / 7) * 2 * i);
      starLeftGroup && starLeftGroup.add(cylinder);
    }
    starLeftGroup.translateY(-3);
    return starLeftGroup;
  }

组合之后的效果:

image.png

3. 设置偏移中心

通过上面的组合我们发现和我们想要的星光效果还是不一样,原因是我们旋转的时候没有设置旋转中心,设置旋转中心函数:

//通过x,y,z指定旋转中心,obj是要旋转的对象
  setPivot(
    x: number,
    y: number,
    z: number,
    obj: THREE.Object3D
  ): THREE.Object3D {
    const wrapper = new THREE.Object3D();
    wrapper.position.set(x, y, z);
    wrapper.add(obj);
    obj.position.set(-x, -y, -z);
    return wrapper;
  }

然后修改组合星光函数如下:

setStarGroup(): THREE.Group {
    const starLeftGroup = new THREE.Group();
    for (let i = 0; i < 1; i++) {
      const geometry = new THREE.CylinderGeometry(0.2, 0.2, 2.5, 32);
      const material = new THREE.MeshLambertMaterial({ color: 0xffcea3 });
      const cylinder = new THREE.Mesh(geometry, material);
      const mesh = this.setPivot(0, 3, 0, cylinder);
      mesh.rotateZ((Math.PI / 7) * 2 * i);
      starLeftGroup && starLeftGroup.add(mesh);
    }
    starLeftGroup.translateY(-3);
    return starLeftGroup;
 }

最后效果如下:

image.png

4. 设置星光位置

左边的星光位置设置:

 setStarLeft(): void {
    this.starLeftGroup = new THREE.Group();
    const starLeftGroup = this.setStarGroup();
    this.starLeftGroup.add(starLeftGroup);
    this.starLeftGroup.position.set(0, 0, 0);
    this.scene && this.scene.add(this.starLeftGroup);
  }

右边的星光位置设置:

setStarRight(): void {
    this.starRightGroup = new THREE.Group();
    const starRightGroup = this.setStarGroup();
    this.starRightGroup.add(starRightGroup);
    this.starRightGroup.position.set(30, 55, 0);
    this.scene && this.scene.add(this.starRightGroup);
  }

效果如下:

image.png

5. 设置旋转动画

左边星光动画:

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

右边星光动画

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

本文效果展示

动画1.gif

整体效果

结合上几篇文章的旋转文字环,整体效果如下:

动画.gif

总结

在整体效果上已经完成了60%了红包封面了,但是在细节上还是有很多不足的地方,不过也希望大家多多点赞和提意见,这样我才有动力努力创作,最后谢谢大家的观看!!!