javascripthtmlcssmouseoveronmouseover

need help creating a mouse over image link that hides top image and reveals bottom image that scrolls vertically within the same space as top image


im looking to acheive the same effect as seen on: https://huemor.rocks/case-studies/

i need help creating a mouse over image link that hides top image and reveals bottom image that scrolls vertically within the same space as top image

the long vertical image (400x755px or longer/shorter) will ease and scroll overtime in the same image size as top image (400x328px)

here is the codepen to what ive tried so far: progress so far

function initProps(el) {
  const scrollMultiple = 5;
  var imageHeight = el.height;
  el.style.bottom = `-${imageHeight - 328}px`;
  el.style.setProperty("--top", `-${imageHeight - 328}px`);
  el.style.setProperty(
    "--animation-duration",
    `${scrollMultiple * imageHeight}ms`
  );
}
.container {
  padding: 10px 0;
}

.scrolling-window {
  border-radius: 10px;
  display: block;
  width: 400px;
  height: 328px;
  overflow: hidden;
  position: relative;
  border: 2px solid #b3b3b3;
  margin: 0 auto;
}

.scrolling-window img {
  width: 100%;
  height: auto;
  position: absolute;
  z-index: 0;
  top: 0;
  margin: 0;
  padding: 0;
  animation: fadeIn 1s;
  /*   filter: grayscale(100%); */
  transition-duration: 0.5s;
}

.scrolling-window:hover img {
  animation: scroll var(--animation-duration) cubic-bezier(0.5, 0, 0.5, 0) infinite alternate;
  animation-delay: 0.2s;
  filter: grayscale(0);
  cursor: pointer;
}

@keyframes scroll {
  /* to stop for a moment while reversing the animation */
  90% {
    bottom: 0px;
    top: var(--top);
  }
  100% {
    bottom: 0px;
    top: var(--top);
  }
}

@keyframes fadeIn {
  0% {
    opacity: 0;
    top: -16px;
  }
  100% {
    opacity: 1;
    top: 0;
  }
}
<div class="container">
  <div class="row">
    <div class="col mt-3">
      <!--<div class="main-image">
        <img src="https://place-hold.it/600x492/" alt="main-image" class="main-image">
      </div>-->
      <div class="scrolling-window">
        <img onload="initProps(this)" class="scrolling-image" src="https://place-hold.it/600x1132/" />
      </div>
    </div>
    <div class="col mt-3">
      <div class="scrolling-window">
        <img onload="initProps(this)" class="scrolling-image" src="https://place-hold.it/600x1132/" />
      </div>
    </div>
    <div class="col mt-3">
      <div class="scrolling-window">
        <img onload="initProps(this)" class="scrolling-image" src="https://place-hold.it/600x1132/" />
      </div>
    </div>
  </div>
</div>


Solution

  • It seems you are only missing the feature of showing a top image that is expected to hide when the target is on hover.

    To achieve that you need to add in your html such picture in the same container .scrolling-window where you wish it to apply:

    <div class="scrolling-window">
        <img class="top-image" src="https://t.ly/tkht2" />    
        <img onload="initProps(this)" class="scrolling-image" src="https://place-hold.it/600x1132/" />
    </div>
    
    /* the -top-image is styled to be on top */
    .scrolling-window .top-image {
        z-index: 1;
        transition: opacity 0.5s;
    }
    
    /* and vanish when hovered */
    .scrolling-window:hover .top-image {
        opacity: 0;
    }
    

    The css rules style the .top-image occurrences so that they will show on top in their corresponding container and they will hide when hovered.

    I added this strategy in your demo only for the first picture of your set to show it in action (consider also that the style of the scrolling image has an addition to be set as z-index: 0;)

    function initProps(el) {
      const scrollMultiple = 5;
      var imageHeight = el.height;
      el.style.bottom = `-${imageHeight - 328}px`;
      el.style.setProperty("--top", `-${imageHeight - 328}px`);
      el.style.setProperty(
        "--animation-duration",
        `${scrollMultiple * imageHeight}ms`
      );
    }
    .container {
      padding: 10px 0;
    }
    
    .scrolling-window {
      border-radius: 10px;
      display: block;
      width: 400px;
      height: 328px;
      overflow: hidden;
      position: relative;
      border: 2px solid #b3b3b3;
      margin: 0 auto;
      
      z-index: 0; /* added */
    }
    
    .scrolling-window img {
      width: 100%;
      height: auto;
      position: absolute;
      z-index: 0;
      top: 0;
      margin: 0;
      padding: 0;
      animation: fadeIn 1s;
      /*   filter: grayscale(100%); */
      transition-duration: 0.5s;
    }
    
    .scrolling-window:hover img {
      animation: scroll var(--animation-duration) cubic-bezier(0.5, 0, 0.5, 0) infinite alternate;
      animation-delay: 0.2s;
      filter: grayscale(0);
      cursor: pointer;
    }
    
    @keyframes scroll {
      /* to stop for a moment while reversing the animation */
      90% {
        bottom: 0px;
        top: var(--top);
      }
      100% {
        bottom: 0px;
        top: var(--top);
      }
    }
    
    @keyframes fadeIn {
      0% {
        opacity: 0;
        top: -16px;
      }
      100% {
        opacity: 1;
        top: 0;
      }
    }
    
    .scrolling-window .top-image {
      z-index: 1;
      transition: opacity 0.5s;
    }
    
    .scrolling-window:hover .top-image {
      opacity: 0;
    }
    <div class="container">
      <div class="row">
        <div class="col mt-3">
          <!--<div class="main-image">
            <img src="https://place-hold.it/600x492/" alt="main-image" class="main-image">
          </div>-->
          <div class="scrolling-window">
            <img class="top-image" src="https://media.istockphoto.com/id/989977830/it/foto/corso-cors-cane-marrone.jpg?s=2048x2048&w=is&k=20&c=VdwtTcNIe6VXrYYMedLT_C3ZE2NYAMiWuKIDvWtaToU=" />
            <img onload="initProps(this)" class="scrolling-image" src="https://place-hold.it/600x1132/" />
          </div>
        </div>
        <div class="col mt-3">
          <div class="scrolling-window">
            <img onload="initProps(this)" class="scrolling-image" src="https://place-hold.it/600x1132/" />
          </div>
        </div>
        <div class="col mt-3">
          <div class="scrolling-window">
            <img onload="initProps(this)" class="scrolling-image" src="https://place-hold.it/600x1132/" />
          </div>
        </div>
      </div>
    </div>