如何在JavaScript中高效获取SVG路径到指定Y坐标的长度
优化SVG路径指定Y坐标对应长度的获取性能
我有一条复杂的SVG路径,已知目标Y坐标,需要获取路径从起点到该Y坐标位置的总长度。
我用二分查找定位对应Y坐标的路径线段,代码如下:
function binarySearchLengthByYCoord(path, yCoord) { const pathTotalLength = +path.getTotalLength(); let low = 0; let high = pathTotalLength; let result = 0; while (low <= high) { const mid = Math.floor((low + high) / 2); const point = path.getPointAtLength(mid); if (point.y < yCoord) { low = mid + 1; result = mid; } else { high = mid - 1; } } return pathTotalLength - result; }
这段代码能正常工作,但每次滚动事件触发都要调用,在低端设备和手机上性能问题明显。我需要保持现有动画效果的同时,实现更高效的代码。完整实现代码如下:
JavaScript代码
scrollLineAnimation(); function scrollLineAnimation() { const decorParent = document.querySelector("[data-line-animation]"), lines = decorParent.querySelectorAll("svg"); if (lines.length) { const line = lines[0], path = line.getElementsByTagName("path")[0], pathTotalLength = +path.getTotalLength(), lastYCoord = path.getPointAtLength(pathTotalLength).y, offsetHeight = decorParent.dataset.lineAnimation ? decorParent.dataset.lineAnimation : 0.8; line.style.strokeDasharray = pathTotalLength; line.style.strokeDashoffset = pathTotalLength; line.style.display = "block"; let position = 0; let prcPostion = 0; updateStrokeDashoffset(); window.addEventListener("scroll", updateStrokeDashoffset); window.addEventListener("resize", updateStrokeDashoffset); // 获取Y坐标并查找路径线段的函数 function updateStrokeDashoffset() { const scrollPosition = window.scrollY, windowHeight = window.innerHeight, svgHeight = line.getBoundingClientRect().height, yCoord = (scrollPosition + windowHeight * offsetHeight) * (lastYCoord / svgHeight), newStrokeDashoffsetValue = binarySearchLengthByYCoord(path, yCoord); prcPostion = (newStrokeDashoffsetValue / pathTotalLength) * 100; } // 平滑动画函数 function setStrokeDashoffset() { let dist = prcPostion - position; position = position + (dist * 70) / 1000; line.style.strokeDashoffset = Math.round( (position * pathTotalLength) / 100 ); requestAnimationFrame(setStrokeDashoffset); } requestAnimationFrame(setStrokeDashoffset); } function binarySearchLengthByYCoord(path, yCoord) { const pathTotalLength = +path.getTotalLength(); let low = 0; let high = pathTotalLength; let result = 0; while (low <= high) { const mid = Math.floor((low + high) / 2); const point = path.getPointAtLength(mid); if (point.y < yCoord) { low = mid + 1; result = mid; } else { high = mid - 1; } } return pathTotalLength - result; } }
CSS代码
body { max-width: 100%; position: relative; padding: 0; margin: 0; min-height: 6000px; } .decor { position: absolute; left: 0; top: 0; width: 100%; height: 100%; max-width: 1440px; } .decor svg { position: absolute; display: none; left: 0; top: 0; width: 100%; height: auto; min-height: 100%; }
HTML代码
<div data-line-animation="0.8" class="decor"> <svg preserveAspectRatio="none" width="1440" height="5141" viewBox="0 0 1440 5141" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M886.805 0.0743205C986.888 -1.4439 1187.91 19.063 1065.22 176.635C911.848 373.6 1455.21 527.592 1367.57 373.601C1279.93 219.61 613.874 395.088 1152.86 656.514C1584.04 865.655 736.569 920.328 258.934 921.522C91.767 929.283 -164.804 1007.13 146.247 1256.43C535.061 1568.06 1238.55 1700.59 1195.7 1890.43C1152.86 2080.27 -384.754 2905.95 146.247 2905.95C1314.52 2905.95 250.102 3383.41 709.046 3545.41C849.007 3594.81 1440.94 3511.17 1410.12 3824.66C1352.7 4408.75 -60.5479 4131.44 95.6015 4451.98C290.788 4852.65 1410.12 5002.4 1440 5140" stroke="#2BB32A" stroke-width="1.5" stroke-linecap="square" /> </svg> </div>
请问是否有更高效的方法来获取SVG路径到指定Y坐标的长度?
内容的提问来源于stack exchange,提问作者Ci4ENb
相关产品推荐
相关产品推荐

