Как реализовать анимацию плавного морфинга границ изображения?

введите сюда описание изображения

Есть картинка, при ховере ее границы должны начать хаотично плавать, изгибаться, пока не убран курсор.

Насколько понял, это должно быть связано с svg morphing, но примера не нашел. Только анимация чистой svg, без картинки. Может у кого есть конкретный пример?


Ответы (3 шт):

Автор решения: MaximLensky

В общем smil

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.container {
  max-width: 300px;
  margin: 0px auto;
}
<div class="container">
  <svg viewBox="0 0 150 150" id="svg" xmlns="http://www.w3.org/2000/svg">
    <defs>
      <clipPath id="mask">
        <path d="m123.3 221.82a47.625 48.57 0 0 1-47.625 48.57 47.625 48.57 0 0 1-47.625-48.57 47.625 48.57 0 0 1 47.625-48.57 47.625 48.57 0 0 1 47.625 48.57z" fill="none" stroke="#000">
        <animate attributeName="d" 
                 dur="12s"
                 begin="svg.mousemove" 
                 end="svg.mouseout"
                 values="m 123.29583,221.82054 c 0,26.82444 -22.2105,55.34697 -47.625,48.56994 -23.20821,-6.1887 -44.672416,-27.65067 -47.625,-48.56994 -3.748893,-26.56118 21.322438,-48.56994 47.625,-48.56994 26.30256,0 47.625,21.7455 47.625,48.56994 z;
m 123.29583,221.82054 c 0,26.82444 -21.32244,48.56994 -47.625,48.56994 -26.302562,0 -55.96245,-23.07411 -47.625,-48.56994 5.885147,-17.99672 25.450452,-42.37792 47.625,-48.56994 25.33341,-7.0741 47.625,21.7455 47.625,48.56994 z;
m 123.29583,221.82054 c 6.27285,26.08068 -21.32244,48.56994 -47.625,48.56994 -26.302562,0 -47.625001,-21.7455 -47.625,-48.56994 -10e-7,-26.82444 22.703382,-56.98051 47.625,-48.56994 23.884403,8.06053 44.04413,33.68173 47.625,48.56994 z;
m 123.29583,221.82054 c 5.53265,28.52679 -13.8157,50.87971 -47.625,48.56994 -26.241395,-1.79275 -47.625001,-21.7455 -47.625,-48.56994 -10e-7,-26.82444 21.322438,-48.56994 47.625,-48.56994 26.30256,0 42.51769,22.2362 47.625,48.56994 z;
m123.3 221.82a47.625 48.57 0 0 1-47.625 48.57 47.625 48.57 0 0 1-47.625-48.57 47.625 48.57 0 0 1 47.625-48.57 47.625 48.57 0 0 1 47.625 48.57z"
                 repeatCount="indefinite"/>
      </path>
   </clipPath>
    </defs>
    
     <g transform="translate(0,-147)">
     <image href="https://sun9-72.userapi.com/c824600/v824600327/19d5b5/4kUSTPvShoQ.jpg?ava=1" 
           x="0" y="150" 
           width="150" height="150"
           clip-path="url(#mask)"
          preserveAspectRatio="none"/>
     </g>
    
    

  </svg>
</div>

→ Ссылка
Автор решения: Alexandr_TT

Решение с помощью SVG mask

Для реализации плавного изменения границ изображения применена анимация маски.
Внутри маски находится path, форма которого будет меняться с помощью анимации атрибута d

Техника получения формул path для начального и конечного состояния линии границы изображения приведена в топике Плавный морфинг одного path в другой path

Используя эти технику вы сможете получить любую собственную форму анимации границ

1. Пример анимации изменения границы

Читайте комментарии в коде, надеюсь это поможет понять работу анимации и маски

