javascript转换静态图片,增加粒子动画效果
使用getImageData接口获取图片的像素点,然后基于像素点实现动画效果,封装成一个简单的lib
<!DOCTYPEhtml> <html> <head> <title>particleimage</title> <metacharset="utf-8"/> <style> #logo{ margin-left:20px; margin-top:20px; width:160px; height:48px; background:url('./images/logo.png'); /*border:1pxsolidred;*/ } </style> <scripttype="text/javascript"src="ParticleImage.js"></script> <script> window.onload=function(){ ParticleImage.create("logo","./images/logo.png","fast"); }; </script> </head> <body> <divid="logo"></div> </body> </html>
ParticleImage.js
/* TheMITLicense(MIT) Copyright(c)2015arest Permissionisherebygranted,freeofcharge,toanypersonobtainingacopyof thissoftwareandassociateddocumentationfiles(the"Software"),todealin theSoftwarewithoutrestriction,includingwithoutlimitationtherightsto use,copy,modify,merge,publish,distribute,sublicense,and/orsellcopiesof theSoftware,andtopermitpersonstowhomtheSoftwareisfurnishedtodoso, subjecttothefollowingconditions: Theabovecopyrightnoticeandthispermissionnoticeshallbeincludedinall copiesorsubstantialportionsoftheSoftware. THESOFTWAREISPROVIDED"ASIS",WITHOUTWARRANTYOFANYKIND,EXPRESSOR IMPLIED,INCLUDINGBUTNOTLIMITEDTOTHEWARRANTIESOFMERCHANTABILITY,FITNESS FORAPARTICULARPURPOSEANDNONINFRINGEMENT.INNOEVENTSHALLTHEAUTHORSOR COPYRIGHTHOLDERSBELIABLEFORANYCLAIM,DAMAGESOROTHERLIABILITY,WHETHER INANACTIONOFCONTRACT,TORTOROTHERWISE,ARISINGFROM,OUTOFORIN CONNECTIONWITHTHESOFTWAREORTHEUSEOROTHERDEALINGSINTHESOFTWARE. */ /** *Addparticleanimationforimage *usage: <scripttype="text/javascript"src="ParticleImage.js"></script> <script> window.onload=function(){ //besuretouseimagefileinyourownserver(preventCORSissue) ParticleImage.create("logo","logo_s2.png","fast"); }; </script> //inhtmlfile <divid="logo"></div> //youcansetdefaultbackgroundimageasusual #logo{ margin-left:20px; margin-top:20px; width:160px; height:48px; background:url('logo_s2.png'); } * *@authortianx.qin(rushi_wowen@163.com) *@fileParticleImage.js *@version0.9 */ varParticleImage=(function(window){ varcontainer=null,canvas=null; varctx=null,_spirit=[],timer=null, cw=0,ch=0,//containerwidth/height iw=0,ih=0,//imagewidth/height mx=0,my=0,//mouseposition bMove=true, MOVE_SPAN=4,DEFAULT_ALPHA=100, speed=100,S={"fast":10,"mid":100,"low":300}, ALPHA=255*255; //spiritclass varSpirit=function(data){ this.orginal={ pos:data.pos, x:data.x,y:data.y, r:data.r,g:data.g,b:data.b,a:data.a }; //changestate,foranimation this.current={ x:data.x, y:data.y, a:data.a }; }; /** *movespirittooriginalposition */ Spirit.prototype.move=function(){ varcur=this.current,orig=this.orginal; if((cur.x===orig.x)&&(cur.y===orig.y)){ //console.log("don'tmove:"+cur.y); returnfalse; } //console.log("move:"+cur.y); varrand=1+Math.round(MOVE_SPAN*Math.random()); varoffsetX=cur.x-orig.x, offsetY=cur.y-orig.y; varrad=offsetX==0?0:offsetY/offsetX; varxSpan=cur.x<orig.x?rand:cur.x>orig.x?-rand:0; cur.x+=xSpan; vartempY=xSpan==0?Math.abs(rand):Math.abs(Math.round(rad*xSpan)); varySpan=offsetY<0?tempY:offsetY>0?-tempY:0; cur.y+=ySpan; cur.a=((cur.x===orig.x)&&(cur.y===orig.y))?orig.a:DEFAULT_ALPHA; returntrue; }; /** *setrandomposition */ Spirit.prototype.random=function(width,height){ varcur=this.current; cur.x=width+Math.round(width*2*Math.random()); this.current.y=height+Math.round(height*2*Math.random()); }; /** *setrandompositionsforallspirits */ var_disorder=function(){ varlen=_spirit.length; for(vari=0;i<len;i++){ _spirit[i].random(cw,ch); } }; /** *starttomovespirit */ var_move=function(){ varsprt=_spirit; varlen=sprt.length; varisMove=false;//whetherneedtomove for(vari=0;i<len;i++){ if(sprt[i].move()){ isMove=true; } } isMove?_redraw():_stopTimer(); }; /** *redrawallspiritswhileanimating */ var_redraw=function(){ varimgDataObj=ctx.createImageData(iw,ih); varimgData=imgDataObj.data; varsprt=_spirit; varlen=sprt.length; //console.log("redrawimage:"+len); for(vari=0;i<len;i++){ vartemp=sprt[i]; //console.log("item:"+JSON.stringify(temp)); varorig=temp.orginal; varcur=temp.current; varpos=(cur.y*iw+cur.x)*4; imgData[pos]=orig.r; imgData[pos+1]=orig.g; imgData[pos+2]=orig.b; imgData[pos+3]=cur.a; } ctx.putImageData(imgDataObj,0,0); }; /** *addmousemove/mouseclickevent */ var_addMouseEvent=function(c){ c.addEventListener("mouseenter",function(e){ //console.log("e.y:"+e.clientY+","+container.offsetTop); _startTimer(); }); c.addEventListener("click",function(){ //disorderallspiritsandstartanimation _startTimer(); }); }; /** *calculateallpixelsofthelogoimage */ var_checkImage=function(imgUrl,callback){ //vartempCanvas=document.getElementById("temp"); //canvas.width=width; //canvas.height=height; varproc=function(image){ varw=image.width,h=image.height; iw=w,ih=h; //console.log("procimage"+image+","+w+","+h); canvas=_createCanvas(); //hidecontainerbackground container.style.backgroundPosition=(-w)+"px"; container.style.backgroundRepeat="no-repeat"; ctx.drawImage(image,0,0); //thismaycausesecurityerrorforCORSissue try{ varimgData=ctx.getImageData(0,0,w,h); vararrData=imgData.data; for(vari=0;i<arrData.length;i+=4){ varr=arrData[i],g=arrData[i+1],b=arrData[i+2],a=arrData[i+3]; if(r>0||g>0||b>0||a>0){ varpos=i/4; _spirit.push(newSpirit({ x:pos%w,y:Math.floor(pos/w), r:r,g:g,b:b,a:a })); } } returntrue; }catch(e){ //donothing returnfalse; } //returnout; }; varimg=newImage(); img.src=imgUrl; if(img.complete||img.complete===undefined){ proc(img)&&callback&&callback(); }else{ img.onload=function(){ proc(img)&&callback&&callback(); }; } }; //use"requestAnimationFrame"tocreateatimer,needbrowsersupport var_timer=function(func,dur){ //console.log("speedis"+dur); vartimeLast=null; varbStop=false; varbRunning=false;//preventrunningmorethanonce var_start=function(){ if(func){ if(!timeLast){ timeLast=Date.now(); func(); }else{ varcurrent=Date.now(); if(current-timeLast>=dur){ timeLast=current; func(); } } } if(bStop){ return; } requestAnimationFrame(_start); }; var_stop=function(){ bStop=true; }; return{ start:function(){ if(bRunning){ //console.log("alreadyrunning.."); return; } //console.log("startrunning.."); bRunning=true; bStop=false; _disorder(); _start(); }, stop:function(){ _stop(); bRunning=false; } }; }; var_startTimer=function(){ if(!timer){ timer=_timer(function(){ bMove&&_move(); },speed); } timer.start(); }; var_stopTimer=function(){ timer&&timer.stop(); }; /** *startprocess */ var_create=function(imgUrl){ _checkImage(imgUrl,function(){ //_createSpirits(); _addMouseEvent(canvas); //_startTimer(); }); }; var_setSpeed=function(s){ S[s]&&(speed=S[s]); }; /** *checkwhetherbrowsersupportscanvas */ var_support=function(){ try{ document.createElement("canvas").getContext("2d"); returntrue; }catch(e){ returnfalse; } }; /** *createacanvaselement */ var_createCanvas=function(){ varcav=document.createElement("canvas"); cav.width=iw; cav.height=ih; container.appendChild(cav); ctx=cav.getContext("2d"); returncav; }; /** *initializecontainerparams */ var_init=function(c,s){ if((!c)||(!_support())){//DIViddoesn'texist returnfalse; } container=c; cw=c.clientWidth; ch=c.clientHeight; s&&_setSpeed(s); returntrue; }; /** *export */ return{ "create":function(cId,imgUrl,s){//usercansetmovespeedby's'['fast','mid','low'] _init(document.getElementById(cId),s)&&_create(imgUrl); } }; })(window);
以上所述就是本文的全部内容了,希望大家能够喜欢。