Canvas小demo(直线和曲线绘制出一个星空,月亮,绿地)

主要包含的知识点:

  1. 直线绘制
  2. 径向渐变(绘制天空井深的情况,由蓝变黑)
  3. 五角星数学知识,点与点之间的角度为72deg。。。
  4. 图形变换与状态保存
  5. 弧线绘制月亮(arc,arcTo)
  6. 贝塞尔曲线绘制绿地(bezierCurveTo)
  7. 线性渐变(绿地颜色从远到近是由深到浅)

    请看完整代码


    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>星空,月亮title>
    head>
    <body>
    <canvas id='canvas' style="border:1px solid #aaa;display:block;margin:50px auto;">canvas>
        <script type="text/javascript">
        var canvas = document.getElementById('canvas');
        canvas.width = 1280;
        canvas.height = 800;

        var context = canvas.getContext('2d');

        // context.fillStyle = '#000000';
        /**
         * 绘制一个镜像渐变的天空,从深蓝色到黑色
         */
        var radialGrad = context.createRadialGradient(640,800,0,640,800,800);

        radialGrad.addColorStop(0.0,'#1b0f53');
        radialGrad.addColorStop(1,'#110d25');

        context.fillStyle = radialGrad;


        //直接绘制一个矩形,即代表星空
        context.fillRect(0,0,canvas.width,canvas.height);
        //绘制很多个不同的五角星
        for(var i = 0 ; i <200 ; i++){
            //得到不同大小的圆的半径
            var r = Math.random() * 5 + 5;//获取5~10之间的随机数
            var x = Math.random() * canvas.width;//获取随机的x偏移量,0~画布宽度之间的随机值
            //乘以0.65的意思让星星不会出现在画布高度的0.65下面
            var y = Math.random() * canvas.height * 0.65;
            var rot = Math.random() * 360;//获取角度在0~360度之间的角度
            drawStar(context,x,y,r,rot);

        }
        /**
         * 绘制星空
         */
        function drawStar(cxt,x,y,R,rot){
            cxt.save();

            //进行平移操作
            cxt.translate(x,y);
            //进行旋转操作
            cxt.rotate(rot/180 * Math.PI);
            //使用scale进行缩放,但是为防止对边框宽度进行缩放,就需要将跟边框相关的属性去掉
            cxt.scale(R,R);
            startPath(cxt);

            cxt.fillStyle = '#fb3';
            /*cxt.strokeStyle = '#fb5';
            cxt.lineWidth = 3;
            cxt.lineJoin = 'round';*/

            cxt.fill();
            //cxt.stroke();
            cxt.restore();
        }
        /*绘制单个五角星的函数*/
        function startPath(cxt){
            cxt.beginPath();
            for(var i = 0 ; i<5;i++){
                cxt.lineTo(Math.cos((18 + i * 72)/180 * Math.PI) ,

                                -Math.sin((18 + i * 72) / 180 * Math.PI) );
                    cxt.lineTo(Math.cos((54 + i * 72)/180 * Math.PI) * 0.5,

                                -Math.sin((54 + i * 72) / 180 * Math.PI) * 0.5 );
            }
        }
        script>
        <script type="text/javascript">
        /*绘制一轮弯月*/
        /**
         * 弯月外面的弧是一段半圆弧线,使用arc绘制即可
         * 里面是一段弧线,要用arcTo绘制
         */
        /*context.arc(400,400,300,0.5 * Math.PI,1.5 * Math.PI ,true);
        context.moveTo(400,100);
        context.arcTo(1200,400,400,700,(400 - 100)  * dis(1200,400,400,100) /(1200 - 400));
        context.stroke();*/

        //直角三角形求斜边长度
        function dis(x1,y1,x2,y2){
            return Math.sqrt((x1 - x2)*(x1 - x2) + (y1-y2) * (y1-y2));
        }

        /**
         * [fillMoon 绘制带有填充颜色的弯月
         *  在正则的环境下绘制,即以0,0点为圆心,1位半径的环境下绘制,这样的话
         *  控制点d的值也应该在这个范围内进行取值
         *
         * 通过translate(),rotate(),scale()对正则环境下的弯月进行位移,旋转,缩放
         * ]
         * @param  {[type]} cxt       [description]
         * @param  {[type]} d         [arcTo控制点的x坐标]
         * @param  {[type]} x         [弯月的位置]
         * @param  {[type]} y         [弯月的位置]
         * @param  {[type]} R         [弯月的半径]
         * @param  {[type]} rot       [弯月旋转的角度]
         * @param  {[type]} fillColor [用什么颜色填充,可选]
         * @return {[type]}           [description]
         */
        function fillMoon(cxt,d,x,y,R,rot,fillColor){
            cxt.save();

            cxt.translate(x,y);
            cxt.rotate(rot * Math.PI /180);
            cxt.scale(R,R);

            pathMoon(cxt,d);

            cxt.fillStyle = fillColor || '#fd5';
            cxt.fill();

            cxt.restore();
        }

        //以0,0点为圆心,1位半径的单位圆进行路径规划
        function pathMoon(cxt,d){
            cxt.beginPath();

            cxt.arc(0,0,1,0.5 * Math.PI,1.5 * Math.PI ,true);
            cxt.moveTo(0,-1);
            cxt.arcTo(d,0,0,1,dis(d,0,0,-1) /d );

            cxt.closePath();
        }

        fillMoon(context,2,1000,200,100,-10);
    script>
    <script type="text/javascript">
        /*绘制绿地*/
        drawLand(context);

        function drawLand(cxt){
            cxt.save();

            cxt.beginPath();

            cxt.moveTo(0,600);
            cxt.bezierCurveTo(450,300,500,800,1280,600);
            cxt.lineTo(1280,800);
            cxt.lineTo(0,800);
            cxt.closePath();

            var linearGrad = cxt.createLinearGradient(0,600,0,800);


            linearGrad.addColorStop(0,'#030');
            linearGrad.addColorStop(1,'#580');

            cxt.fillStyle = linearGrad; 
            cxt.fill();

            cxt.restore();
        }
    script>
    body>
    html> 

你可能感兴趣的:(web前端)