简体   繁体   中英

Script to draw simple SVG-path slows down the entire PC

I've got a svg-based loading animation for a web project, which draws a 360°-arc on hover. This takes about .8s to finish. After that a container slides in, see my fiddle: http://jsfiddle.net/s2XCL/2/

        function drawCircle(arc) {
            var i = 0;
            var circle = document.getElementById(arc);
            var angle = 0;
            var radius = 75;
            window.timer = window.setInterval(

            function () {
                angle -= 5;
                angle %= 360;
                var radians = (angle / 180) * Math.PI;
                var x = 200 + Math.cos(radians) * radius;
                var y = 200 + Math.sin(radians) * radius;
                var e = circle.getAttribute("d");
                if (i === 0) {
                    var d = e + " M " + x + " " + y;
                } else {
                    var d = e + " L " + x + " " + y;
                }
                circle.setAttribute("d", d);
                i++;
            }, 10);


        }

        function removeCircle() {
          //  var circle = document.getElementById(arc);
          //  circle.style.display = "none";
        }

The function is called inside of the svg-tag in the HTML-markup:

        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" preserveAspectRatio="xMidYMid" style="width:400px; height:400px;" onmouseover="drawCircle('arc2'); removeCircle();">
            <path d="M200,200 " id="arc2" fill="none" stroke="rgba(255,255,255,0.3)" stroke-width="5"></path>
        </svg>

This works as intended, but occupies an entire 3 GHz-core on both of my two testing machines. I am currently learning JS, so I can only guess what causes the performance lack.

I also want the svg to disappear after completing the animation or the mouse leaving the container, so if anyone got a tip on that, that'd be great.


For any fellow googlers, see here http://jsfiddle.net/s2XCL/4/ for the solution. Feel free to use the snippet aswell.

The problem is that you never clear your timeouts. This will cause your timer to keep running, and every time you move your mouse above the svg element, it will keep creating new timers. That means that if you move your mouse a bit too long, it'll keep adding more and more to the path tag, and it will create a lot of lag.

To fix this, simply add a clearInterval for your global timer variable:

clearInterval(timer);

You'll also want to make sure this only runs when you initially move your mouse on top of the svg, not every time you move within it, by changing the event handler to mouseenter , not mousemove . And finally, you would need to clear the path's d attribute, otherwise the circle won't ever be removed.

The function would have the following: ( http://jsfiddle.net/s2XCL/3/ )

clearInterval(window.timer||0); //clear the previous timer, or "timer 0" (nonexistent) when it's not defined yet
circle.setAttribute("d", "M200,200 "); //reset d attribute to default

window.timer = window.setInterval(//interval

Also, building a whole path each time is not a very efficient way to do it.

A better way would be to use the dasharray trick for animating drawing of a path. What you do is slowly increase the first number in stroke-dasharray until it is equal to the length of the path. In this case, that's the circumference of the circle.

stroke-dasharray="0 1000"
stroke-dasharray="5 1000"
stroke-dasharray="10 1000"
...etc...

Here's a fiddle showing this trick applied to your case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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