2026/5/21 14:47:11
网站建设
项目流程
设计公司官网首页,沧州企业网站优化,重庆高端网站建设公司,流量联盟网站源码文章目录 前言一、网页效果预览二、功能和交互式体验三、 技术实现详解1. 技术栈2. 分级渲染策略3. Three.js 3D场景搭建3.1 粒子系统#xff08;星空背景#xff09;3.2信息墙面#xff08;数据展示#xff09;3.3 光线效果 4. 数据管理与模态窗口 四、完整代码五、我的拉…文章目录前言一、网页效果预览二、功能和交互式体验三、 技术实现详解1. 技术栈2. 分级渲染策略3. Three.js 3D场景搭建3.1 粒子系统星空背景3.2信息墙面数据展示3.3 光线效果4. 数据管理与模态窗口四、完整代码五、我的拉票心声六、投票方式七、 最后想说前言CSDN博客之星年度评选投票再度开启紧张刺激的时刻如期而至。今年我荣幸入选TOP 300首次以候选人身份参与这场技术人的年度盛会。观察过往的拉票方式无论是转发链接、群发文字还是发红包、送礼物似乎都已显得常规。作为一名开发者我不禁思考为什么不将技术创作本身变成拉票的媒介呢于是这一次我决定不仅用文字更想用代码来表达——我花了一些时间基于 Three.js 制作了一个互动式 3D 星图拉票页面。它不只是拉票工具更是我在CSDN创作历程的可视化呈现。希望它能为你带来不一样的投票体验也让你看见技术可以让表达更有趣。如果你也喜欢这种“用代码说话”的方式欢迎体验这个小小作品并为我投上一票。一、网页效果预览如果技术人有浪漫那大概就是把抽象的付出变成一片可触碰的星空。点击这里在线体验二、功能和交互式体验这不是一张静态图片。它是一个活着的、呼吸的微型宇宙。星空粒子背景由5000颗低性能设备自适应为1500颗粒子组成的星云持续缓缓脉动。悬浮数据墙面8面可交互的3D墙面清晰展示着我的关键博客数据。实时交互鼠标拖拽旋转视角滚轮缩放探索细节触摸设备亦可流畅操作。响应式设计适配PC和移动端在华丽与流畅间取得平衡。三、 技术实现详解1. 技术栈整个项目采用原生HTMLCSSJavaScript实现核心3D渲染使用Three.js。2. 分级渲染策略针对移动端和pc端做了不同渲染策略保证移动端运行流畅。// 设备性能检测detectLowEndDevice(){constcanvasdocument.createElement(canvas);constglcanvas.getContext(webgl2)||canvas.getContext(webgl);if(!gl)returntrue;constdebugInfogl.getExtension(WEBGL_debug_renderer_info);constrendererdebugInfo?gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL):;constisMobile/iPhone|iPad|iPod|Android/i.test(navigator.userAgent);constisLowEndGPU/Mali|Adreno|Mesa/i.test(renderer);constisLowMemorynavigator.deviceMemorynavigator.deviceMemory4;returnisMobile||isLowEndGPU||isLowMemory;}// 根据设备性能调整渲染质量init(){constisLowEndthis.detectLowEndDevice();this.renderer.setPixelRatio(Math.min(window.devicePixelRatio,1.2));this.createOptimizedParticles(isLowEnd);this.createLightBeams(isLowEnd);this.setupLighting(isLowEnd);}3. Three.js 3D场景搭建3.1 粒子系统星空背景动态设置粒子数低端设备检测为低性能时1500个粒子高端设备5000个粒子//创建粒子系统createOptimizedParticles(isLowEnd){constparticleCountisLowEnd?1500:5000;constpositionsnewFloat32Array(particleCount*3);constcolorsnewFloat32Array(particleCount*3);constsizesnewFloat32Array(particleCount);for(leti0;iparticleCount;i){consti3i*3;constradiusMath.pow(Math.random(),0.7)*8020;constangleMath.random()*Math.PI*2;constheight(Math.random()-0.5)*40;positions[i3]radius*Math.cos(angle);positions[i31]height;positions[i32]radius*Math.sin(angle);colors[i3]0.2Math.random()*0.3;colors[i31]0.4Math.random()*0.4;colors[i32]0.8Math.random()*0.2;sizes[i]Math.random()*41;}constgeometrynewTHREE.BufferGeometry();geometry.setAttribute(position,newTHREE.BufferAttribute(positions,3));geometry.setAttribute(color,newTHREE.BufferAttribute(colors,3));geometry.setAttribute(size,newTHREE.BufferAttribute(sizes,1));constmaterialnewTHREE.ShaderMaterial({uniforms:{uTime:{value:0},uPixelRatio:{value:Math.min(window.devicePixelRatio,1.2)}},vertexShader:attribute float size; attribute vec3 color; varying vec3 vColor; uniform float uTime; uniform float uPixelRatio; void main() { vColor color; vec3 pos position; pos.y sin(uTime position.x * 0.01) * 0.3; vec4 mvPosition modelViewMatrix * vec4(pos, 1.0); gl_PointSize size * uPixelRatio * (400.0 / -mvPosition.z); gl_Position projectionMatrix * mvPosition; },fragmentShader:varying vec3 vColor; void main() { float dist distance(gl_PointCoord, vec2(0.5)); if (dist 0.5) discard; float alpha 1.0 - smoothstep(0.0, 0.5, dist); alpha * 0.7; gl_FragColor vec4(vColor, alpha); },transparent:true,blending:THREE.AdditiveBlending,depthWrite:false});constparticlesnewTHREE.Points(geometry,material);this.particles.push(particles);this.scene.add(particles);}3.2信息墙面数据展示每个墙面都是一个独立的3D平面采用Canvas动态生成纹理//创建墙面createEnhancedTexture(){constcanvasdocument.createElement(canvas);canvas.width512;canvas.height384;constctxcanvas.getContext(2d);constgradientctx.createLinearGradient(0,0,512,384);gradient.addColorStop(0,rgba(0, 0, 0, 0.95));gradient.addColorStop(0.5,rgba(10, 5, 20, 0.85));gradient.addColorStop(1,rgba(0, 15, 20, 0.9));ctx.fillStylegradient;ctx.fillRect(0,0,512,384);// 半透明边框ctx.strokeStylethis.data.color60;ctx.lineWidth3;ctx.shadowColorthis.data.color;ctx.shadowBlur15;ctx.strokeRect(6,6,500,372);ctx.shadowBlur0;ctx.fontbold 70px Arial;ctx.textAligncenter;ctx.textBaselinemiddle;ctx.fillStylethis.data.color;ctx.shadowColorthis.data.color;ctx.shadowBlur20;ctx.fillText(this.data.icon,256,90);ctx.shadowBlur0;ctx.fontbold 52px -apple-system, BlinkMacSystemFont, sans-serif;ctx.fillStyle#00ffff;ctx.shadowColor#00ffff;ctx.shadowBlur15;ctx.fillText(this.data.value,256,200);ctx.shadowBlur0;ctx.font26px -apple-system, BlinkMacSystemFont, sans-serif;ctx.fillStyle#ffffff;ctx.fillText(this.data.title,256,290);returncanvas;}3.3 光线效果为重要数据如阅读量、粉丝数添加了动态光束//创建光束createLightBeams(isLowEnd){if(isLowEnd){this.lightBeams[];return;}constbeamIds[read,fans];this.walls.forEach((wall,index){if(beamIds.includes(wall.data.id)){constgeometrynewTHREE.CylinderGeometry(0.3,3,35,8,1,true);constmaterialnewTHREE.MeshBasicMaterial({color:wall.data.color,transparent:true,opacity:0.06,side:THREE.DoubleSide,blending:THREE.AdditiveBlending});constbeamnewTHREE.Mesh(geometry,material);beam.position.copy(wall.mesh.position);beam.position.y18;beam.rotation.zMath.PI;beam.userData{originalOpacity:0.06};this.lightBeams.push(beam);this.scene.add(beam);}});}4. 数据管理与模态窗口所有博客数据都存储在BLOG_STAR_DATA对象中点击墙面时会显示详细信息的模态窗口showDetailModal(data){// 动态填充数据document.getElementById(detailIcon).textContentdata.icon;document.getElementById(detailTitle).textContentdata.title;document.getElementById(detailValue).textContentdata.value;document.getElementById(detailDescription).innerHTMLdata.detail;document.getElementById(detailThanks).textContentdata.thanks;// 显示模态窗口modal.style.displayblock;}四、完整代码git clone https://gitcode.com/sd1sd2/3d_Vote.git五、我的拉票心声做这个页面不仅仅是为了拉票更是想展示技术人的浪漫——我们用代码构建世界用算法描绘星空。在CSDN的5年多创作历程中我写了130篇原创文章收获了2.2万粉丝的支持总阅读量超过39万次。每篇文章都凝聚着我的心血都源于实战的打磨、经验总结、反复的调试与无私的分享。您的一票便是对我这些年坚持创作最好的认可。这次评选对我来说不只是荣誉。我想证明一件事坚持技术分享是有价值的用心写的内容会被看见。六、投票方式点击这个按钮前往投票每天都可以投票根据你的码龄、博客等级决定投票数可以把所有票投给同一个用户2025年12月21日之后注册用户、未发布过原创文章无权投票。投票截止2026年1月23日 23:59:59如果你愿意多帮一点把星空页面分享给你的技术群把文章分享给你觉得可能感兴趣的朋友如果你也是入围的博主我们也可以互投七、 最后想说感谢你花费时间阅读至此甚至体验了那个小小的星空。技术之路犹如星空探索浩瀚无垠又充满惊喜。感谢每一位在技术路上同行的伙伴感谢CSDN这个让我们相遇的平台。技术人的浪漫就是把抽象的逻辑变成可视的美感。 我把我的技术足迹变成了星空现在我想邀请你成为这片星空里的一颗光点。你的每一票都会让这个星空更亮一点。