HTML5-SVG+CSS3图片鼠标HOVER动画效果

如果你曾经访问过新版的Christmas Experiments网站,那么你一定被网站上的日历效果所吸引。今天我们将和大家一起来研究如何使用SVG和Snap.svg来实现这种效果。思路是用svg创建一个带标题的背景,然后在鼠标hover的时候使它变形为另一种形状。有很多可行的方案来制作它,今天我们将创建三种不同的效果。利用SVG的好处是,我们可以任意调整它在父容器中的大小,将它们做成流式布局。

HTML结构:

我们要做的第一件事是什么呢?应该先用矢量软件制作一个矢量图形。可以用Adobe Illustrator或者Inkscape。每个图形都包含一条路径,我们需要使用它四个角的坐标来完成svg。这里我们将一个矩形转换为路径,如果你使用Inkscape,你可以将整个图形选中,然后选择Path > Object to Path,点的坐标可以在Edit > XML Editor中得到…,可以参考下面的截图:

201410192103

html结构我们使用一个section,给它加上class grid,然后在其下放置a标签,并在a标签中放入figure,这里你也可以使用无序列表,但会多写一些代码。

figure中将包含一张图片、我们制作的图形和一个figcaption

<section id="grid" class="grid clearfix">
    <a href="#" data-path-hover="m 180,34.57627 -180,0 L 0,0 180,0 z">
        <figure>
            <img src="img/1.png">
            <svg viewBox="0 0 180 320" preserveAspectRatio="none"><path d="M 180,160 0,218 0,0 180,0 z"></path></svg>
            <figcaption>
                <h2>Crystalline</h2>
                <p>Soko radicchio bunya nuts gram dulse.</p>
                <button>View</button>
            </figcaption>
        </figure>
    </a>
    <!-- ... -->
</section>

每个SVG将有自己的viewBox值,并将preserveAspectRatio设置为none。

这将使我们能够将形状调整和拉伸到我们想要的尺寸。我们将在样式表中定义它的宽度和高度。鼠标hover时图形的信息将保存在data-path-hover中。

CSS样式:

注意:下面的css没有包含各个厂商的前缀。

这些样式将被三种效果使用。首先写通用样式,然后在为每种效果写自己的样式。

先从grid开始,让它居中,并给它一个max-width和一个百分比的宽度,使它具有响应性。

.grid {
    margin: 40px auto 120px;
    max-width: 1000px;
    width: 90%;
}

a元素要左浮动,我们给它一个最大宽度250px,并给它一个25%的实际宽度,这样一行能放4张图片,并且是响应式的。我们后面还要处理小屏幕(平板和手机)的问题。

.grid a {
    float: left;
    max-width: 250px;
    width: 25%;
    color: #333;
}

为了给奇数的图片一些偏移,我们设置顶部的margin 30px,底部的amrgin -30px,这将做出一个很好看的网格,就像Christmas Experiments网站上的那样。

.grid a:nth-child(odd) {
    margin: 30px 0 -30px 0;
}                              

figure要设置为相对定位,因为我们需要设置它的一些子元素为绝对定位。由于鼠标悬停效果可能会导致一些溢出,所以我们要设置overflow为“hidden”。

.grid figure {
    position: relative;
    overflow: hidden;
    margin: 5px;
    background: #333;
}                             

图片要和它的父元素一样宽,透明度设置为0.7左右。当鼠标hover的时候我们希望透明度有所变化,所以加上个transition。

.grid figure img {
    position: relative;
    display: block;
    width: 100%;
    opacity: 0.7;
    transition: opacity 0.3s;
}

figcaption需要绝对定位,并且宽度和高度都设置为100%。

.grid figcaption {
    position: absolute;
    top: 0;
    z-index: 11;
    padding: 10px;
    width: 100%;
    height: 100%;
    text-align: center;
}

h2p元素在鼠标hover时都会运动,所以我们分别给他们设置transitions。

