Why svg animateTransform only activate on first item?

Viewed 43

When the first item was hovered and the others would activate too. But when the second item was hovered and the others won't work. How can I let every item animation trigger one by one?

body {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100vw;
  height: 100vh;
}

.bubble-wrap {
  width: 400px
}
<div class="bubble-wrap">
  <svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" style="position: relative;" id="clip_svg_wrap">
          <clipPath id="clipPath1" transform="translate(100 100) scale(0.8)">
            <path d="M44.7,-77.9C57.7,-70,67.8,-57.5,76.2,-43.7C84.6,-30,91.4,-15,92.7,0.8C94.1,16.5,89.9,33,81.3,46.4C72.7,59.8,59.6,70.2,45.3,77.5C31,84.8,15.5,89.2,-0.1,89.4C-15.7,89.5,-31.4,85.6,-44.7,77.7C-57.9,69.7,-68.8,57.8,-75.6,44.2C-82.4,30.6,-85.3,15.3,-84.7,0.3C-84.1,-14.7,-80.2,-29.3,-72.9,-42.1C-65.6,-55,-55,-65.9,-42.3,-74C-29.6,-82,-14.8,-87.1,0.5,-88.1C15.9,-89,31.8,-85.8,44.7,-77.9Z" transform="scale(2)">
              <animateTransform attributeName="transform" attributeType="XML" type="scale" from="3 3" to="1 1" begin="clip_svg_wrap.mouseenter" dur="1s" repeatCount="1" fill="freeze"/>
              <animateTransform attributeName="transform" attributeType="XML" type="scale" from="1 1" to="3 3" begin="clip_svg_wrap.mouseleave" dur="1.5s" repeatCount="1" fill="freeze"/>
            </path>
          </clipPath>
          <image href="https://images.unsplash.com/photo-1639569266292-0c11a1dcb91c?crop=entropy&cs=srgb&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTY0MTgwMTgzMA&ixlib=rb-1.2.1&q=85" clip-path="url(#clipPath1)" width='100%' height='100%' style="position: relative;"></image>
        </svg>
</div>

<div class="bubble-wrap">
  <svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" style="position: relative;" id="clip_svg_wrap">
          <clipPath id="clipPath1" transform="translate(100 100) scale(0.8)">
            <path d="M44.7,-77.9C57.7,-70,67.8,-57.5,76.2,-43.7C84.6,-30,91.4,-15,92.7,0.8C94.1,16.5,89.9,33,81.3,46.4C72.7,59.8,59.6,70.2,45.3,77.5C31,84.8,15.5,89.2,-0.1,89.4C-15.7,89.5,-31.4,85.6,-44.7,77.7C-57.9,69.7,-68.8,57.8,-75.6,44.2C-82.4,30.6,-85.3,15.3,-84.7,0.3C-84.1,-14.7,-80.2,-29.3,-72.9,-42.1C-65.6,-55,-55,-65.9,-42.3,-74C-29.6,-82,-14.8,-87.1,0.5,-88.1C15.9,-89,31.8,-85.8,44.7,-77.9Z" transform="scale(2)">
              <animateTransform attributeName="transform" attributeType="XML" type="scale" from="3 3" to="1 1" begin="clip_svg_wrap.mouseenter" dur="1s" repeatCount="1" fill="freeze"/>
              <animateTransform attributeName="transform" attributeType="XML" type="scale" from="1 1" to="3 3" begin="clip_svg_wrap.mouseleave" dur="1.5s" repeatCount="1" fill="freeze"/>
            </path>
          </clipPath>
          <image href="https://images.unsplash.com/photo-1639972585193-e360d1bd1dd2?crop=entropy&cs=srgb&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTY0MTgwMTgzMA&ixlib=rb-1.2.1&q=85" clip-path="url(#clipPath1)" width='100%' height='100%' style="position: relative;"></image>
        </svg>
</div>

1 Answers

In this example there is an SVG element for each image. This includes a <image> with a unique id and a <defs> where the clip-path is defined. The <clipPath> also have a unique id. The result is that a unique image is making use of a unique clip-path, and the animation is started and ended with reference to that particular image.

