• Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.


    To learn more about how to use our BBCode feature, please click here.

    Thank you, Code Forum.

HTML & CSS Background image map with clickable areas to bring up popup

scully_a

New Coder

Hello, I am trying to make an image map with multiple clickable areas that will bring up pop ups.

The problem that I have is that the image also needs to move with cursor in a set frame. To achieve this function I set the image as a background image in the css. I do not know if there is anyway to set an image map on an image that is located in the css file.

If not, then I need to figure out how to still get the image to move with cursor movement in a set frame, while image resides in the HTML file so I can create an image map for it.

I am very novice at coding, this is for an art project. I do not know if this is at all achievable, but damn I am trying.
If anyone has any ideas, I would appreciate the help.

HTML:
<!DOCTYPE html>
<lang=en>
<html>
<head>
    <title>Unum project</title>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="210203_overflow test.css">

    <!--background move with cursor-->
    <meta name="viewport" content="width=device-width, initialscale=1.0">
    <!--background move with cursor-->

</head>
<body>
    <!--background move with cursor-->
    <div class="box" id="box"
    value="PLAY"  onmouseover="play()" loop="loop">
        <!--music plays on image click-->D
    </div>
    
    <script>
        const el = document.querySelector('#box')

        el.addEventListener('mousemove', (e) => {
            el.style.setProperty('--x', -e.offsetX + 'px')
            el.style.setProperty('--y', -e.offsetY + 'px')
        })
    </script>
    <!--background move with cursor-->

    <!--music plays on image click-->
    <script>
        function play(){
            var audio = document.getElementById("audio");
            audio.play();
        }
    </script>

    <audio id="audio" src="262259__shadydave__snowfall-final.mp3" ></audio>

    <audio src="262259__shadydave__snowfall-final.mp3" id="bg_music" loop="loop" ></audio>
    <!--music plays on image click-->

    <!--image mapping-->
    




</body>
</html>

CSS:
body {
    /*background move with cursor*/
    height: 100vh;
    margin: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: #222;
    /*background move with cursor*/
}

.box {
    /*background move with cursor*/
    width: 800px;
    height: 600px;
    border: 1px solid white;
    background-image: url(images/scene1/big-image.jpg);
    --x: 0px;
    --y: 0px;
    background-position: var(--x) var(--y);
    background-size: 3000px;
    /*background move with cursor*/

}
 

LTomy

Active Coder
Staff Team
Guardian
Hello scully_a,

Quite interesting that you made a video to explain the problem ;)

I am thinking about it, but for now, I did not find any simple way to achieve that...
 

ivan.moony

Active Coder
If you are up to Javascript, here is something that may be of interest. There are people around here that can help you with relative positioning of picture inside HTML canvas where you know the current offset of the image. Then you just add the image offset to the mouse coordinates to get a point and pass it through the poly-check function.
 

scully_a

New Coder
Hello scully_a,

Quite interesting that you made a video to explain the problem ;)

I am thinking about it, but for now, I did not find any simple way to achieve that...
Thank you so much for even responding, I was very nervous to try to reach out on a platform like this, where I feel very much like an outsider. As you can tell by my pauses and ums, though, I am not confident even with my coding vocabulary to talk about it, which is why I felt I could better show what I was trying to achieve by doing a screen cast. The idea is that the main image would be an establishing shot of the scene, and we could move the cursor to explore it, the cursor would change when hovered over a point, such as a fern, when clicked it would bring a pop-up with a close up image of that part of the scene and have some text accompany it. I've made image maps, and pop-ups and got almost all functionality figured out except this moving the image with the cursor to explore around, (actually I just figured out this method yesterday), but still have all the other functionality. I'm beginning to think that it may just not be possible- or so difficult that there's only one god-like coder out there that knows the answer, and I'll never find it.
 

scully_a

New Coder
If you are up to Javascript, here is something that may be of interest. There are people around here that can help you with relative positioning of picture inside HTML canvas where you know the current offset of the image. Then you just add the image offset to the mouse coordinates to get a point and pass it through the poly-check function.
Thank you, I'll search into this.
 

LTomy

Active Coder
Staff Team
Guardian
I had thought of a solution, but the problem is that it is not really simple:

You put the background, as an <img>, inside a <div>. You give the <div> a smaller size than the <img> and you give the property overflow: hidden; to the <div> so there is not scrollbars that appears (Only a section of the <img> will be visible, because its overflowing part will be hidden inside the <div>).

Now, to make sure that the background <img> is displayed below the clickable images (Added after it), you set its position by giving it the property position: absolute;.

Inside the <div>, you add additionnal <img> for which you will react, using Javascript, when they are clicked (They will be drawn above the <img> used as background). (Alternatively, you can simply put those <img> inside <a> tags so a link is followed when the <img> are clicked).