.grid figcaption h2 {
    margin: 0 0 20px 0;
    color: #3498db;
    text-transform: uppercase;
    letter-spacing: 1px;
    font-weight: 300;
    font-size: 130%;
    transition: transform 0.3s;
}
.grid figcaption p {
    padding: 0 20px;
    color: #aaa;
    font-weight: 300;
    transition: opacity 0.3s, transform 0.3s;
}
.grid figcaption h2,
.grid figcaption p {
    transform: translateY(50px);
}

所有效果中的按钮样式都是一样的。按钮在hover时也有一些动画,所以添加一个transition来改变它的透明度和动画效果。

.grid figure button {
    position: absolute;
    padding: 4px 20px;
    border: none;
    text-transform: uppercase;
    letter-spacing: 1px;
    font-weight: bold;
    transition: opacity 0.3s, transform 0.3s;
}

为了避免一些闪烁和抖动,我们需要将所有的动画元素和它们的父元素的backface-visibility设置为hidden。

.grid figcaption,
.grid figcaption h2,
.grid figcaption p,
.grid figure button {
    backface-visibility: hidden;
}

SVG也应该是绝对定位的,并将它的宽和高设置为100%,在Firefox26.0中顶部定位会有一些偏差,所以我们给它的top设置为-1px来修补这个bug。

.grid svg {
    position: absolute;
    top: -1px; /* fixes rendering issue in FF */
    z-index: 10;
    width: 100%;
    height: 100%;
}

使用白色来填充图形的路径。

.grid svg path {
    fill: #fff;
}

通用的鼠标hover效果应该像下边这样:

.grid a:hover figure img {
    opacity: 1;
}
.grid a:hover figcaption h2,
.grid a:hover figcaption p {
    transform: translateY(0);
}
.grid a:hover figcaption p {
    opacity: 0;
}

当标题上升到指定位置后,图片的透明度应该设置为1。

现在,让我们来为每种效果制作各自的样式。

在第一种效果中,我们希望按钮有白色的边并且居中。在最开始的时候它是隐藏和缩小的。我们使用transforms来定位它,并使它缩小,当鼠标hover的时候,我们将使按钮慢慢放大。

.demo-1 body {
    background: #3498db;
}
.demo-1 .grid figure button,
.demo-3 .grid figure button {
    top: 50%;
    left: 50%;
    border: 3px solid #fff;
    background: transparent;
    color: #fff;
    opacity: 0;
    transform: translateY(-50%) translateX(-50%) scale(0.25);
}
.demo-1 .grid a:hover figure button,
.demo-3 .grid a:hover figure button {
    opacity: 1;
    transform: translateY(-50%) translateX(-50%) scale(1);
}

在第二种效果中,我们定义了其它一些颜色来使按钮隐藏在figure下面。我们设置它的bottom为0,然后translate它到100%,当鼠标hover的时候,我们将它的上升效果设置为“ease-out”。

.demo-2 body {
    background: #e74c3c;
}
.demo-2 .grid figcaption h2 {
    color: #e74c3c;
}
.demo-2 .grid figcaption p {
    transition-delay: 0.05s;
}
.demo-2 .grid figure button {
    bottom: 0;
    left: 0;
    padding: 15px;
    width: 100%;
    background: #fff;
    color: #333;
    font-weight: 300;
    transform: translateY(100%);
}
.demo-2 .grid a:hover figure button {
    transition-timing-function: ease-out;
    transform: translateY(0);
}

第二和第三种效果的标题和段落设置一种“cubic-bezier”效果,这将有助于模拟弹性过渡,当鼠标悬停的时候我们设置段落的延时为0,这将能确保党SVG图形到达顶部时段落能很快的消失。