<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
     width="250" height="250"   viewBox="0 0 250 250" preserveAspectRatio="xMinYMin meet" >  
 <defs>
  <mask id="msk1">
      <!-- Ко всему изображению применён чёрный цвет маски, поэтому всё пространство вне элипса становится невидимым -->
     <rect width="100%" height="100%" fill="black" />   
        <!-- Участок изображения ограниченный кривой при fill="white" становится видимым -->
    <path  fill="white" d ="M 0.65716244,24.31501 C 0.65716244,12.769206 14.091902,-0.12750335 25.629335,0.31207405 95.055812,2.95723 165.66239,2.95723 224.74955,-0.15260996 236.62119,-0.777431 250.69703,12.426939 250.69703,24.31501 c 0,73.172941 0,139.28327 0,200.43454 0,12.31193 -13.63555,26.2865 -25.94748,26.2865 -63.86693,0 -130.775322,0 -199.120215,0 -12.085756,0 -24.97217256,-14.20074 -24.97217256,-26.2865 0,-61.39127 0,-133.050269 0,-200.43454 z" > 
       <!-- анимация изменения формы границы -->
    <animate
      attributeName="d"
      begin="0s"
      dur="8s"
      repeatCount="indefinite"
      values="
      M 0.65716244,24.31501 C 0.65716244,12.769206 14.091902,-0.12750335 25.629335,0.31207405 95.055812,2.95723 165.66239,2.95723 224.74955,-0.15260996 236.62119,-0.777431 250.69703,12.426939 250.69703,24.31501 c 0,73.172941 0,139.28327 0,200.43454 0,12.31193 -13.63555,26.2865 -25.94748,26.2865 -63.86693,0 -130.775322,0 -199.120215,0 -12.085756,0 -24.97217256,-14.20074 -24.97217256,-26.2865 0,-61.39127 0,-133.050269 0,-200.43454 z;
      
     M 18.400548,36.143934 C 9.9101837,13.70807 43.926223,-0.54996925 51.25867,13.455323 c 76.33542,145.803977 86.46964,86.869767 141.28992,2.163965 18.44086,-28.493975 46.29247,8.882468 40.40505,19.210321 -38.20947,67.028001 -97.855,59.568605 -3.94297,138.004111 21.54722,17.99629 -0.61149,66.59059 -19.37585,46.00136 C 198.19796,206.28598 136.75871,43.292058 55.858806,212.92063 41.687846,242.63389 13.162026,189.96512 27.600822,178.74818 116.80291,109.45052 37.717611,87.189447 18.400548,36.143934 Z;
      
      M 0.65716244,24.31501 C 0.65716244,12.769206 14.091902,-0.12750335 25.629335,0.31207405 95.055812,2.95723 165.66239,2.95723 224.74955,-0.15260996 236.62119,-0.777431 250.69703,12.426939 250.69703,24.31501 c 0,73.172941 0,139.28327 0,200.43454 0,12.31193 -13.63555,26.2865 -25.94748,26.2865 -63.86693,0 -130.775322,0 -199.120215,0 -12.085756,0 -24.97217256,-14.20074 -24.97217256,-26.2865 0,-61.39127 0,-133.050269 0,-200.43454 z;" 
      />
    </path>
   </mask>
    </defs>  
       <!-- К изображению девушки применена маска -->
<image id="img1" xlink:href="https://i.stack.imgur.com/73YNh.jpg"  width="100%" height="100%"
       pointer-events="fill" mask="url(#msk1)" />
</svg>

2. Пример анимации изменения формы с помощью JS при клике по изображению

