Canvas实现文字散粒子化

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <meta name="Generator" content="EditPlus®">
  <meta name="Author" content="">
  <meta name="Keywords" content="">
  <meta name="Description" content="">
  <title>Document</title>
    <style type="text/css">
        *{
            margin:0;
            padding:0;
        }
        body,html{
            font-family:"Microsoft Yahei";
        }
        #can{
            display:block;
            margin:0 auto;
        }
        #wrap{
            width:500px;
            height:100px;
            margin:0 auto;
            text-align:center;
        }
    </style>
 </head>
 <body>
    <canvas id="can" width="1000" height="500">浏览器不支持canvas</canvas>
    <div id="wrap">
        <input type="text" id="text" value="人决定一切" width="80px"><input type="submit" id="submit">
    </div>

    <script type="text/javascript">
        window.onload = function(){
            var submitDom = document.getElementById("submit");
            var textDom = document.getElementById("text");
            var can = document.getElementById("can");
            var ctx = can.getContext("2d");

            var textVal = "";
            var initz = 250;
            var thisTIme = null;
            var animTime = null;
            var grains = [];

            function initAnimate(){
                grains = [];
                textVal = textDom.value;
                drawText(textVal);
                var imgDate = ctx.getImageData(0,0,can.width,can.height);
                ctx.clearRect(0,0,can.width , can.height);
                for(var i=0;i<imgDate.width;i+=6){
                    for(var j=0;j<imgDate.height;j+=6){
                        var index = (j*imgDate.width + i)*4;
                        if(imgDate.data[index]>128){
                            var grain = new Grain(i,j,0,3);
                            grains.push(grain);
                        }
                    }
                }
                animate();
            }

            var lock = true;
            var pause = false;
        
            /*
                this.x = Math.random()*can.width;//x轴坐标
                this.y = Math.random()*can.height;//y轴坐标
                this.z = Math.random()*initz*2;//z轴坐标
                this.ix = Math.random()*can.width;//初始化x轴坐标
                this.iy = Math.random()*can.height;//初始化y轴坐标
                this.iz = Math.random()*initz*2;//初始化z轴坐标
                this.tx = x;//目标x轴坐标
                this.ty = y;//目标y轴坐标
                this.tz = z;//目标z轴坐标
            */

            function animate(){
                thisTIme = new Date();
                ctx.clearRect(0,0,can.width,can.height);
                grains.forEach(function(item){
                    if(lock){
                        if(Math.abs(item.tx-item.x)<0.1&&Math.abs(item.ty-item.y)<0.1&&Math.abs(item.tz-item.z)<0.1){
                            item.x = item.tx;
                            item.y = item.ty;
                            item.z = item.tz;
                            if(thisTIme-animTime>300) lock = false;
                        } else{
                            item.x += (item.tx-item.x)*0.1;
                            item.y += (item.ty-item.y)*0.1;
                            item.z += (item.tz-item.z)*0.1;
                            animTime = new Date();
                        }
                    }else{
                        if(Math.abs(item.ix-item.x)<0.1&&Math.abs(item.iy-item.y)<0.1&&Math.abs(item.iz-item.z)<0.1){
                            item.x = item.ix;
                            item.y = item.iy;
                            item.z = item.iz;
                            pause = true;
                            console.log("执行完毕!");
                        } else{
                            item.x += (item.ix-item.x)*0.1;
                            item.y += (item.iy-item.y)*0.1;
                            item.z += (item.iz-item.z)*0.1;
                            pause = false;
                        }
                    }
                    item.draw();
                })
                
                 if(!pause) {
                    if("requestAnimationFrame" in window){
                        requestAnimationFrame(animate);
                    }
                    else if("webkitRequestAnimationFrame" in window){
                        webkitRequestAnimationFrame(animate);
                    }
                    else if("msRequestAnimationFrame" in window){
                        msRequestAnimationFrame(animate);
                    }
                    else if("mozRequestAnimationFrame" in window){
                        mozRequestAnimationFrame(animate);
                    }
                }
            }

            function Grain(x,y,z,r){
                this.x = Math.random()*can.width;//x轴坐标
                this.y = Math.random()*can.height;//y轴坐标
                this.z = Math.random()*initz*2-initz;//z轴坐标
                this.ix = Math.random()*can.width;//初始化x轴坐标
                this.iy = Math.random()*can.height;//初始化y轴坐标
                this.iz = Math.random()*initz*2-initz;//初始化z轴坐标
                this.tx = x;//目标x轴坐标
                this.ty = y;//目标y轴坐标
                this.tz = 0;
                this.r = r;//粒子半径
            }

            Grain.prototype = {
                draw : function(){
                    ctx.save();
                    ctx.beginPath();
                    var scale = initz/(initz + this.z);
                    ctx.fillStyle = "rgba(50,50,50,"+ scale +")";
                    ctx.arc(can.width/2 + (this.x-can.width/2)*scale , can.height/2 + (this.y-can.height/2) * scale, this.r*scale , 0 , 2*Math.PI);
                    ctx.closePath();
                    ctx.fill();
                    ctx.restore();
                }
            }

            function drawText(text){
                ctx.save();
                ctx.font = "200px 微软雅黑 bold";
                ctx.fillStyle = "rgba(168,168,168,1)";
                ctx.textAlign = "center"
                ctx.textBaseLine = "middle";
                ctx.fillText(text,can.width/2,can.height/2);
                ctx.restore();
            }
            
            submitDom.onclick = function(){
                initAnimate();
                lock = true;
                pause = false;
            }

            initAnimate();
        }
    </script>
</body>
</html>

效果图:

 

IT技术和行业交流群 417691667

posted @ 2016-08-07 22:24  悬崖边上  阅读(1353)  评论(0编辑  收藏  举报