简体   繁体   中英

SVG Morph element of SVG

Is it possible to do SVG element transformation without using third-party libraries? Small example

 .game_block { position: relative; width: 100%; height: 100%; min-height: 100vh; } .btn_gamePlay { width: 100vh; height: 100vh; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: none; transition: 0.2s all; } .st7 { fill: #70203c; } .st8 { fill: #ef447e; stroke: #5e112d; stroke-width: 0.5; stroke-miterlimit: 10; } 
 <div id="fullImage" class="game_block"> <button class="btn_gamePlay" type="button" title="Play"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 240 240"> <path d="M171.5 182s11.5-.2 14.5-7.2 4.7-30 4.7-30l1.1-74.8s-.8-19.8-15.3-25.8-110.8 0-110.8 0S52.3 40 52 89.5s1.8 81.5 1.8 81.5 1 9.5 12.3 10.5 105.4.5 105.4.5z" fill="#ef457e" stroke="#5e102d" stroke-miterlimit="10" id="za_x5F_btn"/> <g id="za_hair"> <path class="st18" id="eyebrow" d="M147 64.5s-5.9.8-7.4 2.5-1.3 2.6-1.3 2.6c2 0 7.5-2.5 10.1-4.1s-1.4-1-1.4-1z"/> <path id="main_hair" d="M137.5 57.8s-8.5 14.3-9.8 15.5.4-3.4-.9-3.5-6.3 10.8-6.9 21.3-1.1-3-1.1-3-.5-5.4-2.7 2.1-3.4 20.6-4.9 22.2c-.8.9-1.2.1-1.3-.9-.2-1-.8-1.9-1.7-2.2-.5-.2-.7.1-1.1 1.4-.6 2.3-.1 2.9-2.4 4s-5.1 1.1-6.5 3.9-2.5 1.2-2.4 3.8.8 4.2-1.6 9.8-1.6 6.4-3.4 8.6-3.4 1.4-3.6.3.8-1.4-.4-2.7-3.3-3.5-4.4-1.4-3.7 10.4-3.7 10.4 1.3-4.9.1.4-.1 7.3-1 9.1-1.9 2-2.7 1.4-2.5-5.4-3.4-4.9-2.2 3.1-3.2 6.9-.3 5.5-2.1 6.7-3.3-2.4-4.2-2.6-2.9 3.1-2.9 3.4-4.4 4.9-3.9 12 .9 9.7.1 10-2.8-4.1-3.6-7.8-5-14.2-3.4-21.3c1.5-6.7-1.3-85.2-.7-92.4.8-9.4 1.9-19.4 4.4-21.8 3.5-3.3 4.8-5.3 14-7.9s38.6-10.8 52-9.8 30.9.4 42.6 5.9 18.3 9 18.3 9c4.4 4.4 12.6 1.6 13.6 25.8s.1 96.3-.1 98.3-3.5 19.9-3.5 19.9c-2.9 6-3.3-1.8-3.3-1.8s-.3-22-1.9-25.4-2.8-.4-2.8-.4-1.4.9-2.3-5.9.6-20-.9-23.9-2.6 4.4-2.6 4.4-.5 4.4-1.5 3.1-2-35.3-2.6-36.4-.4-1-2 1.6-1.3-7.9-2-10-2.8.6-3.3-3.4-1-7-3.3-8.1c-.7-.4-1.3-.2-1.7.2-1 .9-2.5.4-3.1-.7-2.5-4.7-6.7-12.6-8-12.5-1.8.1-2.3 0-2.6.6s-1.8-2.3-2-6.1c-.1-1.7-1.3-2.4-2.4-2.7-1.2-.3-2.3-1.1-3.2-2 .1-.3-.1-.5-.1-.5z" fill="#1a1416" stroke="#171617" stroke-miterlimit="10"> <animate attributeName="d" fill="freeze" dur="2s" calcMode="discrete" begin=fullImage.mouseenter to="M138.8 200s-.3.8-1.5 2-.9-4.9-2.3-5-3.4-15.8-4-5.3-1-3.8-1-3.8-2.6-3.3-4.8 4.3-2-3.1-3.5-1.5c-.8.9-2.5-2.7-2.5-1.8 1.3 41.2-2.6 14.7-3.5 13-1.8-3.3-.1-9.8-.5-8.5-.6 2.3-2.4 7.6-4.8 8.8s-.6-10.3-2-7.5-2.6 2.2-2.5 4.8-2.4-10.4-4.8-4.8-.9-5.4-2.8-3.3-5-2.8-6.8-6.5c-.3-1 .4 8.5-.8 7.3s-.1-5.8-1.3-3.8-4.3 2-4.3 2-.6-10.4-1.8-5-.4 3.3-.5 5.3c-.3 6.5-3.5 12.5-6.3-5.3-.2-1-1.3-5.5-1.3-4.5 3.1 31.8-4.8-1.8-5.8 2s-1 3.6-2.8 4.8-2.6-2.7-2.5-1.8c1.8 21.3-4.3 4.4-4.3 4.8s-5.3-18.3-4.9-11.2.9 9.7.1 10-2.8-4.1-3.6-7.8-5-14.2-3.4-21.3c1.5-6.7-1.3-85.2-.7-92.4.8-9.4 1.9-19.4 4.4-21.8 3.5-3.3 4.8-5.3 14-7.9s38.6-10.8 52-9.8 30.9.4 42.6 5.9 18.3 9 18.3 9c4.4 4.4 12.6 1.6 13.6 25.8s.1 96.3-.1 98.3-3.5 19.9-3.5 19.9c-2.9 6-3.3-1.8-3.3-1.8-.2 2-9 30.8-8.5 10.3.1-3.7-3-7.5-3-7.5s-1.9 23.3-2.8 16.5.8 7.6-.8 3.8.8-1 .8-1-2.8-25.8-3.8-27-1.6 24.1-2.3 23-3.1-24.1-4.8-21.5-1.5 15.9-2.3 13.8-2.5 9.8-3 5.8-2-8.1-4.3-9.3c-.7-.4-2.8-1-1.5 16.3.1 1.3-1.8 1.2-1.5 2.5 1.8 8.5-1.8 1.6-2.3.5-4.3-11.4.1-3-1.8-12-2.3-10.8-.3 6.9-.3 10.8 3.3-20-.9 12.8.3-12.3-6.9 2.4-4.1 14.1-4.8 7.8.1-5.6-.1-8.9-.5-3.3.2 14.3.7-2.8.7-2.8z"> </animate> <animate attributeName="d" fill="freeze" dur="2s" calcMode="discrete" begin=fullImage.mouseleave to="M137.5 57.8s-8.5 14.3-9.8 15.5.4-3.4-.9-3.5-6.3 10.8-6.9 21.3-1.1-3-1.1-3-.5-5.4-2.7 2.1-3.4 20.6-4.9 22.2c-.8.9-1.2.1-1.3-.9-.2-1-.8-1.9-1.7-2.2-.5-.2-.7.1-1.1 1.4-.6 2.3-.1 2.9-2.4 4s-5.1 1.1-6.5 3.9-2.5 1.2-2.4 3.8.8 4.2-1.6 9.8-1.6 6.4-3.4 8.6-3.4 1.4-3.6.3.8-1.4-.4-2.7-3.3-3.5-4.4-1.4-3.7 10.4-3.7 10.4 1.3-4.9.1.4-.1 7.3-1 9.1-1.9 2-2.7 1.4-2.5-5.4-3.4-4.9-2.2 3.1-3.2 6.9-.3 5.5-2.1 6.7-3.3-2.4-4.2-2.6-2.9 3.1-2.9 3.4-4.4 4.9-3.9 12 .9 9.7.1 10-2.8-4.1-3.6-7.8-5-14.2-3.4-21.3c1.5-6.7-1.3-85.2-.7-92.4.8-9.4 1.9-19.4 4.4-21.8 3.5-3.3 4.8-5.3 14-7.9s38.6-10.8 52-9.8 30.9.4 42.6 5.9 18.3 9 18.3 9c4.4 4.4 12.6 1.6 13.6 25.8s.1 96.3-.1 98.3-3.5 19.9-3.5 19.9c-2.9 6-3.3-1.8-3.3-1.8s-.3-22-1.9-25.4-2.8-.4-2.8-.4-1.4.9-2.3-5.9.6-20-.9-23.9-2.6 4.4-2.6 4.4-.5 4.4-1.5 3.1-2-35.3-2.6-36.4-.4-1-2 1.6-1.3-7.9-2-10-2.8.6-3.3-3.4-1-7-3.3-8.1c-.7-.4-1.3-.2-1.7.2-1 .9-2.5.4-3.1-.7-2.5-4.7-6.7-12.6-8-12.5-1.8.1-2.3 0-2.6.6s-1.8-2.3-2-6.1c-.1-1.7-1.3-2.4-2.4-2.7-1.2-.3-2.3-1.1-3.2-2 .1-.3-.1-.5-.1-.5z"> </animate> </path> <path id="curl_hair" d="M137.5 57.8s-.8-6.2-10.3-7.2-7.4-2.3-7.4-2.3" fill="none" stroke="#161516" stroke-miterlimit="10"/> </g> </svg> </button> </div> 
It is necessary to realize that when you hover the cursor over the "full image" wrapper, your hair transforms from the first path to the second. When the cursor came out of the area, everything would go in the reverse order. Is it possible? 头发

Yes. The key is that the 'before' state and the 'after' state of the svg object need to have the same amount of points.

Within your vector editor, start with you before state, lets' call this 'Shape A'. Export the before shape and save the 'points' within this svg code for Shape A. Now, back to the program, move the vector's points around until it matches the 'after' shape you desire, we will call the after state, 'Shape B'.

Once you meet your desired shape, export this svg and pull out the vectors path 'points. This will be your Shape B, (after state).

Now, you should have a copy of the path points for Shape A (the before state) and Shape B (the after state).

Take these points and enter them within the initial path tag as well as within the 'values' for the animate tag. See the template below for an example on how to insert these points within the animate tag and see the snippet code for a more detailed breakdown on where these points are inserted.

<animate dur=”5s” repeatCount=”indefinite” attributeName=”d” 
values=”shapeAPoints;shapeBPoints;shapeAPoints”>

After you insert your points, you will then add the fill, calcMode and keySplines as shown in the example. You can play around with these as you wish. Hope this helps! This write up helped me figure it out https://codeburst.io/svg-morphing-the-easy-way-and-the-hard-way-c117a620b65f

Let me know how you make out.

Update: edited snippet to show animation on 'mouseover'. Note the added attribute of begin , with a value of 'thesvg.mouseover'. This takes the element ID ('thesvg') and connects it with the 'mouseover' event. You can give your body an ID and swap the 'thesvg' id with your body 'id' for the same affect. For this snippet, using the Body ID did not work, but I tested this within firefox and it works fine.

 #thesvg{ height: 300px; width: 300px; } #thepath{ fill: red; } 
 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Page Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" media="screen" href="main.css" /> <script src="main.js"></script> </head> <body> <div id="svgcontainer"> <svg id="thesvg" width="100" height="130" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> <path id="thepath" d="M39.29,39.27,36,45,8,39.27,0,21l8-7L23,5l16.29,9L45,32l-5.71,7.27Z" fill-rule="nonzero" fill="#070707"> <animate id="the-animation" begin="thesvg.mouseover" dur="1s" repeatCount="1" attributeName="d" values= "M39.29,39.27,36,45,8,39.27,0,21l8-7L23,5l16.29,9L45,32l-5.71,7.27Z; M39.29,39.27,28,33,8,39.27,14,26,8,14l18,5,13.29-5L34,27l5.29,12.27Z; M39.29,39.27,36,45,8,39.27,0,21l8-7L23,5l16.29,9L45,32l-5.71,7.27Z;" fill="freeze" calcMode="spline" keySplines="0.4 0 0.2 1; 0.4 0 0.2 1"> </path> </svg> </div> <script src="main.js"></script> </body> </html> 

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