<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
     width="250" height="250"   viewBox="0 0 250 250" preserveAspectRatio="xMinYMin meet" >  
 <defs>
  <mask id="msk1">
      <!-- Ко всему изображению применён чёрный цвет маски, поэтому всё пространство вне пр\моугольника становится невидимым -->
     <rect width="100%" height="100%" fill="black" />   
       <!-- Участок изображения ограниченный кривой при fill="white" становится видимым -->
    <path  fill="white" d ="M 0.65716244,24.31501 C 0.65716244,12.769206 14.091902,-0.12750335 25.629335,0.31207405 95.055812,2.95723 165.66239,2.95723 224.74955,-0.15260996 236.62119,-0.777431 250.69703,12.426939 250.69703,24.31501 c 0,73.172941 0,139.28327 0,200.43454 0,12.31193 -13.63555,26.2865 -25.94748,26.2865 -63.86693,0 -130.775322,0 -199.120215,0 -12.085756,0 -24.97217256,-14.20074 -24.97217256,-26.2865 0,-61.39127 0,-133.050269 0,-200.43454 z" > 
      
      <!-- Анимация изменения формы границы после клика по изображению -->
    <animate id="open"
      attributeName="d"
      begin="idefinite"
      dur="1s"
      repeatCount="1"
      fill="freeze"
    restart="whenNotActive"
      values="
      M 0.65716244,24.31501 C 0.65716244,12.769206 14.091902,-0.12750335 25.629335,0.31207405 95.055812,2.95723 165.66239,2.95723 224.74955,-0.15260996 236.62119,-0.777431 250.69703,12.426939 250.69703,24.31501 c 0,73.172941 0,139.28327 0,200.43454 0,12.31193 -13.63555,26.2865 -25.94748,26.2865 -63.86693,0 -130.775322,0 -199.120215,0 -12.085756,0 -24.97217256,-14.20074 -24.97217256,-26.2865 0,-61.39127 0,-133.050269 0,-200.43454 z;
      
     M 18.400548,36.143934 C 9.9101837,13.70807 43.926223,-0.54996925 51.25867,13.455323 c 76.33542,145.803977 86.46964,86.869767 141.28992,2.163965 18.44086,-28.493975 46.29247,8.882468 40.40505,19.210321 -38.20947,67.028001 -97.855,59.568605 -3.94297,138.004111 21.54722,17.99629 -0.61149,66.59059 -19.37585,46.00136 C 198.19796,206.28598 136.75871,43.292058 55.858806,212.92063 41.687846,242.63389 13.162026,189.96512 27.600822,178.74818 116.80291,109.45052 37.717611,87.189447 18.400548,36.143934 Z" 
      />  
      <!-- Анимация возврата к первоначальной форме границы после повторного клика по изображению -->
      <animate id="close"
      attributeName="d"
      begin="idefinite"
      dur="1s"
      repeatCount="1"
      fill="freeze"
    restart="whenNotActive"
      values="
            M 18.400548,36.143934 C 9.9101837,13.70807 43.926223,-0.54996925 51.25867,13.455323 c 76.33542,145.803977 86.46964,86.869767 141.28992,2.163965 18.44086,-28.493975 46.29247,8.882468 40.40505,19.210321 -38.20947,67.028001 -97.855,59.568605 -3.94297,138.004111 21.54722,17.99629 -0.61149,66.59059 -19.37585,46.00136 C 198.19796,206.28598 136.75871,43.292058 55.858806,212.92063 41.687846,242.63389 13.162026,189.96512 27.600822,178.74818 116.80291,109.45052 37.717611,87.189447 18.400548,36.143934 Z;
      
           M 0.65716244,24.31501 C 0.65716244,12.769206 14.091902,-0.12750335 25.629335,0.31207405 95.055812,2.95723 165.66239,2.95723 224.74955,-0.15260996 236.62119,-0.777431 250.69703,12.426939 250.69703,24.31501 c 0,73.172941 0,139.28327 0,200.43454 0,12.31193 -13.63555,26.2865 -25.94748,26.2865 -63.86693,0 -130.775322,0 -199.120215,0 -12.085756,0 -24.97217256,-14.20074 -24.97217256,-26.2865 0,-61.39127 0,-133.050269 0,-200.43454 z" 
      /> 
    </path>
  
 </mask>
    </defs>  
    
       
    
            <!-- К изображению девушки применена маска -->
<image id="img1" xlink:href="https://i.stack.imgur.com/73YNh.jpg"  width="100%" height="100%"
       pointer-events="fill" mask="url(#msk1)" />
