Home  >  Article  >  Web Front-end  >  Example of using HTML5 to draw 3D graphics composed of points, lines and surfaces_html5 tutorial skills

Example of using HTML5 to draw 3D graphics composed of points, lines and surfaces_html5 tutorial skills

WBOY
WBOYOriginal
2016-05-16 15:46:441996browse

I have been playing with Canvas for two or three weeks, and playing with flat objects is just the same, so I started to mess around with 3D.

Because the Canvas canvas is still flat after all, so if you want to have 3D, you must abstract a Z-axis. Then convert the 3D coordinates into 2D coordinates, draw them on the canvas, and then use rotation and other transformation effects to create a 3D feeling. Doing 3D generally involves going from points to lines, and then from lines to surfaces.

【Point】

If you click on it, I have written a blog post about 3D before Parsing 3D tag cloud is actually very simple Although this blog post talks about the 3D tag cloud implemented using div, but the root cause is The principle of 3D is the same, it is the simplest 3D composed of points. Each label is a point. You can also watch this DEMO directly:
2015512164236104.png (344×329)

3DBall
There are a total of five hundred point objects in it. Each point object changes its size and transparency according to their Z axis, and then evenly distributes it on the sphere. It forms a point sphere.

【Line】

Once you know how to make dots, the line will be easy, just connect the dots. I haven't done a DEMO on this, but it's really not difficult. Just loop moveTo, then lineTo, and the line will come out.

【Noodles】

This blog post mainly talks about face.
Without further ado, let’s do a DEMO first:
2015512164305697.png (170×168)

3D Cube

To make a cube, I used three objects: point object, area object, and the cube itself:

The following is a point object. x, y, z are the three-dimensional coordinates of the point. The _get2d method converts the three-dimensional coordinates to the two-dimensional level. fallLength is the focal length.

