Элемент SVG Morph 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>
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? hair


person BlackStar1991    schedule 20.10.2018    source источник
comment
Вы просто хотите запустить существующую анимацию при наведении курсора мыши?   -  person Robert Longson    schedule 20.10.2018
comment
Да. Первая анимация на event.mouseenter, а вторая на event.mouseleave. Изменить форму пути   -  person BlackStar1991    schedule 20.10.2018
comment
Взгляните на это перо: Кнопка преобразования формы. Также может быть полезна эта статья: Как работает SVG Shape Morphing   -  person enxaneta    schedule 21.10.2018
comment
Я не могу получить правильный результат для событий mouseenter/mouseleave для родительского элемента.   -  person BlackStar1991    schedule 21.10.2018


Ответы (1)


Да. Ключевым моментом является то, что состояние «до» и состояние «после» объекта svg должны иметь одинаковое количество точек.

В вашем векторном редакторе начните с вас перед состоянием, давайте назовем это «Форма А». Экспортируйте форму «до» и сохраните «точки» в этом коде svg для формы A. Теперь вернитесь к программе, перемещайте точки вектора, пока они не совпадут с желаемой формой «после». Мы будем называть состояние после «Форма». Б'.

Как только вы встретите желаемую форму, экспортируйте этот svg и вытащите точки пути векторов. Это будет ваша форма B (после состояния).

Теперь у вас должна быть копия точек пути для формы A (состояние до) и формы B (состояние после).

Возьмите эти точки и введите их в тег начального пути, а также в «значения» тега анимации. См. приведенный ниже шаблон для примера того, как вставить эти точки в тег анимации, и см. фрагмент кода для более подробной информации о том, куда вставляются эти точки.

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

После того, как вы вставите свои точки, вы добавите fill, calcMode и keySplines, как показано в примере. Вы можете играть с ними, как хотите. Надеюсь это поможет! Эта запись помогла мне понять это https://codeburst.io/svg-morphing-the-easy-way-and-the-hard-way-c117a620b65f

Дайте мне знать, как вы разберетесь.

Обновление: отредактированный фрагмент для отображения анимации при наведении курсора мыши. Обратите внимание на добавленный атрибут begin со значением 'thesvg.mouseover'. Это берет идентификатор элемента ("thesvg") и связывает его с событием "mouseover". Вы можете присвоить своему телу идентификатор и поменять местами идентификатор "thesvg" с вашим 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>

person skaz    schedule 21.10.2018
comment
Можете ли вы показать, как будет работать ваш код, если вы повесите события mouseenter/mouseleave на тег body без repeatCount=indefinite? - person BlackStar1991; 21.10.2018
comment
Я обновил свой ответ дополнительными подробностями, связанными с запуском анимации при наведении курсора мыши, а также обновил фрагмент, чтобы анимировать событие «наведение курсора». Примечание. Фрагмент не будет работать с выбранным элементом body, но я проверил снаружи в firefox, и выбор элемента body с идентификатором сработал. Итак, посмотрите на новую строку с «begin=youelementid.mouseover» и измените «youelementid» на селектор идентификатора вашего тела. Вы также можете изменить RepeatCount на «1». - person skaz; 21.10.2018
comment
Это круто, но это не то, что я хочу. Я хочу что-то подобное jsfiddle.net/hf2cn09a - person BlackStar1991; 21.10.2018
comment
да без библиотеки будет сложно. SMIL, похоже, имеет слабую поддержку, а текущий CSS не имеет кросс-браузерной поддержки для морфинга точек пути. Chrome представил метод преобразования точек в CSS, где вы можете использовать эффект наведения для достижения своей цели, но он работает только в Chrome. - person skaz; 21.10.2018