zoukankan      html  css  js  c++  java
  • 雪花特效登录页面

    前文已经讲过如何制作雪花特效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%;100%" >
                <canvas  id="canvas">你的浏览器不支持</canvas>
            </div>
                <div  id="loginDiv"style="position: absolute;  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

  • 相关阅读:
    TCP/IP四层模型
    Java编程题
    大整数阶乘的运算(可以计算1000!) .
    sleep和wait的区别
    Javascript保留字(Javascript Reserved Words)
    WEBLOGIC 内存溢出 解决方案
    Java学习的30个目标以及系统架构师推荐的书
    笔记分析
    MySQL分区(Partition)功能试验
    Java线程:生产者消费者模型
  • 原文地址:https://www.cnblogs.com/x0216u/p/7602173.html
Copyright © 2011-2022 走看看