javascript - 为什么 svg animateTransform 只在第一项上激活?

标签 javascript html css svg

当第一个元素悬停时,其他元素也会激活。但是当第二个元素悬停时,其他元素将不起作用。如何让每一个item的动画都一个一个的触发?

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>

最佳答案

在此示例中,每个图像都有一个 SVG 元素。这包括 <image>具有唯一 ID 和 <defs>定义剪辑路径的位置。 <clipPath>也有一个唯一的ID。结果是一个独特的图像使用了一个独特的剪辑路径,动画开始和结束时引用了该特定图像。

如果有很多图像需要这个剪辑路径,我们可以同意这不是最佳解决方案。重复使用已经定义的剪辑路径会更好,但是当您发现所有图像的“通用”剪辑路径将同时在所有图像上设置动画剪辑路径时。我对此进行了研究,还尝试了一些 JavaScript 并阅读了 begin-value 的规范,但没有解决此问题的任何线索。

寻求基于 CSS 的动画可能是一种解决方案,但同时它也限制了您在这样的设置中可以做的事情。

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>

关于javascript - 为什么 svg animateTransform 只在第一项上激活?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70649485/

相关文章:

javascript - 如何使移动用户界面按特定宽度自动打开?

javascript - 通过ajax post(jQuery)发送输入类型="file"表单数据

php - 如何使用 HTML 5 从 Torrent 流式传输视频?

html - 增加R中表格行的高度

css - 添加过渡到伪元素 (SASS)

css - 散列后如何定位 CSS 模块类?

javascript - http 请求的成功处理程序不调用函数

瘦客户端和 pc 之间的 javascript 性能

javascript - 在 Codeigniter 中使用 jQuery ajax 方法将 id 作为属性分配给新添加的行

javascript - 添加 "required"到选择框