</svg>  
<script>
var lion_svg1 = document.getElementById("svg1"),
  close = document.getElementById('close'),
  open = document.getElementById("open");

let flag = true;

lion_svg1.addEventListener('click', function() {
  if (flag == true) {
    open.beginElement();
    flag = false;
  } else {
    close.beginElement();
    flag = true;
  }
}); 
</script>

3. Пример анимации изменения границы после наведения или ухода курсора

Добавление широкой границы с окраской в красный цвет делает её полупрозрачной
stroke-width="10" stroke="red"

<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
     width="250" height="250"   viewBox="0 0 250 250" preserveAspectRatio="xMinYMin meet" >  
 <defs>
  <mask id="msk1">
      <!-- Ко всему изображению применён чёрный цвет маски, поэтому всё пространство вне пр\моугольника становится невидимым -->
     <rect width="100%" height="100%" fill="black" />   
       <!-- Участок изображения ограниченный кривой при fill="white" становится видимым --> 
         <!-- Добавление широкой границы с окраской в красный цвет делает её полупрозрачной   stroke-width="10" stroke="red" -->
    <path  fill="white" stroke-width="10" stroke="red" d ="M 0.65716244,24.31501 C 0.65716244,12.769206 14.091902,-0.12750335 25.629335,0.31207405 95.055812,2.95723 165.66239,2.95723 224.74955,-0.15260996 236.62119,-0.777431 250.69703,12.426939 250.69703,24.31501 c 0,73.172941 0,139.28327 0,200.43454 0,12.31193 -13.63555,26.2865 -25.94748,26.2865 -63.86693,0 -130.775322,0 -199.120215,0 -12.085756,0 -24.97217256,-14.20074 -24.97217256,-26.2865 0,-61.39127 0,-133.050269 0,-200.43454 z" > 
    
      <!-- анимация изменения формы кривой при наведении курсора -->
    <animate id="open"
      attributeName="d"
      begin="svg1.mouseover"
      dur="0.25s"
      repeatCount="1"
      fill="freeze"
    restart="WhenNotActive"
      values="
      M 0.65716244,24.31501 C 0.65716244,12.769206 14.091902,-0.12750335 25.629335,0.31207405 95.055812,2.95723 165.66239,2.95723 224.74955,-0.15260996 236.62119,-0.777431 250.69703,12.426939 250.69703,24.31501 c 0,73.172941 0,139.28327 0,200.43454 0,12.31193 -13.63555,26.2865 -25.94748,26.2865 -63.86693,0 -130.775322,0 -199.120215,0 -12.085756,0 -24.97217256,-14.20074 -24.97217256,-26.2865 0,-61.39127 0,-133.050269 0,-200.43454 z;
      
     M 18.400548,36.143934 C 9.9101837,13.70807 43.926223,-0.54996925 51.25867,13.455323 c 76.33542,145.803977 86.46964,86.869767 141.28992,2.163965 18.44086,-28.493975 46.29247,8.882468 40.40505,19.210321 -38.20947,67.028001 -97.855,59.568605 -3.94297,138.004111 21.54722,17.99629 -0.61149,66.59059 -19.37585,46.00136 C 198.19796,206.28598 136.75871,43.292058 55.858806,212.92063 41.687846,242.63389 13.162026,189.96512 27.600822,178.74818 116.80291,109.45052 37.717611,87.189447 18.400548,36.143934 Z" 
      /> 
     
   <!-- анимация изменения формы кривой при покидании курсора -->
     <animate id="close"
      attributeName="d"
      begin="svg1.mouseleave"
      dur="0.25s"
      repeatCount="1"
      fill="freeze"
    restart="WhenNotActive"
      values="
            M 18.400548,36.143934 C 9.9101837,13.70807 43.926223,-0.54996925 51.25867,13.455323 c 76.33542,145.803977 86.46964,86.869767 141.28992,2.163965 18.44086,-28.493975 46.29247,8.882468 40.40505,19.210321 -38.20947,67.028001 -97.855,59.568605 -3.94297,138.004111 21.54722,17.99629 -0.61149,66.59059 -19.37585,46.00136 C 198.19796,206.28598 136.75871,43.292058 55.858806,212.92063 41.687846,242.63389 13.162026,189.96512 27.600822,178.74818 116.80291,109.45052 37.717611,87.189447 18.400548,36.143934 Z;
      
           M 0.65716244,24.31501 C 0.65716244,12.769206 14.091902,-0.12750335 25.629335,0.31207405 95.055812,2.95723 165.66239,2.95723 224.74955,-0.15260996 236.62119,-0.777431 250.69703,12.426939 250.69703,24.31501 c 0,73.172941 0,139.28327 0,200.43454 0,12.31193 -13.63555,26.2865 -25.94748,26.2865 -63.86693,0 -130.775322,0 -199.120215,0 -12.085756,0 -24.97217256,-14.20074 -24.97217256,-26.2865 0,-61.39127 0,-133.050269 0,-200.43454 z" 
      /> 
    </path>
   </mask>
    </defs>  
           <!-- К изображению девушки применена маска -->
