3

I have divided sm image into five different triangles. I'm trying to change an image's src attribute value on hover, and show the hovered' image in the center square.

This is what I'm trying to do, but with SVGs: 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" width="200" height="100" 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>

When we hover on each polygon, the center image should change.

TylerH
  • 20,799
  • 66
  • 75
  • 101
Husna
  • 1,286
  • 4
  • 19
  • 48

2 Answers2

4

You could simply use javascript and listen for the mouseenter event on your <use> elements:

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" width="200" height="100" 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>

You could also do it only with CSS by modifying a bit your document's structure:

You need to separate each polygons overlay as their own <svg> element so that you can target them when they are hovered as siblings of your .big container.

.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 width="0" height="0" 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" width="200" height="100" 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>
Kaiido
  • 123,334
  • 13
  • 219
  • 285
2

I would update my previous answer like below. I will add the extra element for the images that you change on hover:

.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>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • Here I want to change head image src as I mention in my code might be my explanation is not clear. your previous answer is correct now the next step I'm trying to do change image onhover individual traingle each traingle change different head image left, right, top etc all views images. your current answer is also correct this is another scenario. but I was looking for `on hover triangle head image src need to change` check once reference link on hover image changes. i tried give `class` to and targetting the images but not getting. – Husna Jun 17 '19 at 09:00
  • @Husna ok missed the question, check the update, it should be fine now – Temani Afif Jun 17 '19 at 09:07