在用户滚动时使用不透明度对SVG路径进行动画处理

时间:2016-10-26 17:25:31

标签: javascript jquery animation svg scroll-position

我已经构建了一个我想要制作动画的SVG,它有三个部分/层,每个部分都有预定义的路径。

SVG是圆形徽标类型的东西,在圆圈的顶部有单词并在剩余空间周围划线,然后键入圆圈的中间。

像这样但更简单: http://pixelcurse.com/wp-content/uploads/2015/11/logo-badges-8.jpg

我想做的是:

  1. 在进入视口之前将svg的不透明度设置为0
  2. 检测SVG何时开始进入视口
  3. 根据滚动位置(向下滚动)顺序更改前两个<g>块中每个路径的不透明度
  4. 向上滚动序列时会反转
  5. 我一直试图连续两天这样做,除了失败之外什么都没有。我成功地使用了简单的jquery动画和css动画(见下面的代码),但是无法通过滚动位置使这些玩得很好。

    我的另一个想法,但后来意识到这将是非常麻烦的,而不是反向工作是有多个if / else基于滚动位置但我不希望它有一个明确的数字,因为不同的分辨率,这将有继续努力。

    HTML:

    <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 640 640" style="enable-background:new 0 0 640 640;" xml:space="preserve">
        <g id="mainsvg">
            <g id="top-circle-words">
                <path/>
                <path/>
                <path/>
                <path/>
                <path/>
                <path/>
                <path/>
                <path/>
                <path/>
                <path/>
            </g>
    
            <g id="bot-circle-dashes">
                <path/>
                <path/>
                <path/>
                <path/>
                <path/>
                <path/>
                <path/>
                <path/>
                <path/>
                <path/>
                <path/>
            </g>
    
            <g id="middle-words">
                <path/>
                <path/>
            </g>
        </g>
    </svg>
    

    CSS - 动画尝试 - 无效但无法控制 - 只需加载:

    svg {width:100%;max-width:50%;margin:50% auto;display:block;}
    
    @-webkit-keyframes animIn { 0% { opacity: 0; } 100% { opacity:1; } }
    @-webkit-keyframes animOut { 0% { opacity: 1; } 100% { opacity:0; } }
    
    .animIn { -webkit-animation: animIn 500ms 1.5s normal backwards; -webkit-animation-fill-mode: both; }
    .animOut { -webkit-animation: animOut 500ms 3s reverse backwards; -webkit-animation-fill-mode: both; }
    
    g#top-circle-words path:nth-child(1) { -webkit-animation-delay: 50ms }
    g#top-circle-words path:nth-child(2) { -webkit-animation-delay: 100ms }
    g#top-circle-words path:nth-child(3) { -webkit-animation-delay: 150ms }
    g#top-circle-words path:nth-child(4) { -webkit-animation-delay: 200ms }
    g#top-circle-words path:nth-child(5) { -webkit-animation-delay: 250ms }
    g#top-circle-words path:nth-child(6) { -webkit-animation-delay: 300ms }
    g#top-circle-words path:nth-child(7) { -webkit-animation-delay: 350ms }
    g#top-circle-words path:nth-child(8) { -webkit-animation-delay: 400ms }
    g#top-circle-words path:nth-child(9) { -webkit-animation-delay: 450ms }
    g#top-circle-words path:nth-child(10) { -webkit-animation-delay: 500ms }
    
    g#bot-circle-dashes path:nth-child(1) {-webkit-animation-delay: 550ms }
    g#bot-circle-dashes path:nth-child(2) {-webkit-animation-delay: 600ms }
    g#bot-circle-dashes path:nth-child(3) {-webkit-animation-delay: 650ms }
    g#bot-circle-dashes path:nth-child(4) {-webkit-animation-delay: 700ms }
    g#bot-circle-dashes path:nth-child(5) {-webkit-animation-delay: 750ms }
    g#bot-circle-dashes path:nth-child(6) {-webkit-animation-delay: 800ms }
    g#bot-circle-dashes path:nth-child(7) {-webkit-animation-delay: 850ms }
    g#bot-circle-dashes path:nth-child(8) {-webkit-animation-delay: 900ms }
    g#bot-circle-dashes path:nth-child(9) {-webkit-animation-delay: 1s }
    g#bot-circle-dashes path:nth-child(10) {-webkit-animation-delay: 1.1s }
    g#bot-circle-dashes path:nth-child(11) {-webkit-animation-delay: 1.2s }
    
    g#middle-words {-webkit-animation-delay: 300ms; -webkit-animation-duration: 2s}
    

    JS - 使用.each();

    $("g#top-circle-words path, g#bot-circle-dashes path").each(function(index) {
        $(this).delay(20*index).animate({opacity: 1}, 50);
    });
    
    $("g#middle-words").delay(50).animate({opacity: 1}, 500);
    

    所以,如果你采用上面的代码,它应该可以工作,它是我无法控制的吗?你可以看到CSS,如果你手动将.animIn类添加到你想要动画的所有元素而不使用JQ,它也可以工作。

    我确实在这里找到了另一篇文章,其中OP与我有类似的问题(有点),我试图调整标记正确的代码,但也无法使其工作?

    $(function() {
        var prevRange = -1;
        var range = -1;
    
        $(document).on('scroll', function() {
            var top = $(document).scrollTop();      
            if (top >= 2200 && top < 2401) {
                range = Math.floor(top/10)-220;
            } else {
                range = -1;
            }
    
            if(range != prevRange) {
                prevRange = range;
                var leftPx = (826 - range*5) + "px";
                $('path').stop().animate({left: leftPx}, 300, "easeOutQuad" );
            }
        });
    }); 
    

    这也是我写的内容,但如果我使用多个IF语句,我可以看到这很麻烦:

    // $(document).ready(function() {
    //  $(window).scroll(function() {
    //      if ($(this).scrollTop() > 100){
    //          $('g#top-circle-words path:nth-child(1)').css( { 'opacity': '.5' } );
    //      }
    //      else {
    //          $('path').css({
    //              'opacity': '.9',
    //              "border": "0"
    //          });
    //      }
    //      console.log($(document).scrollTop());
    //  });
    // });
    

    任何人都可以帮我解决这个问题 - 一直在做我的大脑 - 道歉,因为我还在学习JS和JQ,所以如果有人可以告诉我正确的方向或提供一些解释,我会非常感激。

1 个答案:

答案 0 :(得分:0)

如果您需要,我建议您使用ScrollMagicGSAP

这应该是正确的设置,但可能需要根据您的确切SVG进行调整:

numStepsHanoi :: Integer -> Integer
numStepsHanoi 0 = 0
numStepsHanoi n = let steps = numStepsHanoi (n-1)
                  in steps + steps + 1