.demo-2 .grid figcaption h2,
.demo-2 .grid figcaption p,
.demo-3 .grid figcaption h2,
.demo-3 .grid figcaption p {
    timing-function: cubic-bezier(0.250, 0.250, 0.115, 1.445);
}
.demo-2 .grid a:hover figcaption p,
.demo-3 .grid a:hover figcaption p {
    transition-delay: 0s;
    transition-duration: 0.1s;
}

第三种效果我们将改变一些颜色,在鼠标hover时将标题translate一点,而不是设为0。

.demo-3 body {
    background: #52be7f;
}
.demo-3 .grid figcaption h2 {
    color: #52be7f;
}
.demo-3 .grid a:hover figcaption h2 {
    transform: translateY(5px);
}

对于小屏幕,我们要改变每行显示的图片数量,我们将重置宽度和奇数子元素的margin,第2、5、8、11个a元素要设置一个margin,可以通过nth-child(3n-1)来实现。

小提示:如果你想快速的找到某种序列的表达式,你可以到WolframAlpha去输入你的序列,它能很快的计算出该序列的表达式。

对于更小尺寸的屏幕,我们将通过设置max-width和标题的margins来控制它。

@media screen and (max-width: 58em) {
    .grid a {
        width: 33.333%;
    }
    .grid a:nth-child(odd) {
        margin: 0;
    }
    .grid a:nth-child(3n-1) {
        margin: 30px 0 -30px 0;
    }
}
@media screen and (max-width: 45em) {
    .grid {
        max-width: 500px;
    }
    .grid a {
        width: 50%;
    }
    .grid a:nth-child(3n-1) {
        margin: 0;
    }
    .grid a:nth-child(even) {
        margin: 30px 0 -30px 0;
    }
    .grid figcaption h2 {
        margin-bottom: 0px;
        transform: translateY(30px);
    }
    .grid figcaption p {
        margin: 0;
        padding: 0 10px;
    }
}
@media screen and (max-width: 27em) {
    .grid {
        max-width: 250px;
    }
    .grid a {
        width: 100%;
    }
    .grid a:nth-child(even) {
        margin: 0;
    }
}

JAVASCRIPT

我们将使用Snap.svg,它是一个很棒的SVGs库,要想知道它是如何工作的,请先看一下它的文档入门教程

我们先设置speed和easing的值,然后创建一个变量来保存路径上的信息和悬停的路径。当鼠标悬停的时候,我们将动画路径转变为“to”状态,鼠标离开时,将动画转变为“form”状态。

(function() {
    
    function init() {
        var speed = 250,
            easing = mina.easeinout;
        [].slice.call ( document.querySelectorAll( '#grid > a' ) ).forEach( function( el ) {
            var s = Snap( el.querySelector( 'svg' ) ), path = s.select( 'path' ),
                pathConfig = {
                    from : path.attr( 'd' ),
                    to : el.getAttribute( 'data-path-hover' )
                };
            el.addEventListener( 'mouseenter', function() {
                path.animate( { 'path' : pathConfig.to }, speed, easing );
            } );
            el.addEventListener( 'mouseleave', function() {
                path.animate( { 'path' : pathConfig.from }, speed, easing );
            } );
        } );
    }
    init();
})();

在线预览 网盘下载

网盘下载密码:y82r

郑重声明:

1 本资源来源于互联网,资源的版权归资源原作者所持有,受《中华人民共和国著作权法》等相关法律保护。

2 由于无法和原作者取得联系,所以上传的部分资源无法先通过原作者的同意就分享给大家了,如本资源侵犯了您(原作者)的权益,请联系我们(微信号 xiaohaimei1989),我们会立马删除您的资源,并向您表达诚挚的歉意!

3 本站是一个公益型网站,分享资源的目的在于传播知识,分享知识,收取一点点打赏的辛苦费是用于网站的日常运营开支,并非用于商业用途。

4 本站资源只提供学习和参考研究使用,使用过后请在第一时间内删除。本站不承担资源被单位或个人商用带来的法律责任。

发表评论