首页 > 解决方案 > SVG 的 SVG 变形元素

问题描述

是否可以在不使用第三方库的情况下进行 SVG 元素转换?小例子

.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>
有必要意识到,当您将光标悬停在“完整图像”包装上时,您的头发会从第一个路径转换为第二个路径。当光标离开该区域时,一切都会以相反的顺序进行。可能吗? 头发

标签: cssanimationsvgsmil

解决方案


是的。关键是 svg 对象的“之前”状态和“之后”状态需要具有相同数量的点。

在您的矢量编辑器中,先从您开始,让我们称之为“形状 A”。导出之前的形状并在此 svg 代码中为形状 A 保存“点”。现在,回到程序,移动向量的点,直到它与您想要的“之后”形状相匹配,我们将后状态称为“形状”乙'。

一旦你达到你想要的形状,导出这个 svg 并拉出向量路径'点。这将是你的形状 B,(在状态之后)。

现在,您应该拥有形状 A(之前状态)和形状 B(之后状态)的路径点的副本。

获取这些点并将它们输入到初始路径标记以及动画标记的“值”中。有关如何在 animate 标记中插入这些点的示例,请参阅下面的模板,并查看片段代码以了解有关插入这些点的位置的更详细细分。

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

插入点后,您将添加填充、calcMode 和 keySplines,如示例所示。你可以随心所欲地玩这些。希望这可以帮助!这篇文章帮助我弄清楚了https://codeburst.io/svg-morphing-the-easy-way-and-the-hard-way-c117a620b65f

让我知道你是怎么做出来的。

更新:编辑片段以在“鼠标悬停”上显示动画。注意begin添加的属性,其值为“thesvg.mouseover”。这需要元素 ID ('thesvg')并将其与'mouseover' 事件连接起来。 你可以给你的身体一个 ID,然后用你的身体 'id' 交换'thesvg' id 以获得相同的效果。对于这个片段,使用 Body ID 不起作用,但我在 Firefox 中测试了它,它工作正常。

#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>


推荐阅读