Even though the scroll bars of the <div> won't appear, you still can scroll inside it using Javascript:
JavaScript:
element.scroll(x, y);
(You scroll when the mouse moves)

I do not know if you understand what I explained, but I do not know of a simpler way.
 

scully_a

New Coder
I had thought of a solution, but the problem is that it is not really simple:

You put the background, as an <img>, inside a <div>. You give the <div> a smaller size than the <img> and you give the property overflow: hidden; to the <div> so there is not scrollbars that appears (Only a section of the <img> will be visible, because its overflowing part will be hidden inside the <div>).

Now, to make sure that the background <img> is displayed below the clickable images (Added after it), you set its position by giving it the property position: absolute;.

Inside the <div>, you add additionnal <img> for which you will react, using Javascript, when they are clicked (They will be drawn above the <img> used as background). (Alternatively, you can simply put those <img> inside <a> tags so a link is followed when the <img> are clicked).

Even though the scroll bars of the <div> won't appear, you still can scroll inside it using Javascript:
JavaScript:
element.scroll(x, y);
(You scroll when the mouse moves)

I do not know if you understand what I explained, but I do not know of a simpler way.
I understand enough to give it a go, and am pretty resourceful with google. :) I will work at this some more later tonight and if let you know how it turned out. Thank you so very much.
 

scully_a

New Coder
This is sort of where things have evolved since we have last spoke. Not perfect, or even close, but there's some progres.

HTML:
<!DOCTYPE html>
<lang=en>
<html>
<head>
    <title>Unum project</title>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="210217codetest.css">
<head>
<body>
<p>Same content above the photo</p>

<div class="img-wrapper">

<img src="images/scene1/big-image.jpg" usemap="#image-map">

<map name="image-map">
    <area target="_top" alt="fern" title="fern" coords="1891,1042,1621,774" shape="rect" href="images/scene1/fern.jpg" onclick="clickmap('Let the path guide your feet and your heart on the journey')">
    <area target="_top" alt="bench" title="bench" coords="580,507,755,644" shape="rect" href="images/scene1/70490.jpg" onclick="clickmap('someinfo 2')">
    <area target="_top" alt="leaves" title="leaves"  coords="209,114,531,290" shape="rect" href="images/scene1/red-beetle-bug-on-leaf.jpg" onclick="clickmap('someinfo 3')">
</map>


</div>

<p>Same content below the photo</p>
<script>
          function clickmap(info) {
              alert(info)

          }
      </script>


<script type="text/javascript">
    const imgWrapper = document.querySelector('.img-wrapper');
const img = imgWrapper.querySelector('img');
let isZoomedIn = false;
const scale = 1.5;

function moveEventHandler(event) {
  shiftContent(event, event.target.parentNode);
  event.currentTarget.style.transition = 'none';
};

function shiftContent(event, container) {
  const element = event.target;
  const { height, width } = element.getBoundingClientRect();
  const containerRect  = container.getBoundingClientRect();
  const cursorPosX = (event.pageX - containerRect.left) / containerRect.width;
  const cursorPosY = (event.pageY - containerRect.top) / containerRect.height;
 
  const imgOverflowLeft = (width - containerRect.width) / 2
  const shiftX = (1 - cursorPosX * 2) * imgOverflowLeft;
  element.style.left = shiftX + 'px';
 
  const imgOverflowTop = (height - containerRect.height) / 2;
  const shiftY = (1 - cursorPosY * 2) * imgOverflowTop;
  element.style.top = shiftY + 'px';
}

function clickEventHandler(event) {
  const element = event.currentTarget;
  element.style.transition = 'transform 0.2s, left 0.3s, top 0.3s';
  const { height, width } = element.getBoundingClientRect();
 
  isZoomedIn = !isZoomedIn;
 
  if (isZoomedIn) {
    // First, zoom in
    element.style.transform = `scale(${scale})`;
    element.style.cursor = 'zoom-out';
    
    // Second, shift the image
    // Note: Shifting the image before it's fully zoomed in may look weird. This is why we delay the shifting.
    setTimeout(() => {
      shiftContent(event, element.parentNode);
      img.addEventListener('mousemove', moveEventHandler, true);
    }, 200);
  } else {
    element.style.cursor = 'zoom-in';
    element.style.left = 0;
    element.style.top = 0;
    img.removeEventListener('mousemove', moveEventHandler, true);
    
    setTimeout(() => {
      element.style.transform = 'scale(1)';
    }, 200);
  }
}

img.style.willChange = 'transform, left, top';
img.addEventListener('click', clickEventHandler, true);
</script>
</body>
</html>
CSS:
body {
  text-align: center;
  padding-top: 50px;
}

.img-wrapper {
  overflow: hidden;
  display: inline-block;
  line-height: 0;
  width: 800px;
    height: 600px;
    border: 1px solid white;
}

img {
  cursor: zoom-in;
  position: relative;
  left: 0;
  top: 0;
}
 

Top