If there are many images that need this clip-path we can agree that this is not an optimal solution. Reusing an already defined clip-path would be better, but as you discovered a "common" clip-path for all images will animate the clip-path on all the images at the same time. I have researched this and also tried a bit of JavaScript and reading the spec for begin-value without any clues on solving this.

Going for a CSS based animation could be a solution, but at the same time it it also limited what you can do in a setup like that.

body {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100vw;
  height: 100vh;
}

.bubble-wrap {
  width: 400px
}
<div class="bubble-wrap">
  <svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" style="position: relative;">
    <defs>
    <clipPath id="clipPath1" transform="translate(100 100)">
      <path d="M44.7,-77.9C57.7,-70,67.8,-57.5,76.2,-43.7C84.6,-30,91.4,-15,92.7,0.8C94.1,16.5,89.9,33,81.3,46.4C72.7,59.8,59.6,70.2,45.3,77.5C31,84.8,15.5,89.2,-0.1,89.4C-15.7,89.5,-31.4,85.6,-44.7,77.7C-57.9,69.7,-68.8,57.8,-75.6,44.2C-82.4,30.6,-85.3,15.3,-84.7,0.3C-84.1,-14.7,-80.2,-29.3,-72.9,-42.1C-65.6,-55,-55,-65.9,-42.3,-74C-29.6,-82,-14.8,-87.1,0.5,-88.1C15.9,-89,31.8,-85.8,44.7,-77.9Z" transform="scale(2)">
        <animateTransform attributeName="transform" attributeType="XML" type="scale" from="2" to=".5" begin="img1.mouseenter" dur="1s" repeatCount="1" fill="freeze"/>
        <animateTransform attributeName="transform" attributeType="XML" type="scale" from=".5" to="2" begin="img1.mouseleave" dur="1.5s" repeatCount="1" fill="freeze"/>
      </path>
    </clipPath>
  </defs>
    <image id="img1" href="https://images.unsplash.com/photo-1639569266292-0c11a1dcb91c?crop=entropy&cs=srgb&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTY0MTgwMTgzMA&ixlib=rb-1.2.1&q=85" clip-path="url(#clipPath1)" width='100%' height='100%' style="position: relative;"/>
  </svg>
</div>

<div class="bubble-wrap">
  <svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" style="position: relative;">
    <defs>
    <clipPath id="clipPath2" transform="translate(100 100)">
      <path d="M44.7,-77.9C57.7,-70,67.8,-57.5,76.2,-43.7C84.6,-30,91.4,-15,92.7,0.8C94.1,16.5,89.9,33,81.3,46.4C72.7,59.8,59.6,70.2,45.3,77.5C31,84.8,15.5,89.2,-0.1,89.4C-15.7,89.5,-31.4,85.6,-44.7,77.7C-57.9,69.7,-68.8,57.8,-75.6,44.2C-82.4,30.6,-85.3,15.3,-84.7,0.3C-84.1,-14.7,-80.2,-29.3,-72.9,-42.1C-65.6,-55,-55,-65.9,-42.3,-74C-29.6,-82,-14.8,-87.1,0.5,-88.1C15.9,-89,31.8,-85.8,44.7,-77.9Z" transform="scale(2)">
        <animateTransform attributeName="transform" attributeType="XML" type="scale" from="2" to=".5" begin="img2.mouseenter" dur="1s" repeatCount="1" fill="freeze"/>
        <animateTransform attributeName="transform" attributeType="XML" type="scale" from=".5" to="2" begin="img2.mouseleave" dur="1.5s" repeatCount="1" fill="freeze"/>
      </path>
    </clipPath>
  </defs>
    <image id="img2" href="https://images.unsplash.com/photo-1639972585193-e360d1bd1dd2?crop=entropy&cs=srgb&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTY0MTgwMTgzMA&ixlib=rb-1.2.1&q=85" clip-path="url(#clipPath2)" width='100%' height='100%' style="position: relative;"/>
  </svg>
</div>

Related