0

I am trying to reveal an image when I hover over a div or a line of text.

here are some references to the effect I am trying to achieve:

https://randellcommercial.uk/ - plugins.
https://1til1landskab.dk/ - really nice, also it changes background colour too which is cool.
http://adasokol.com/works/ - bit mental, but you get the idea.

this is what I have been basing my efforts off. however, it seems there is so much unnecessary code. I've been trimming it down and ended up with this. However, it's no good. it's glitchy and feels over-engineered.

document.documentElement.className = "js";
var supportsCssVars = function() {
  var e,
    t = document.createElement("style");
  return (
    (t.innerHTML = "root: { --tmp-var: bold; }"),
    document.head.appendChild(t),
    (e = !!(
      window.CSS &&
      window.CSS.supports &&
      window.CSS.supports("font-weight", "var(--tmp-var)")
    )),
    t.parentNode.removeChild(t),
    e
  );
};

{
  const mapNumber = (X, A, B, C, D) => ((X - A) * (D - C)) / (B - A) + C;

  const getMousePos = (e) => {
    let posx = 0;
    let posy = 0;
    if (!e) e = window.event;
    if (e.pageX || e.pageY) {
      posx = e.pageX;
      posy = e.pageY;
    } else if (e.clientX || e.clientY) {
      posx =
        e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
      posy =
        e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
    }
    return {
      x: posx,
      y: posy
    };
  };
  // Generate a random float.
  const getRandomFloat = (min, max) =>
    (Math.random() * (max - min) + min).toFixed(2);

  class HoverImgFx2 {
    constructor(el) {
      this.DOM = {
        el: el
      };
      this.DOM.reveal = document.createElement("div");
      this.DOM.reveal.className = "hover-reveal";
      this.DOM.reveal.innerHTML = `<div class="hover-reveal__inner"><div class="hover-reveal__img" style="background-image:url(${this.DOM.el.dataset.img})"></div></div>`;
      this.DOM.el.appendChild(this.DOM.reveal);
      this.DOM.revealInner = this.DOM.reveal.querySelector(".hover-reveal__inner");
      this.DOM.revealInner.style.overflow = "hidden";
      this.DOM.revealImg = this.DOM.revealInner.querySelector(
        ".hover-reveal__img"
      );

      this.initEvents();
    }
    initEvents() {
      this.positionElement = (ev) => {
        const mousePos = getMousePos(ev);
        const docScrolls = {
          left: document.body.scrollLeft + document.documentElement.scrollLeft,
          top: document.body.scrollTop + document.documentElement.scrollTop
        };
        this.DOM.reveal.style.top = `${mousePos.y + 20 - docScrolls.top}px`;
        this.DOM.reveal.style.left = `${mousePos.x + 20 - docScrolls.left}px`;
      };
      this.mouseenterFn = (ev) => {
        this.positionElement(ev);
        this.showImage();
      };
      this.mousemoveFn = (ev) =>
        requestAnimationFrame(() => {
          this.positionElement(ev);
        });
      this.mouseleaveFn = () => {
        this.hideImage();
      };

      this.DOM.el.addEventListener("mouseenter", this.mouseenterFn);
      this.DOM.el.addEventListener("mousemove", this.mousemoveFn);
      this.DOM.el.addEventListener("mouseleave", this.mouseleaveFn);
    }
    showImage() {
      TweenMax.killTweensOf(this.DOM.revealInner);
      TweenMax.killTweensOf(this.DOM.revealImg);

      this.tl = new TimelineMax({
          onStart: () => {
            this.DOM.reveal.style.opacity = 1;
            TweenMax.set(this.DOM.el, {
              zIndex: 1000
            });
          }
        })
        .add("begin")
        .add(
          new TweenMax(this.DOM.revealInner, 0.4, {
            ease: Quint.easeOut,
            startAt: {
              x: "-100%",
              y: "-100%"
            },
            x: "0%",
            y: "0%"
          }),
          "begin"
        )
        .add(
          new TweenMax(this.DOM.revealImg, 0.4, {
            ease: Quint.easeOut,
            startAt: {
              x: "100%",
              y: "100%"
            },
            x: "0%",
            y: "0%"
          }),
          "begin"
        );
    }
    hideImage() {
      TweenMax.killTweensOf(this.DOM.revealInner);
      TweenMax.killTweensOf(this.DOM.revealImg);

      this.tl = new TimelineMax({
          onStart: () => {
            TweenMax.set(this.DOM.el, {
              zIndex: 999
            });
          },
          onComplete: () => {
            TweenMax.set(this.DOM.el, {
              zIndex: ""
            });
            TweenMax.set(this.DOM.reveal, {
              opacity: 0
            });
          }
        })
        .add("begin")
        .add(
          new TweenMax(this.DOM.revealInner, 0.3, {
            ease: Quint.easeOut,
            x: "100%",
            y: "100%"
          }),
          "begin"
        )

        .add(
          new TweenMax(this.DOM.revealImg, 0.3, {
            ease: Quint.easeOut,
            x: "-100%",
            y: "-100%"
          }),
          "begin"
        );
    }
  }

  [...document.querySelectorAll('[data-fx="2"] > a, a[data-fx="2"]')].forEach(
    (link) => new HoverImgFx2(link)
  );

  [
    ...document.querySelectorAll(
      ".block__title, .block__link, .content__text-link"
    )
  ].forEach((el) => {
    const imgsArr = el.dataset.img.split(",");
    for (let i = 0, len = imgsArr.length; i <= len - 1; ++i) {
      const imgel = document.createElement("img");
      imgel.style.visibility = "hidden";
      imgel.style.width = 0;
      imgel.src = imgsArr[i];
      imgel.className = "preload";
      contentel.appendChild(imgel);
    }
  });
  imagesLoaded(document.querySelectorAll(".preload"), () =>
    document.body.classList.remove("loading")
  );
}
.hover-reveal {
  position: fixed;
  width: 200px;
  height: 150px;
}

