遵义市网站建设_网站建设公司_HTTPS_seo优化
2026/1/17 19:39:58 网站建设 项目流程

文章目录

  • 前言
  • 一、网页效果预览
  • 二、功能和交互式体验
  • 三、 技术实现详解
    • 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. 技术栈

整个项目采用原生HTML+CSS+JavaScript实现,核心3D渲染使用Three.js。

2. 分级渲染策略

针对移动端和pc端做了不同渲染策略,保证移动端运行流畅。

// 设备性能检测detectLowEndDevice(){constcanvas=document.createElement('canvas');constgl=canvas.getContext('webgl2')||canvas.getContext('webgl');if(!gl)returntrue;constdebugInfo=gl.getExtension('WEBGL_debug_renderer_info');constrenderer=debugInfo?gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL):'';constisMobile=/iPhone|iPad|iPod|Android/i.test(navigator.userAgent);constisLowEndGPU=/Mali|Adreno|Mesa/i.test(renderer);constisLowMemory=navigator.deviceMemory&&navigator.deviceMemory<4;returnisMobile||isLowEndGPU||isLowMemory;}
// 根据设备性能调整渲染质量init(){constisLowEnd=this.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){constparticleCount=isLowEnd?1500:5000;constpositions=newFloat32Array(particleCount*3);constcolors=newFloat32Array(particleCount*3);constsizes=newFloat32Array(particleCount);for(leti=0;i<particleCount;i++){consti3=i*3;constradius=Math.pow(Math.random(),0.7)*80+20;constangle=Math.random()*Math.PI*2;constheight=(Math.random()-0.5)*40;positions[i3]=radius*Math.cos(angle);positions[i3+1]=height;positions[i3+2]=radius*Math.sin(angle);colors[i3]=0.2+Math.random()*0.3;colors[i3+1]=0.4+Math.random()*0.4;colors[i3+2]=0.8+Math.random()*0.2;sizes[i]=Math.random()*4+1;}constgeometry=newTHREE.BufferGeometry();geometry.setAttribute('position',newTHREE.BufferAttribute(positions,3));geometry.setAttribute('color',newTHREE.BufferAttribute(colors,3));geometry.setAttribute('size',newTHREE.BufferAttribute(sizes,1));constmaterial=newTHREE.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});constparticles=newTHREE.Points(geometry,material);this.particles.push(particles);this.scene.add(particles);}

3.2信息墙面(数据展示)

每个墙面都是一个独立的3D平面,采用Canvas动态生成纹理:

//创建墙面createEnhancedTexture(){constcanvas=document.createElement('canvas');canvas.width=512;canvas.height=384;constctx=canvas.getContext('2d');constgradient=ctx.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.fillStyle=gradient;ctx.fillRect(0,0,512,384);// 半透明边框ctx.strokeStyle=this.data.color+'60';ctx.lineWidth=3;ctx.shadowColor=this.data.color;ctx.shadowBlur=15;ctx.strokeRect(6,6,500,372);ctx.shadowBlur=0;ctx.font='bold 70px Arial';ctx.textAlign='center';ctx.textBaseline='middle';ctx.fillStyle=this.data.color;ctx.shadowColor=this.data.color;ctx.shadowBlur=20;ctx.fillText(this.data.icon,256,90);ctx.shadowBlur=0;ctx.font='bold 52px -apple-system, BlinkMacSystemFont, sans-serif';ctx.fillStyle='#00ffff';ctx.shadowColor='#00ffff';ctx.shadowBlur=15;ctx.fillText(this.data.value,256,200);ctx.shadowBlur=0;ctx.font='26px -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)){constgeometry=newTHREE.CylinderGeometry(0.3,3,35,8,1,true);constmaterial=newTHREE.MeshBasicMaterial({color:wall.data.color,transparent:true,opacity:0.06,side:THREE.DoubleSide,blending:THREE.AdditiveBlending});constbeam=newTHREE.Mesh(geometry,material);beam.position.copy(wall.mesh.position);beam.position.y+=18;beam.rotation.z=Math.PI;beam.userData={originalOpacity:0.06};this.lightBeams.push(beam);this.scene.add(beam);}});}

4. 数据管理与模态窗口

所有博客数据都存储在BLOG_STAR_DATA对象中,点击墙面时会显示详细信息的模态窗口:

showDetailModal(data){// 动态填充数据document.getElementById('detailIcon').textContent=data.icon;document.getElementById('detailTitle').textContent=data.title;document.getElementById('detailValue').textContent=data.value;document.getElementById('detailDescription').innerHTML=data.detail;document.getElementById('detailThanks').textContent=data.thanks;// 显示模态窗口modal.style.display='block';}


四、完整代码

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这个让我们相遇的平台。

技术人的浪漫,就是把抽象的逻辑变成可视的美感。 我把我的技术足迹变成了星空,现在,我想邀请你成为这片星空里的一颗光点。

你的每一票,都会让这个星空更亮一点。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询