<image id="img1" xlink:href="https://i.stack.imgur.com/73YNh.jpg"  width="100%" height="100%"
       pointer-events="fill" mask="url(#msk1)" />
</svg>

4. Морфинг прямоугольника в овал при наведении курсора

<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
     width="250" height="250"   viewBox="0 0 250 250" preserveAspectRatio="xMinYMin meet" >  
 <defs>
  <mask id="msk1">
      <!-- Ко всему изображению применён чёрный цвет маски, поэтому всё пространство вне пр\моугольника становится невидимым -->
     <rect width="100%" height="100%" fill="black" />   
       <!-- Участок изображения ограниченный кривой при fill="white" становится видимым --> 
         <!-- Добавление широкой границы с окраской в красный цвет делает её полупрозрачной   stroke-width="10" stroke="red" -->
    <path  fill="white" stroke-width="10" stroke="red" d ="m 249.74954,120.11816 c -0.032,33.80035 0.94749,70.87812 0.71924,101.39854 -0.0941,12.58837 -12.25359,28.03187 -24.83532,28.45154 -32.01304,1.06781 -66.74462,1.86496 -100.05841,-0.0897 -33.048172,-1.93908 -64.250431,1.15753 -99.314815,0.21055 C 18.620731,249.88275 2.7940939,236.54064 2.2155966,225.78362 0.65716244,196.8049 1.3036891,156.87429 1.4005632,122.41823 1.4912502,90.1628 0.65716244,60.443397 2.707633,25.660386 3.3483296,14.791976 15.595091,3.365135 26.481903,3.2644139 59.685029,2.95723 92.106049,2.5598942 124.91789,2.1867235 c 32.54245,-0.370107 66.11789,0.1133441 97.62686,-1.1517993 9.43211,-0.37871659 28.01925,11.9761648 28.05329,24.6882068 0.099,36.962802 -0.81868,62.928765 -0.8485,94.395029 z" > 
    
      <!-- анимация изменения формы кривой при наведении курсора -->
    <animate id="open"
      attributeName="d"
      begin="svg1.mouseover"
      dur="0.5s"
      repeatCount="1"
      fill="freeze"
      restart="whenNotActive"
      values="
      m 249.74954,120.11816 c -0.032,33.80035 0.94749,70.87812 0.71924,101.39854 -0.0941,12.58837 -12.25359,28.03187 -24.83532,28.45154 -32.01304,1.06781 -66.74462,1.86496 -100.05841,-0.0897 -33.048172,-1.93908 -64.250431,1.15753 -99.314815,0.21055 C 18.620731,249.88275 2.7940939,236.54064 2.2155966,225.78362 0.65716244,196.8049 1.3036891,156.87429 1.4005632,122.41823 1.4912502,90.1628 0.65716244,60.443397 2.707633,25.660386 3.3483296,14.791976 15.595091,3.365135 26.481903,3.2644139 59.685029,2.95723 92.106049,2.5598942 124.91789,2.1867235 c 32.54245,-0.370107 66.11789,0.1133441 97.62686,-1.1517993 9.43211,-0.37871659 28.01925,11.9761648 28.05329,24.6882068 0.099,36.962802 -0.81868,62.928765 -0.8485,94.395029 z;
      
     m 221.49156,121.76107 c -0.69227,23.05451 -6.7151,46.60634 -17.68131,66.89751 -6.97552,12.90704 -17.15264,24.69924 -29.43545,32.7231 -14.53539,9.49538 -32.09533,16.21404 -49.45691,16.33934 -16.56191,0.11952 -33.444079,-5.98391 -47.398985,-14.9042 -13.467298,-8.60861 -24.66387,-21.4135 -32.259169,-35.4772 C 34.532257,167.47628 29.118446,144.3228 28.344223,121.76107 27.76932,105.00775 30.919476,87.720522 37.537242,72.318919 45.292705,54.26954 56.430489,36.398301 72.154692,24.622193 87.101007,13.428659 106.24474,5.7671169 124.91789,5.8011169 c 18.87659,0.03437 38.10425,7.9785591 53.2684,19.2202361 14.61764,10.836531 25.23724,27.129484 32.65343,43.745917 7.34348,16.453518 11.19263,34.98401 10.65184,52.9938 z" 
      /> 
     
   <!-- анимация изменения формы кривой при покидании курсора -->
     <animate id="close"
      attributeName="d"
      begin="svg1.mouseleave"
      dur="0.5s"
      repeatCount="1"
      fill="freeze"
      restart="whenNotActive"
      values="
            m 221.49156,121.76107 c -0.69227,23.05451 -6.7151,46.60634 -17.68131,66.89751 -6.97552,12.90704 -17.15264,24.69924 -29.43545,32.7231 -14.53539,9.49538 -32.09533,16.21404 -49.45691,16.33934 -16.56191,0.11952 -33.444079,-5.98391 -47.398985,-14.9042 -13.467298,-8.60861 -24.66387,-21.4135 -32.259169,-35.4772 C 34.532257,167.47628 29.118446,144.3228 28.344223,121.76107 27.76932,105.00775 30.919476,87.720522 37.537242,72.318919 45.292705,54.26954 56.430489,36.398301 72.154692,24.622193 87.101007,13.428659 106.24474,5.7671169 124.91789,5.8011169 c 18.87659,0.03437 38.10425,7.9785591 53.2684,19.2202361 14.61764,10.836531 25.23724,27.129484 32.65343,43.745917 7.34348,16.453518 11.19263,34.98401 10.65184,52.9938 z;
      
           m 249.74954,120.11816 c -0.032,33.80035 0.94749,70.87812 0.71924,101.39854 -0.0941,12.58837 -12.25359,28.03187 -24.83532,28.45154 -32.01304,1.06781 -66.74462,1.86496 -100.05841,-0.0897 -33.048172,-1.93908 -64.250431,1.15753 -99.314815,0.21055 C 18.620731,249.88275 2.7940939,236.54064 2.2155966,225.78362 0.65716244,196.8049 1.3036891,156.87429 1.4005632,122.41823 1.4912502,90.1628 0.65716244,60.443397 2.707633,25.660386 3.3483296,14.791976 15.595091,3.365135 26.481903,3.2644139 59.685029,2.95723 92.106049,2.5598942 124.91789,2.1867235 c 32.54245,-0.370107 66.11789,0.1133441 97.62686,-1.1517993 9.43211,-0.37871659 28.01925,11.9761648 28.05329,24.6882068 0.099,36.962802 -0.81868,62.928765 -0.8485,94.395029 z" 
      /> 
    </path>
  
 </mask>
    </defs>  
            <!-- К изображению девушки применена маска -->
