
1条回答 默认 最新
console.log( ) 2021-08-30 09:35关注这个一般用canvas
我有个例子你可以参考一下,不过我的只是随机生成圆,自动旋转,和soul的功能差的很多
你可以在此基础上自己添加鼠标移入停止旋转,鼠标拖动旋转、点击、hover功能等<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <title>3D Globe (Pure canvas)</title> <link rel="stylesheet" href="css/style.css"> </head> <body> <canvas id="scene"></canvas> <script src="js/index.js"></script> </body> </html>console.clear(); // Get the canvas element from the DOM const canvas = document.querySelector('#scene'); canvas.width = canvas.clientWidth; canvas.height = canvas.clientHeight; // Store the 2D context const ctx = canvas.getContext('2d'); if (window.devicePixelRatio > 1) { canvas.width = canvas.clientWidth * 2; canvas.height = canvas.clientHeight * 2; ctx.scale(2, 2); } /* ====================== */ /* ====== VARIABLES ===== */ /* ====================== */ let width = canvas.clientWidth; // Width of the canvas let height = canvas.clientHeight; // Height of the canvas let rotation = 0; // Rotation of the globe let dots = []; // Every dots in an array /* ====================== */ /* ====== CONSTANTS ===== */ /* ====================== */ /* Some of those constants may change if the user resizes their screen but I still strongly believe they belong to the Constants part of the variables */ const DOTS_AMOUNT = 1000; // Amount of dots on the screen const DOT_RADIUS = 4; // Radius of the dots let GLOBE_RADIUS = width * 0.7; // Radius of the globe let GLOBE_CENTER_Z = -GLOBE_RADIUS; // Z value of the globe center let PROJECTION_CENTER_X = width / 2; // X center of the canvas HTML let PROJECTION_CENTER_Y = height / 2; // Y center of the canvas HTML let FIELD_OF_VIEW = width * 0.8; class Dot { constructor(x, y, z) { this.x = x; this.y = y; this.z = z; this.xProject = 0; this.yProject = 0; this.sizeProjection = 0; } // Do some math to project the 3D position into the 2D canvas project(sin, cos) { const rotX = cos * this.x + sin * (this.z - GLOBE_CENTER_Z); const rotZ = -sin * this.x + cos * (this.z - GLOBE_CENTER_Z) + GLOBE_CENTER_Z; this.sizeProjection = FIELD_OF_VIEW / (FIELD_OF_VIEW - rotZ); this.xProject = (rotX * this.sizeProjection) + PROJECTION_CENTER_X; this.yProject = (this.y * this.sizeProjection) + PROJECTION_CENTER_Y; } // Draw the dot on the canvas draw(sin, cos) { this.project(sin, cos); // ctx.fillRect(this.xProject - DOT_RADIUS, this.yProject - DOT_RADIUS, DOT_RADIUS * 2 * this.sizeProjection, DOT_RADIUS * 2 * this.sizeProjection); ctx.beginPath(); ctx.arc(this.xProject, this.yProject, DOT_RADIUS * this.sizeProjection, 0, Math.PI * 2); ctx.closePath(); ctx.fill(); } } function createDots() { // Empty the array of dots dots.length = 0; // Create a new dot based on the amount needed for (let i = 0; i < DOTS_AMOUNT; i++) { const theta = Math.random() * 2 * Math.PI; // Random value between [0, 2PI] const phi = Math.acos((Math.random() * 2) - 1); // Random value between [-1, 1] // Calculate the [x, y, z] coordinates of the dot along the globe const x = GLOBE_RADIUS * Math.sin(phi) * Math.cos(theta); const y = GLOBE_RADIUS * Math.sin(phi) * Math.sin(theta); const z = (GLOBE_RADIUS * Math.cos(phi)) + GLOBE_CENTER_Z; dots.push(new Dot(x, y, z)); } } /* ====================== */ /* ======== RENDER ====== */ /* ====================== */ function render(a) { // Clear the scene ctx.clearRect(0, 0, width, height); // Increase the globe rotation rotation = a * 0.0004; const sineRotation = Math.sin(rotation); // Sine of the rotation const cosineRotation = Math.cos(rotation); // Cosine of the rotation // Loop through the dots array and draw every dot for (var i = 0; i < dots.length; i++) { dots[i].draw(sineRotation, cosineRotation); } window.requestAnimationFrame(render); } // Function called after the user resized its screen function afterResize () { width = canvas.offsetWidth; height = canvas.offsetHeight; if (window.devicePixelRatio > 1) { canvas.width = canvas.clientWidth * 2; canvas.height = canvas.clientHeight * 2; ctx.scale(2, 2); } else { canvas.width = width; canvas.height = height; } GLOBE_RADIUS = width * 0.7; GLOBE_CENTER_Z = -GLOBE_RADIUS; PROJECTION_CENTER_X = width / 2; PROJECTION_CENTER_Y = height / 2; FIELD_OF_VIEW = width * 0.8; createDots(); // Reset all dots } // Variable used to store a timeout when user resized its screen let resizeTimeout; // Function called right after user resized its screen function onResize () { // Clear the timeout variable resizeTimeout = window.clearTimeout(resizeTimeout); // Store a new timeout to avoid calling afterResize for every resize event resizeTimeout = window.setTimeout(afterResize, 500); } window.addEventListener('resize', onResize); // Populate the dots array with random dots createDots(); // Render the scene window.requestAnimationFrame(render);body { display: flex; margin: 0; align-items: center; justify-content: center; height: 100vh; } canvas { width: 98vmin; height: 98vmin; }评论 打赏 举报解决 3无用