CSS过渡与过滤器中断剪切路径

时间:2017-08-09 18:03:12

标签: javascript jquery html css css3

浏览器:Chrome 60

** TLDR:**似乎在div的子项上使用带有过滤器的过渡并且应用了剪切路径会导致奇怪的行为(请查看实时代码示例和图片)。但是,这仅在后台儿童也有blur过滤器时才会发生。

我正在尝试使用jQuery和CSS转换创建滚动触发动画。我在页面上有两个div:左侧有一个固定div,有一个斜边(使用剪切路径制作),右边div包含内容:

Working clipping path

当页面检测到用户滚动浏览页面中的某个点时,它会向左侧div中的文本添加一个类,使其模糊。这一切都正常,直到我向文本添加transition: filter 0.5s; - 这会导致剪切路径中断(在100px左右随机跳跃),同时发生转换:

Broken clipping path

看一个实例(包括代码):

https://codepen.io/sunnylan/full/eEWKYX

我试图找出问题所在的位置,但我遇到了麻烦,因为似乎多个元素的组合导致问题。例如,删除剪切路径时问题消失。当我从导航列表项中删除转换时它也会消失。更具体地说,这里是问题区域(删除它们中的任何一个都将解决问题):

向侧栏添加剪切路径

clip-path: polygon( // line 191
              0 0,
              100% 0,
              100% - $sidebar-angle 100%,
              0 100%); 

向侧边栏背景添加模糊滤镜:

filter: blur(20px); //line 201

向导航项添加转换:

transition: filter $animation-speed ease, opacity $animation-speed ease; // line 222

1 个答案:

答案 0 :(得分:1)

这是一个棘手的问题。看起来它是Chrome特有的东西,因为FF工作正常减去一些奇怪的东西。

看起来问题的具体原因是在nav-bar类应用于selected时动画selected。如果你不这样做,那么剪辑路径会正确动画,但之后没有不透明度/模糊动画。您可以看到,当应用 $(window).scroll(function () { var s = $(window).scrollTop(), d = $(document).height(), c = $(window).height(); var percent = s.map(0, d - c, 0, 100); if (percent > 15) { $('.nav-bar-wrapper .nav-bar').css('top', s.map(0, d - c, 10, -10) + '%'); $('.sidebar').addClass('closed'); $('.nav-bar-wrapper').addClass('closed'); $('.nav-item').addClass('selected'); } else { $('.nav-bar-wrapper .nav-bar').css('top', '40%'); $('.sidebar').removeClass('closed'); $('.nav-bar-wrapper').removeClass('closed'); $('.nav-item').removeClass('selected'); } });类时,剪辑路径会在转换期间变得混乱,然后在完成时按照您想要的方式进行。我猜这是从最里面的孩子向外渲染。

修复,是将两者分开,而不是嵌套它们。



.sidebar {
  background: black;

  //fix on left side of page
  position: fixed;
  left: 0;
  top: 0;
  bottom: 0;

  //initial width
  width: $sidebar-open;

  //make slanted edge
  clip-path: polygon(
                  0 0,
                  100% 0,
                  100% - $sidebar-angle 100%,
                  0 100%);

  //background picture layer
  .background {
    @include fill-parent-bg;
    background-image: url('/img/cb-colour-nightsky.jpg');
    filter: blur(20px);
    background-size: cover;
    z-index: -1;
  }

  //center sliding nav bar
  @include flex;
  justify-content: center;

  //animate it!
  transition: width $animation-speed ease;

  &.closed {
    width: $sidebar-closed;
  }
}

//moving component
.nav-bar-wrapper {
  top: 0;
  left: 0;
  bottom: 0;
  position: fixed;
  width: $sidebar-open;
  transition: width $animation-speed ease;
  
  &.closed {
    width: $sidebar-closed;
  }
  
  .nav-bar {
    background: gray;
    //keep component where it is, unless modified by jQuery
    position: absolute;
    top: 40%; //default vertical position
    left: 50%;
    transform: translateX(-50%);

    //animate it!
    transition: top $animation-speed ease;

    .nav-item {
      //fade in/out animations
      transition: filter $animation-speed ease, opacity $animation-speed ease;
      filter: blur(15px);
      opacity: 0.5;
      &.selected {
        opacity: 1;
        filter: blur(0);
      }
    }
  }
}

<div class="sidebar background"></div>
<div class="nav-bar-wrapper">
  <div class="nav-bar">
    <h1 class="nav-item" style="color:white; height: 100px;">Test content</h1>
  </div>
</div>
&#13;
Debug.WriteLine
&#13;
&#13;
&#13;

此处修改了CodePen:https://codepen.io/anon/pen/RZVBNJ

但是,有了这个,看起来片刻文本会被渲染两次,即使它只在那里播放过一次。同样,这是特定于Chrome的问题。