6.用canvas绘制漫天飞舞的雪花1

javascript/jquery

浏览数:286

2020-5-22

附:用canvas绘制漫天飞舞的雪花2
用canvas绘制漫天飞舞的雪花3

效果预览:https://codepen.io/andy-js/pen/OJPzpdE
建议右键新标签或窗口打开预览

今天看到 comehope老师发表的 用纯 CSS 绘制一朵美丽的雪花
心血来潮 ,即用canvas也画了一个样的。

1.首先我们创建一个canvas并将背景涂黑
将00坐标映射到正中间后,通过以前讲过的旋转画布的方法,可以绘制出简单的六个主干线和顶端圆。

<canvas class="snowflake" id="c1" width="600" height="600">  
<script>
var oC1=document.getElementById('c1'),
    ctx = oC1.getContext("2d");
var w=oC1.offsetWidth,
    radius = w / 2;;

ctx.fillStyle="#000";
ctx.fillRect(0,0,w,w);  //背景涂黑
ctx.translate(radius,radius);//重新映射画布上的 (0,0) 位置  映射到画布正中间   

var lineWidth=parseInt(w/60),
    lineHeight=radius*0.8;  //主干线的宽度 长度

ctx.lineWidth=lineWidth;
ctx.strokeStyle='#fff';
ctx.fillStyle="#fff";

for(var i=0;i<6;i++){
    ctx.lineCap="round";//向线条的每个末端添加圆形线帽。

    ctx.fillStyle="#fff";
    ctx.beginPath();
    ctx.moveTo(0,0);
    ctx.lineTo(0,-lineHeight);
    ctx.stroke();
    

    //画顶端圆
    ctx.beginPath();
    ctx.arc(0,-lineHeight,lineWidth*1.5,0,Math.PI*2,true);
    ctx.fill();

    ctx.rotate(Math.PI/3);   //旋转画布
}
</script>

  1. 这个时候应该画每一主干上的支线。
    以之前的方法同理,也是在旋转之前计算好位置

贴出全代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>andy-js:用canvas绘制一朵美丽的雪花</title>
    <style>
    *{margin:0;padding:0}
    #c1{margin:20px auto;display: block;}

    /* .snowflake {
     animation: round 10s linear infinite;
    }

    @keyframes round {
        to {
            transform: rotate(1turn);
        }
    } */
    </style>
</head>
<body>
<canvas class="snowflake" id="c1" width="600" height="600">  
<script>
var oC1=document.getElementById('c1'),
    ctx = oC1.getContext("2d");
var w=oC1.offsetWidth,
    radius = w / 2;;

ctx.fillStyle="#000";
ctx.fillRect(0,0,w,w);  //背景涂黑
ctx.translate(radius,radius);//重新映射画布上的 (0,0) 位置  映射到画布正中间   

var lineWidth=parseInt(w/60),
    lineHeight=radius*0.8;  //主干线的宽度 长度

ctx.lineWidth=lineWidth;
ctx.strokeStyle='#fff';
ctx.fillStyle="#fff";

for(var i=0;i<6;i++){
    ctx.lineCap="round";//向线条的每个末端添加圆形线帽。

    ctx.fillStyle="#fff";
    ctx.beginPath();
    ctx.moveTo(0,0);
    ctx.lineTo(0,-lineHeight);
    ctx.stroke();
    

    //画顶端圆
    ctx.beginPath();
    ctx.arc(0,-lineHeight,lineWidth*1.5,0,Math.PI*2,true);
    ctx.fill();

    
    //画支线
    branch();
    
    //补一个圆  更好看
    var xy=getXY(37,lineHeight*0.13);   //37度和长度是通过效果,试出来的
    ctx.beginPath();
    ctx.arc(xy.x,xy.y-8,lineWidth*0.8,0,Math.PI*2,true);  //圆的半径也是试出来的
    ctx.fill();

    //旋转
    ctx.rotate(Math.PI/3);
};

function branch(){
    var start=-10,    
        gap=parseInt( (lineHeight-20)  /4),   //每根分支的间距
        spot;

    var heightArr=[ lineHeight*0.12,lineHeight*0.12,lineHeight*.2,lineHeight*0.3 ];
    for(var i=0;i<4;i++){
        ctx.lineCap=i==0?"square":"round";//向线条的每个末端添加圆形线帽。
        spot=getXY(45,heightArr[i]); 
        ctx.beginPath();
        ctx.moveTo(0,start);
        ctx.lineTo(spot.x, start+spot.y );
        ctx.stroke();
       
        ctx.beginPath();
        ctx.moveTo(0,start);
        ctx.lineTo(-(spot.x), start+spot.y );
        ctx.stroke();

        start-=gap;
    };
};


function getXY(angle,radius){      //通过正余弦区取XY坐标 
    return {
        x:Math.sin((180-angle)*Math.PI/180)*radius,
        y:Math.cos((180-angle)*Math.PI/180)*radius
    }
};
</script>
</body>
</html>

要旋转,就将CSS中的动画打开就即可。

在下一篇文章中,我计划封成JS方法,来绘制一个满天飞舞的雪花效果。

作者:andy