Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
225 views
in Technique[技术] by (71.8m points)

javascript - Animate a SVG to show percentage of svg on scroll

Hello I'm try to create a animation on SVG, when we scroll it shows a part of the svg smooth. For example, when we scroll to element 1 second after 50% of svg is show, and 2 seconds after 100% is show. Example:

 <svg id="forma" width="100vw" height="426" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path d="M181.661 251.791C190.764 240.228 202.907 234.579 208.774 239.188L211.212 241.101C211.285 241.159 211.332 241.228 211.394 241.272C318.436 324.319 435.262 369.505 549.447 371.936C651.861 374.131 746.714 336.75 851.229 291.374C943.672 251.25 1054.46 206.315 1175.33 177.304C1179.3 176.351 1183.3 175.413 1187.32 174.477L1187.34 174.57L1187.5 174.531C1194.76 172.855 1203.35 183.106 1206.67 197.442C1209.99 211.778 1206.79 224.689 1199.52 226.377L1196.5 227.069C1196.37 227.097 1196.19 227.161 1196.06 227.176C1193.28 227.823 1190.56 228.474 1187.82 229.137C1178.02 231.49 1168.1 234.134 1158.42 236.693C1052.76 264.684 955.287 304.337 872.538 340.253C798.226 372.508 728.353 400.948 656.072 415.348C620.984 422.34 585.316 426.022 548.303 425.24C428.773 422.689 307.557 378.318 196.071 296.407C189.333 291.455 182.515 285.222 175.862 280.016L175.921 279.93L175.786 279.828C169.943 275.234 172.557 263.368 181.661 251.791Z" fill="#7E348E"/>
    
      <defs>
          
        <filter id="fillpartial" primitiveUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%">
          <feFlood x="0%" y="0%" width="100%" height="100%" flood-color="#4151E6" />
          <feOffset dx="0">
            <animate id="anim" attributeName="dx" from="0" to="1" dur="2s" begin="indefinite" />
          </feOffset>
          <feComposite operator="in" in2="SourceGraphic" />
          <feComposite operator="over" in2="SourceGraphic" />
        </filter>
      </defs>
    <path  filter="url(#fillpartial)" d="M1141.06 186.014L1141.18 185.985C1152.62 182.918 1164.11 179.999 1175.32 177.304C1255.71 158.008 1325.24 148.158 1387.9 147.164C1470.46 145.87 1543 160.341 1603.51 190.196C1659.16 217.668 1702.21 257.565 1724.74 302.551L1724.77 302.605L1725.1 303.321C1728.2 310.098 1719.81 320.823 1706.4 326.928C1692.98 333.02 1680.67 332.376 1676.61 325.611L1675.82 324.196C1658.13 290.418 1624.16 259.875 1579.85 238.012C1527.04 211.953 1462.74 199.331 1388.76 200.5C1330.08 201.426 1264.37 210.805 1187.83 229.164C1178.44 231.421 1168.92 233.992 1159.32 236.531L1157.4 237.065L1154.76 237.762C1147.54 239.635 1138.68 229.611 1134.96 215.372C1131.25 201.148 1133.9 187.944 1141.06 186.014Z" fill="#00D3AF"/>
    <path d="M-27.5853 6.8053C-14.9606 -0.780953 -1.59381 -1.75453 2.24145 4.62716L3.82708 7.25161C63.1129 104.289 143.341 192.216 230.257 255.434C230.318 255.478 230.382 255.496 230.43 255.539L232.955 257.342C239.013 261.694 236.956 274.893 228.343 286.834C219.744 298.776 207.859 304.94 201.802 300.589L201.642 300.472L201.593 300.429C107.234 232.435 -43.3742 32.2596 -43.3742 32.2596L-43.4771 32.0823C-47.3263 25.7125 -40.21 14.3915 -27.5853 6.8053Z" fill="#FFCB26"/>
    </svg>
question from:https://stackoverflow.com/questions/65883459/animate-a-svg-to-show-percentage-of-svg-on-scroll

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You will need an extra path similar to the curve you have but only the stroke. You will use this path to mask the shapes you have. In order to show only part of the curve you have you can use stroke-dasharray for the mask.

Observation: in my example I'm using an input type range because it's not very clear what you want to do with the scroll.

Also for the maskPath I'm using fragments of your code. You may want to draw a better curve with Illustrator or whatever graphics editor you are using.