.hover-reveal__inner,
.hover-reveal__img {
  width: 100%;
  height: 100%;
  position: relative;
}

.hover-reveal__img {
  background-size: cover;
  background-position: 50% 50%;
}
<script src="https://cdn.jsdelivr.net/npm/gsap@3.0.1/dist/gsap.min.js"></script>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
  <main>
    <div class="content">
      <div class="block" data-fx="2">
        <a class="block__link" data-img="https://www.kaspersky.co.uk/content/en-gb/images/product-icon-KSOS.png">Asli</a>
        <a class="block__link" data-img="https://www.kaspersky.co.uk/content/en-gb/images/product-icon-KSOS.png">D24</a>
        <a class="block__link" data-img="https://www.kaspersky.co.uk/content/en-gb/images/product-icon-KSOS.png">Jantung</a>
        <a class="block__link" data-img="https://www.kaspersky.co.uk/content/en-gb/images/product-icon-KSOS.png">Tracka</a>
      </div>
    </div>
  </main>
  <script src="js/TweenMax.min.js"></script>
  <script src="js/demo.js"></script>
</body>

How can I create a simple image reveal on rollover that is clean and simple?

Mr. Jo
  • 4,946
  • 6
  • 41
  • 100
  • 1
    Just replace the google image by your own or dynamic image. – Mr. Jo May 03 '20 at 18:41
  • 1
    Yes @Mr.Jo yes it does, Earlier today I saw this and used it but it was breaking when I added more than 1 instance, on the thread you link too here I can see that there is help for multiple instances. thank you – Joseph Lion May 03 '20 at 18:53
  • I mean this Fiddle here: http://jsfiddle.net/HJf8q/2/ But yes, you need to adjust it. If you can't go for this I'll post an answer for your question with a different content. – Mr. Jo May 03 '20 at 18:53

0 Answers0