如何使用 SVG 更改悬停时的图像源?

Posted

技术标签:

【中文标题】如何使用 SVG 更改悬停时的图像源?【英文标题】:How to change an image source on hover with SVGs? 【发布时间】:2019-10-30 16:31:51 【问题描述】:

我已将 sm 图像划分为五个不同的三角形。我正在尝试在悬停时更改图像的 src 属性值,并在中心正方形中显示悬停的图像。

这就是我想要做的,但使用 SVG:How to change an image source on hover?

.overlay 
  background-image: url('https://picsum.photos/id/118/1000/800');
  background-repeat: no-repeat;
  background-size: cover;


.overlay use 
  opacity: 0;
  transition: all 0.4s linear;


.overlay use:hover 
  opacity: 1;


.vr-head-tilt 
  position: relative;


.big img 
  width: 200px;
  height: 200px;
  object-fit: cover;


.overlay .vr-images1:hover~.big .default 
  opacity: 0;


.overlay .vr-images1:hover~.big>img:nth-child(1) 
  z-index: 5;
  opacity: 1;


.overlay .vr-images2:hover~.big>img:nth-child(2) 
  z-index: 5;
  opacity: 1;


.overlay .vr-images3:hover~.big>img:nth-child(3) 
  z-index: 5;
  opacity: 1;


.overlay .vr-images4:hover~.big>img:nth-child(4) 
  z-index: 5;
  opacity: 1;


.overlay .vr-images5:hover~.big>img:nth-child(5) 
  z-index: 5;
  opacity: 1;


.big 
  position: relative;


.big img 
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translate(-50%, 7%);
  opacity: 0;
  transition: .2s .1s ease-out;


.big .default 
  opacity: 1;
<svg class="overlay" viewBox="0 0 200 100">
            <defs>
                <clipPath id='clip-1'>
                <polygon points="0,100 100,100 0,50"/>
                </clipPath>
                <clipPath id='clip-2'>
                <polygon points="0,50 100,100 50,00 0,0"/>
                </clipPath>
                <clipPath id='clip-3'>
                <polygon points="100,100 50,00 150,0"/>
                </clipPath>
                <clipPath id='clip-4'>
                <polygon points="100,100 200,50 200,0 150,0"/>
                </clipPath>
                <clipPath id='clip-5'>
                <polygon points="100,100 200,100, 200,50"/>
                </clipPath>
                <image id="img" x="0" y="0"   preserveAspectRatio="xMidYMid slice"
                xlink:href="https://picsum.photos/id/1/1000/800" />
            </defs>
            <use xlink:href="#img" class="vr-images1" clip-path="url(#clip-1)"/>
            <use xlink:href="#img" class="vr-images2" clip-path="url(#clip-2)"/>
            <use xlink:href="#img" class="vr-images3" clip-path="url(#clip-3)"/>
            <use xlink:href="#img" class="vr-images4" clip-path="url(#clip-4)"/>
            <use xlink:href="#img" class="vr-images5" clip-path="url(#clip-5)"/>
        </svg>
<div class="box"></div>
<div class='big'>
  <img src="https://i.ibb.co/rxX8VMq/left.png" class='default'>
  <img src="https://i.ibb.co/r77CrCC/topleft.png">
  <img src="https://i.ibb.co/CzRdRtp/top.png">
  <img src="https://i.ibb.co/L8cSs3p/topright.png">
  <img src="https://i.ibb.co/D1cjqfD/right.png">
</div>

当我们将鼠标悬停在每个多边形上时,中心图像应该会发生变化。

【问题讨论】:

【参考方案1】:

您可以简单地使用 javascript 并在 元素上监听 mouseenter 事件:

const sources = [
  "rxX8VMq/left.png",
  "r77CrCC/topleft.png",
  "CzRdRtp/top.png",
  "L8cSs3p/topright.png",
  "D1cjqfD/right.png"
];
document.querySelectorAll('use[class^="vr-images"]').forEach(elem => 
  elem.addEventListener('mouseenter', updateImageSrc);
);

function updateImageSrc(evt) 
  const index = parseInt(this.classList[0].replace('vr-images', '')) || 1;
  const src = "https://i.ibb.co/" + sources[index - 1];
  document.querySelector('img').src = src;
.overlay 
  background-image: url('https://picsum.photos/id/118/1000/800');
  background-repeat: no-repeat;
  background-size: cover;


.overlay use 
  opacity: 0;
  transition: all 0.4s linear;


.overlay use:hover 
  opacity: 1;


.vr-head-tilt 
  position: relative;


.big img 
  width: 200px;
  height: 200px;
  object-fit: cover;


.big 
  position: relative;


