SOURCE

console 命令行工具 X clear

                    
>
console
   document.onreadystatechange = function(){
    var H = window.innerHeight,W = window.innerWidth;
    var canvas = new Canvas("canvas",W,H);
    var ctx = canvas.ctx;
    ctx.font = "160px 微软雅黑";
    ctx.fillStyle ="#fff";
    ctx.textBaseline="top";
    ctx.fillText("BiyugWv",0,0);
    //console.log(ctx)
    var textWidth = parseInt(ctx.measureText("BiyugWv").width)+20;
    var L = (W-textWidth)/2,T = (H-160)/2;
    
    // 获取文字位置
    var adata = ctx.getImageData(0,0,textWidth,200).data;
    var l = adata.length;
    var tdata = [];
    for(var i=0;i<l;i+=4){
        if(adata[i] == 255){
            var index = i/4,x = index%textWidth,y = parseInt(index/textWidth);
            tdata.push([x,y])
        }
    }
    ctx.clearRect(0,0,W,H);

    // particle
    var particle = [];
    for(var x in tdata){
        var v = tdata[x];
        if(x%30 == 0){
            
            particle.push({
                o : [v[0]+L,v[1]+T],
                c : [Math.random()*W,Math.random()*H],
                d : [0,0],
                f : 0,
            })
        }
    }
    
    for(var x in particle){
        var v  = particle[x];
        ctx.beginPath();
        ctx.fillStyle = "#fff";
        ctx.arc(v.c[0],v.c[1],1,0,Math.PI*2);
        ctx.fill();
        ctx.closePath();
    }

    function run(){
        ctx.clearRect(0,0,W,H);
        for(var x in particle){
            var v  = particle[x];
            if(Math.abs(v.c[0]-v.o[0])>1 || Math.abs(v.c[0]-v.o[0])>1){
                if(v.f){
                    if(distans(v.c[0],v.c[1],v.o[0],v.o[1])>100){
                        v.f = 0;
                    }else{
                        if(v.d[0]>1) v.d[0]*=0.9;
                        
                        if(v.d[1]>1)v.d[1]*=0.9;
                    }
                }else{
                    v.d[0] = (v.o[0]-v.c[0])/50;
                    v.d[1] = (v.o[1]-v.c[1])/50;
                }
                v.c[0]+=v.d[0];
                v.c[1]+=v.d[1];
            }else{
                v.c[0]+= Math.random()>0.5 ? Math.random() : - Math.random();
                v.c[1]+= Math.random()>0.5 ? Math.random() : - Math.random();
            }
            ctx.beginPath();
            ctx.fillStyle = "#fff";
            ctx.arc(v.c[0],v.c[1],1,0,Math.PI*2);
            ctx.fill();
            ctx.closePath();
            
        }
        requestAnimationFrame(run)
    }
    canvas.canvas.addEventListener("click",function(e){
        var x = e.offsetX,y = e.offsetY;
        for(var xx in particle){
            var v  = particle[xx];
            if(distans(v.c[0],v.c[1],x,y)<50){
                
                v.f = 1;
                v.d[0] = v.c[0]-x
                v.d[1] = v.c[1]-y
            }
        }
    })
    run()


    // 

    function distans(x1,y1,x2,y2){
        return Math.sqrt(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)));
    }
}


/////////////////////////////////////////////////////////////////////////

/*
 *  添加canvas
 *  @param Sring id  ,int w , int h
 */

