Страницы

Поиск по вопросам

понедельник, 9 декабря 2019 г.

Как сделать morphing анимацию частей SVG элемента по наведению мышки?

#javascript #css #svg #анимация #smil


Подскажите, есть ли возможность без подключения сторонних библиотек (GSAP / SVG-Morpheus)
произвести изменения формы? Приведу пример: 



.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;
}
Необходимо реализовать чтобы по наведению курсора на обёртку "волосы" кнопки сползали за 2 сек. с позиции 1 в позицию 2, при уходе курсора, всё в обратном порядке. (Количество контрольных точек SVG вроде как сохранил) Не могу понять где допускаю ошибку? Если SMIL событие повесить на begin=za_hair.mouseenter, то что-то происходит, но всё равно не то.


Ответы

Ответ 1



После многодневных танцев с бубном над решением данной задачи и перечитыванию документации по SVG-анимациям (хотя это ничего не дало) я пришёл к мысли, что количество точек в обоих путях должно быть одинаковым и эти точки должны быть расположены определённым образом. К сожалению, об этом нигде не написано. Чтобы все эти зависимости наглядно вам показать я приготовил такое изображение: На нём мы видим 14 красных и 28 синих точек на обоих картинках. Одинаковое количество красных и синих точек, а также их расположение очень важно для данного случая, т.к. иначе будет несоответствие количества точек и анимация такой, какую мы хотим, не получится. Также как мне уже после написания моего ответа подсказал Alexandr_TT нужно учитывать что: должны быть одни и те же команды у одинаковых от начала по счёту точек в начальном и в конечном виде (путях). Допустим у третьей точки первого пути стоит C50 и у второго пути у этой же 3-ей точки должна быть команда C... Это также означает, что начало (M..., m...) и конец путей должны совпадать. Если этого всего не сделать, то будут ошибки. Чтобы эти ошибки наглядно увидеть достаточно в вашем коде изменить calcMode="discrete" в двух местах на calcMode="linear" и перенести id="fullImage" с внешнего div-а на SVG элемент. А вот from="..." указывать не нужно. Выглядеть это будет вот так: .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; }
Обратите внимание на то, что IE не поддерживает SVG анимацию. И для того, чтобы всё это заработало правильно нужно пути написать соответствующим образом. Для того, чтобы это наглядно показать я изменил в пути path свойство d="..." и в элементах animate свойства to="..." на те точки, которые я описал выше. И всё заработало правильным образом. Правильное решение .game_block{position: relative; width: 100%; height: 100%; min-height: 100vh} .btn_gamePlay { width: 210px; height: 270px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: none; }
Для того, чтобы это хорошо рассмотреть нажмите над snippet-ом ссылку «На всю страницу».

Ответ 2



Вот рабочий вариант того что вы здесь написали. Ошибки: 1. Надо поставить клик на g элемент (begin="za_hair.mouseenter") 2. В animate надо указать начало анимации (from=".....") .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. То здесь в помощь идет js. $(document).ready(function(){ $('#fullImage').mouseenter(function(){ document.getElementById("animEnter").beginElement(); }); $('#fullImage').mouseleave(function(){ document.getElementById("animLeave").beginElement(); }); }); .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; }


Ответ 3



Вот еще один вариант. Здесь уже в animate надо задать values. Но здесь опять плавности не будет. И это уже от вашего 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; }
Вот пример другой svg картинки. и здесь уже та же самая анимация, с идентичными параметрами работает правильно.

Комментариев нет:

Отправить комментарий