<image id="img1" xlink:href="https://i.stack.imgur.com/73YNh.jpg"  width="100%" height="100%"
       pointer-events="fill" mask="url(#msk1)" />
</svg>  

→ Ссылка
Автор решения: CbIPoK2513

Простой вариант на CSS с использованием "псевдо-маски" сделанной из картинки с прозрачной "кляксой".
"Псевдо-маска" идёт поверх изображения, изначально со свойством scale(2), при наведение на родителя применяется scale(1).

.image {
  display: inline-block;
  overflow: hidden;
  position: relative;
}

.image .pseudo-mask {
  display: block;
  width: 100%;
  height: 100%;
  background: url('https://i.imgur.com/nj9o1MA.png') no-repeat center center / 100% 100%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(2);
  transition: all .3s linear;
  z-index: 1;
}

.image > img {
  display: block;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border: 0;
  border-radius: 20px;
}

.image:hover .pseudo-mask {
  transform: translate(-50%, -50%) scale(1);
}
<div class="image">
  <div class="pseudo-mask"></div>
  <img src="https://i.imgur.com/5NBOFbo.png">
</div>


С анимацией вращения после наведения.

Придётся увеличить размер картинки, так, чтобы сама "клакса" осталась того же размера, а её фон стал больше. Я увеличил в .5 раз, от предыдущего размера.
После этого придётся изменить начальный scale(2), на 2.5, и конечный на 1.5.

