html5实例闪烁的星星

一、绘制五角星

1.1页面结构

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title>绘制五角星</title>
        <style type="text/css">
            canvas{
                background: #00113F;
            }
        </style>
        <script type="text/javascript">
            window.onload = function() {
                var canvas = document.getElementById('canvas');
                var context = canvas.getContext('2d');
            }
        </script>
    </head>
    <body>
        <canvas id="canvas" width="500" height="500"></canvas>
    </body>
</html>

1.2封装一个绘制多边形的函数

  • 在绘制之前首先我们需要画图分析一下,如何绘制一个多边形

  • 由上图我们可以知道,五角星其实是由10个点连接起来的,而五角星外角的五个点是在一个大圆上,内角的五个点也是在一个小圆上,并且这两个圆的圆心是一样的。因此我们只要知道这两个圆的半径以及点的角度(角度等于360度/点的个数),即可绘制出这些点。
  • 由上面分析可知,我们只需要知道原点坐标,大圆的半径,小圆的半径,以及确定需要绘制的边数,即可绘制出一个多边形,在这里我们默认绘制五边形
  • 现在我们编写绘制多边形的函数,首先我们需要设置一些默认值
  function drawStart(Object) {  
  /*设置一些默认值*/ Object = Object || {}; Object.x = Object.x; //多边形的x轴坐标 Object.y = Object.y; //多边形的y轴坐标 Object.radius1 = Object.radius1; //多边形外面大圆的半径 Object.radius2 = Object.radius2; //多边形内部小圆的半径 Object.angle = 360 / (Object.num * 2); //每个点所对应的角度 Object.num = Object.num || 5; //设置绘制几边形,默认为五边形 Object.drawType = Object.drawType || 'fill'; //绘制填充多边形还是不填充多边形 Object.fillStyle = Object.fillStyle || '#fff'; //设置多边形的填充颜色 Object.strokeStyle = Object.strokeStyle || '#ccc' //设置多边形的边的颜色*/
}
  •  接下来我们需要确定五角星的所有点的坐标,并且把每个点的信息存放在对象里面,然后放在一个数组中
    var arr = [];
    for(var i = 0; i < Object.num * 2; i++) {
        var oStar = {};
        if(i % 2 == 0) { //判断是小圆上的点还是大圆上的点
            oStar.x = Object.x + Object.radius1 * Math.cos(i * Object.angle * Math.PI / 180); //x坐标:圆点横坐标+半径*cos(弧度)
            oStar.y = Object.y + Object.radius1 * Math.sin(i * Object.angle * Math.PI / 180);//y坐标:圆点纵坐标+半径*sin(弧度)
        } else {
            oStar.x = Object.x + Object.radius2 * Math.cos(i * Object.angle * Math.PI / 180);
            oStar.y = Object.y + Object.radius2 * Math.sin(i * Object.angle * Math.PI / 180);
        }
        arr.push(oStar);
    }
  • 再接下来我们把这些点利用直线连起来就可以绘制一个五角星了
    /*开始绘制多边形*/
    context.beginPath();
    context.moveTo(arr[0].x, arr[0].y);
    for(var i = 0; i < arr.length; i++) {
        context.lineTo(arr[i].x, arr[i].y);
    }
    context.closePath(); //关闭路径可以使首尾节点连接起来
    if(Object.drawType == 'fill') { //判断需不需要填充多边形
        context.fillStyle = Object.fillStyle;
        context.strokeStyle = Object.strokeStyle;
        context.stroke();
        context.fill();
    } else if(Object.drawType == 'stroke') {
        context.strokeStyle = Object.strokeStyle;
        context.stroke();
    }

二、让星星闪烁

2.1 canvas图形合成api