XML/HTML CodeCopy content to clipboard
  1. var Vector = function(x,y,z){
  2. this.x = x;
  3. this.y = y;
  4. this.z = z;
  5. this._get2d = function(){
  6. var scale = fallLength/(fallLength this.z);
  7. var x = centerX this.x*scale;
  8. var y = centerY this.y*scale;
  9. return {x:x, y:y};
  10.                                                                 
  11.                                                                                  

  12. Then the target audience:

    The property page of the face object is easy to understand. A face is a square, v1v2v3v4 are the four vertices of the face. The zIndex attribute is very important. It represents the level of the face, whether it is on the outside or inside. This must be Yes, so that when drawing with canvas, this surface can be drawn at the front and will not be covered by other surfaces. The value of zIndex is also easy to understand. It is the average z-axis coordinate of the vertex, which is actually the z-axis coordinate of the center point. The color is the color of this surface.

    XML/HTML CodeCopy content to clipboard
    1. var Face = function(vector1,vector2,vector3,vector4,color){   
    2.             this.v1 = vector1;   
    3.             this.v2 = vector2;   
    4.             this.v3 = vector3;   
    5.             this.v4 = vector4;   
    6.             this.color = color;   
    7.             this.zIndex = (this.v1.z   this.v2.z   this.v3.z   this.v4.z)/4;   
    8.             this.draw = function(){   
    9.                 ctx.save();   
    10.                 ctx.beginPath();   
    11.                 ctx.moveTo(this.v1._get2d().x , this.v1._get2d().y);   
    12.                 ctx.lineTo(this.v2._get2d().x , this.v2._get2d().y);   
    13.                 ctx.lineTo(this.v3._get2d().x , this.v3._get2d().y);   
    14.                 ctx.lineTo(this.v4._get2d().x , this.v4._get2d().y);   
    15.                 ctx.closePath();   
    16.                 // ctx.fillStyle = "rgba(" parseInt(Math.random()*255) "," parseInt(Math.random()*255) "," parseInt(Math.random()*255) ",0.2)";   
    17.                 ctx.fillStyle = this.color;   
    18.                 ctx.fill();   
    19.             }   
    20.         }  


      最后是立方体本身对象:

      因为立方体最后要旋转,所以,立方体对象里面不仅有面对象,还要有点对象,点旋转后才会引起面的旋转。length是立方体的边长,_initVector是初始化立方体的各个顶点,_draw方法就是把所有点形成面,将面放入数组,然后对面进行排序(就是根据面里的zIndex排序),排序好后,调用每个面里的draw方法。立方体就出来了。

    XML/HTML Code复制内容到剪贴板
    1. var Cube = function(length){   
    2.             this.length = length;   
    3.             this.faces = [];   
    4.             this.vectors = [];   
    5.         }   
    6.         Cube.prototype = {   
    7.             _initVector:function(){   
    8.                 this.vectors[0] = new Vector(-this.length/2 , -this.length/2 , this.length/2);   
    9.                 this.vectors[1] = new Vector(-this.length/2 , this.length/2 , this.length/2);    
    10.                 this.vectors[2] = new Vector(this.length/2 , -this.length/2 , this.length/2);    
    11.                 this.vectors[3] = new Vector(this.length/2 , this.length/2 , this.length/2);    
    12.                 this.vectors[4] = new Vector(this.length/2 , -this.length/2 , -this.length/2);   
    13.                 this.vectors[5] = new Vector(this.length/2 , this.length/2 , -this.length/2);   
    14.                 this.vectors[6] = new Vector(-this.length/2 , -this.length/2 , -this.length/2);   
    15.                 this.vectors[7] = new Vector(-this.length/2 , this.length/2 , -this.length/2);   
    16.             },   
    17.             _draw:function(){   
    18.                 this.faces[0] = new Face(this.vectors[0] , this.vectors[1] , this.vectors[3] , this.vectors[2] , "#6c6");   
    19.                 this.faces[1] = new Face(this.vectors[2] , this.vectors[3] , this.vectors[5] , this.vectors[4] , "#6cc");   
    20.                 this.faces[2] = new Face(this.vectors[4] , this.vectors[5] , this.vectors[7] , this.vectors[6] , "#cc6");   
    21.                 this.faces[3] = new Face(this.vectors[6] , this.vectors[7] , this.vectors[1] , this.vectors[0] , "#c6c");   
    22.                 this.faces[4] = new Face(this.vectors[1] , this.vectors[3] , this.vectors[5] , this.vectors[7] , "#666");   
    23.                 this.faces[5] = new Face(this.vectors[0] , this.vectors[2] , this.vectors[4] , this.vectors[6] , "#ccc");   
    24.   
    25.                 this.faces.sort(function(a , b){   
    26.                     return b.zIndex - a.zIndex;   
    27.                 });   
    28.                 this.faces.foreach(function(){   
    29.                     this.draw();   
    30.                 })   
    31.             }   
    32.         }  


      立方体做好了,接下来就可以让它动起来了。根据鼠标位置改变立方体转动的角度。rotateX和rotateY方法就是让所有点绕X轴旋转以及绕Y轴旋转。这个的原理我在之前那个博文上好像有说过。。。。如果想了解更多,可以自己去百度一下计算机图形学3D变换。绕X轴和绕Y轴是最简单的旋转矩阵了。当然,如果有兴趣的还可以去搜一下绕任意轴旋转矩阵。。。这个有点复杂,我本来想用它来做个魔方,不过遇到一些问题,暂时还没解决。好吧,扯远了。通过rotateX和rotateY两个方法可以让每个点获得下一帧的位置,在动画循环中重绘。这样,转动的立方体就做出来了。

    XML/HTML Code复制内容到剪贴板
    1. if("addEventListener" in window){   
    2.             window.addEventListener("mousemove" , function(event){   
    3.                 var x = event.clientX - canvas.offsetLeft - centerX;   
    4.                 var y = event.clientY - canvas.offsetTop - centerY;   
    5.                 angleY = x*0.0001;   
    6.                 angleX = y*0.0001;   
    7.             });   
    8.         }   
    9.         else {   
    10.             window.attachEvent("onmousemove" , function(event){   
    11.                 var x = event.clientX - canvas.offsetLeft - centerX;   
    12.                 var y = event.clientY - canvas.offsetTop - centerY;   
    13.                 angleY = x*0.0001;   
    14.                 angleX = y*0.0001;   
    15.             });   
    16.         }  
    17.            
    18.   
    19.         function rotateX(vectors){   
    20.             var cos = Math.cos(angleX);   
    21.             var sin = Math.sin(angleX);   
    22.             vectors.foreach(function(){   
    23.                 var y1 = this.y * cos - this.z * sin;   
    24.                 var z1 = this.z * cos   this.y * sin;   
    25.                 this.y = y1;   
    26.                 this.z = z1;   
    27.             });   
    28.         }   
    29.   
    30.         function rotateY(vectors){   
    31.             var cos = Math.cos(angleY);   
    32.             var sin = Math.sin(angleY);   
    33.             vectors.foreach(function(){   
    34.                 var x1 = this.x * cos - this.z * sin;   
    35.                 var z1 = this.z * cos   this.x * sin;   
    36.                 this.x = x1;   
    37.                 this.z = z1;   
    38.             })   
    39.         }  
    40.   
    41.            
    42.   
    43.         cube = new Cube(80);   
    44.         cube._initVector();   
    45.         function initAnimate(){   
    46.             cube._draw();   
    47.   
    48.             animate();   
    49.         }   
    50.   
    51.         function animate(){   
    52.             ctx.clearRect(0,0,canvas.width,canvas.height)   
    53.                
    54.             rotateY(cube.vectors);   
    55.             rotateX(cube.vectors);   
    56.             cube._draw();   
    57.             if("requestAnimationFrame" in window){   
    58.                 requestAnimationFrame(animate);   
    59.             }   
    60.             else if("webkitRequestAnimationFrame" in window){   
    61.                 webkitRequestAnimationFrame(animate);   
    62.             }   
    63.             else if("msRequestAnimationFrame" in window){   
    64.                 msRequestAnimationFrame(animate);   
    65.             }   
    66.             else if("mozRequestAnimationFrame" in window){   
    67.                 mozRequestAnimationFrame(animate);   
    68.             }   
    69.             else {   
    70.                 setTimeout(animate , 16);   
    71.             }   
    72.         }   


    I won’t post all the code, you can see it through the console in the DEMO. I didn't reference any other frameworks or anything like that, just copy it and you can use it.

    After you can write a rotating cube, you can also create multiple rotating cubes.
    2015512164340019.png (484×463)

    Poke DEMO: Face: 3D Cube 2 3D Cube Line (I just think this is cooler without faces)

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn