2016-03-01 149 views
1

我试图模仿Twitter的通知动画推拉门动画


enter image description here


这就是我想出了这么远:

$('button').click(function() { 
 
    $('#left').css('width', '400px'); 
 
    $('#right').css('width', '400px'); 
 
});
.wrapper { 
 
    position: relative; 
 
    min-height: 50px; 
 
} 
 

 
.left { 
 
    position: absolute; 
 
    left: 0; 
 
    height: 50px; 
 
    background: #00AEEF; 
 
} 
 

 
.right { 
 
    position: absolute; 
 
    right: 0; 
 
    height: 50px; 
 
    background: #00AEEF; 
 
} 
 

 
.banner { 
 
    width: 0%; 
 
    overflow: hidden; 
 
    -webkit-transition: width 1s ease-in-out; 
 
    -moz-transition: width 1s ease-in-out; 
 
    -o-transition: width 1s ease-in-out; 
 
    transition: width 1s ease-in-out; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div> 
 
    <div class="wrapper"> 
 
    <div id="left" class="banner left"></div> 
 
    <div id="right" class="banner right"></div> 
 
    </div> 
 
    <div style="margin: 10px;"> 
 
    <button>start animation</button> 
 
    </div> 
 
</div>

但是使用2个不同的div用于左右动画就像是黑客。

是否有更好的内置CSS类型的动画(用于单个div)?

回答

5

推拉门的效果(仅)

(参见下面的完整效果演示)

你可以动画background-position两个linear-gradients放置在一个单一的元素(这样你就不会连为了造型的目的,需要使用两个更多的空元素)例如

div { 
    background: 
     linear-gradient(to left, #00AEEF 50%, transparent 0), 
     linear-gradient(to right, #00AEEF 50%, transparent 0); 
    background-position: 50vw 0, -50vw 0; 
    background-repeat: no-repeat; 
    height: 50px; 
    transition: background-position 1s; 
} 

:checked + div { 
    background-position: 0 0, 0 0; 
} 

只要经由js设置一个类来触发转换(为简单起见,我已激活与:checked伪类的效果)

Codepen demo


您也可以通过以下方式获得相同的效果:相反的动画:如果你把一个白色的梯度蓝色background-color你可以只是动画渐变的background-size像这样

div { 
    background: #00AEEF linear-gradient(to right, #fff, #fff); 
    background-position: 50% 0; 
    background-repeat: no-repeat; 
    background-size: 100% 100%; 
    height: 50px; 
    transition: background-size 1s; 
} 

:checked ~ div { background-size: 0 100%; } 

Codepen demo


Comparing the two approaches我个人比较喜欢最后一个(输入较少的代码,一个单独的渐变动画,看起来更平滑。此外,第二演示防止了恼人的舍入问题,有时发生在第一个,重新定位两个梯度发生时,因为你可以从下面看到的截图)

enter image description here


全效(带所有的动画/转换)

要重新创建此通知的全部效果,标记和样式当然应该稍微改变:从最后一个演示开始,我将主效应移动到包装器中的<a>元素,并且我插入了其他效果,如@用动画脉动并在5秒后最后滑下。

右箭头是Unicode符号U+3009制成,它被放置为a::after pseudoelement

注意的content:所有属性都前缀的。添加必要

Codepen Demo (Full effect)

标记前缀

<div class="notification"> 
    <a href="#"><span>@</span>Miro mentioned you</a> 
</div> 

CSS(从谷歌的字体嵌入字体拉托)

* { 
    font   : 1rem "Lato", Arial; 
    box-sizing : border-box; 
} 

.notification { 
    position  : relative; 
    overflow  : hidden; 
    font-weight : 100; 
    font-size : 1.5rem; 
} 

.notification a { 
    display  : block; 
    padding  : 1em 3em 1em 2.25em; 
    width  : 100%; 
    font-size : inherit; 
    font-weight : inherit; 
    color  : transparent; 
    background : #00AEEF linear-gradient(to right, #fff, #fff); 
    text-decoration : none;  
    background-position : 50% 0; 
    background-repeat : no-repeat; 
    background-size  : 100% 100%; 
} 

/* The at-sign: I've also tried to use :first-letter but it 
* is unreliable when the first char is not a letter or a digit 
*/ 
.notification a span { 
    position : absolute; 
    line-height : 1; 
    top   : 50%; 
    left  : 50%; 
    color  : #fff; 
    font-weight : bold; 
    transform : translate(-50%, -50%) scale(0); 
    transform-origin : 50% 50%; 
} 

/* The arrow */ 
.notification a:after { 
    position : absolute; 
    content : "\3009"; 
    right  : 1em; 
    top  : 50%; 
    transform : translateY(-50%); 
} 


/* sliding doors effect, color change and final slide down 
* all with proper delays 
*/ 
:checked ~ .notification a { 
    transition: background-size .2s, color .33s 1s, transform 1s 5s; 
    transform: translateY(100%); 
    background-size: 0 100%; 
    color: #fff; 
} 

/* pulsing and moving the @-sign */ 
:checked ~ .notification a span { 
    animation: pulse-at .66s ease-in-out .33s forwards; 
} 


@keyframes pulse-at { 
    0% { transform: scale(0) translate(-50%, -50%); } 
    20% { transform: scale(1.1) translate(-50%, -50%); } 
    25% { transform: scale(1) translate(-50%, -50%); } 
    40% { transform: scale(1) translate(-50%, -50%); left: 50%; } 
    100% { transform: scale(1) translate(0, -50%); left: 1em; } 
} 

最终结果

enter image description here

+0

辉煌。谢谢! – Daniel

+0

再次感谢,所以为了确保我明白,实际上动画的两个方面(而不是从左到右)是“背景位置:50%0”属性? – Daniel

+0

@丹尼尔,是的,它相当于'背景位置:顶部中心',所以白色背景总是居中。为了好玩,我试图重新创建完整的效果。我可能会用一个完整的例子再次编辑这个帖子 – fcalderan