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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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 };
}
}