当我的页面加载时,将显示视口中的内容(内容不在视图中获取容器上的hidden
类)并执行动画(flipInX
)。然后,当用户向下滚动页面时,hidden
类将从容器中删除,内容淡入(使用fadeIn()
)到页面上,然后应该进行动画。
我的问题是它在页面上淡化(fadeIn()
),做动画,然后再次执行fadeIn()
。
编辑:我在某些浏览器(Firefox和Chrome)上发现它最后会发出额外的“反弹”,而不是第二次褪色(Safari)
HTML
<body class="homepage">
<main id="main" class="main" role="main" tabindex="-1">
<div class="main-3">
<article class="post flipInX animated" data-delay="2">
<h1 class="h-1">Service 1</h1>
<div class="entry">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas vestibulum, lectus id sollicitudin mattis, quam tortor lobortis orci, sed iaculis mi nulla non ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec non felis mollis, congue neque eu, rhoncus libero. Nunc ut mattis ante.</div>
</article>
<article class="post flipInX animated" data-delay="4">
<h1 class="h-1">Service 2</h1>
<div class="entry">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas vestibulum, lectus id sollicitudin mattis, quam tortor lobortis orci, sed iaculis mi nulla non ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec non felis mollis, congue neque eu, rhoncus libero. Nunc ut mattis ante.</div>
</article>
<article class="post flipInX animated" data-delay="6">
<h1 class="h-1">Service 3</h1>
<div class="entry">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas vestibulum, lectus id sollicitudin mattis, quam tortor lobortis orci, sed iaculis mi nulla non ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec non felis mollis, congue neque eu, rhoncus libero. Nunc ut mattis ante.</div>
</article>
<article class="post flipInX animated" data-delay="8">
<h1 class="h-1">Service 4</h1>
<div class="entry">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas vestibulum, lectus id sollicitudin mattis, quam tortor lobortis orci, sed iaculis mi nulla non ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec non felis mollis, congue neque eu, rhoncus libero. Nunc ut mattis ante.</div>
</article>
<article class="post flipInX animated" data-delay="10">
<h1 class="h-1">Service 5</h1>
<div class="entry">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas vestibulum, lectus id sollicitudin mattis, quam tortor lobortis orci, sed iaculis mi nulla non ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec non felis mollis, congue neque eu, rhoncus libero. Nunc ut mattis ante.</div>
</article>
<article class="post flipInX animated" data-delay="12">
<h1 class="h-1">Service 6</h1>
<div class="entry">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas vestibulum, lectus id sollicitudin mattis, quam tortor lobortis orci, sed iaculis mi nulla non ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec non felis mollis, congue neque eu, rhoncus libero. Nunc ut mattis ante.</div>
</article>
</div>
</main>
</body>
CSS
* {
border: 0;
margin: 0;
padding: 0;
-webkit-appearance: none;
-webkit-border-radius: 0;
}
*,
*:before,
*:after {
box-sizing: border-box;
}
.hidden {
visibility: hidden;
}
.main {
position: relative;
display: inline-block;
height: auto;
width: 98%;
margin: 40px auto 0 auto;
text-align: left;
}
.main.minify {
margin-top: 150px;
}
.main-3 {
min-height: 400px;
font-size: 16px;
line-height: 24px;
}
[class|=h] {
margin-bottom: 42px;
font-size: 30px;
font-weight: normal;
line-height: 1;
}
.animated {
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both
}
.animated.bounceIn,
.animated.bounceOut,
.animated.flipOutX,
.animated.flipOutY {
-webkit-animation-duration: .75s;
animation-duration: .75s
}
@-webkit-keyframes flipInX {
0% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
opacity: 0
}
40% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in
}
60% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
opacity: 1
}
80% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
transform: perspective(400px) rotate3d(1, 0, 0, -5deg)
}
100% {
-webkit-transform: perspective(400px);
transform: perspective(400px)
}
}
@keyframes flipInX {
0% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
opacity: 0
}
40% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in
}
60% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
opacity: 1
}
80% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
transform: perspective(400px) rotate3d(1, 0, 0, -5deg)
}
100% {
-webkit-transform: perspective(400px);
transform: perspective(400px)
}
}
.flipInX {
-webkit-backface-visibility: visible !important;
backface-visibility: visible !important;
-webkit-animation-name: flipInX;
animation-name: flipInX
}
.homepage .main-3 {
width: 80%;
margin: 0 auto;
text-align: center;
}
.homepage .post {
display: inline-block;
width: 49%;
margin-bottom: 40px;
vertical-align: top;
-webkit-text-stroke: 0.5px;
}
.homepage .post .h-1 {
font-size: 26px;
line-height: 110%;
margin: 14px 0 10px;
text-align: center;
}
.homepage .post .entry {
padding: 0 10%
}
JS
function isScrolledIntoView(elem) {
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
$(document).ready(function() {
$('.post').each(function(index) {
var delay = $(this).attr('data-delay');
if (typeof delay !== typeof undefined && delay !== false) {
$(this).css('animation', 'flipInX 2s .' + delay + 's');
$(this).css('-webkit-animation', 'flipInX 2s .' + delay + 's');
}
});
$('.post').not('.post:first').each(function() {
if (!isScrolledIntoView($(this))) {
$(this).addClass('hidden');
}
});
$(document).on('scroll', function() {
$('.post.hidden').each(function() {
if (isScrolledIntoView($(this))) {
$(this).removeClass('hidden').css({
'display': 'none'
}).fadeIn();
}
});
});
});
答案 0 :(得分:3)
通过仅使用关键帧动画而不依赖于jQuery的fadeIn
,可以更好地完成您描述的视觉效果(淡入,然后设置动画)。
我改变了一堆东西,想出了一个非常自然的动画。虽然这可能不是您所期望的,但您可以将其用作接近所需结果的基础(使用少量代码)。
这是我改进/更改的内容:
animation-state
属性和一些javascript来控制每个动画的初始状态和播放flipInX
中的现有关键帧。在那里,您可以调整opacity
值以获得更好的结果animation-duration
)animation-fill-mode: forwards
停留在最后一帧。咨询来源:
您可以在这个小提琴中看到结果: https://jsfiddle.net/wazaraki/czwrgqdq/
包含评论的新代码(已更新):
$(function() {
/** Reccomended technique for detecting visible elements
take from https://stackoverflow.com/a/7557433/4405615
Removed width detection since we only need the heights */
function isScrolledIntoView (el) {
//special bonus for those using jQuery
if (typeof jQuery === "function" && el instanceof jQuery) {
el = el[0];
}
var rect = el.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) /*or $(window).height() */
);
}
/* Not longer needed as we now assign delays dinamically on scroll (see below) */
/* $('.post').each(function(index) {
var delay = $(this).data('delay');
if (typeof delay !== typeof undefined && delay !== false) {
//$(this).css('animation-delay', delay + 's');
//$(this).css('-webkit-animation-delay', delay + 's');
}
});*/
var delay = 0;
$('.post').each(function() {
var post = $(this);
if (isScrolledIntoView(post)) {
/* start animation for visible elements
see the CSS for more info */
post.css({
'-webkit-animation-delay': delay + 's',
'animation-delay': delay + 's',
'webkit-animation-play-state': 'running',
'animation-play-state': 'running'
});
delay += 0.2;
} else {
post.addClass('hidden');
}
});
$(document).on('scroll', function() {
/** every round starts with 0s delay so following scrolls
can start animating immediately */
var delay = 0;
$('.post.hidden').each(function() {
if (isScrolledIntoView(this)) {
$(this).removeClass('hidden').css({
'-webkit-animation-delay': delay + 's',
'animation-delay': delay + 's',
'webkit-animation-play-state': 'running',
'animation-play-state': 'running'
});
delay += 0.2;
}
});
});
});
* {
border: 0;
margin: 0;
padding: 0;
-webkit-appearance: none;
-webkit-border-radius: 0;
}
*,
*:before,
*:after {
box-sizing: border-box;
}
/** this class doesn't really do anything, just used it for
marking invisible elements. You could use data
attributes instead, for example */
.hidden {}
.main {
position: relative;
display: inline-block;
height: auto;
width: 98%;
margin: 40px auto 0 auto;
text-align: left;
}
.main-3 {
min-height: 400px;
font-size: 16px;
line-height: 24px;
}
[class|=h] {
margin-bottom: 42px;
font-size: 30px;
font-weight: normal;
line-height: 1;
}
.animated {
-webkit-animation-duration: 1s;
animation-duration: 1s;
/** once the animation finishes we stay on the last
keyframe */
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
@-webkit-keyframes flipInX {
0% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
opacity: 0;
}
40% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in
}
60% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
opacity: 1;
}
80% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
}
100% {
-webkit-transform: perspective(400px);
transform: perspective(400px);
opacity: 1;
}
}
@keyframes flipInX {
0% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
opacity: 0;
}
40% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
60% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
opacity: 1;
}
80% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
}
100% {
-webkit-transform: perspective(400px);
transform: perspective(400px);
opacity: 1;
}
}
.flipInX {
-webkit-backface-visibility: visible !important;
backface-visibility: visible !important;
-webkit-animation-name: flipInX;
animation-name: flipInX;
-webkit-animation-duration: 2s;
animation-duration: 2s;
/* this is a nice way to control animation playback */
-webkit-animation-play-state: paused;
animation-play-state: paused;
}
.homepage .main-3 {
width: 80%;
margin: 0 auto;
text-align: center;
}
.homepage .post {
display: inline-block;
width: 49%;
margin-bottom: 40px;
vertical-align: top;
-webkit-text-stroke: 0.5px;
opacity: 0;
}
.homepage .post .h-1 {
font-size: 26px;
line-height: 110%;
margin: 14px 0 10px;
text-align: center;
}
.homepage .post .entry {
padding: 0 10%
}
答案 1 :(得分:-1)
flipInX
动画也可以为0%到60%之间的元素的opacity
设置动画。尝试删除动画中对opacity
的引用。