function Canvas(id,w,h){
    Canvas.version = "1.0.1";
    Canvas.list = Canvas.list || [];
    Canvas.canvasIds = Canvas.canvasIds || {}
    const count = Canvas.list.length
    Canvas.count = count+1;
    this.create(id,w,h,count);
}
Canvas.prototype = {
    create(id,w,h,count){
        let canvas = document.createElement("canvas");
        if(Canvas.canvasIds[id]){
            console.error(id+"---此ID名已存在");
            return false;
        }
        w = w == "100%" ? window.innerWidth : w;
        h = h == "100%" ? window.innerHeight : h;
        canvas.setAttribute("dataid",id);
        canvas.width = w;
        canvas.height = h;
        canvas.style.width = w+"px";
        canvas.style.height = h+"px";
        canvas.style.position ="absolute";
        canvas.style.top  = 0;
        canvas.style.left = 0;
        canvas.style.backgroundColor = "#000";
        canvas.style.zIndex = 1000+count;
        Canvas.canvasIds[id] = canvas;
        this.w = w;
        this.h = h;
        this.index = count;
        this.canvas = canvas;
        this.ctx = canvas.getContext("2d");
        Canvas.list.push(id)
        document.body.appendChild(canvas)
        return this;
    },
    setStyle(opt){
        for(let x in opt){
            this.canvas.style[this.styleHump(x)] = opt[x];
        }
        return this;
    },
    hide(id){
	    if(id && Canvas.canvasIds[id])Canvas.canvasIds[id].style.dispaly = "none";
	    else  this.canvas.style.dispaly = "none";
	    return this;
	    
    },
    show(id){
	    if(id && Canvas.canvasIds[id])Canvas.canvasIds[id].style.dispaly = "block";
	    else  this.canvas.style.dispaly = "block";
	    return this;
    },
    remove(id){
	    if(id && Canvas.canvasIds[id]){
		    const canvas =  Canvas.canvasIds[id];
	    }
	    else {
		   const canvas =  this.canvas;
	    }
	    document.body.removeChild(canvas)
	    return this;
    },
    setGrid(i,j,s){
	    const ctx = this.ctx;
	    s = s || "rgba(255,255,255,.2)";
	    i = parseInt(i) || 10;
	    j = parseInt(j) || 10;
	    dx = (this.w/i).toFixed(2);
	    dy = (this.h/j).toFixed(2);
	    ctx.strokeStyle = s;
	    ctx.lineWidth=1;
	    i+=1;j+=1;
	    while(i--){
		    let x = i*dx;
		    x = parseInt(x)+0.5;
		    ctx.beginPath();
		    ctx.moveTo(x,0);
		    ctx.lineTo(x,this.h);
		    ctx.closePath();
		    ctx.stroke();
	    }
	    while(j--){
		    let y = j*dy;
		    y = parseInt(y)+0.5;
		    ctx.beginPath();
		    ctx.moveTo(0,y);
		    ctx.lineTo(this.w,y);
		    ctx.closePath();
		    ctx.stroke();
	    }
	    return this;
    },
    animate(opt,time,type,cb){
	    if(!this.animateQueue) this.animateInit();
		// add animate to queue
		if(typeof type === 'function'){
			cb = type;
			type  = 'line';
		}
		if(!type){
			cb = false;
			type  = 'line';
		}
		opt = this.optFilter(opt);
		const animation = {
			opt : opt,
			time : time,
			type : type,
			cb : cb,
			addTime :  +new Date,
			startTime : 0,
		} 
		this.animateQueue.push(animation);
	    if(!this.animateStat){
		    this.animateStat = 1;
		    this.animateRun();
	    }
	    return this;
    },
    optFilter(opt){
	    let ropt = {};
	    const k = "margin-left,margin-right,margin-top,margin-bottom,top,left,right,bottom,width,height,opacity,";
	    for(let x in opt){
		    if(k.indexOf(x+',')>-1){
			    let v = opt[x].toString();
			    if(v.indexOf("%")>-1){
				    if(x == "marfgin-left"  || x == "marfgin-right" || x == "left" || x == "right"){
					    v = window.innerWidth*parseInt(v)/100;
				    }
				    if(x == "marfgin-top"  || x == "marfgin-bottom" || x == "top" || x == "bottom"){
					    v = window.innerHeight*parseInt(v)/100;
				    }
				    if(x == "height"){
					    v = this.h*parseInt(v)/100;
				    }
				    if(x == "width"){
					    v = this.h*parseInt(v)/100;
				    }
			    }
			    ropt[x] = v;
		    }
		    
	    }
	    return ropt;
    },
    styleHump(string){
        if(string.indexOf("-")){
    		const arr = string.split("-");
    		string = '';
    		for(let  x in arr){
    			let v = arr[x];  // toLocaleUpperCase
    			if(x>0)  v = v[0].toLocaleUpperCase()+v.substr(1);
    			string+=v;
    		}
    	}
    	return string;
    },
    animateInit(){
	    this.animateQueue = [];
	    this.animateStat = 0;
	    this.animateInterval = 0;
	 	this.getStyle();
    },
    getStyle(){
	    const style0 = JSON.stringify(getComputedStyle(this.canvas,false));
  	const style = JSON.parse(style0);
	    this.animateStyle = style;  
    },
    animateRun(){
	    const _this = this;
	    if(this.animateQueue.length && this.animateStat > 0 ){
			let currentAnimation = this.animateQueue[0];
			// run animation
			if(!currentAnimation.startTime) currentAnimation.startTime = +new Date;
			let opt = {};
			const d = (+new Date) -  currentAnimation.startTime;
			for(let x in currentAnimation.opt){
				let v = parseInt(currentAnimation.opt[x])
				let ov = parseInt(this.animateStyle[this.styleHump(x)]);
				let nv = Easing[currentAnimation.type](d,ov,v-ov,currentAnimation.time);
				opt[x] = nv+"px";
				//console.log(v,ov,nv)
			}
			if((+new Date)- currentAnimation.startTime>= currentAnimation.time){
				this.setStyle(currentAnimation.opt);
				this.getStyle();
				this.animateQueue.shift(0,1);
				if(currentAnimation.cb)currentAnimation.cb();
			}else{
				this.setStyle(opt)
			}
			requestAnimationFrame(function(){_this.animateRun()});
		    
	    }else{
		    this.animateStat = 0;
	    }
    }
}



 const Easing = {
    line :  function(t,b,c,d){
		return c*(t/d) + b
	},
	swing: function ( t, b, c, d) {
		return this.easeOutQuad( t, b, c, d);
	},
	easeInQuad: function ( t, b, c, d) {
		return c*(t/=d)*t + b;
	},
	easeOutQuad: function ( t, b, c, d) {
		return -c *(t/=d)*(t-2) + b;
	},
	easeInOutQuad: function ( t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t + b;
		return -c/2 * ((--t)*(t-2) - 1) + b;
	},
	easeInCubic: function ( t, b, c, d) {
		return c*(t/=d)*t*t + b;
	},
	easeOutCubic: function ( t, b, c, d) {
		return c*((t=t/d-1)*t*t + 1) + b;
	},
	easeInOutCubic: function ( t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t + b;
		return c/2*((t-=2)*t*t + 2) + b;
	},
	easeInQuart: function ( t, b, c, d) {
		return c*(t/=d)*t*t*t + b;
	},
	easeOutQuart: function ( t, b, c, d) {
		return -c * ((t=t/d-1)*t*t*t - 1) + b;
	},
	easeInOutQuart: function ( t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
		return -c/2 * ((t-=2)*t*t*t - 2) + b;
	},
	easeInQuint: function ( t, b, c, d) {
		return c*(t/=d)*t*t*t*t + b;
	},
	easeOutQuint: function ( t, b, c, d) {
		return c*((t=t/d-1)*t*t*t*t + 1) + b;
	},
	easeInOutQuint: function ( t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
		return c/2*((t-=2)*t*t*t*t + 2) + b;
	},
	easeInSine: function ( t, b, c, d) {
		return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
	},
	easeOutSine: function ( t, b, c, d) {
		return c * Math.sin(t/d * (Math.PI/2)) + b;
	},
	easeInOutSine: function ( t, b, c, d) {
		return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
	},
	easeInExpo: function ( t, b, c, d) {
		return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
	},
	easeOutExpo: function ( t, b, c, d) {
		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
	},
	easeInOutExpo: function ( t, b, c, d) {
		if (t==0) return b;
		if (t==d) return b+c;
		if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
		return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
	},
	easeInCirc: function ( t, b, c, d) {
		return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
	},
	easeOutCirc: function ( t, b, c, d) {
		return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
	},
	easeInOutCirc: function ( t, b, c, d) {
		if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
		return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
	},
	easeInElastic: function ( t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
	},
	easeOutElastic: function ( t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
	},
	easeInOutElastic: function ( t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
	},
	easeInBack: function ( t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		return c*(t/=d)*t*((s+1)*t - s) + b;
	},
	easeOutBack: function ( t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
	},
	easeInOutBack: function ( t, b, c, d, s) {
		if (s == undefined) s = 1.70158; 
		if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
	},
	easeInBounce: function ( t, b, c, d) {
		return c - this.easeOutBounce ( d-t, 0, c, d) + b;
	},
	easeOutBounce: function ( t, b, c, d) {
		if ((t/=d) < (1/2.75)) {
			return c*(7.5625*t*t) + b;
		} else if (t < (2/2.75)) {
			return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
		} else if (t < (2.5/2.75)) {
			return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
		} else {
			return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
		}
	},
	easeInOutBounce: function ( t, b, c, d) {
		if (t < d/2) return this.easeInBounce ( t*2, 0, c, d) * .5 + b;
		return this.easeOutBounce ( t*2-d, 0, c, d) * .5 + c*.5 + b;
	}
}










<script src="js/canvas.js"></script>