用three.js实现掘金红包封面-3D旋转LOGO(2)

1,404 阅读3分钟

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

背景

上一篇文章(用threejs实现掘金红包封面-3D旋转文字环)我们实现了3D旋转文字环,本篇文章我准备实现3D旋转掘金LOGO,首先我们看见掘金的logo是由三个部分组合而成的:一个三角锥,两个中空的梯形立方体,接下来我就来实现它吧!

image.png

技术

threejs知识点

1. 组(Group)

可以通过.add( object )方法来将对象进行组合,该方法将对象添加为子对象,组合成一个整体。

2. 圆锥几何体(ConeGeometry)

一个用于生成圆锥几何体的类。

radius — 圆锥底部的半径,默认值为1

height — 圆锥的高度,默认值为1。

radialSegments — 圆锥侧面周围的分段数,默认为8。

heightSegments — 圆锥侧面沿着其高度的分段数,默认值为1。

openEnded — 一个Boolean值,指明该圆锥的底面是开放的还是封顶的。默认值为false,即其底面默认是封顶的。

thetaStart — 第一个分段的起始角度,默认为0。(three o'clock position)

thetaLength — 圆锥底面圆扇区的中心角,通常被称为“θ”(西塔)。默认值是2*Pi,这使其成为一个完整的圆锥。

3. 圆柱缓冲几何体(CylinderGeometry)

一个用于生成圆柱几何体的类。

radiusTop — 圆柱的顶部半径,默认值是1。

radiusBottom — 圆柱的底部半径,默认值是1。

height — 圆柱的高度,默认值是1。

radialSegments — 圆柱侧面周围的分段数,默认为8。

heightSegments — 圆柱侧面沿着其高度的分段数,默认值为1。

openEnded — 一个Boolean值,指明该圆锥的底面是开放的还是封顶的。默认值为false,即其底面默认是封顶的。

thetaStart — 第一个分段的起始角度,默认为0。(three o'clock position)。

thetaLength — 圆柱底面圆扇区的中心角,通常被称为“θ”(西塔)。默认值是2*Pi,这使其成为一个完整的圆柱。

4. Lambert网格材质(MeshLambertMaterial)

一种非光泽表面的材质,没有镜面高光。

实现3DLOGO

1. 创造一个三角锥

setCone(): THREE.Mesh {
    const geometry = new THREE.ConeGeometry(5, 5, 4, 1, true, 0, 6.3);
    const material = new THREE.MeshLambertMaterial({
      color: new THREE.Color(0xffcea3),
      side: THREE.DoubleSide,
    });
    const cone = new THREE.Mesh(geometry, material);
    cone.position.set(0, 20, 0);
    cone.castShadow = true;
    return cone;
}

效果如下:

image.png

2. 创造第二层梯形立方体

 setCylinder1(): THREE.Mesh {
    const geometry = new THREE.CylinderGeometry(10, 14, 5, 4, 1, true);
    const material = new THREE.MeshLambertMaterial({
      color: new THREE.Color(0xffcea3),
      side: THREE.DoubleSide,
    });
    const cylinder1 = new THREE.Mesh(geometry, material);
    cylinder1.position.set(0, 10, 0);
    cylinder1.castShadow = true;

    return cylinder1;
  }

效果如下:

image.png

3. 创造第三层梯形立方体

setCylinder2(): THREE.Mesh {
    const geometry = new THREE.CylinderGeometry(20, 24, 5, 4, 1, true);
    const material = new THREE.MeshLambertMaterial({
      color: new THREE.Color(0xffcea3),
      side: THREE.DoubleSide,
    });
    const cylinder2 = new THREE.Mesh(geometry, material);
    cylinder2.position.set(0, 0, 0);
    cylinder2.castShadow = true;
    return cylinder2;
  }

效果如下:

image.png

4. 组合LOGO

setLogo(): void {
    const cone = this.setCone();
    const cylinder1 = this.setCylinder1();
    const cylinder2 = this.setCylinder2();
    this.logoGroup = new THREE.Group();
    this.logoGroup.add(cone);
    this.logoGroup.add(cylinder1);
    this.logoGroup.add(cylinder2);
    this.scene && this.scene.add(this.logoGroup);
  }

5. 增加倾斜

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

效果如下:

image.png

6.增加旋转动画

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

效果如下:

动画.gif

整体效果

结合上一篇文章的旋转文字环,整体效果如下: 动画1.gif