雪花特效登录页面

前文已经讲过如何制作雪花特效demo,但是之前的雪花特效较为单一,本文将分为两部分一部分讲述如何制作复杂状态的雪花,另一部分讲述登录页面的制作

1.雪花特效的制作

var SNOW = function(width, height, center, havaCreated){
    this.width = width;
    this.height = height;
    this.center = center;
    this.init(havaCreated);
};
SNOW.prototype = {
    RADIUS : 20,//雪花半径
    DISTANCE : 4,  //雪花内部线条 间距
    COLOR : '#FFFAFA',//雪花颜色
    SCALE : {INIT : 0.04, DELTA : 0.01},//雪花比例 递增
    DELTA_ROTATE : {MIN : -Math.PI / 180 *0.5, MAX : Math.PI / 180 *0.5},//旋转角度
    MOVE : {MIN : -1, MAX : 1}, //位移速率
    LINE_WIDTH : 2, //雪花线宽

    init : function(havaCreated){
        this.setParameters(havaCreated);
        this.createSnow();
    },
    setParameters : function(havaCreated){
        this.topRadius = 2;//雪花顶部 小圆 半径
        if(!this.canvas){
            this.radius = this.RADIUS + this.LINE_WIDTH+this.topRadius+2;//获取半径
            this.length = this.radius * 2;
            this.canvas = $('<canvas />').attr({width : this.length, height : this.length}).get(0);
            this.context = this.canvas.getContext('2d');
        }
        
        
        var theta = Math.PI * 2 * Math.random(); //随机角度值
        
        this.x = this.center.x + 20 * Math.cos(theta);//随机x位置
        this.y = this.center.y + 20* Math.sin(theta);//随机y位置  使x,Y 都随机
        this.vx = this.getRandomValue(this.MOVE);//x随机扩散位置及速率
        this.vy = this.getRandomValue(this.MOVE);//y随机扩散位置及速率
        
        this.deltaRotate = this.getRandomValue(this.DELTA_ROTATE);//旋转速率
        this.scale = this.SCALE.INIT;//比例 0.04
        this.deltaScale = 1 + Math.random()*this.SCALE.DELTA;       //1->1.005
        this.rotate = 0;
        
        if(havaCreated){
            //经过几百次迭代 使初始雪花 获取不同位置 大小 速率
            for(var i = 0, count = 700; i < count; i++){
                this.x += this.vx;
                 this.y += this.vy;
                 this.scale *= this.deltaScale;//大小比例  0.04=>0.0404
                 this.rotate += this.deltaRotate;//旋转角度比率 -0.5->0.5
            }
        }
    },
    getRandomValue : function(range){
        return range.MIN + (range.MAX - range.MIN) * Math.random();
    },
    createSnow : function(){
        this.context.clearRect(0, 0, this.length, this.length);
        
        this.context.save();
        this.context.beginPath();
        this.context.translate(this.radius, this.radius);
        this.context.strokeStyle = this.COLOR;
        this.context.lineWidth = this.LINE_WIDTH;
        this.context.shadowColor = this.COLOR;
        
        //画雪花
        var angle60 = Math.PI / 180 * 60,
            sin60 = Math.sin(angle60),
            cos60 = Math.cos(angle60),
            threshold = Math.random() * this.RADIUS / this.DISTANCE , //0->5 雪花内部一个分支线条数量
            rate = 0.5 + Math.random() * 0.4,
            offsetY = this.DISTANCE * Math.random() * 2,//雪花外围线条 间距 不连接在一起
            offsetCount = this.RADIUS / this.DISTANCE;   // 5
        
        for(var i = 0; i < 6; i++){
            this.context.save();
            this.context.rotate(angle60 * i);//旋转角度 实现复制雪花
            //画出雪花的一部分
            
            //画出雪花内部线条 半径: 0->threshold
            for(var j = 0; j <= threshold; j++){
                var y = this.DISTANCE * j;//
                this.context.moveTo(0, y);
                this.context.lineTo(y * sin60, y * cos60);
            }
            //画出雪花外围 分散线条 半径: threshold->radius/DISTANCE
            for(var j = threshold; j < offsetCount; j++){
                var y = -this.DISTANCE * j, 
                    x = j * (offsetCount - j + 1) * rate;// rate 要求所画的线长度不得低于 0.5
                //因为要有间距 所以要减去offsetY 使复制的时候线条不连接在一起
                this.context.moveTo(x, y - offsetY);
                this.context.lineTo(0, y);
                this.context.lineTo(-x, y - offsetY);
            }
            this.context.moveTo(0, 0);
            //画出雪花主线
            this.context.lineTo(0, this.RADIUS);
            //线条尾部 加 小圆
            this.context.arc(0, this.RADIUS + this.topRadius, this.topRadius, 0, Math.PI * 2, false);
            this.context.restore();
        }
        this.context.stroke();
        this.context.restore();
    },
    render : function(context){
        context.save();
        
        if(this.scale > 0.5){ //大小大于0.5
            //透明度 无限接近于0
            context.globalAlpha = Math.max(0, (1 - this.scale) / 0.5);
            //大小比例大于1 或者没界 
            if(this.scale > 1 || this.x < -this.radius || this.x > this.width  || this.y < -this.radius || this.y > this.height ){
                context.restore(); //重置
                return false;
            }
        }
        context.translate(this.x, this.y); //每次移动的距离
        context.rotate(this.rotate);//旋转的角度
        context.scale(this.scale, this.scale);//x,y比例
        context.drawImage(this.canvas, this.radius, this.radius); //画画布
        context.restore();
        
         this.x += this.vx;
         this.y += this.vy;
         this.scale *= this.deltaScale;
         this.rotate += this.deltaRotate;
         return true;
    }
};

