代码改变世界

canvas —— javascript实现各种复杂规律图案

2013-04-30 22:27  MoltBoy  阅读(2377)  评论(3编辑  收藏  举报

  在HTML5中新增的元素中,个人最喜欢的就是canvas元素。这个元素负责在页面里设定一个区域,然后在这个区域内通过javascript动态绘制图形。目前大部分浏览器新版本都支持此元素。

  canvas元素具备绘图能力的上下文环境,另外还建议了一个名为WebGL的3D上下文,但是目前大部分浏览器对canvas的3D上下文支持不够好,特别是老版本的浏览器,甚至在window xp中缺少支持必要的绘图驱动程序。

  那么,今天我们就在2d上下文中,共同探讨下这个非常有意思的新元素。

  要使用canvas元素,必须先设置其width和height,默认值分别为300和150。设置的时候有点奇怪,使用CSS设置不成功,必须使用内联属性style方式。这里就不追究原因,猜想是对元素的支持不够完善。

  要在这个画布canvas上绘图,就先得取得绘图上下文,而取得绘图上下文对象的引用,就得先调用getContent()方法并传入上下文的名字如:2d。记得保持良好的编程习惯,使用新方法时,先检测方法是否存在,其中的好处相信大家都知道。  

                2d上下文中绘制的图形,非常神奇吧!那接下来看看怎么做到的?

  使用2d上下文提供的方法,可以绘制一些相对简单的图形,例如:矩形、弧形、圆形、路径等。上面图形其实也是路径,只不过加入了一些相对麻烦的三角函数的算法。2D上下文中的坐标起始于canvas元素的左上角。所有的坐标值都是基于这个点,当然可以通过上下文中提供的translate()改变原点坐标。

  大部分2D上下文操作都属于填充和描边两个操作,而操作的结果又取决于两个属性:fillStyle和strokeStyle。这两个属性的值可以为字符串、渐变对象和模式对象。

  绘制矩形

  与矩形相关的方法包括:fillRect()、strokeRect()和clearRect()。这三个方法都接受四个参数:X坐标、Y坐标、宽度、高度,默认单位像素,所以后面不用再跟单位。

var canvas = document.getElementById("canvas");
if(canvas.getContent){
    var ctx = canvas.getContent("2d");
    ctx.fillStyle = "red";
    ctx.fillRect(10, 10, 20, 20);    //绘制红色20px的矩形

    ctx.strokeStyle = "blue";
    ctx.strokeRect(40, 10, 20, 20);

   ctx.clearRect(15, 15, 5, 5);  //清除出一个小矩形          
}

 

  绘制路径

  绘制路径是重点也是难点,可以通过绘制路径绘制出各种图形和线条。要使用绘制路径方式,首先必须调用beginPath(),表示要开始绘制新路径。然后可以通过调用以下方法来绘制各式各样图形。

  ①、arc(x, y, radius, startAngle, endAngle, counterClockwise),前三个参数顾名思义,后面三个参数分别代表:起始的弧度和结束弧度(0 至 2 * Math.PI),最后一个参数是否逆时针计算,默认为逆时针,也就是ture为逆时针。

  ②、arcTo(x1, y1, x2, y2, radius),从上一点开始绘制一条曲线,到(x2, y2)为止,给定的半径穿过(x1, y1);

  ③、lineTo(x, y),从上一点绘制一条直线到(x, y);

  ④、moveTo(x, y),将绘图游标移动到(x, y),不绘图;

  ⑤、quadraticCurveTo(cx, cy, x, y),从上一点开始绘制一条二次曲线,到(x2, y2)为止,并以(cx, cy)作为控制点。

  ⑥、rect(x, y, width, height),从(x, y)开始绘制一个矩形,宽度为width,高度为height。

  下面就来看看上述图形的具体实现,其实并不复杂,关键在于三角函数的算法有点绕。

<html>
    <head>
        <title>canvas demo</title>
    </head>
    <body>        
        <canvas id="canvas" width=700 height=700>A drawing of something.</canvas>
        <script>
            (function(){
                var canvas = document.getElementById("canvas");
                
                if(canvas.getContext){        
                    var context = canvas.getContext("2d");
                    context.translate(350, 350);    //转换了原点
                    context.strokeStyle = "#0f0";        
                    drawGraph(context, 399, -239, 100);
                }
                
                function drawGraph(ctx, R, r, O){
                    var x1 = R - O, y1 = 0, i = 1;
                    ctx.beginPath();
                    for(; i < 20000 || (x2 == R - O && y2 === 0); i++){  //最大迭代20000次,调的太大页面容易挂起,比较耗资源
                        var x2 = (R+r)*Math.sin(i*Math.PI/72) - (r+O)*Math.sin(((R+r)/r)*(i*Math.PI/72)),  //下一个坐标位置的三角函数算法
                            y2 = (R+r)*Math.cos(i*Math.PI/72) - (r+O)*Math.cos(((R+r)/r)*(i*Math.PI/72));  //不太理解的TX可以画图,有助于理解
                        ctx.lineTo(x2, y2);
                        x1 = x2; y1 = y2;   //这步骤不能漏掉,交换坐标,进入下次路径
                    }
                    ctx.stroke();
                }
            })();
        </script>
    </body>
</html>

  当然,你喜欢的话,也可以修改三角函数和一些参数,有兴趣的话可以研究研究三角函数和弧形的一些复杂运算规律。最后的我尝试的各种有趣的图形汇总:

  图形比较多,所以就缩的很小,非常有意思!兴趣是学习的最大动力,多多挖掘这方面的兴趣吧!神奇的计算机世界,充满了神秘和奥妙!