.big img 
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translate(-50%, 7%);
  opacity: 0;
  transition: .2s .1s ease-out;


.big .default 
  opacity: 1;
<svg class="overlay" viewBox="0 0 200 100">
  <defs>
    <clipPath id='clip-1'>
      <polygon points="0,100 100,100 0,50"/>
    </clipPath>
    <clipPath id='clip-2'>
      <polygon points="0,50 100,100 50,00 0,0"/>
    </clipPath>
    <clipPath id='clip-3'>
      <polygon points="100,100 50,00 150,0"/>
    </clipPath>
    <clipPath id='clip-4'>
      <polygon points="100,100 200,50 200,0 150,0"/>
    </clipPath>
    <clipPath id='clip-5'>
      <polygon points="100,100 200,100, 200,50"/>
    </clipPath>
    <image id="img" x="0" y="0"   preserveAspectRatio="xMidYMid slice"
    xlink:href="https://picsum.photos/id/1/1000/800" />
  </defs>
  <use xlink:href="#img" class="vr-images1" clip-path="url(#clip-1)"/>
  <use xlink:href="#img" class="vr-images2" clip-path="url(#clip-2)"/>
  <use xlink:href="#img" class="vr-images3" clip-path="url(#clip-3)"/>
  <use xlink:href="#img" class="vr-images4" clip-path="url(#clip-4)"/>
  <use xlink:href="#img" class="vr-images5" clip-path="url(#clip-5)"/>
</svg>
<div class="box"></div>
<div class='big'>
  <img src="https://i.ibb.co/rxX8VMq/left.png" class='default'>
</div>

您也可以只使用 CSS 来修改文档的结构:

您需要将每个多边形叠加层分离为它们自己的 元素,这样当它们作为.big 容器的兄弟元素悬停时,您就可以定位它们。

.container 
  position: relative;

.background 
  background-image: url('https://picsum.photos/id/118/1000/800');
  background-repeat: no-repeat;
  background-size: cover;

.overlay 
  position: absolute;
  pointer-events: none;
  top: 0;
  right: 0;


.overlay use 
  opacity: 0;
  transition: all 0.4s linear;
  pointer-events: all;


.overlay use:hover 
  opacity: 1;


.vr-head-tilt 
  position: relative;


.big img 
  width: 200px;
  height: 200px;
  object-fit: cover;


.vr-images1:hover ~ .big img:nth-of-type(1) 
  opacity: 1;

.vr-images2:hover ~ .big img:nth-of-type(2) 
  opacity: 1;

.vr-images3:hover ~ .big img:nth-of-type(3) 
  opacity: 1;

.vr-images4:hover ~ .big img:nth-of-type(4) 
  opacity: 1;

.vr-images5:hover ~ .big img:nth-of-type(5) 
  opacity: 1;


svg[class*="vr-images"]:not(.vr-images1):hover ~ .big img.default 
  opacity: 0;


.big 
  position: relative;
  background: white;

.big .default 
  opacity: 1;

.big img, .big .white-bg 
  position: absolute;
  bottom: 0;
  left: 50%;
  opacity: 0;
  transform: translate(-50%, 7%);
  transition: .2s .1s ease-out;
  background-size: cover;
  pointer-events: none;

.big .white-bg 
  background: white;
  width: 200px;
  height: 200px;
  opacity: 1;

.container:not(:hover) .vr-images1 opacity:1; 
<svg   style="position:aboslute;pointer-events:none">
  <defs>
    <clipPath id='clip-1'>
    <polygon points="0,100 100,100 0,50"/>
    </clipPath>
    <clipPath id='clip-2'>
    <polygon points="0,50 100,100 50,00 0,0"/>
    </clipPath>
    <clipPath id='clip-3'>
    <polygon points="100,100 50,00 150,0"/>
    </clipPath>
    <clipPath id='clip-4'>
    <polygon points="100,100 200,50 200,0 150,0"/>
    </clipPath>
    <clipPath id='clip-5'>
    <polygon points="100,100 200,100, 200,50"/>
    </clipPath>
    <image id="img" x="0" y="0"   preserveAspectRatio="xMidYMid slice"
    xlink:href="https://picsum.photos/id/1/1000/800" />
  </defs>
