css - 从底部到顶部动画 svg 填充

标签 css svg css-animations

我有一个简单的布局:

  • 分屏,一节为白,一节为黑。
  • 居中的标志,一半黑一半白
  • 当您将鼠标悬停在黑色部分时,它会从下到上被白色填充

现在,我尝试做的事情:

  • 当我将鼠标悬停在右侧的部分时,用黑色从下到上填充 Logo 。
  • 当我将鼠标悬停在左侧部分时,从上到下用白色填充 Logo

我尝试了很多事情......但我总是失败。

我认为最简单的解决方案是将具有线性渐变的矩形作为背景图像,添加 mask ,然后移动背景位置。

这是一个片段:

$( document ).ready(function() {
  $(".split-half").hover(function(){
    var elem = $(this);
    $(".split-half").each(function(){
      $(this).removeClass('active');
      setTimeout(function(){ 
        elem.addClass('active');
      }, 400);      
    });
  });
});
body *, *:after, *:before {
  box-sizing: border-box;
  margin:0;
  padding:0;
}
html, body {
  height: 100%;
}
.split-half {
  display: block;
  width: 50%;
  height: 100%;
  position: absolute;
  z-index: 1;
  padding: 5%;
}
.split-half:nth-child(1) {
  background: #fff;
  left: 0;
}
.split-half:nth-child(1):after {
  content: '';
  width: 100%;
  height: 0;
  position: absolute;
  top: 0;
  left: 0;
  background: #000;
  transition: height .3s;
}
.split-half:nth-child(1).active:hover:after {
  height: 100%;
  z-index: -1;
}
.split-half:nth-child(2) {
  background: #000;
  right: 0;
}
.split-half:nth-child(2):after {
  content: '';
  width: 100%;
  height: 0;
  position: absolute;
  bottom: 0;
  left: 0;
  background: #fff;
  transition: height .3s;
}
.split-half:nth-child(2).active:hover:after {
  height: 100%;
  z-index: -1;
}
.split-half:nth-child(2).active:hover + #logo #rect {
  background-position: 0% 100%;
}
#logo {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-39.8%, -50%);
  max-width: 420px;
  min-width: 120px;
  width: 10%;
  height: auto;
  z-index: 10;
}
#logo #rect {
  background-image: linear-gradient(to bottom, white 0%, white 50%, black 50%, black 100%);
  background-position: 0% 0%;
  background-size: 100% 200%;
  height: 100%;
  width: 100%;
  transition: all .3s;
  mask: url(#mhSvg);
  position: absolute;
  top: 0;
  right: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section>
            <div class="split-half"></div>
            <div class="split-half">
            </div>
            <div id="logo">
                <svg width="100%" height="100%" viewBox="0 0 187 174" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">   
                    <defs>
                        <g id="hSvg">
                            <path d="M74.624,173.782l111.609,-55.886l-24.82,-12.41l-24.82,12.41l-24.82,-12.41l24.82,-12.41l-24.82,-12.41l-111.773,55.804l24.984,12.492l61.969,-31.066l24.82,12.41l-61.969,31.066" style="fill:#fff;"/>
                        </g>
                        <mask id="mhSvg" x="0" y="0" width="100%" height="100%">
                            <g id="hSvg">
                                <path d="M74.624,173.782l111.609,-55.886l-24.82,-12.41l-24.82,12.41l-24.82,-12.41l24.82,-12.41l-24.82,-12.41l-111.773,55.804l24.984,12.492l61.969,-31.066l24.82,12.41l-61.969,31.066" style="fill:#fff;"/>
                            </g>       
                        </mask>                 
                        <g id="aSvg">
                            <path d="M0.082,0l74.542,37.271l0,136.511l-24.82,-12.41l0,-62.05l-24.902,-12.451l0,62.05l-24.82,-12.41l0,-136.511Zm24.902,62.091l0,-24.82l24.82,12.41l0,24.821l-24.82,-12.411Z"/>
                        </g>    
                    </defs>       
                    <g>
                        <use xlink:href="#hSvg" x="0" y="0" />
                        <use xlink:href="#aSvg" x="0" y="0" />
                    </g>                  
                </svg>
                <div id="rect">
                </div>      
            </div>
        </section>

目前,如您所见,我无法定位 mask 。

你知道我如何定位面具吗?

或者你有没有想出更好的方法来达到这个效果?

提前致谢!

编辑:

好吧,我找到了一个带掩码的解决方案......但它不是一个好的解决方案,因为它不能跨浏览器。

$( document ).ready(function() {
  $(".split-half").hover(function(){
    var elem = $(this);
    $(".split-half").each(function(){
      $(this).removeClass('active');
      setTimeout(function(){ 
        elem.addClass('active');
      }, 400);      
    });
  });
});
/* line 3, ../sass/style.scss */
body *, *:after, *:before {
  box-sizing: border-box;
}
html, body {
  height: 100%;
  margin:0;
  padding: 0;
}
.split-half {
  display: block;
  width: 50%;
  height: 100%;
  position: absolute;
  z-index: 1;
  padding: 5%;
}
.split-half:nth-child(1) {
  background: #fff;
  left: 0;
}
.split-half:nth-child(1):after {
  content: '';
  width: 100%;
  height: 0;
  position: absolute;
  top: 0;
  left: 0;
  background: #000;
  transition: height .3s;
}
.split-half:nth-child(1).active:hover:after {
  height: 100%;
  z-index: -1;
}
.split-half:nth-child(1).active:hover ~ #logo #A {
  background-position: 0% 0%;
}
.split-half:nth-child(2) {
  background: #000;
  right: 0;
}
.split-half:nth-child(2):after {
  content: '';
  width: 100%;
  height: 0;
  position: absolute;
  bottom: 0;
  left: 0;
  background: #fff;
  transition: height .3s;
}
.split-half:nth-child(2).active:hover:after {
  height: 100%;
  z-index: -1;
}
/* line 58, ../sass/style.scss */
.split-half:nth-child(2).active:hover + #logo #H {
  background-position: 0% 100%;
}
#logo {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-38.5%, -50%);
  z-index: 10;
}
#logo #H {
  background-image: linear-gradient(to bottom, white 0%, white 50%, black 50%, black 100%);
  background-position: 0% 0%;
  background-size: 100% 200%;
  height: 100%;
  width: 100%;
  transition: all .3s;
  mask: url(#mhSvg);
  position: absolute;
  top: 0;
  right: 0;
}
#logo #A {
  background-image: linear-gradient(to bottom, white 0%, white 50%, black 50%, black 100%);
  background-position: 0% 100%;
  background-size: 100% 200%;
  height: 100%;
  width: 100%;
  transition: all .3s;
  mask: url(#maSvg);
  position: absolute;
  top: 0;
  right: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section>
            <div class="split-half"></div>
            <div class="split-half">
            </div>
            <div id="logo">
                <svg width="194" height="181" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">   
                    <defs>
                        <g id="hSvg">
                            <path d="M74.624,173.782l111.609,-55.886l-24.82,-12.41l-24.82,12.41l-24.82,-12.41l24.82,-12.41l-24.82,-12.41l-111.773,55.804l24.984,12.492l61.969,-31.066l24.82,12.41l-61.969,31.066" style="fill:#fff;"/>
                        </g>
                        <mask id="mhSvg" x="0" y="0" width="120" height="114">
                            <g id="hSvg">
                                <path d="M74.624,173.782l111.609,-55.886l-24.82,-12.41l-24.82,12.41l-24.82,-12.41l24.82,-12.41l-24.82,-12.41l-111.773,55.804l24.984,12.492l61.969,-31.066l24.82,12.41l-61.969,31.066" style="fill:#fff;"/>
                            </g>       
                        </mask>
                        <mask id="maSvg" x="0" y="0" width="120" height="114">                                      
                            <g id="aSvg">
                                <path d="M0.082,0l74.542,37.271l0,136.511l-24.82,-12.41l0,-62.05l-24.902,-12.451l0,62.05l-24.82,-12.41l0,-136.511Zm24.902,62.091l0,-24.82l24.82,12.41l0,24.821l-24.82,-12.411Z" style="fill:#fff"/>
                            </g>
                        </mask>    
                    </defs>       
                    <g>              
                </svg>
                <div id="H">
                </div>      
                <div id="A">
                </div>                 
            </div>
        </section>

我可能不得不深入研究@RobertLongson 提出的建议,即为线性渐变的停止设置动画。

编辑 2:

感谢 kute.js,我尝试为线性渐变位置设置动画。 它适用于 firefox、chrome,但不适用于 IE/Edge 或网站,它们确实有一个 exemple working on IE/Edge .

这是我的笔,我仍然想知道为什么它不起作用。 https://codepen.io/AmauryH/pen/brBgKo

最佳答案

这是一种方法。我正在使用动画 CSS linear-gradient对于 split-half <div>元素。并使用 mix-blend-mode: difference以确保 Logo 与动画背景形成对比。

这应该适用于除 IE/Edge 之外的所有浏览器。

body *, *:after, *:before {
  box-sizing: border-box;
  margin:0;
  padding:0;
}
html, body {
  height: 100%;
}
.split-half {
  display: block;
  width: 50%;
  height: 100%;
  position: absolute;
  z-index: 1;
  padding: 5%;
}

.split-half:nth-child(1) {
  background: linear-gradient(to top, #ffffff 50%,#000000 50%);
  background-size: 100% 200%;
  background-position: 0 100%;
  left: 0;
  transition: background-position 0.5s;
}
.split-half:nth-child(1):hover {
  background-position: 0 0;
}

.split-half:nth-child(2) {
  background: linear-gradient(to top, #ffffff 50%,#000000 50%);
  background-size: 100% 200%;
  right: 0;
  transition: background-position 0.5s;
}
.split-half:nth-child(2):hover {
  background-position: 0 100%;
}

#logo {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-39.8%, -50%);
  max-width: 420px;
  min-width: 120px;
  width: 10%;
  height: auto;
  z-index: 10;
  mix-blend-mode: difference;
}
<section>
  <div class="split-half"></div>
  <div class="split-half"></div>

  <div id="logo">
    <svg width="100%" height="100%" viewBox="0 0 187 174" style="fill-rule:evenodd;">   
      <defs>
        <linearGradient x1="0" y1="100%" x2="0" y2="0">
          <stop offset="0" stop-color="white"/>
          <stop offset="0" stop-color="black"/>
        </linearGradient>
      </defs>

      <g>
        <path id="hSvg" d="M74.624,173.782l111.609,-55.886l-24.82,-12.41l-24.82,12.41l-24.82,-12.41l24.82,-12.41l-24.82,-12.41l-111.773,55.804l24.984,12.492l61.969,-31.066l24.82,12.41l-61.969,31.066" style="fill:#fff;"/>
        <path id="aSvg" d="M0.082,0l74.542,37.271l0,136.511l-24.82,-12.41l0,-62.05l-24.902,-12.451l0,62.05l-24.82,-12.41l0,-136.511Zm24.902,62.091l0,-24.82l24.82,12.41l0,24.821l-24.82,-12.411Z" style="fill:#fff;"/>
      </g>    
    </svg>

  </div>
</section>

关于css - 从底部到顶部动画 svg 填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45481126/

相关文章:

javascript - 想要在向下滚动到顶部时更改悬停时的导航链接颜色 --jquery

javascript - 在 Javascript 中循环访问 SVG 文件

javascript - 向 D3 力定向图中的链接添加标签

javascript - 如何使用 CSS 缩放 SVG 宽度?

css - Sass Keyframes 动画混合生成无效的 CSS

CSS - 禁用菜单动画

css - 单击 div 与过渡 div 一起滑动

javascript - 如何作为加载程序无限重复动画?

html - 我的想法哪里错了?浏览器缩放简单的 <div> 框

Jquery: Accordion 菜单 slideDown 和 slideUp