云雷纹案例
-
如下图
-
main.js
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import "./style.css";
import mesh from "./ylw.js";
const scene = new THREE.Scene();
scene.add(mesh);
const light = new THREE.DirectionalLight(0xffffff);
light.position.set(500, 300, 600);
scene.add(light);
const light2 = new THREE.AmbientLight();
scene.add(light2);
const axesHelper = new THREE.AxesHelper(1000);
scene.add(axesHelper);
const width = window.innerWidth;
const height = window.innerHeight;
const camera = new THREE.PerspectiveCamera(60, width / height, 1, 10000);
camera.position.set(0, 200, 600);
camera.lookAt(0, 0, 0);
const renderer = new THREE.WebGLRenderer({
antialias: true,
});
renderer.setSize(width, height);
console.log(mesh);
function render() {
renderer.render(scene, camera);
requestAnimationFrame(render);
}
render();
document.body.append(renderer.domElement);
const controls = new OrbitControls(camera, renderer.domElement);
第一步画圈
- lyw.js
import * as THREE from "three";
// 用来画粗线
import { Line2 } from "three/examples/jsm/lines/Line2";
import { LineGeometry } from "three/examples/jsm/lines/LineGeometry.js";
import { LineMaterial } from "three/examples/jsm/lines/LineMaterial";
const group = new THREE.Group();
const arc1 = new THREE.EllipseCurve(0, 0, 110, 110, 0, Math.PI * 2);
const pointsArr1 = arc1.getPoints(50);
const geometry1 = new LineGeometry();
geometry1.setFromPoints(pointsArr1);
const material1 = new LineMaterial({
color: new THREE.Color("white"),
linewidth: 4,
});
const line1 = new Line2(geometry1, material1);
group.add(line1);
const arc2 = new THREE.EllipseCurve(0, 0, 120, 120, 0, Math.PI * 2);
const pointsArr2 = arc2.getPoints(50);
const geometry2 = new THREE.BufferGeometry();
geometry2.setFromPoints(pointsArr2);
const material2 = new THREE.LineBasicMaterial({
color: new THREE.Color("white"),
});
const line2 = new THREE.Line(geometry2, material2);
group.add(line2);
// 创建一个 group,里面单独画一些圆
const circleGroup = new THREE.Group();
for (let angle = 0; angle < Math.PI * 2; angle += Math.PI / 12) {
const R = 130;
const x = R * Math.cos(angle);
const y = R * Math.sin(angle);
const arc = new THREE.EllipseCurve(x, y, 10, 10, 0, Math.PI * 2);
const pointsArr = arc.getPoints(50);
const geometry = new THREE.BufferGeometry();
geometry.setFromPoints(pointsArr);
const material = new THREE.LineBasicMaterial({
color: new THREE.Color("white"),
});
const line = new THREE.Line(geometry, material);
circleGroup.add(line);
}
group.add(circleGroup);
// 再画一个圈包裹一下
const arc3 = new THREE.EllipseCurve(0, 0, 142.5, 142.5, 0, Math.PI * 2);
const pointsArr3 = arc3.getPoints(50);
const geometry3 = new LineGeometry();
geometry3.setFromPoints(pointsArr3);
const material3 = new LineMaterial({
color: new THREE.Color("white"),
linewidth: 5,
});
const line3 = new Line2(geometry3, material3);
group.add(line3);
export default group;
- 如下图:
第二步画中间的小圈圈并循环构建出来并添加到group中
- 计算x轴离原点的距离
- 第二个圆: 120
- 第三个圆: 142.5 并且线的LineWidth为5
- 计算的位置就是 142.5 - 5 / 2 - 120 => 130
// 角度从 0 到 2π,每个角度的位置用 R * Math.cos(angle) 和 R * Math.sin(angle) 确定圆心位置。
// 创建一个 group,里面单独画一些圆
const circleGroup = new THREE.Group();
for (let angle = 0; angle < Math.PI * 2; angle += Math.PI / 12) {
const R = 130;
const x = R * Math.cos(angle);
const y = R * Math.sin(angle);
const arc = new THREE.EllipseCurve(x, y, 10, 10, 0, Math.PI * 2);
const pointsArr = arc.getPoints(50);
const geometry = new THREE.BufferGeometry();
geometry.setFromPoints(pointsArr);
const material = new THREE.LineBasicMaterial({
color: new THREE.Color("white"),
});
const line = new THREE.Line(geometry, material);
circleGroup.add(line);
}
group.add(circleGroup);
第三步:做不规则的图形
- 如下图:
- 基础就是用点来确定形态用线来串联
// 画图形
const figureGroup = new THREE.Group();
// 360 ° 每次加 10弧度
for (let angle = 0; angle < Math.PI * 2; angle += Math.PI / 10) {
const R = 200;
const x = R * Math.cos(angle);
const y = R * Math.sin(angle);
// 用11点画线
const pointsArr = [
new THREE.Vector3(0, 0, 0),
new THREE.Vector3(10, 0, 0),
new THREE.Vector3(10, 10, 0),
new THREE.Vector3(-10, 10, 0),
new THREE.Vector3(-10, -10, 0),
new THREE.Vector3(20, -10, 0),
new THREE.Vector3(20, 20, 0),
new THREE.Vector3(-20, 20, 0),
new THREE.Vector3(-20, -20, 0),
new THREE.Vector3(20, -20, 0),
];
const geometry = new THREE.BufferGeometry();
geometry.setFromPoints(pointsArr);
const material = new THREE.LineBasicMaterial({
color: new THREE.Color("white"),
});
const line = new THREE.Line(geometry, material);
line.position.set(x, y, 0);
line.rotation.z = angle;
figureGroup.add(line);
}
group.add(figureGroup);
- 效果如下图
第四步再来一圈调一下位置
const figureGroup2 = new THREE.Group();
for (let angle = 0; angle < Math.PI * 2; angle += Math.PI / 10) {
const R = 260;
const x = R * Math.cos(angle);
const y = R * Math.sin(angle);
const pointsArr = [
new THREE.Vector3(0, 0, 0),
new THREE.Vector3(15, 0, 0),
new THREE.Vector3(15, 15, 0),
new THREE.Vector3(-15, 15, 0),
new THREE.Vector3(-15, -15, 0),
new THREE.Vector3(30, -15, 0),
new THREE.Vector3(30, 30, 0),
new THREE.Vector3(-30, 30, 0),
new THREE.Vector3(-30, -30, 0),
new THREE.Vector3(30, -30, 0),
];
const geometry = new THREE.BufferGeometry();
geometry.setFromPoints(pointsArr);
const material = new THREE.LineBasicMaterial({
color: new THREE.Color("white"),
});
const line = new THREE.Line(geometry, material);
line.position.set(x, y, 0);
line.rotation.z = angle;
figureGroup2.add(line);
}
group.add(figureGroup2);
- 如下图
第五步:来点动画每一个child都间隔反向转动
- main.js 的render方法处理一下
function render() {
renderer.render(scene, camera);
requestAnimationFrame(render);
mesh.children.forEach((item, index) => {
const flag = index % 2 === 0 ? 1 : -1;
item.rotation.z += 0.001 * index * flag;
});
}
render();
- 上述就会转动啦
//这个是按照半径生成位置点位的要理解一下
const R = 130;
const x = R * Math.cos(angle);
const y = R * Math.sin(angle);