zoukankan      html  css  js  c++  java
  • [读码][js,css3]能感知鼠标方向的图片遮罩效果

    效果图:

    无意间看到过去流行的一个效果:[能感知鼠标方向的图片遮罩效果]
    近来不忙,就仔细的看了一看
    看到后来发现,网上有好多版本,谁是原著者似乎已经无法考证。
    读码就要读比较全面的,读像是原著的代码。
    代码随然不难,不过要能想到这个创意,并成功应用却很难!

    另外,对于初学者,这也是不错的学习例子。
    含Jquery插件写法,css3等

    英文教程:http://tympanus.net/TipsTricks/DirectionAwareHoverEffect/
    源码下载:http://tympanus.net/TipsTricks/DirectionAwareHoverEffect/DirectionAwareHoverEffect.zip

    先大致翻译一下,再细看加点东西:

    效果:在缩略图上遮盖一个图层,能够根据鼠标进入的方向遮盖缩略图,当鼠标离开时,该图层也会跟着鼠标方向离开。这个会是一个有趣的效果。

    实现方法:
    1.HTML 我们放置一个无序的li列表,存放缩略图以及遮盖层

     1 <ul id="da-thumbs" class="da-thumbs">
     2 <li>
     3 <a href="http://dribbble.com/shots/502538-Natalie-Justin-Cleaning">
     4 <img src="images/7.jpg" />
     5 <div><span>Natalie & Justin Cleaning by Justin Younger</span></div>
     6 </a>
     7 </li>
     8 <li>
     9 <!-- ... -->
    10 </li>
    11 <!-- ... -->
    12 </ul>

    2.CSS 该列表使用左浮动样式,并定义使用相对位置,这样可以对遮盖层[描述层]使用决定位置定位

    关于css定位:http://www.divcss5.com/rumen/r403.shtml

     1 .da-thumbs li {
     2 float: left;
     3 margin: 5px;
     4 background: #fff;
     5 padding: 8px;
     6 position: relative;
     7 box-shadow: 0 1px 3px rgba(0,0,0,0.1);
     8 }
     9 .da-thumbs li a,
    10 .da-thumbs li a img {
    11 display: block;
    12 position: relative;
    13 }
    14 .da-thumbs li a {
    15 overflow: hidden;
    16 }
    17 .da-thumbs li a div {
    18 position: absolute;
    19 background: rgba(75,75,75,0.7);
    20 width: 100%;
    21 height: 100%;
    22 }

    3.JS 后面要做的是:

    先根据鼠标进入的位置,我们可以给遮盖层赋予计算出来的from样式[遮盖层初期位置]
    再使用[css3 transition]进行属性变化的过度,时遮盖层达到最终状态
    最后当鼠标离开时,鼠标移出事件中计算得到的from样式移出遮盖层位置,并移除上次的最终状态
    下面是JQuery小插件核心代码:

     1 /*
     2 鼠标移入,移出事件监听
     3 监听的事件加入了命名空间,便于该事件的管理
     4 最好在on方法前使用off方法解除其他代码中对该命名空间事件可能的绑定
     5 */
     6 this.$el.on( 'mouseenter.hoverdir, mouseleave.hoverdir', function( event ) {    
     7 /*定义变量,存储遮盖层,计算得到的方向,计算得到的样式*/
     8 var $el = $( this ),
     9 $hoverElem = $el.find( 'div' ),
    10 direction = self._getDir( $el, { x : event.pageX, y : event.pageY } ),
    11 styleCSS = self._getStyle( direction );
    12 if( event.type === 'mouseenter' ) {
    13 /*
    14 鼠标移入时
    15 隐藏遮盖层
    16 赋予初始位置
    17 清除延迟动画计时器
    18 显示遮盖层后
    19 如果支持css3 transition
    20 赋予transition属性
    21 使用延迟动画计时器进行动画效果[_applyAnimation方法]
    22 如果支持css3 transition,则只做样式变更
    23 否则,使用动画方法animate,实现过度效果
    24 */
    25 $hoverElem.hide().css( styleCSS.from );
    26 clearTimeout( self.tmhover );
    27 self.tmhover = setTimeout( function() {
    28 $hoverElem.show( 0, function() {
    29 var $el = $( this );
    30 if( self.support ) {
    31 $el.css( 'transition', self.transitionProp );
    32 }
    33 self._applyAnimation( $el, styleCSS.to, self.options.speed );
    34 } );
    35 }, self.options.hoverDelay );
    36 }
    37 else {
    38 /*
    39 鼠标移出时
    40 如果支持css3 transition
    41 赋予transition属性
    42 清除延迟动画计时器
    43 使用延迟动画计时器进行动画效果[_applyAnimation方法]
    44 */
    45 if( self.support ) {
    46 $hoverElem.css( 'transition', self.transitionProp );
    47 }
    48 clearTimeout( self.tmhover );
    49 self._applyAnimation( $hoverElem, styleCSS.from, self.options.speed );
    50 }
    51 } );

    4.JS JS全部代码加,追加注释说明

      1 /**
      2  * jquery.hoverdir.js v1.1.0
      3  * http://www.codrops.com
      4  *
      5  * Licensed under the MIT license.
      6  * http://www.opensource.org/licenses/mit-license.php
      7  * 
      8  * Copyright 2012, Codrops
      9  * http://www.codrops.com
     10  */
     11 ;( function( $, window, undefined ) {
     12     'use strict';
     13     $.HoverDir = function( options, element ) {
     14         this.$el = $( element ); // li元素
     15         this._init( options );
     16     };
     17     // the options
     18     $.HoverDir.defaults = {
     19         speed : 300,
     20         easing : 'ease',
     21         hoverDelay : 0,
     22         inverse : false
     23     };
     24     $.HoverDir.prototype = {
     25         _init : function( options ) {
     26             /*
     27             初期化
     28             1.参数获取
     29             2.css3 transition 设定
     30             3.是否支持css3 transition判定
     31             4.事件绑定
     32             */
     33             // options
     34             this.options = $.extend( true, {}, $.HoverDir.defaults, options );
     35             // transition properties
     36             this.transitionProp = 'all ' + this.options.speed + 'ms ' + this.options.easing;
     37             // support for CSS transitions
     38             this.support = Modernizr.csstransitions;
     39             // load the events
     40             this._loadEvents();
     41         },
     42         _loadEvents : function() {
     43             /*参照博文3.JS*/
     44             var self = this;
     45             this.$el.on( 'mouseenter.hoverdir, mouseleave.hoverdir', function( event ) {
     46                 var $el = $( this ),
     47                     $hoverElem = $el.find( 'div' ),
     48                     direction = self._getDir( $el, { x : event.pageX, y : event.pageY } ),
     49                     styleCSS = self._getStyle( direction );
     50                 if( event.type === 'mouseenter' ) {
     51                     $hoverElem.hide().css( styleCSS.from );
     52                     clearTimeout( self.tmhover );
     53                     self.tmhover = setTimeout( function() {
     54                         $hoverElem.show( 0, function() {
     55                             var $el = $( this );
     56                             if( self.support ) {
     57                                 $el.css( 'transition', self.transitionProp );
     58                             }
     59                             self._applyAnimation( $el, styleCSS.to, self.options.speed );
     60                         } );
     61                     
     62                     }, self.options.hoverDelay );
     63                 }
     64                 else {
     65                     if( self.support ) {
     66                         $hoverElem.css( 'transition', self.transitionProp );
     67                     }
     68                     clearTimeout( self.tmhover );
     69                     self._applyAnimation( $hoverElem, styleCSS.from, self.options.speed );
     70                 }
     71             } );
     72         },
     73         // credits : http://stackoverflow.com/a/3647634
     74         _getDir : function( $el, coordinates ) {
     75             /*返回鼠标事件的当前相对方位(上右下左=0123)*/
     76             // the width and height of the current div
     77             var w = $el.width(),
     78                 h = $el.height(),
     79                 // calculate the x and y to get an angle to the center of the div from that x and y.
     80                 //根据鼠标位置x,y计算角度
     81                 // gets the x value relative to the center of the DIV and "normalize" it
     82                 /*
     83                     通过鼠标移动事件发生的页面坐标x,y,计算出以div中心为原点的x,y坐标
     84                     计算关联到div偏移位置,div长宽度以及长宽比
     85                 */
     86                 x = ( coordinates.x - $el.offset().left - ( w/2 )) * ( w > h ? ( h/w ) : 1 ),
     87                 y = ( coordinates.y - $el.offset().top  - ( h/2 )) * ( h > w ? ( w/h ) : 1 ),
     88                 // the angle and the direction from where the mouse came in/went out clockwise (TRBL=0123);
     89                 // first calculate the angle of the point,
     90                 // add 180 deg to get rid of the negative values
     91                 // divide by 90 to get the quadrant
     92                 // add 3 and do a modulo by 4  to shift the quadrants to a proper clockwise TRBL (top/right/bottom/left) **/
     93                 /*
     94                     Math.atan2(y, x):所表达的意思是坐标原点为起点,指向(x,y)的射线在坐标平面上与x轴正方向之间的角的角度。
     95                     http://baike.baidu.com/link?url=PNCFllbtSbLmkZxWtADv9c27UuA4iUPNEkZtPmn0PItjGRcUqs_CfnkAV1I528bCG7-l2UT3EfUefP6S_RhFz_
     96                     1.计算与X轴的夹角角度
     97                     2.加180,变为正数
     98                     3.除90,分为4份
     99                     4.转为(上右下左=0123)的形式
    100                 */
    101                 direction = Math.round( ( ( ( Math.atan2(y, x) * (180 / Math.PI) ) + 180 ) / 90 ) + 3 ) % 4;
    102             return direction;
    103         },
    104         _getStyle : function( direction ) {
    105             /*返回移入的初期,最终位置;移出的最终位置*/
    106             // js中定义初期位置,有的会直接在css中定义
    107             var fromStyle, toStyle,
    108                 slideFromTop = { left : '0px', top : '-100%' },
    109                 slideFromBottom = { left : '0px', top : '100%' },
    110                 slideFromLeft = { left : '-100%', top : '0px' },
    111                 slideFromRight = { left : '100%', top : '0px' },
    112                 slideTop = { top : '0px' },
    113                 slideLeft = { left : '0px' };
    114             /*direction(上右下左=0123)*/
    115             switch( direction ) {
    116                 case 0:
    117                     // from top
    118                     // 鼠标初期位置[移入初始位置,移除最终位置]this.options.inverse为反向判断
    119                     fromStyle = !this.options.inverse ? slideFromTop : slideFromBottom;
    120                     // 鼠标移入最终位置
    121                     toStyle = slideTop;
    122                     break;
    123                 case 1:
    124                     // from right
    125                     fromStyle = !this.options.inverse ? slideFromRight : slideFromLeft;
    126                     toStyle = slideLeft;
    127                     break;
    128                 case 2:
    129                     // from bottom
    130                     fromStyle = !this.options.inverse ? slideFromBottom : slideFromTop;
    131                     toStyle = slideTop;
    132                     break;
    133                 case 3:
    134                     // from left
    135                     fromStyle = !this.options.inverse ? slideFromLeft : slideFromRight;
    136                     toStyle = slideLeft;
    137                     break;
    138             };
    139             return { from : fromStyle, to : toStyle };
    140         },
    141         // apply a transition or fallback to jquery animate based on Modernizr.csstransitions support
    142         /*过度动画兼容方法*/
    143         _applyAnimation : function( el, styleCSS, speed ) {
    144             $.fn.applyStyle = this.support ? $.fn.css : $.fn.animate;
    145             el.stop().applyStyle( styleCSS, $.extend( true, [], { duration : speed + 'ms' } ) );
    146         },
    147     };
    148     var logError = function( message ) {
    149         /*处理错误信息输出方法*/
    150         if ( window.console ) {
    151             window.console.error( message );
    152         }
    153     };
    154     /*Jquery扩展方法*/
    155     $.fn.hoverdir = function( options ) {
    156         // 先获取该li的缓存中的hoverdir
    157         var instance = $.data( this, 'hoverdir' );
    158         if ( typeof options === 'string' ) {
    159             /*参数为字符串类型时,好像目前用不到,暂时没有想到这段代码的目的*/
    160             // 数组化参数
    161             var args = Array.prototype.slice.call( arguments, 1 );
    162             this.each(function() {
    163                 if ( !instance ) {
    164                     // 缓存中没有hoverdir数据,报错
    165                     logError( "cannot call methods on hoverdir prior to initialization; " +
    166                     "attempted to call method '" + options + "'" );
    167                     return;
    168                 }
    169                 if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) {
    170                     // instance[options]不是方法,或第一字符不是_
    171                     logError( "no such method '" + options + "' for hoverdir instance" );
    172                     return;
    173                 }
    174                 instance[ options ].apply( instance, args );
    175             });
    176         } 
    177         else {
    178             /*参数不为字符串类型时,正常入口*/
    179             this.each(function() {
    180                 if ( instance ) {
    181                     instance._init();
    182                 }
    183                 else {
    184                     instance = $.data( this, 'hoverdir', new $.HoverDir( options, this ) );
    185                 }
    186             });
    187         }
    188         return instance;
    189     };
    190 } )( jQuery, window );// 闭包,jquery插件写法
    View Code

    5.CSS3

    transition: property duration timing-function delay;

    CSS3过渡,定义应用过渡效果的 CSS 属性名称列表以逗号分隔。

    6.HTML 调用

    $(function() {
    $(' #da-thumbs > li ').each( function() { $(this).hoverdir(); } );
    });

    7.我们对列表的li绑定了‘mouseenter’ 和 ‘mouseleave’事件,

    _getDir方法会判断鼠标是从哪4个方向移入或移出。
    源码文件里还有
    类型2[做了一点点延迟过度动画处理],
    类型3[做了反向动画处理]
    另外,如果浏览器不支持css3,将会使用animate方法处理过度动画

    8.该插件读码完了,非常简单,适合初学者学习参考。
    参考借鉴后,综合应用,做一个属于自己的Jquery特效插件。

  • 相关阅读:
    单链表
    队列

    面向对象的数组与查找算法
    线性结构
    数据结构与算法概述
    webstorm 格式化代码快捷键
    Web规范小记录1:Web文件规范
    豆瓣 API报错 ( "code":104 问题 )
    舔狗日记二之心灵日记(H5版本)
  • 原文地址:https://www.cnblogs.com/wangxinsheng/p/4445137.html
Copyright © 2011-2022 走看看