Andy Bui Posted November 16, 2022 Share Posted November 16, 2022 Hi all, First time working with DrawSVG so I don't fully understand how it works with drawing. As you can see from my codepen, I set the time for 10s but it only takes about 2-3s to finish drawing the house and when I check on browser, the stroke value is still running even through the house and tree is already completed. Can anyone help me set up the correct time for the img to draw exactly with the time set ? Thanks a lot See the Pen poKrOXN by tcb2307 (@tcb2307) on CodePen Link to comment Share on other sites More sharing options...
Solution GreenSock Posted November 16, 2022 Solution Share Posted November 16, 2022 Yeah, the problem is actually your artwork - you've got a single <path> that has a bunch of different segments (indicated by "M" commands). If you getTotalLength() on the path, you'll see that it's like 1157, so drawSVG correctly animates the stroke according to that length (as you can see in Dev Tools), but the browser doesn't render it correctly because it's not like there's a single stroke that can go through all of those segments. If anything, it's a browser issue. Normally, people use DrawSVG on single-segment <path> elements. So you'd need to bust the multi-segment <path> into a separate <path> for each segment. Sounds painful, right? Don't worry - I spent some time tonight writing this helper function for you that automates it all (and requires MotionPathPlugin): // helper function that busts apart a single <path> that has multiple segments into a <path> for each segment (indicated by an "M" command); function splitPaths(paths) { let toSplit = gsap.utils.toArray(paths), newPaths = []; if (toSplit.length > 1) { toSplit.forEach(path => newPaths.push(...splitPaths(path))); } else { let path = toSplit[0], rawPath = MotionPathPlugin.getRawPath(path), parent = path.parentNode, attributes = [].slice.call(path.attributes); newPaths = rawPath.map(segment => { let newPath = document.createElementNS("http://www.w3.org/2000/svg", "path"), i = attributes.length; while (i--) { newPath.setAttributeNS(null, attributes[i].nodeName, attributes[i].nodeValue); } newPath.setAttributeNS(null, "d", "M" + segment[0] + "," + segment[1] + "C" + segment.slice(2).join(",") + (segment.closed ? "z" : "")); parent.insertBefore(newPath, path); return newPath; }); parent.removeChild(path); } return newPaths; } Usage: let newPaths = splitPaths("path"); // or any selector text or element // returns an Array of the newly created <path> elements See the Pen RwJZEOv?editors=1010 by GreenSock (@GreenSock) on CodePen You could split a single path and then create a sequenced set of tweens if you want it to go from start to finish across all those segments too. Lots of options. Does that clear things up? 2 1 Link to comment Share on other sites More sharing options...
GreenSock Posted November 16, 2022 Share Posted November 16, 2022 By the way, here's an isolated CodePen that shows how to sequence all the segments in a linear fashion that maintains a consistent speed too: See the Pen yLEzJNE?editors=0010 by GreenSock (@GreenSock) on CodePen 2 Link to comment Share on other sites More sharing options...
Andy Bui Posted November 16, 2022 Author Share Posted November 16, 2022 Thanks a lot @GreenSock. This is exactly the answer I am looking for and it also helps me understand how svg works. I really appreciate you spending time writing that function to clear up the problem I face. Hope you have a great day 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now