// 一个坐标点的类 classDot{ constructor(text, duration = 0) { this.text = text; this.theta = Math.random() * 2 * Math.PI; // Random value between [0, 2Pi] this.phi = Math.acos(Math.random() * 2 - 1); // Random value between [0, Pi]
// x, y, z 初始值 this.x = 0; this.y = 0; this.z = 0;
// The projected coordinates will be calculated in the project() function this.xProjected = 0; this.yProjected = 0; this.scaleProjected = 0;
// Add some animation to the sphere rotate TweenMax.to(this, duration + Math.random() * 5, { theta: this.theta + Math.PI * 2, repeat: -1, ease: Power0.easeNone, }); } // Project our element from its 3D world to the 2D canvas project() { // Calculate the x, y, z coordinates in the 3D world this.x = GLOBE_RADIUS * Math.sin(this.phi) * Math.cos(this.theta); this.y = GLOBE_RADIUS * Math.cos(this.phi); this.z = GLOBE_RADIUS * Math.sin(this.phi) * Math.sin(this.theta) + GLOBE_RADIUS;
// Project the 3D coordinates to the 2D canvas this.scaleProjected = PERSPECTIVE / (PERSPECTIVE + this.z); this.xProjected = this.x * this.scaleProjected + PROJECTION_CENTER_X; this.yProjected = this.y * this.scaleProjected + PROJECTION_CENTER_Y; } // Draw the dot on the canvas draw() { // We first calculate the projected values of our dot this.project(); // We define the opacity of our element based on its distance ctx.globalAlpha = Math.abs(1 - this.z / width); // In this case we are drawing a circle instead of a rectangle // ctx.beginPath(); // 小圆点 // // The arc function takes 5 parameters (x, y, radius, angle start, angle end) // ctx.arc(this.xProjected, this.yProjected, 10 * this.scaleProjected, 0, Math.PI * 2); // // Fill the circle in black // ctx.fill(); // 图片 // var img = new Image(); // img.src = "https://via.placeholder.com/300/09f/fff.png"; // ctx.drawImage(img, this.xProjected, this.yProjected, 50, 50); // 文字 ctx.font = `${Math.floor(ctx.globalAlpha * 14)}px serif`; ctx.fillText(this.text, this.xProjected, this.yProjected); } }
// 需要添加的缓慢运动中的数据 for (let i = 0; i < 300; i++) { dots.push(new Dot("测试", 5)); } // 需要添加的快速运动中的数据 for (let i = 0; i < 300; i++) { dots2.push(new Dot("还是测试", 0)); } // #endregion } start = () => { this.setState( { status: 1, }, () => { if (animationStopId) { window.cancelAnimationFrame(animationStopId); } let that = this; functionrender() { ctx.clearRect(0, 0, width, height); for (var i = 0; i < dots.length; i++) { dots2[i].draw(); } if (that.state.status == 1) { animationStartId = window.requestAnimationFrame(render); } } render(); } ); }; stop = () => { this.setState( { status: 0, }, () => { if (animationStartId) { window.cancelAnimationFrame(animationStartId); } let that = this; functionrender() { ctx.clearRect(0, 0, width, height); for (var i = 0; i < dots.length; i++) { dots[i].draw(); } if (that.state.status == 0) { animationStopId = window.requestAnimationFrame(render); } } render(); } ); }; }