You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
salary-management-oneself/src/pages/demo/threeLogin/modules/earth/index.ts

241 lines
9.1 KiB
TypeScript

import type Viewer from "../Viewer";
import { GUI } from "three/examples/jsm/libs/lil-gui.module.min";
import * as THREE from "three";
class Params {
x: number = 0;
y: number = 0;
z: number = 100;
size: number = 3;
length: number = 10;
radius: number = 16;
visible: boolean = true;
widthSegments: number = 64;
heightSegments: number = 32;
color: string = "#000";
}
export default class Earth {
protected viewer: Viewer;
public particles_init_position!: number;
public zprogress!: number; // 声明点在z轴上移动的进度
public zprogress_second!: number; // 声明同上(第二个几何点)
public particles_first!: any[]; // 声明粒子1
public particles_second!: any[]; // 声明粒子1
public parameters!: any; // 声明点的参数
public materials!: any[]; // 声明点材质
public cloudParameter_first!: any; // 声明流动的云对象1包含路径、云实例
public cloudParameter_second!: any; // 声明流动的云对象2包含路径、云实例
public renderCloudMove_first!: any; // 声明云流动的渲染函数1
public renderCloudMove_second!: any; // 声明云流动的渲染函数1
public gui!: any; // 声明调试工具
constructor(viewer: Viewer) {
this.viewer = viewer;
this.materials = [];
this.gui = new GUI();
this.particles_init_position = -this.viewer.zAxisNumber - this.viewer.depth / 2;
this.zprogress = this.particles_init_position;
this.zprogress_second = this.particles_init_position * 2;
this.particles_first = this.initSceneStar(this.particles_init_position);
this.particles_second = this.initSceneStar(this.zprogress_second);
this.cloudParameter_first = this.initTubeRoute(
[
new THREE.Vector3(-this.viewer.viewerDom.clientWidth / 10, 0, -this.viewer.depth / 2),
new THREE.Vector3(-this.viewer.viewerDom.clientWidth / 4, this.viewer.viewerDom.clientHeight / 8, 0),
new THREE.Vector3(-this.viewer.viewerDom.clientWidth / 4, 0, this.viewer.zAxisNumber)
],
400,
200
);
this.cloudParameter_second = this.initTubeRoute(
[
new THREE.Vector3(this.viewer.viewerDom.clientWidth / 8, this.viewer.viewerDom.clientHeight / 8, -this.viewer.depth / 2),
new THREE.Vector3(this.viewer.viewerDom.clientWidth / 8, this.viewer.viewerDom.clientHeight / 8, this.viewer.zAxisNumber)
],
200,
100
);
this.renderCloudMove_first = this.initCloudMove(this.cloudParameter_first, 0.0002);
this.renderCloudMove_second = this.initCloudMove(this.cloudParameter_second, 0.0008, 0.001);
this.initGUI();
const animate = () => {
if (this.viewer.isDestroy) return;
requestAnimationFrame(animate);
this.renderStarMove();
this.renderCloudMove_first();
this.renderCloudMove_second();
this.viewer.updateDom();
this.viewer.renderDom();
};
animate();
}
// 初始化gui
public initGUI = () => {
const params = new Params();
this.gui.add(params, "x", -1500, 1500).onChange((x: number) => {
//点击颜色面板e为返回的10进制颜色
this.viewer.Sphere_Group.position.x = x;
});
this.gui.add(params, "y", -50, 1500).onChange((y: number) => {
//点击颜色面板e为返回的10进制颜色
this.viewer.Sphere_Group.position.y = y;
});
this.gui.add(params, "z", -200, 1000).onChange((z: number) => {
//点击颜色面板e为返回的10进制颜色
this.viewer.Sphere_Group.position.z = z;
});
// this.gui.add(params, "widthSegments", 0, 64).onChange((widthSegments: number) => {
// //点击颜色面板e为返回的10进制颜色
// // this.viewer.sphereGeometry.parameters.widthSegments = widthSegments;
// });
// this.gui.add(params, "heightSegments", 0, 32).onChange((heightSegments: number) => {
// //点击颜色面板e为返回的10进制颜色
// // this.viewer.sphereGeometry.parameters.heightSegments = heightSegments;
// });
// this.gui.add(params, "radius", 5, 30).onChange((radius: number) => {
// //点击颜色面板e为返回的10进制颜色
// // this.viewer.sphereGeometry.parameters.radius = radius;
// this.viewer.renderer.render(this.viewer.scene, this.viewer.camera);
// });
// this.gui.add(params, "visible").onChange((e: any) => {
// //这是一个单选框因为params.visible是一个布尔值e返回所选布尔值
// // points.visible = e
// });
// this.gui.addColor(params, "color").onChange((e: any) => {
// //点击颜色面板e为返回的10进制颜色
// // pointsMaterial.color.set(e)
// });
};
private initSceneStar(initZposition: number) {
const geometry = new THREE.BufferGeometry();
const vertices: number[] = [];
const pointsGeometry: any[] = [];
const textureLoader = new THREE.TextureLoader();
const sprite1 = textureLoader.load("/images/starflake1.png");
const sprite2 = textureLoader.load("/images/starflake2.png");
this.parameters = [
[[0.6, 100, 0.75], sprite1, 50],
[[0, 0, 1], sprite2, 20]
];
// 初始化500个节点
for (let i = 0; i < 500; i++) {
/**
* const x: number = Math.random() * 2 * width - width
*
* THREE.MathUtils.randFloatSpread(width)
*/
const x: number = THREE.MathUtils.randFloatSpread(this.viewer.viewerDom.clientWidth);
const y: number = _.random(0, this.viewer.viewerDom.clientHeight / 2);
const z: number = _.random(-this.viewer.depth / 2, this.viewer.zAxisNumber);
vertices.push(x, y, z);
}
geometry.setAttribute("position", new THREE.Float32BufferAttribute(vertices, 3));
// 创建2种不同的材质的节点500 * 2
for (let i = 0; i < this.parameters.length; i++) {
const color = this.parameters[i][0];
const sprite = this.parameters[i][1];
const size = this.parameters[i][2];
this.materials[i] = new THREE.PointsMaterial({
size,
map: sprite,
blending: THREE.AdditiveBlending,
depthTest: true,
transparent: true
});
this.materials[i].color.setHSL(color[0], color[1], color[2]);
const particles = new THREE.Points(geometry, this.materials[i]);
particles.rotation.x = Math.random() * 0.2 - 0.15;
particles.rotation.z = Math.random() * 0.2 - 0.15;
particles.rotation.y = Math.random() * 0.2 - 0.15;
particles.position.setZ(initZposition);
pointsGeometry.push(particles);
this.viewer.scene.add(particles);
}
return pointsGeometry;
}
// 渲染星星的运动
public renderStarMove() {
const time = Date.now() * 0.00005;
this.zprogress += 1;
this.zprogress_second += 1;
if (this.zprogress >= this.viewer.zAxisNumber + this.viewer.depth / 2) {
this.zprogress = this.particles_init_position;
} else {
this.particles_first.forEach((item) => {
item.position.setZ(this.zprogress);
});
}
if (this.zprogress_second >= this.viewer.zAxisNumber + this.viewer.depth / 2) {
this.zprogress_second = this.particles_init_position;
} else {
this.particles_second.forEach((item) => {
item.position.setZ(this.zprogress_second);
});
}
for (let i = 0; i < this.materials.length; i++) {
const color = this.parameters[i][0];
const h = ((360 * (color[0] + time)) % 360) / 360;
this.materials[i].color.setHSL(color[0], color[1], parseFloat(h.toFixed(2)));
}
}
// 初始化云的运动函数
public initCloudMove = (cloudParameter: any, speed: number, scaleSpeed = 0.0006, maxScale = 1, startScale = 0) => {
let cloudProgress = 0;
return () => {
if (startScale < maxScale) {
startScale += scaleSpeed;
cloudParameter.cloud.scale.setScalar(startScale);
}
if (cloudProgress > 1) {
cloudProgress = 0;
startScale = 0;
} else {
cloudProgress += speed;
if (cloudParameter.curve) {
const point = cloudParameter.curve.getPoint(cloudProgress);
if (point && point.x) {
cloudParameter.cloud.position.set(point.x, point.y, point.z);
}
}
}
};
};
// 初始化流动路径
private initTubeRoute(route?: any, geometryWidth?: number, geometryHeigh?: number) {
const curve = new THREE.CatmullRomCurve3(route, false);
const tubeGeometry = new THREE.TubeGeometry(curve, 100, 2, 50, false);
const tubeMaterial = new THREE.MeshBasicMaterial({
// color: '0x4488ff',
opacity: 0,
transparent: true
});
const tube = new THREE.Mesh(tubeGeometry, tubeMaterial);
this.viewer.scene.add(tube);
const clondGeometry = new THREE.PlaneGeometry(geometryWidth, geometryHeigh);
const textureLoader = new THREE.TextureLoader();
const cloudTexture = textureLoader.load("/images/cloud.png");
const clondMaterial = new THREE.MeshBasicMaterial({
map: cloudTexture,
blending: THREE.AdditiveBlending,
depthTest: false,
transparent: true
});
const cloud = new THREE.Mesh(clondGeometry, clondMaterial);
this.viewer.scene.add(cloud);
return { cloud, curve };
}
}