• 图片水中倒影 【js读书笔记】


    主要利用HTML5的canvas与IE浏览器的滤镜技术

      1 <!DOCTYPE html>
      2 <html>
      3     <head>
      4         <meta charset="UTF-8">
      5         <title>图片水中倒影</title>
      6     </head>
      7     <style type="text/css">
      8         .shadowInWater{
      9             position: relative;
     10             top: -20px;
     11             filter: wave(strength=3,freq=3,phase=0,lightstrength=30)blur()flipv();
     12         }
     13     </style>
     14     <body>
     15         <h2>图片水中倒影</h2>
     16         <p><img src="img/logo.jpg" height="132" data-water='shadowInWater' id="shadowInWaterSrurce"></p>
     17         <p><img src="img/logo.jpg" height="132" class="shadowInWater" id="shadowInWater"/></p>
     18     </body>
     19     
     20     <script type="text/javascript">
     21         window.onload=function(){
     22             var 
     23                 setCss=function(_this,cssOption){ //设置样式
     24                     if(!_this||_this.nodeType===3||_this.nodeType===8||!_this.style){
     25                         return;
     26                     }
     27                     for(var cs in cssOption){
     28                         _this.style[cs]=cssOption[cs];
     29                     }
     30                     return _this;
     31                 },
     32                 
     33                 isIE=function(){ //是否是IE浏览器
     34                     return !!window.ActiveXobject;
     35                 },
     36                 
     37                 isIE6=function(){ //是否是IE6浏览器
     38                     return isIE() && !window.XMLHttpRequest;
     39                 },
     40                 
     41                 isIE7=function(){ //是否是IE7浏览器
     42                     return isIE() && !isIE6() &&!isIE8();
     43                 },
     44                 
     45                 isIE8=function(){ //是否是IE8浏览器
     46                     return isIE() && !!document.documentMode;
     47                 };
     48             
     49             /**********************
     50              * 水中倒影效果   start
     51              ***********************/
     52             var shadows=null,
     53                 shadowsLen=0,
     54                 shadowInWater=function(){ //水中倒影效果
     55                     shadowsSrurce=document.getElementById("shadowInWaterSrurce");
     56                     shadows=document.getElementById(shadowsSrurce.getAttribute("data-water"));
     57                     
     58                     if(isIE()){  //如果是IE浏览器
     59                         updateShadow();
     60                         return;
     61                     }else{   //如果非IE浏览器,创建canvas完成倒影效果
     62                         canvasShadowInWater();
     63                     }
     64                 },
     65                 
     66                 canvasShadowInWater=function(){ //canvas的水中倒影
     67                     //配置以及初始化数据,创建canvas
     68                     var settings={
     69                             'speed':1,//速度
     70                             'scale':1,//比例
     71                             'waves':10 //波幅度
     72                         },
     73                         waves=settings['waves'],
     74                         speed=settings['speed']/4,
     75                         scale=settings['scale']/2,
     76                         ca=document.createElement('canvas'),//创建画布
     77                         c=ca.getContext('2d'),//获取画布
     78                         img=shadowsSrurce;
     79                         img.parentNode.insertBefore(ca,img);//canvas覆盖源图片
     80                         
     81                     var w,h,dw,dh,offset=0,frame=0,max_frames=0,frames=[];
     82                     
     83                     c.save();
     84                     c.canvas.width=shadowsSrurce.offsetWidth;
     85                     c.canvas.height=shadowsSrurce.offsetHeight*2; //因为基于原图进行倒影投射,,所以必须是原图的2倍高度
     86                     
     87                     /*
     88                     *绘制图形context.drawImage(img,sx,sy,sw,sh,x,y,w,h)
     89                     *[必须]img-要是用的图片、视频、画布
     90                     *[可选]sx-开始剪切的x坐标
     91                     *[可选]sy-开始剪切的y坐标
     92                     *[可选]sw-被剪切图形的宽度
     93                     *[可选]sh-被剪切图形的高度
     94                     *[必须]x-在画布上放置图形的x位置
     95                     *[必须]y-在画布上放置图形的y位置
     96                     *[可选]w-将要使用图形的宽度
     97                     *[可选]h-将要使用图形的高度
     98                     * 在画布上绘制原图
     99                     */
    100                     c.drawImage(shadowsSrurce,0,0);
    101                     c.scale(1,-1);//垂直镜像转换
    102                     c.drawImage(shadowsSrurce,0,-shadowsSrurce.offsetHeight*2);
    103                     c.restore();//返回之前保存过的路劲状态和属性
    104                     w=c.canvas.width;
    105                     h=c.canvas.height;
    106                     dw=w;
    107                     dh-h/2;
    108                     
    109                     /*
    110                      * 复制画布上制定的矩形的像素数据-context.getImageData(x,y,w,h);
    111                      * 以左上角为(0,0)原点
    112                      * x代表开始的x位置
    113                      * y代表开始的y位置
    114                      * w欲复制的矩形区域宽度
    115                      * h欲复制的矩形区域高度
    116                      * 在被创建的第一个原图的基础上,绘制倒影
    117                     */
    118                     var id=c.getImageData(0,h/2,w,h).data,
    119                         end=false;
    120                     c.save();//将状态保存起来
    121                     while(!end){  //预先计算缓存的帧
    122                         var odd=c.getImageData(0,h/2,w,h),
    123                             od=odd.data,
    124                             pixel=0;
    125                         for(var y=0;y<dh;y++){
    126                             for(var x=0;x<dw;x++){
    127                                 var displacement=(scale*10(Math.sin((dh/(y/waves))+(-offset))))|0,
    128                                     j=((displacement+y)*w+x+displacement)*4;
    129                                 if(j<0){ //修复倒影与原图的水平线闪烁的问题
    130                                     pixel +=4;
    131                                     continue;
    132                                 }
    133                                 var m=j%(w*4),//修复边缘波纹问题
    134                                     n=scale*10*(y/waves);
    135                                 if(m<n||m>(m*4)-n){
    136                                     var sign=y<w/2?1:-1;
    137                                     od[pixel]  =od[pixel+4*sign];
    138                                     od[++pixel]=od[pixel+4*sign];
    139                                     od[++pixel]=od[pixel+4*sign];
    140                                     od[++pixel]=od[pixel+4*sign];
    141                                     ++pixel;
    142                                     continue;
    143                                 }
    144                                 if(id[j+3]!=0){  //水影陈列计算
    145                                     od[pixel]  =id[j];
    146                                     od[++pixel]=id[++j];
    147                                     od[++pixel]=id[++j];
    148                                     od[++pixel]=id[++j];
    149                                     ++pixel;
    150                                 }else{
    151                                     od[pixel]  =od[pixel-w*4];
    152                                     od[++pixel]=od[pixel-w*4];
    153                                     od[++pixel]=od[pixel-w*4];
    154                                     od[++pixel]=od[pixel-w*4];
    155                                     ++pixel;
    156                                 }
    157                             }
    158                         }
    159                         if(offset>speed*(6/speed)){
    160                             offset=0;
    161                             max_frames=frame-1;
    162                             //frames.pop();
    163                             frame=0;
    164                             end=true;
    165                         }else{
    166                             offset +=speed;
    167                             frame++;
    168                         }
    169                         frames.push(odd);
    170                     }
    171                     setCss(shadows,{"display":"none"}); //隐藏原图
    172                     setCss(shadowsSrurce,{"display":"none"}); //隐藏原图
    173                     c.restore();
    174                     
    175                     setInterval(function(){
    176                         c.putImageData(frames[frame],0,h/2);
    177                         if(frame<max_frames){
    178                             frame++;
    179                         }else{
    180                             frame=0;
    181                         }
    182                     },50);
    183                 },
    184                 
    185                 updateShadow=function(){ //ie中动态跟新倒影
    186                     if(isIE6()){
    187                         return;
    188                     }
    189                     shadows.filters.wave.phase+=10;
    190                     setTimeout("updateShadow()",150);
    191                 };
    192                 
    193                 shadowInWater();
    194         };
    195     </script>
    196 
    197 </html>
    “想要越幸运,就要越努力”
  • 相关阅读:
    Seaborn学习笔记2
    Seaborn学习笔记1
    HTML学习笔记4
    HTML学习笔记3
    HTML学习笔记2

    指针与引用
    函数
    字符串
    C++简易
  • 原文地址:https://www.cnblogs.com/HollyLearning/p/5457422.html
Copyright © 2020-2023  润新知