简体   繁体   English

滚动显示SVG动画

[英]Animate SVG on scroll

I'm animating an SVG line based on my scroll position. 我正在根据滚动位置为SVG线设置动画。 It works but the FPS is really low and the animation itself is laggy. 它可以工作,但FPS确实很低,动画本身也很滞后。 I pretty sure it's my native Javascript skills that are screwing things up, but I don't know how to solve it. 我很确定这是我的本机Javascript技能在搞砸,但我不知道如何解决。

I made a quick and dirty JSbin replica of what I currently have on the actual website; 我对当前实际网站上的内容做了一个快速而肮脏的JSbin副本;

http://jsbin.com/vigaqoxiru/edit?html,css,js,output http://jsbin.com/vigaqoxiru/edit?html,css,js,output

window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || function(f){setTimeout(f, 1000/60)}

document.addEventListener('DOMContentLoaded', function() {
    Timeline();
});

function Timeline() {
    requestAnimationFrame(animateLine)

    function convertRange( value, r1, r2 ) { 
         return ( value - r1[ 0 ] ) * ( r2[ 1 ] - r2[ 0 ] ) / ( r1[ 1 ] - r1[ 0 ] ) + r2[ 0 ];
    }

    function animateLine() {
        var offset = window.scrollY;
        var wheight = window.innerHeight;
        var timeline = document.querySelector(".Approach--steps");
        var theight = timeline.getBoundingClientRect().top - wheight;

        if (theight < 0) {
            var timelineMin = timeline.offsetHeight;
            var objectMin = timeline.offsetTop;
            var objectMax = timeline.offsetTop + timeline.offsetHeight;

            document.querySelector(".Approach--timeline svg").setAttribute("style", "transform: scaleY(" + Math.floor(convertRange( (offset + wheight), [objectMin, objectMax], [0, 1.0]) * 100) / 100 + ")");
        }
    }

    window.addEventListener('scroll', function(){
        requestAnimationFrame(animateLine)
    });
}

As you can see it's jumpy it doesn't scroll at 60fps, altho I'm using the scale attribute, requestAnimationFrame and rounded values. 如您所见,它跳动不快,无法以60fps的速度滚动,不过我正在使用scale属性,requestAnimationFrame和舍入值。 Any idea what a better way of implementing this animation is? 任何想法实现此动画的更好方法是什么? Preferably without jQuery. 最好没有jQuery。 GSAP is okay since I'm already running it. GSAP还可以,因为我已经在运行它了。

Why don't you add a transition time to make it work more smoothly? 您为什么不添加transition时间以使其工作更流畅?

.Approach--timeline svg {
    transition: .5s ease;
}

 window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || function(f){setTimeout(f, 1000/60)} document.addEventListener('DOMContentLoaded', function() { Timeline(); }); function Timeline() { requestAnimationFrame(animateLine) function convertRange( value, r1, r2 ) { return ( value - r1[ 0 ] ) * ( r2[ 1 ] - r2[ 0 ] ) / ( r1[ 1 ] - r1[ 0 ] ) + r2[ 0 ]; } function animateLine() { var offset = window.scrollY; var wheight = window.innerHeight; var timeline = document.querySelector(".Approach--steps"); var theight = timeline.getBoundingClientRect().top - wheight; if (theight < 0) { var timelineMin = timeline.offsetHeight; var objectMin = timeline.offsetTop; var objectMax = timeline.offsetTop + timeline.offsetHeight; document.querySelector(".Approach--timeline svg").setAttribute("style", "transform: scaleY(" + Math.floor(convertRange( (offset + wheight), [objectMin, objectMax], [0, 1.0]) * 100) / 100 + ")"); } } window.addEventListener('scroll', function(){ requestAnimationFrame(animateLine) }); } 
 .Approach--steps { margin-top: 600px; margin-bottom: 200px } .Approach--header { margin-top: 80px; } .Approach--step { margin-top: 500px; padding-left: 56px; } .Approach--timeline { } .Approach--timeline svg { position: absolute; margin-top: -100px; height: 100%; width: 4px; transition: .5s ease; transform: scaleY(0); transform-origin: top left; } .Approach--steps { position: relative; } 
 <div class="Approach--steps"> <div class="Approach--timeline"> <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 1 1" preserveAspectRatio="none"> <linearGradient id="grad" x1="0%" y1="0%" x2="0%" y2="100%" gradientUnits="userSpaceOnUse"> <stop stop-color="#22D9BC" stop-opacity="1.0" offset="0%" /> <stop stop-color="#1674F5" stop-opacity="1.0" offset="50%" /> <stop stop-color="#7D00FF" stop-opacity="1.0" offset="100%" /> </linearGradient> <rect x="0" y="0" width="1" height="1" fill="url(#grad)" id="Approach--svg" /> </svg> </div> <div class="Approach--step"> <p>1. Khaled Ipsum</p> <p>Lorem Khaled Ipsum is a major key to success. Eliptical talk. How's business? Boomin. They will try to close the door on you, just open it. You see the hedges, how I got it shaped up? It's important to shape up your hedges, it's like getting a haircut, stay fresh. Wraith talk. We don't see them, we will never see them. Life is what you make it, so let's make it. Another one. Hammock talk come soon. It's important to use cocoa butter. It's the key to more success, why not live smooth? Why live rough?</p> </div> <div class="Approach--step"> <p>2. Lion</p> <p>The ladies always say Khaled you smell good, I use no cologne. Cocoa butter is the key. Hammock talk come soon. Put it this way, it took me twenty five years to get these plants, twenty five years of blood sweat and tears, and I'm never giving up, I'm just getting started. Major key, don't fall for the trap, stay focused. It's the ones closest to you that want to see you fail. The key to success is to keep your head above the water, never give up.</p> </div> <div class="Approach--step"> <p>3. We the best</p> </div> </div> 

Here's a gist of a working GSAP example. 这是一个可行的GSAP示例的要点

You mentioned you plan on adding other elements to your SVG. 您提到计划在SVG中添加其他元素。 I would recommend you read the GSAP/SVG docs here . 我建议您在此处阅读GSAP / SVG文档。

When animating with GSAP, I'd pretty much always recommend using an ID selector. 使用GSAP制作动画时,我几乎总是建议使用ID选择器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM