Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why svg animateTransform only activate on first item?

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>
like image 291
Penny Chang Avatar asked Nov 16 '25 14:11

Penny Chang


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>
like image 74
chrwahl Avatar answered Nov 19 '25 03:11

chrwahl



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!