2.2设置多个星星的参数

  • 利用for语句循环遍历50次,每循环一次设置一个星星的参数,然后把这些参数放在一个数组中
    var starArr = [];
    for(var i = 0; i < 50; i++) {
        var oStar2 = {
            x: 30 + (canvas.width - 60) * Math.random(),
            y: 30 + (canvas.height - 60) * Math.random(),
            radius1: 10 + 5 * Math.random(),
            radius2: 5,                        
            angle1: 360 * Math.random(), //初始角度
            changeAngle: -5 + 10 * Math.random(), //每次旋转的角度
        }
        starArr.push(oStar2);
    }
  • 让星星每60ms变换一次
    setInterval(function() {
        context.clearRect(0, 0, 500, 500);
        for(var i = 0; i < starArr.length; i++) {
            starArr[i].angle1 += starArr[i].changeAngle;
            context.save(); //保存之前的绘图环境
            context.beginPath();
            context.translate(starArr[i].x, starArr[i].y); 
            context.rotate(starArr[i].angle1 * Math.PI / 180) //缩放
            context.scale(Math.sin(starArr[i].angle1 * Math.PI / 180), Math.sin(starArr[i].angle1 * Math.PI / 180));
            context.globalAlpha = Math.abs(Math.sin(starArr[i].angle1 * Math.PI / 180));
            drawStart({
                x: 0,
                y: 0,
                radius1: starArr[i].radius1,
                radius2: starArr[i].radius2,
                num: 5
            });
            context.restore();
        }
    }, 60)
  • 完整代码
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>绘制五角星</title>
        <style type="text/css">
            canvas {
                background: #00113F;
            }
        </style>
        <script type="text/javascript">
            window.onload = function() {
                var canvas = document.getElementById('canvas');
                var context = canvas.getContext('2d');

                function drawStart(Object) {
                    /*设置一些默认值*/
                    Object = Object || {};
                    Object.x = Object.x; //多边形的x轴坐标
                    Object.y = Object.y; //多边形的y轴坐标
                    Object.radius1 = Object.radius1; //多边形外面大圆的半径
                    Object.radius2 = Object.radius2; //多边形内部小圆的半径
                    Object.angle = 360 / (Object.num * 2);
                    Object.num = Object.num || 5; //设置绘制几边形,默认为五边形
                    Object.drawType = Object.drawType || 'fill'; //绘制填充多边形还是不填充多边形
                    Object.fillStyle = Object.fillStyle || '#fff'; //设置多边形的填充颜色
                    Object.strokeStyle = Object.strokeStyle || '#ccc' //设置多边形的边的颜色*/

                    var arr = [];
                    for(var i = 0; i < Object.num * 2; i++) {
                        var oStar = {};
                        if(i % 2 == 0) { //判断是小圆上的点还是大圆上的点
                            oStar.x = Object.x + Object.radius1 * Math.cos(i * Object.angle * Math.PI / 180); //x坐标:圆点横坐标+半径*cos(弧度)
                            oStar.y = Object.y + Object.radius1 * Math.sin(i * Object.angle * Math.PI / 180); //y坐标:圆点纵坐标+半径*sin(弧度)
                        } else {
                            oStar.x = Object.x + Object.radius2 * Math.cos(i * Object.angle * Math.PI / 180);
                            oStar.y = Object.y + Object.radius2 * Math.sin(i * Object.angle * Math.PI / 180);
                        }
                        arr.push(oStar);
                    }

                    /*开始绘制多边形*/
                    context.beginPath();
                    context.moveTo(arr[0].x, arr[0].y);
                    for(var i = 0; i < arr.length; i++) {
                        context.lineTo(arr[i].x, arr[i].y);
                    }
                    context.closePath(); //关闭路径可以使首尾节点连接起来
                    if(Object.drawType == 'fill') { //判断需不需要填充多边形
                        context.fillStyle = Object.fillStyle;
                        context.strokeStyle = Object.strokeStyle;
                        context.stroke();
                        context.fill();
                    } else if(Object.drawType == 'stroke') {
                        context.strokeStyle = Object.strokeStyle;
                        context.stroke();
                    }
                }

                var starArr = [];
                for(var i = 0; i < 50; i++) {
                    var oStar2 = {
                        x: 30 + (canvas.width - 60) * Math.random(),
                        y: 30 + (canvas.height - 60) * Math.random(),
                        radius1: 10 + 5 * Math.random(),
                        radius2: 5,
                        angle1: 360 * Math.random(), //初始角度
                        changeAngle: -5 + 10 * Math.random(), //每次旋转的角度
                    }
                    starArr.push(oStar2);
                }

                setInterval(function() {
                    context.clearRect(0, 0, 500, 500);
                    for(var i = 0; i < starArr.length; i++) {
                        starArr[i].angle1 += starArr[i].changeAngle;
                        context.save(); //保存之前的绘图环境
                        context.beginPath();
                        context.translate(starArr[i].x, starArr[i].y);
                        context.rotate(starArr[i].angle1 * Math.PI / 180) //缩放
                        context.scale(Math.sin(starArr[i].angle1 * Math.PI / 180), Math.sin(starArr[i].angle1 * Math.PI / 180));
                        context.globalAlpha = Math.abs(Math.sin(starArr[i].angle1 * Math.PI / 180));
                        drawStart({
                            x: 0,
                            y: 0,
                            radius1: starArr[i].radius1,
                            radius2: starArr[i].radius2,
                            num: 5
                        });
                        context.restore();
                    }
                }, 60)

            }
        </script>
    </head>
    <body>
        <canvas id="canvas" width="500" height="500"></canvas>
    </body>
</html>
  • 效果演示

     点击预览demo

原文地址:https://www.cnblogs.com/Anne1991/p/6606396.html