2.实现颜色渐变背景及批量生产雪花

    var backGround = {
    SNOWDATA: {COUNT : 800, DELTA : 1},
    COLOR : 'hsl(%h, 50%, %l%)', //色相(H)、饱和度(S)、明度(L
    HUE : 180,//初始色相
    DELTA_HUE : 0.1,//色相变化变量
    
    init : function(){
        this.setParameters();
        this.reconstructMethod();
        this.createSnow(this.SNOWDATA.COUNT, true);
        this.render();
    },
    setParameters : function(){
        this.width = $('#container').width();
        this.height = $('#container').height();
        this.center = {x : this.width / 2, y : this.height / 2};//中心位置
         this.canvas =document.getElementById("canvas");
         $('canvas').attr({width : this.width, height : this.height});
        this.context = this.canvas.getContext('2d');
        
        this.radius = Math.sqrt(this.center.x * this.center.x + this.center.y * this.center.y);//画布半径
        this.hue = this.HUE;
        this.snows = [];
    },
    reconstructMethod : function(){
        this.render = this.render.bind(this);
    },
    createSnow : function(count, toRandomize){
        for(var i = 0; i < count; i++){
            this.snows.push(new SNOW(this.width, this.height, this.center, toRandomize));
        }
    },
    render : function(){
        requestAnimationFrame(this.render);//按帧数渲染图形
        try{
            //创建圆形渐变 由 (x,y,0)->(x,y,radius)
        var gradient = this.context.createRadialGradient(this.center.x, this.center.y, 0, this.center.x, this.center.y, this.radius),
            backgroundColor = this.COLOR.replace('%h', this.hue);
        //按范围替换颜色
        gradient.addColorStop(0, backgroundColor.replace('%l', 30));
        gradient.addColorStop(0.2, backgroundColor.replace('%l', 20));
        gradient.addColorStop(1, backgroundColor.replace('%l', 5));
        
        this.context.fillStyle = gradient;
        this.context.fillRect(0, 0, this.width, this.height);
        
        for(var i = this.snows.length - 1; i >= 0; i--){
            if(!this.snows[i].render(this.context)){
                this.snows.splice(i, 1);//返回false  删除雪花  重置画布
            }
        }
        this.hue += this.DELTA_HUE;
        
        }
        catch(e){
            this.hue=this.HUE;
        }
        this.createSnow(this.SNOWDATA.DELTA, false);
    }
};

3.登录及整体HTML界面  ----(部分标签)

    <link href="css/font-awesome.min.css" rel="stylesheet" type="text/css" media="all">
         <link href="css/style.css" rel="stylesheet" type="text/css" media="all" />
        <script type='text/javascript' src="jquery.min.js"></script>
    </head>
    <body style="height:1000px;">
        <div id="container" style="height:100%;width:100%" >
            <canvas  id="canvas">你的浏览器不支持</canvas>
        </div>
            <div  id="loginDiv"style="position: absolute; width: 700px;z-index: 4;top:200px;left: 300px;">
            <div class="form-w3-agile">
                <h2 class="sub-agileits-w3layouts">登录</h2>
                <form action="#" method="post">
                    <input type="email" name="Eamil" placeholder="用户" required="" />
                    <input type="password" name="Password" placeholder="密码" required="" />
                    <a href="#" class="forgot-w3layouts">忘记密码 ?</a>
                    <div class="submit-w3l">
                        <input type="submit" value="登录">
                    </div>
                    <p class="p-bottom-w3ls">
                        <a href="signup.html">点击注册</a>如果你没有一个帐户。 .
                    </p>
                </form>
            </div>
        </div>

也可以灵活修改js文件实现不同效果

如下两种效果:

 github地址:https://github.com/x0216u/snow-Canvas#snow-canvas

posted @ 2017-09-27 15:54  绯叶阿卡丽  阅读(475)  评论(0编辑  收藏  举报