<div class="container">
  <svg class="background" viewBox="0 0 200 100"></svg>

  <svg class="overlay vr-images1" viewBox="0 0 200 100">
    <use xlink:href="#img" class="vr-images1" clip-path="url(#clip-1)"/>
  </svg>
  <svg class="overlay vr-images2" viewBox="0 0 200 100">
    <use xlink:href="#img" class="vr-images2" clip-path="url(#clip-2)"/>
  </svg>
  <svg class="overlay vr-images3" viewBox="0 0 200 100">
    <use xlink:href="#img" clip-path="url(#clip-3)"/>
  </svg>
  <svg class="overlay vr-images4" viewBox="0 0 200 100">
    <use xlink:href="#img" clip-path="url(#clip-4)"/>
  </svg>
  <svg class="overlay vr-images5" viewBox="0 0 200 100">
    <use xlink:href="#img" clip-path="url(#clip-5)"/>
  </svg>
  <div class="box"></div>
  <div class='big'>
   <div class="white-bg"></div>
   <img src="https://i.ibb.co/rxX8VMq/left.png" class='default'>
   <img src="https://i.ibb.co/r77CrCC/topleft.png">
   <img src="https://i.ibb.co/CzRdRtp/top.png">
   <img src="https://i.ibb.co/L8cSs3p/topright.png">
   <img src="https://i.ibb.co/D1cjqfD/right.png">
  </div>
</div>

【讨论】:

我应该如何在默认情况下激活一个三角形悬停。 默认情况下,一个三角形是活动悬停阶段,我试图喜欢这个.overlay use.vr-images1:hover opacity: 1; 不来。 你对默认悬停的一个小铃铛有任何想法吗? 是的,我已经在第二个 sn-p 上应用了它。还是您想要的其他东西?【参考方案2】:

我会更新my previous answer,如下所示。我将为您在悬停时更改的图像添加额外的元素:

.box 
  width: 450px;
  height: 250px;
  position: relative;
  overflow: hidden;
  z-index: 0; 
  background: url(https://picsum.photos/id/13/1000/800) center/cover;
 


.box>div:not(.big) 
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-image: url(https://picsum.photos/id/118/1000/800);
  background-size: cover;
  background-position: center;
  opacity: 0;



.box>div:nth-child(1) 
  clip-path: polygon(20% 0, 80% 0, 50% 100%);


.box>div:nth-child(2) 
  clip-path: polygon(0 0, 20% 0, 50% 100%, 0 40%);


.box>div:nth-child(3) 
  clip-path: polygon(100% 0, 80% 0, 50% 100%, 100% 40%);


.box>div:nth-child(4) 
  clip-path: polygon(0 100%, 50% 100%, 0 40%);


.box>div:nth-child(5) 
  clip-path: polygon(100% 100%, 50% 100%, 100% 40%);


.box>div:hover 
  opacity: 1;


.big 
  position: absolute;
  bottom:0;
  width:150px;
  height:150px;
  left:calc(50% - 75px);
  
.big img 
  position: absolute;
  width: 100%;
  height:100%;
  top:0;
  left:0;
  object-fit: cover;
  opacity: 0;
  transition: .2s .1s ease-out;


.big .default 
  opacity: 1;


.box>div:nth-child(1):hover ~ .big > img:nth-child(1) 
  opacity:1;
  z-index:1;

.box>div:nth-child(2):hover ~ .big > img:nth-child(2) 
  opacity:1;
  z-index:1;

.box>div:nth-child(3):hover ~ .big > img:nth-child(3) 
  opacity:1;
  z-index:1;

.box>div:nth-child(4):hover ~ .big > img:nth-child(4) 
  opacity:1;
  z-index:1;

.box>div:nth-child(5):hover ~ .big > img:nth-child(5) 
  opacity:1;
  z-index:1;
<div class="box">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div class='big'>
    <img src="https://i.ibb.co/CzRdRtp/top.png">
    <img src="https://i.ibb.co/r77CrCC/topleft.png">
    <img src="https://i.ibb.co/L8cSs3p/topright.png">
    <img src="https://i.ibb.co/rxX8VMq/left.png" class='default'>
    <img src="https://i.ibb.co/D1cjqfD/right.png">
  </div>
</div>

【讨论】:

这里我想更改头像 src,因为我在代码中提到可能是我的解释不清楚。您之前的答案是正确的,现在下一步我正在尝试更改图像 onhover 单个 traingle 每个 traingle 更改不同的头部图像左、右、顶部等所有视图图像。您当前的答案也是正确的,这是另一种情况。但我一直在寻找 on hover triangle head image src need to change 检查悬停图像更改的参考链接。我尝试将class 提供给 并定位图像但没有得到。 @Husna ok 错过了问题,检查更新,现在应该没问题

以上是关于如何使用 SVG 更改悬停时的图像源?的主要内容,如果未能解决你的问题,请参考以下文章

如何在悬停时更改图像源?

将鼠标悬停在图像上时如何更改 SVG 的颜色?

如何在悬停事件中更改 SVG 图像中的笔触颜色? [复制]

悬停时的jquery图像预览-如何设置固定位置?

悬停按钮时如何更改svg颜色

悬停时的 SVG 不进行过渡