После добавить анимацию вращения, учитывая предыдущие записи в transform.

Получается как-то так:

.image {
  display: inline-block;
  overflow: hidden;
  position: relative;
}

.image .pseudo-mask {
  display: block;
  width: 100%;
  height: 100%;
  background: url('https://i.imgur.com/cmz0d0O.png') no-repeat center center / 95% 95%;
  /* Пришлось немного уменьщить размер, чтобы не вылезало за края */
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(2.5);
  transition: all .3s linear;
  z-index: 1;
}

.image > img {
  display: block;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border: 0;
  border-radius: 20px;
}

.image:hover .pseudo-mask {
  transform: translate(-50%, -50%) scale(1.5);
  animation: pseudo-mask-rotate 30s .3s linear infinite;
  /* .3s это задержка, чтобы анимация "появления" при наведение отработала нормально, а после началось вращение */
}

@keyframes pseudo-mask-rotate {
  100% {
    transform: translate(-50%, -50%) scale(1.5) rotate(1turn);
  }
}
<div class="image">
  <div class="pseudo-mask"></div>
  <img src="https://i.imgur.com/5NBOFbo.png">
</div>

Но есть минус, когда :hover сбрасывается, сбрасывается и резко анимация..

Всё что смог придумать, переделать scale() на width и height:

.image {
  display: inline-block;
  overflow: hidden;
  position: relative;
}

.image .pseudo-mask {
  display: block;
  width: calc(100% * 2.5);
  height: calc(100% * 2.5);
  background: url('https://i.imgur.com/cmz0d0O.png') no-repeat center center / 95% 95%;
  /* Пришлось немного уменьщить размер, чтобы не вылезало за края */
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  transition: all .3s linear;
  z-index: 1;
}

.image > img {
  display: block;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border: 0;
  border-radius: 20px;
}

.image:hover .pseudo-mask {
  width: calc(100% * 1.5);
  height: calc(100% * 1.5);
  animation: pseudo-mask-rotate 30s .3s linear infinite;
  /* .3s это задержка, чтобы анимация "появления" при наведение отработала нормально, а после началось вращение */
}

@keyframes pseudo-mask-rotate {
  100% {
    transform: translate(-50%, -50%) rotate(1turn);
  }
}
<div class="image">
  <div class="pseudo-mask"></div>
  <img src="https://i.imgur.com/5NBOFbo.png">
</div>

→ Ссылка