动画 SVG 路径在用户滚动时不透明

Animate SVG paths with opacity on user scroll sequentially

我构建了一个我想要制作动画的 SVG,它有三个 parts/layers,每个都有预定义数量的路径。

SVG 是一个圆圈标志类型的东西,在圆圈的顶部有文字,在剩余的圆圈周围有破折号 space,然后在圆圈的中间键入。

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

我想做的是:

  1. 在进入视口之前将 svg 的不透明度设置为 0
  2. 检测 SVG 何时开始进入视口
  3. 根据滚动位置(向下滚动)依次更改前两个 <g> 块中每个路径的不透明度
  4. 向上滚动时顺序反转

我断断续续尝试了两天,但都失败了。我成功地使用了简单的 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 class 添加到您想要在其中设置动画的所有元素而不使用 JQ,它也可以工作。

我确实在此处找到了另一个 post,其中 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,所以如果有人可以告诉我正确的方向或提供一些解释的见解,我将非常感激它。

如果需要,我建议使用 ScrollMagic and potentially GSAP

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

var tween = TweenMax.fromTo("path", 1, { opacity: 0 }, { opacity: 1 });
var scene = new ScrollMagic.Scene({triggerElement: "#mySvg" })
                .setTween(tween)
                .addIndicators({name: "tween css class"}) // add indicators (requires plugin)
                .addTo(controller);