let length = maskPath.getTotalLength()
maskPath.setAttribute("stroke-dasharray", length/2 )

itr.addEventListener("input",()=>{
let stroke = length * itr.value/100;
let gap = length - stroke
maskPath.setAttribute("stroke-dasharray", `${stroke} ${gap}` )
output.innerHTML = itr.value + "%"
})
svg{border:solid;}
<p><input type="range" id="itr" value="50" /><span id="output">50%</span></p>

<svg id="forma" fill="none" viewBox="-70 -50 1850 500" >
<g mask="url(#m)">
<path d="M-27.5853 6.8053C-14.9606 -0.780953 -1.59381 -1.75453 2.24145 4.62716L3.82708 7.25161C63.1129 104.289 143.341 192.216 230.257 255.434C230.318 255.478 230.382 255.496 230.43 255.539L232.955 257.342C239.013 261.694 236.956 274.893 228.343 286.834C219.744 298.776 207.859 304.94 201.802 300.589L201.642 300.472L201.593 300.429C107.234 232.435 -43.3742 32.2596 -43.3742 32.2596L-43.4771 32.0823C-47.3263 25.7125 -40.21 14.3915 -27.5853 6.8053Z" fill="gold"/>
<path d="M181.661 251.791C190.764 240.228 202.907 234.579 208.774 239.188L211.212 241.101C211.285 241.159 211.332 241.228 211.394 241.272
         C318.436 324.319 435.262 369.505 549.447 371.936C651.861 374.131 746.714 336.75 851.229 291.374C943.672 251.25 1054.46 206.315 1175.33 177.304C1179.3 176.351 1183.3 175.413 1187.32 174.477L1187.34 174.57L1187.5 174.531C1194.76 172.855 1203.35 183.106 1206.67 197.442C1209.99 211.778 1206.79 224.689 1199.52 226.377L1196.5 227.069
         
         C1196.37 227.097 1196.19 227.161 1196.06 227.176C1193.28 227.823 1190.56 228.474 1187.82 229.137C1178.02 231.49 1168.1 234.134 1158.42 236.693C1052.76 264.684 955.287 304.337 872.538 340.253C798.226 372.508 728.353 400.948 656.072 415.348C620.984 422.34 585.316 426.022 548.303 425.24C428.773 422.689 307.557 378.318 196.071 296.407C189.333 291.455 182.515 285.222 175.862 280.016L175.921 279.93L175.786 279.828C169.943 275.234 172.557 263.368 181.661 251.791Z" fill="rebeccapurple"/>
 
<path  d="M1141.06 186.014L1141.18 185.985C1152.62 182.918 1164.11 179.999 1175.32 177.304C1255.71 158.008 1325.24 148.158 1387.9 147.164C1470.46 145.87 1543 160.341 1603.51 190.196C1659.16 217.668 1702.21 257.565 1724.74 302.551L1724.77 302.605L1725.1 303.321C1728.2 310.098 1719.81 320.823 1706.4 326.928C1692.98 333.02 1680.67 332.376 1676.61 325.611L1675.82 324.196C1658.13 290.418 1624.16 259.875 1579.85 238.012C1527.04 211.953 1462.74 199.331 1388.76 200.5C1330.08 201.426 1264.37 210.805 1187.83 229.164C1178.44 231.421 1168.92 233.992 1159.32 236.531L1157.4 237.065L1154.76 237.762C1147.54 239.635 1138.68 229.611 1134.96 215.372C1131.25 201.148 1133.9 187.944 1141.06 186.014Z" fill="DarkTurquoise"/>
  </g>
  
<mask id="m">
<path id="maskPath" stroke-dasharray="1000 956" transform="translate(-20,5)" d="M0, 0
         C63.1129 104.289 143.341 192.216 230.257 255.434
         C230.318 255.478 230.382 255.496 230.43 255.539
         
         C318.436 324.319 435.262 369.505 549.447 371.936
         C651.861 374.131 746.714 336.75 851.229 291.374
         C943.672 251.25 1054.46 206.315 1175.33 177.304
         
         C1255.71 158.008 1325.24 148.158 1387.9 147.164C1470.46 145.87 1543 160.341 1603.51 190.196C1659.16 217.668 1702.21 257.565 1740 312" stroke="white" stroke-width="120"/>
    </mask>
</svg>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...