强制 CSS 动画完成

Forcing a CSS animation to complete

对于一个艺术家的网站,图片完全填满浏览器 window,我想显示一条缩略图,它会消失,只在角落里留下当前图片的缩略图。当您将鼠标滚动到该缩略图上时,缩略图带应该会再次出现,以便您可以选择新图片。

我在下面包含了此效果的模型,以及一个 jsFiddle 您可以在其中看到它的实际效果。

如果将鼠标滑到缩略图上,然后再次快速离开,动画将停止,并保持暂停状态 1 秒,然后反转。我应该如何更改 CSS 以便滑出动画在开始后始终播放到结束?

<html>
<head>
<style>
  html, body {
  height: 100%;
  margin:0;
  overflow: hidden;
  }
  div {
  position:absolute;
  left:0;
  width: 100px
  }
  #cue, #thumb {
  bottom:0;
  height:50px;
  }
  #cue, #thumb {
  bottom:0;
  height:50px;
  }
  #cue {
  background: none;
  opacity: 0.2;
  z-index: 2;
  }
  #thumb {
  background: blue;
  opacity: 0.5;
  }
  #strip {
  background: blue;
  opacity: 0.2;
  z-index:1;
  height: 99%;
  top: 100%;
  -webkit-transition: all 500ms cubic-bezier(0.420, 0.000, 0.580, 1.000);
  -moz-transition: all 500ms cubic-bezier(0.420, 0.000, 0.580, 1.000);
  -o-transition: all 500ms cubic-bezier(0.420, 0.000, 0.580, 1.000);
  transition: all 500ms cubic-bezier(0.420, 0.000, 0.580, 1.000);
  -webkit-transition-delay: 1s;
  transition-delay: 1s;
  }
  #cue:hover + #strip, #strip:hover {
  top: 1%;
  -webkit-transition-delay: 0s;
  transition-delay: 0s;
  }
  #thumb {
  -webkit-transition: all 300ms cubic-bezier(0.420, 0.000, 0.580, 1.000);
  -moz-transition: all 300ms cubic-bezier(0.420, 0.000, 0.580, 1.000);
  -o-transition: all 300ms cubic-bezier(0.420, 0.000, 0.580, 1.000);
  transition: all 300ms cubic-bezier(0.420, 0.000, 0.580, 1.000);
  -webkit-transition-delay: 1200ms;
  transition-delay: 1200ms;
  }
  #cue:hover ~ #thumb, #strip:hover+#thumb {
  opacity: 0;
  -webkit-transition-delay: 0s;
  transition-delay: 0s;
  }
</style>
</head>
  <div id="cue"></div>
  <div id="strip"></div>
  <div id="thumb"></div>
</html>

最明显的解决方案是将缩略图设置为 width/height 并将图像设置为 css 背景图像,背景大小为 "cover" 或 "contain",背景位置为 "center center".

.thumb {
    background-image: url('some-image.png');
    background-position: center center;
    background-size: cover;
}

如果你真的想要动态 width/height 在你的缩略图上,我建议你可能看看 javascript 插件,它可以像砖石或同位素一样操纵 css:

http://masonry.desandro.com/

http://isotope.metafizzy.co/

我不确定如果没有 JavaScript,您如何做到这一点。您可以切换 类 而不是使用悬停选择器,并使用 transitionend 检测动画何时完成以切换悬停 类.

https://jsfiddle.net/w5b1hm0w/2/

经过进一步调查,我需要通过两种方式修改@Moogs 给出的答案,但我的问题中均未指定:

  • 我问题中的 cue div 比缩略图条高 z-index,所以不可能 select 最底部的缩略图脱衣舞
  • 如果您将光标拖离打开的条带,然后在它开始关闭之前再次将其移回,它应该保持打开状态

这是我的最终解决方案的演示,还有一个 jsFiddle 您可以在其中进行测试。非常感谢@Moogs 让我走上正轨。

<html>
<head>
    <style>
        html, body {
            height: 100%;
            margin:0;
            overflow: hidden;
        }
        div {
            position:absolute;
            left:0;
            width: 100px
        }
        #cue, #thumb {
            bottom:0;
            height:50px;
        }
         #cue {
            opacity: 0;
            z-index: 1;
        }
        #thumb {
            background: blue;
            opacity: 0.5;
        }
        #strip {
            background: blue;
            opacity: 0.2;
            z-index:1;
            height: 99%;
            top: 100%;
            -webkit-transition: all 500ms cubic-bezier(0.420, 0.000, 0.580, 1.000);
            -moz-transition: all 500ms cubic-bezier(0.420, 0.000, 0.580, 1.000);
            -o-transition: all 500ms cubic-bezier(0.420, 0.000, 0.580, 1.000);
            transition: all 500ms cubic-bezier(0.420, 0.000, 0.580, 1.000);
            -webkit-transition-delay: 1s;
            transition-delay: 1s;
        }
        #strip.hover {
            top: 1%;
            -webkit-transition-delay: 0s;
            transition-delay: 0s;
        }
        #thumb {
            -webkit-transition: all 300ms cubic-bezier(0.420, 0.000, 0.580, 1.000);
            -moz-transition: all 300ms cubic-bezier(0.420, 0.000, 0.580, 1.000);
            -o-transition: all 300ms cubic-bezier(0.420, 0.000, 0.580, 1.000);
            transition: all 300ms cubic-bezier(0.420, 0.000, 0.580, 1.000);
            -webkit-transition-delay: 1200ms;
            transition-delay: 1200ms;
        }
        #strip.hover+#thumb {
            opacity: 0;
        }
        /* .inProgress is needed to ensure that the thumb will reappear if
           you move the mouse off the strip before it is completely open.
           If the following rule is merged with the #strip.hover+#thumb rule,
           then the change from #strip.hover+#thumb to #strip+#thumb (with
           no .hover) may fail to be acted on by the #thumb.
        */
        #thumb.inProgress {
            -webkit-transition-delay: 0s;
            transition-delay: 0s;
        }
    </style>

    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>

<body>
<div id="cue"></div>
<div id="strip"></div>
<div id="thumb"></div>

<script>
    ;(function filmroll_animation() {
        var cue = document.getElementById('cue')
        var strip = document.getElementById('strip')
        var thumb = document.getElementById('thumb')

        var hover = "hover"
        var inProgress = "inProgress"

        var mouseover = false
        var transitionDone = false

        cue.onmouseover = function triggerSlideIn() {
            transitionDone = false
            strip.classList.add(hover)
            thumb.classList.add(inProgress)
        }

        strip.onmouseleave = function viewPortLeave() {
            mouseover = false;
            if (transitionDone) {
                strip.classList.remove(hover)
            }
        }

        strip.onmouseover = function viewPortEnter() {
            mouseover = true;
            strip.classList.add(hover)
        }

        strip.addEventListener("transitionend", function viewPortShown() {
            transitionDone = true;
            thumb.classList.remove(inProgress)
            if (!mouseover) {
                strip.classList.remove(hover)
            }
        }, false)
    })()
</script>
</body>
</html>