`
mixer_b
  • 浏览: 115470 次
社区版块
存档分类
最新评论

HTML5实现3D球效果

阅读更多

  本文乃原创demo,转载请注明出处:http://blog.csdn.net/qingfeilee/article/details/7437972 ,使用代码请保留作者署名,谢谢!

    曲终人即散,每当看到这个词汇总是略感的伤感。现在的我们周围的生活节奏是如此之快,尤其是生活在北京这个经济高速发展的地方。有时曲可能尚未终,可是人已经散!当我们下班后漫步在繁华都市的夜幕之下,总是略感孤独和伤感。或许是由于工作压力,也或许是因为亲人爱人不在身边,更或许是自己的心一次次的被冲击。京城周末的夜晚丝毫没有因为是夜晚而变得静谧,而我总是急匆匆的上了回家的夜班车。或许我应该停下脚步去聆听、去感受、去享受,但是我却找不到一个这样的地方,唯独小区里的那张长长的木椅。喧嚣的夜幕总是让我想起电视上看见的迪厅里悬挂的那个水晶球,如此的耀眼,如此的抢眼。人们在球的衬托下排遣着自己的疲惫,宣泄着自己的寂寞,放纵着自己的形态……

   作为IT小生制造那支能够在头顶上旋转的球有一定难度,但可以让其在电脑中为人们表演。

   这篇博客描述的是如何实现一个3D球的效果,主要是通过HTML5里面的canvas来实现。整片文章属于原创若有相同纯属有缘,在做这个效果之前简略的学习了一下《3D数学基础》收获颇丰,因为大学里面学的数学基本上都还给了老师。闲话少说,先看实现的效果如图一:

图一

    要想使得整个球动起来,需要先激活。然后再改变他的旋转方向或者改变这个小球的半径。看启动后的效果,如图二:

图二


    这里为什么要设定一个2秒冻结,因为如果立刻冻结的话整个求的样式就无法及时改变所以就采取了这样一个迂回之策。详见代码如下:

 

[html]   view plain copy
  1. < html >   
  2.     < head >   
  3.         < title >   
  4.             再回首,那只小球已停止转动——HTML5实现3D球效果  
  5.         </ title >   
  6.         < meta   charset = "utf-8" >   
  7.         < style   type = "text/css" >     
  8.             #box{     
  9.                 border:2px solid #f60; margin:0 auto;    
  10.             }    
  11.         </ style >     
  12.         < script >   
  13.             var spaceX  =  30 ; //X方向的密度  
  14.             var spaceY  =  30 ; //Y方向的密度  
  15.             var PI  =  Math .PI; //数学角度π  
  16.             var radius  =  200 ; //球的半径  
  17.             var radian  =  PI  / 180; //弧度  
  18.             var speedX  =  0 ; //X方向的速度  
  19.             var speedY  =  0 ; //Y方向的速度  
  20.             var offsetX  =  300 ; //X方向的偏移量相当于将球的中心X坐标移之到画布中央  
  21.             var offsetY  =  300 ; //Y方向的偏移量相当于将球的中心Y坐标移之到画布中央  
  22.             var spheres  =  new  Array(); //存储像素点  
  23.             var canvas; //画布  
  24.             var context; //上下文  
  25.             var focalLength  =  300 ; //控制球距离屏幕的距离  
  26.             var start  =  true ; //是否启动  
  27.             var sx  =  0 ; //sinx  
  28.             var cx  =  0 ; //cosx  
  29.             var sy  =  0 ; //siny  
  30.             var cy  =  0 ; //cosy  
  31.             var sz  =  0 ; //sinz  
  32.             var cz  =  0 ; //cosz  
  33.             var innerStaColor  =  "GREEN" ; //表示内部颜色  
  34.             var outerStaColor  =  "RED" ; //外部颜色  
  35.             var objectRadius  =  10 ; //绘制原点半径  
  36.             var scaleRatio  =  0 ;  
  37.               
  38.             var cameraView  = {  
  39.                 x: 0,  
  40.                 y: 0,  
  41.                 z: 0,  
  42.                 rotX: 0,  
  43.                 rotY: 0,  
  44.                 rotZ: 0  
  45.             }; //视角角度  
  46.             /**  
  47.             author:qingfeilee  
  48.             date:2012-03-28  
  49.             description:初始化系统画布信息  
  50.         **/  
  51.             function initCanvas() {  
  52.                 try{   
  53.                     canvas  =  document .getElementById("sphere");  
  54.                     context  =  canvas .getContext("2d");  
  55.                 }catch(e){  
  56.                      document.getElementById("tip_info").innerHTML  =  "您的浏览器不支持!" ;    
  57.                 }  
  58.             }  
  59.             /**  
  60.             author:qingfeilee  
  61.             date:2012-03-28  
  62.             description:初始化小球实体  
  63.         **/  
  64.             function initSphere() {  
  65.                 for (var i  =  spaceY ; i  <   180 ; i += spaceY) {  
  66.                     for (var angle  =  0 ; angle  <   360 ; angle += spaceX) {  
  67.                         var object  = {};  
  68.                         var x  =  Math .sin(radian * i) * radius;  
  69.   
  70.                         object.x  =  Math .cos(angle * radian) * x;  
  71.                         object.y  =  Math .cos(radian * i) * radius;  
  72.                         object.z  =  Math .sin(angle * radian) * x;  
  73.                         object.glow  = .5; //亮度的范围  
  74.                         spheres.push(object);  
  75.                     }  
  76.                 }  
  77.             }  
  78.             /**  
  79.             author:qingfeilee  
  80.             date:2012-03-28  
  81.             description:初始化系统函数  
  82.         **/  
  83.             function init() {  
  84.                 initCanvas();  
  85.                 initSphere();  
  86.                 setInterval(this.update, 1000 / 60, this);  
  87.                 setTimeout(function() {  
  88.                     start  =  false ;  
  89.                 },  
  90.                 1000);  
  91.             }  
  92.             /**  
  93.             author:qingfeilee  
  94.             date:2012-03-28  
  95.             description:设置整个大球的运转速度  
  96.         **/  
  97.             function setSpeed(speedX, speedY) {  
  98.                 this.speedX  =  speedX ;  
  99.                 this.speedY  =  speedY ;  
  100.             }  
  101.             /**  
  102.             author:qingfeilee  
  103.             date:2012-03-28  
  104.             description:更新整个球的状态以实现动态效果  
  105.         **/  
  106.             function update() {  
  107.                 if (start) {  
  108.                     setParam();  
  109.                 }  
  110.             }  
  111.             /**  
  112.             author:qingfeilee  
  113.             date:2012-03-28  
  114.             description:设置各个小球的属性  
  115.         **/  
  116.             function setParam() {  
  117.                 //根据速度大小计算出一次旋转的角度大小  
  118.                 var rotYstep  =  speedX  / 10000;  
  119.                 var rotXstep  =  speedY  / 10000;  
  120.                 cameraView.rotY  =  rotYstep ;  
  121.                 cameraView.rotX  = -rotXstep;  
  122.                 //计算出对应的cos和sin  
  123.                 sx  =  Math .sin(cameraView.rotX);  
  124.                 cx  =  Math .cos(cameraView.rotX);  
  125.                 sy  =  Math .sin(cameraView.rotY);  
  126.                 cy  =  Math .cos(cameraView.rotY);  
  127.                 sz  =  Math .sin(cameraView.rotZ);  
  128.                 cz  =  Math .cos(cameraView.rotZ);  
  129.   
  130.                 // 设置画布的效果  
  131.                 context.fillStyle  =  'rgba(0,0,0,0.1)' ;  
  132.                 context.fillRect(0, 0, canvas.width, canvas.height);  
  133.   
  134.                 var l  =  spheres .length - 1;  
  135.   
  136.                 for (var i  =  l ,  
  137.                 obj; obj  =  spheres [i]; i--) {  
  138.                     render(obj);  
  139.                 }  
  140.             }  
  141.             /**  
  142.             author:qingfeilee  
  143.             date:2012-03-28  
  144.             description:渲染整个画布  
  145.         **/  
  146.             function render(object) {  
  147.                 var xy, xz, yx, yz, zx, zy;  
  148.   
  149.                 // 计算出物体的相对于照相机的位置  
  150.                 var x  =  object .x - cameraView.x;  
  151.                 var y  =  object .y - cameraView.y;  
  152.                 var z  =  object .z - cameraView.z;  
  153.                   
  154.                 // 绕X轴旋转  
  155.                 xy  =  cx  * y - sx * z;  
  156.                 xz  =  sx  * y + cx * z;  
  157.                 // 绕Y轴旋转  
  158.                 yz  =  cy  * xz - sy * x;  
  159.                 yx  =  sy  * xz + cy * x;  
  160.                 // 绕Z轴旋转  
  161.                 zx  =  cz  * yx - sz * xy;  
  162.                 zy  =  sz  * yx + cz * xy;  
  163.                 //给各个球重新定位  
  164.                 object.x  =  zx ;  
  165.                 object.y  =  zy ;  
  166.                 object.z  =  yz ;  
  167.   
  168.                 //根据z轴数据来缩放球  
  169.                 scaleRatio  =  focalLength  / (focalLength + yz);  
  170.                 scale  =  scaleRatio ;  
  171.   
  172.                 if (object.glow >  .5) {  
  173.                     object.glow - = .02;  
  174.                 }  
  175.   
  176.                 var sphereStyle  =  context .createRadialGradient(offsetX + object.x * scaleRatio, offsetY + object.y * scaleRatio,   
  177.                 scaleRatio * .5, offsetX + object.x * scaleRatio, offsetY + object.y * scaleRatio, scaleRatio * objectRadius * .5);  
  178.                 sphereStyle.addColorStop(0, innerStaColor);  
  179.                 sphereStyle.addColorStop(object.glow, outerStaColor);  
  180.                 sphereStyle.addColorStop(1, 'rgba(0,0,0,0)');  
  181.   
  182.                 context.fillStyle  =  sphereStyle ;  
  183.                 context.fillRect(offsetX + object.x * scaleRatio - scaleRatio * objectRadius * .5,   
  184.                 offsetY + object.y * scaleRatio - scaleRatio * objectRadius * .5, scaleRatio * objectRadius, scaleRatio * objectRadius);  
  185.                  document.getElementById("tip_info").innerHTML  =  "当前速度:" +speedX+"  "+ speedY+"   小球半径:"+objectRadius;    
  186.                   
  187.             }  
  188.             /**  
  189.             author:qingfeilee  
  190.             date:2012-03-28  
  191.             description:冻结/激活真个大球状态  
  192.         **/  
  193.             function startOrPause() {  
  194.                 if (start) {  
  195.                     setTimeout(function() {  
  196.                         start  =  false ;  
  197.                     },  
  198.                     2000);  
  199.                     document.getElementById("swi").innerHTML  =  "激活" ;  
  200.                     innerStaColor  =  "GREEN" ;  
  201.                     outerStaColor  =  "RED" ;  
  202.                 } else {  
  203.                     start  =  true ;  
  204.                     document.getElementById("swi").innerHTML  =  "2秒后冻结" ;  
  205.                     innerStaColor  =  "RED" ;  
  206.                     outerStaColor  =  "GREEN" ;  
  207.                 }  
  208.             }  
  209.             /**  
  210.             author:qingfeilee  
  211.             date:2012-03-28  
  212.             description:改变球的大小  
  213.         **/  
  214.             function changeObjectRadius(val) {  
  215.                 this.objectRadius  =  val ;  
  216.             }  
  217.             window.addEventListener("load", init, true);  
  218.         </ script >   
  219.     </ head >   
  220.     < body >   
  221.         < div   id = "box"   style = "width:600px; height:600px" >     
  222.             < canvas   id = "sphere"   width = "600"   height = "600"   style = "background:#0066FF" >   
  223.             </ canvas >   
  224.             < div   align = "center" >   
  225.                 < button   id = "swi"   onclick = "startOrPause()" >   
  226.                     激活  
  227.                 </ button >   
  228.                 < button   onclick = "setSpeed(-150,0)" >   
  229.                     向东  
  230.                 </ button >   
  231.                 < button   onclick = "setSpeed(150,0)" >   
  232.                     向西  
  233.                 </ button >   
  234.                 < button   onclick = "setSpeed(0,-150)" >   
  235.                     向南  
  236.                 </ button >   
  237.                 < button   onclick = "setSpeed(0,150)" >   
  238.                     向北  
  239.                 </ button >   
  240.                 小球大小:  
  241.                 < input   type = "range"   min = "10"   max = "30"   value = "10"   step = "2"   onchange = "changeObjectRadius(this.value)" />   
  242.             </ div >   
  243.             < div   align = "center" >   
  244.                 < a   href = 'http://blog.csdn.net/qingfeilee/' >   
  245.                         阿飞blog  
  246.                 </ a >   
  247.                 < a   id = "tip_info" >   
  248.                 </ a >   
  249.             </ div >   
  250.               
  251.         </ div >   
  252.     </ body >   
  253. </ html >   


  仅仅看代码可能一时半会看不出端倪,下面将这块儿的几何图形贴上供参考,由于非常外行所以图形画的比较粗糙,如下图三:

图三

      通过上面的图形我们很容易得出initSphere函数里面的一些计算。这样就可以将球的各个点进行了初始化。

      然后就是旋转,我们以绕Y轴旋转为例。假设当前时刻某点P(X,Y,Z)绕Y轴旋转α度,到P1(X1,Y1,Z1)这两者有何关系呢?不再赘述直接给出公式:X1 = X*cosα + Z*sinα;Y1 = Y;Z1=-X*sinα+Z*cosα不懂的复习一下高等书写,O(∩_∩)O哈哈~。绕其他轴旋转同理,这样就得到了update方法里面的算法。当然在3D中还存在一个视角角度,就相当于摄像机一样,本例子中默认是是0,0,0。

     由代码注释较详细,具体就不再赘述。哪位大牛有好的算法实现希望能够多多交流,共同学习,共同进步,欢迎拍砖。

     本文乃原创demo,转载请注明出处:http://blog.csdn.net/qingfeilee/article/details/7437972 ,使用代码请保留作者署名,谢谢!

    附件:http://download.csdn.net/detail/qingfeilee/4208565

分享到:
评论
1 楼 逝叶1314 2013-10-14  
     

相关推荐

    HTML5实现3D旋转球

    变换包括平移、旋转和缩放,其中旋转尤为重要,因为它能实现3D球的动态效果。在HTML5的Canvas中,我们通常使用矩阵乘法来实现这些变换。 首先,我们需要创建一个3D球体模型。这通常涉及到计算球面上每个像素的坐标...

    html5酷炫3D球形文字云动画特效

    在这个"html5酷炫3D球形文字云动画特效"中,主要运用了HTML5的Canvas元素来实现一个引人注目的视觉效果。 Canvas是HTML5中的一个画布标签,通过JavaScript可以进行动态图形绘制。在这个3D球形文字云动画中,开发者...

    HTML5 3D旋转球体

    为了实现3D效果,我们需要借助WebGL,这是一个基于OpenGL标准的JavaScript API,能够在浏览器上进行硬件加速的3D图形渲染。 1. **WebGL基础**: - WebGL是JavaScript与GPU交互的桥梁,它提供了一组用于处理3D图形...

    html5 canvas酷炫的3D球形文字云动画特效

    - 3D坐标系统:在Canvas中实现3D效果需要理解X、Y、Z三个轴的概念。 - `translate()`、`rotate()`、`scale()`:这些是2D绘图变换方法,但通过巧妙组合,可以模拟3D效果。 - 投影原理:将3D坐标映射到2D平面上,...

    JavaScript实现的3D球面标签云效果

    在这个项目中,Canvas是实现3D球面标签云的基础。 2. **WebGL**: WebGL是一种基于OpenGL标准的JavaScript API,用于在浏览器中实现硬件加速的3D图形渲染。通过WebGL,开发者可以构建复杂的3D场景,包括在这个案例中...

    HTML5 Canvas五彩缤纷的3D发光水晶球动画

    同时,为了实现3D发光效果,可能使用了颜色渐变和光照模型,通过调整颜色的透明度和亮度,使水晶球看起来像是在发光。 水晶球的五彩缤纷色彩可能是通过循环绘制多个不同颜色的同心圆或弧线来实现的,每个圆或弧线...

    纯css3-球形3d旋转-多图3d球形旋转

    本项目“纯css3-球形3d旋转-多图3d球形旋转”着重展示了如何利用CSS3的特性来实现一个动态的、三维球形的图像旋转展示效果。这种效果可以用于网站的轮播图、产品展示或任何需要吸引用户注意力的地方。 首先,我们来...

    HTML5 Canvas 3D球形文字标签云动画

    个人博客程序中经常会使用的一个功能叫标签云,就是把许多标签文字...今天要分享的就是一款基于HTML5 Canvas的3D球形标签云动画,你可以定义任意的文字,然后调用HTML5代码初始化一个3D的球形标签云,效果非常不错。

    HTML5实现的3D乒乓球比赛动画

    这是一个使用CSS3实现的3D乒乓球比赛动画,场面效果令人震撼,最关键的是全部用HTML和CSS实现。画面中的乒乓球桌、球拍以及乒乓球都是通过CSS3绘制而成,包括球桌的阴影和乒乓球运动时的投影,3D效果表现得非常逼真...

    3D球体标签云特效,JavaScript CSS实现.rar

    "3D球体标签云特效,JavaScript CSS实现.rar"是一个压缩包,其中包含了一个利用这两种技术创建的3D球体标签云效果的源代码。这种特效将传统的标签云提升到一个新的层次,它不仅呈现了3D视觉效果,而且还能响应用户的...

    HTML5 CSS3实现3D感极强的彩色立体文字.rar

    HTML5 CSS3实现3D感极强的彩色立体文字源码,这个效果超赞啊,这种三维风格我很喜欢,而且颜色很鲜艳,当然了,字符的颜色可以自己定义,具体请参见HTML演示文件,文字内容的自定义也很方便,在HTML中输入文字内容...

    PYQT5结合html实现年会抽奖系统(3D旋转动态)

    在这个“PYQT5结合html实现年会抽奖系统(3D旋转动态)”项目中,开发者利用了PYQT5的功能来构建一个互动的、具有3D旋转效果的年会抽奖应用。这个系统可能包含以下几个关键知识点: 1. **PYQT5基础**:PYQT5是...

    基于 Express + Three.js的 3D 球体抽奖程序源码.zip

    Three.js提供了强大的动画功能,可以实现3D物体的平滑移动和旋转。在抽奖程序中,球体会根据设定的动画路径运动,当用户点击时,特定的球体会有突出的反馈,表示被选中。 ### 8. 数据交换 Express和前端之间可能...

    酷炫html5实现太阳系星球演示效果

    在本项目中,“酷炫html5实现太阳系星球演示效果”是一个使用HTML5、CSS以及可能涉及JavaScript技术创建的互动展示。这个演示旨在通过网页浏览器模拟太阳系内行星的运动,为用户呈现一个动态的、视觉上吸引人的科普...

    js+html5地球仪3D旋转网页特效.zip

    8. **WebGL**: 虽然没有直接提到,但实现3D地球仪特效很可能使用了WebGL技术,这是一个JavaScript API,允许在浏览器中进行硬件加速的3D图形渲染,无需插件。 这个项目对于想要学习和实践HTML5、CSS3以及JavaScript...

    3D视觉效果的球体

    在3D图形学中,球体通常通过数学模型如球坐标系统或多边形网格来创建,但在不同的光照、纹理映射、透视设置以及相机角度的影响下,球体可能会呈现出非正圆形的视觉效果。这可能是由于光学错觉、渲染技术或者设计者的...

    H5 three.js 3D足球,服务器运行

    在本项目中,three.js是实现3D足球游戏的核心技术,它提供了场景、摄像机、几何体、材质、光源、动画等一系列功能,让开发者能够轻松构建复杂的3D模型和场景。 四、3D足球游戏开发 1. 场景设置:使用three.js创建3D...

    html5 canvas绘制3D地球旋转动画特效

    同时,为了实现3D效果,需要对每个切片进行适当的缩放和平移。 接下来,我们要引入颜色渐变,模拟地球的海洋和陆地。这可以通过创建线性或径向渐变对象,并在`fillStyle`中使用它们。对于旋转动画,我们可以利用`...

    纯CSS3实现3D小球动画 纯CSS3实现3D小球动画网页特效.zip

    在本项目中,"纯CSS3实现3D小球动画 纯CSS3实现3D小球动画网页特效.zip",我们关注的核心是利用CSS3技术来创建动态、立体感的3D小球动画效果。这是一项前端开发中的高级技巧,涉及到HTML5、jQuery和JavaScript的综合...

Global site tag (gtag.js) - Google Analytics