Image Map wrongly darkening the highlighted area

Hey Community,

I’ve been building a custom image map for our different light environments, where we display the different areas our light solutions can be used.

Professionell geplante Bürobeleuchtung – positiv für Mitarbeiter und Unternehmen | elumico (webflow.io). Under “Zielsetzungen” you can see the image map I’m talking about.

It is expected, that the user can hover over any of the 4 areas on the main image, and that the respective area get’s highlighted in orange, while the rest of the image is darkened.

Here is the image setup I’ve used:

  1. main base image in white to greyscale that you see when not hovered
    2-5) for one area each, there is a png cutout with the building colored in our CI’s orange.

I’ve fixed the first stages of code already so that now the respective areas are highlighted, but are still darkened by the functions. I thought that using png’s with transparent bg, would only darken the main image underneath, but currently even the highlighted png’s are darkened aswell. Which I’m trying to solve but don’t know how.

I can only think about some issue with the Z-Index of the cutout png’s, but maybe someone could check my code to see if there is some minor error I’ve overlooked?

<style>
  .main-image {
    transition: 0.3s;
    position: relative;
    background-image: url('https://uploads-ssl.webflow.com/634723edf4a76fbc19fabbf3/64393083e51864f3cc4dfce0_industriebereiche_anwendung_startbild_transparent-bg-40pct-scale.png');
    background-size: cover;
  }
  .darkened {
    filter: brightness(50%);
  }
  #tooltip {
    z-index: 100;
  }
</style>

<div id="tooltip" style="display: none; position: absolute; pointer-events: none; background-color: rgba(0, 0, 0, 0.8); color: white; padding: 10px; border-radius: 5px; font-size: 14px;">
  <p id="tooltip-text"></p>
</div>

<img src="https://uploads-ssl.webflow.com/634723edf4a76fbc19fabbf3/64393083e51864f3cc4dfce0_industriebereiche_anwendung_startbild_transparent-bg-40pct-scale.png" usemap="#image-map" class="main-image" id="main-image">

<map name="image-map">
  <area target="_self" alt="Lager- und Logistikbereiche" title="Lager- und Logistikbereiche" href="#" coords="854,529,1206,358,1203,288,1061,215,709,385,705,454" shape="poly" onmouseover="setImageSource('https://uploads-ssl.webflow.com/634723edf4a76fbc19fabbf3/6439a8c31ba631d09bbf87ff_industriebereiche_anwendung_lager-highlight-40pct-final.png'); darkenImage(); showTooltip('Lager- und Logistikbereiche');" onmouseout="resetImageSource(); undarkenImage(); hideTooltip();" onmousemove="updateTooltipPosition(event);">
  <area target="_self" alt="Produktionsbereiche" title="Produktionsbereiche" href="#" coords="883,284,979,238,982,157,744,35,624,97,619,178,846,301" shape="poly" onmouseover="setImageSource('https://uploads-ssl.webflow.com/634723edf4a76fbc19fabbf3/6439a8c3e244ea05c146db2e_industriebereiche_anwendung_produktion-highlight-40pct-final.png'); darkenImage(); showTooltip('Produktionsbereiche');" onmouseout="resetImageSource(); undarkenImage(); hideTooltip();" onmousemove="updateTooltipPosition(event);">
  <area target="_self" alt="Nebenbereiche" title="Nebenbereiche" href="#" coords="227,379,423,255,686,406,686,460,901,575,746,647" shape="poly" onmouseover="setImageSource('https://uploads-ssl.webflow.com/634723edf4a76fbc19fabbf3/6439a8c300f7746d13ef3eaa_industriebereiche_anwendung_nebenbereiche-highlight-40pct-final.png'); darkenImage(); showTooltip('Nebenbereiche');" onmouseout="resetImageSource(); undarkenImage(); hideTooltip();" onmousemove="updateTooltipPosition(event);">
  <area target="_self" alt="Spezielle Leuchten" title="Spezielle Leuchten" href="#" coords="209,370,39,283,538,29,610,95" shape="poly" onmouseover="setImageSource('https://uploads-ssl.webflow.com/634723edf4a76fbc19fabbf3/6439a8c308c482bbb4be2660_industriebereiche_anwendung_spezielle-leuchten-highlight-40pct-final.png'); darkenImage(); showTooltip('Spezielle Leuchten');" onmouseout="resetImageSource(); undarkenImage(); hideTooltip();" onmousemove="updateTooltipPosition(event);">
</map>

<script>
  var mainImage = document.getElementById('main-image');

  function setImageSource(src) {
    mainImage.src = src;
  }

  function resetImageSource() {
    mainImage.src = 'https://uploads-ssl.webflow.com/634723edf4a76fbc19fabbf3/64393083e51864f3cc4dfce0_industriebereiche_anwendung_startbild_transparent-bg-40pct-scale.png';
  }

  function darkenImage() {
    mainImage.classList.add('darkened');
  }

  function undarkenImage() {
    mainImage.classList.remove('darkened');
  }

  function showTooltip(text) {
    document.getElementById('tooltip-text').innerText = text;
    document.getElementById('tooltip').style.display = 'block';
  }

  function hideTooltip() {
    document.getElementById('tooltip').style.display = 'none';
  }

  function updateTooltipPosition(event) {
    var tooltip = document.getElementById('tooltip');
    tooltip.style.left = event.pageX + 10 + 'px';
    tooltip.style.top = event.pageY + 10 + 'px';
  }
</script>

Would greatly appreciate any guidance, hints to my problem. Have a great weekend :slight_smile:


Here is my site Read-Only: LINK
(how to share your site Read-Only link)

hi @desperad0s you are adding filter on whole element so it make sense that when image is changed filter is applied to it. Did you tried to use pseudo class :before on main-image? This is just pure guess and it may include rethinking how to place orange images on top of main image. I can’t provide example but look eg. on codepen how filter on background image with :before works here is one example but it is simple.

Hey there and thanks for the reply @Stan :slight_smile:

ChatGPT also suggested using a pseudo-element, but when I tried the code suggested, it didn’t work for me.

Also, am I missing something, or is the codepen not working for me?
I don’t see any changes when hovering over that image.

Also, I don’t really understand what you mean by I’m adding a filter on the whole element, could you elaborate on that?

Cheers and have a great weekend :slight_smile:

:face_with_raised_eyebrow: there are better ways to learn or find solutions.

As you can see the codepen example doesn’t have :hover. I meant is as barebone example to have something to thing about.

you have one <img> tag where you change image src and darkened is applied to it.

What I meant with :before is to have your orange images :after this mean that you may on orange image :hover or mouseover change :before brightness of main image. That is why I have mentioned you may re-think how things should work. But there may be a different ways how to :person_shrugging:

EDIT: I have created in 10 min just simple example as confirmation that this mental model should work for you as starting point.

Hey there,

sorry for the late reply but I had to take some time off that project for some different client project.

You are totally right and I guess learning with ChatGPT is definitely not the best approach. Though it helped me to understand some concepts a little better than just watching a copious amount of videos on Youtube :smiley:

I’ll take some time to study your codepen this evening and just wanted to thank you from the bottom of my heart for taking the time! Really appreciate it :slight_smile:

If I have some more questions regarding that after studying, is it okay if I post them here?

Have a great day!

hi @desperad0s if questions will be related to the original topic you can post them here. But I’m not an expert to answer every question you may have. :wink:

Haha, of course I would only ask related questions!

So, I’ve spend a few hours examining, reading up on concepts and attributes I didn’t fully grasp yet and have come up with a little summary of my own, on how your code works. It would be cool if you can look over that and maybe clarify, if I got something wrong:

The basic gist of the codepen is, that using HTML and CSS we’re trying to achieve an effect where a user can hover over an image, causing it to darken while a highlighted area appears.

In the HTML, there is a “section” element which is used to group related contents. Inside that “section”, there is also a “div” element with the class of “container”. This container is used to style and position the image.

Within the CSS code, it is determined, that both the section and the container are using flexbox to display the image in the center of the user’s viewport (horizintally, and vertically)

We are then introducing the before pseudo element on the container, positioning it absolute to insert the original base image. The background attributes are used to make sure the image is contained within those restrictions of the container and that they don’t repeat.

The container:hover:before is used to apply the darkening filter to that image, when the container is being hovered over and the image get’s reduced 50% in brightness.

We then insert the highlighted area with the container:hover:after into the container, using the visibility property to override it’s default of being hidden.


This is as to how far I think I understand what’s happening in the codepen and for me that makes somehow sense. Am I right?

I now only have the problem about adding more layers into this and not destroying stuff. How can I now insert an area map that I have specified before, plus achieving the desired effect of a tooltip box appearing and following the user’s input while hoverin that specific area and changing when hovering on another area? (I already have those working with the code before, but don’t know if I can use them with the approach now)

Thanks for that so far, Stan!
You’re really helping me learn here :slight_smile:

hi @desperad0s I have looked on how to to just find that you have another issue and it is related to responsiveness. Your area coordinates are offset when the image changes its size. This happens because generated coordinates are fixed values related to the original image size and not precentage. They are ways to generate responsive coords but I do not have time to investigate further in-depth so I leave it to you.

There is possible to use SVG instead image map area, so here is one link that may be a starting point for further investigation.

EDIT:
https://imagemapper.noc.io/#/

once you will solve it, it will be a good source for an article many devs will love to read including me.

BTW: it looks to me as if the text above the line was generated by chatGPT or a prompt for chatGPT. :rofl:

You have helped me out here tremendously so far, so the least thing I can do when finding a definite solution, is to share it with you and others in form of an article. Will do, if I succeed (but I know that it must be true, because on of my client’s biggest competitors has figured it out in a responsive way - trilux) :slight_smile:

Thanks for leading me towards imagemapper.noc.io, I just checked it out and it looks really promising! (One more thing regarding this: Does it require me to export the base image and cutouts as SVGs or is this referring to how the coords itself are calculated?)

And damn, are you some sort of wizard or can read my mind? Yes, I have used ChatGPT to help me explain the concept of your codepen after studying it myself. I’ve used to fill the gaps that I didn’t fully understand in regards to the pseudo-element, but rephrased it in my own words after I thought I understood it, lol.

There is no magic :wink: only the way how it was formulated.

I really didn’t dive deeper into it as it may take to me a few hours to investigate and find an optimal solution. SVG is responsive and areas will change too.

Generally speaking, what I think is to create one SVG with designated areas (with names like building-1 or …) that will sit on the very top and use pointer events when the pointer is over the area grab the name and have a function that will change image source based on this. But it is just what is in my mind right now. As I said I didn’t investigate it further.

EDIT: One more thing to have in mind. As WF is not SVG friendly (characters limitation) when you create areas make these as simple as you can. But you can find more on this forum for some tricks on how to implement SVG’s larger than 10.000 characters.

Good luck :wink:

1 Like

Will give this a thorough look this evening :slight_smile: and update on any progress I’m making!

Mhh, I think it’s not feasible to realize with SVG especially with this image.
I converted it with Illustrator Image Trace and it’s a mess…Exported to SVG the file is 9mb big and the pure code is 96000 lines of code :smiley:

I might need to think about another solution or use another, more simple base image to begin with. Trilux kinda has a simple svg image and I think it won’t work with my base image in that state.

I’ll have to think about it

EDIT:

ImageMapper seems promising, but I couldn’t get it to work with the current image either, as it only allows me to use rectangle and not poly for the coords :confused:

But I found their github and contacted the guys who contributed on the project and am hoping to get some guidance (or a clear no with the current image from there).

Will keep this updated as things progress!

I’ve found this and am gonna study it:

EDIT:

I think the key to success will be this jquery plugin to calculate the image map in a responsive way :slight_smile:

EDIT2:

I found https://image-map.weebly.com/ which let’s you create responsive image-map with the mentioned plugin above directly in the browser and it created the following code for me, which I’m going to test after my evening run:

<img src="64393083e51864f3cc4dfce0_industriebereiche_anwendung_startbild_transparent-bg-40pct-scale.png" id="map-image" style="width: 1350px; max-width: 100%; height: auto;" alt="" usemap="#map" />
<map name="map">
    <area shape="poly" coords="702, 403, 703, 381, 1052, 214, 986, 185, 982, 155, 744, 36, 698, 58, 601, 9, 570, 25, 658, 70, 660, 75, 618, 98, 617, 163, 502, 220, 535, 236, 468, 274" href="#" target="_self" alt="produktionsbereiche" title="Produktionsbereiche" />
    <area shape="poly" coords="12, 282, 215, 385, 276, 354, 276, 324, 413, 261, 469, 269, 530, 238, 498, 224, 491, 220, 613, 162, 614, 96, 653, 73, 556, 25, 524, 43, 513, 33, 215, 169" href="#" target="_self" alt="spezielle leuchten" title="Spezielle Leuchten" />
    <area shape="poly" coords="221, 388, 282, 357, 283, 327, 411, 269, 464, 276, 706, 412, 705, 445, 621, 489, 857, 603, 751, 650" href="#" target="_self" alt="nebenbereiche" title="Nebenbereiche" />
    <area shape="poly" coords="637, 488, 686, 463, 710, 450, 712, 383, 1065, 215, 1347, 367, 866, 600" href="#" target="_self" alt="lager- und logistikbereiche" title="Lager- und Logistikbereiche" />
</map>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="imageMapResizer.min.js"></script>
<script>$(document).ready(function(e){$("map").imageMapResize();});</script>

I think you have misunderstood how to create SVG with areas. place your image as background create a new main layer and in this layer create a new layer and from several points create shape around a building. Create a new inside layer … and export the main layer… SSVG will have a few kb but I see you have found a solution.

Think about that WF has jQuery internally running so you may not need this script calling jQuery again. I’m not a big fan of jQuery so I never learned its syntax and who is using jQuery these days anyway, (oh sorry WF :shushing_face:) but if it does the job who cares. :person_shrugging:

OMG, I feel stupid now for misunderstanding you so entirely with the SVG :smiley: But I think I got it now.

In regards to learning future-proof technologies, would you recommend me trying and learning it the way you suggested it initially with the SVG or would it be a waste of time?

Thank you man, you kinda ignited my spirit to dive in a little deeper than I would have usually :slight_smile:

In programming is always many ways how to achieve your goals and it is on the developer what technologies he/she uses for it. You can look into competitors website you have mentioned and try reverse engineering to figure out what and how.

here is just a simple test of 3 buildings SVG before optimization on omgsvg it has cca 4kb.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 1350 658" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
    <g transform="matrix(1.05469,0,0,0.8225,0,0)">
        <rect id="Artboard1" x="0" y="0" width="1280" height="800" style="fill:none;"/>
        <g id="Artboard11" serif:id="Artboard1">
            <g id="b-1" transform="matrix(0.948148,0,0,1.21581,0,0)">
                <path d="M622,91L746,32L987,156L986,242L854,305L786,270L754,287L700,261L703,225L616,184L622,91Z" style="fill:rgb(136,127,127);stroke:black;stroke-width:1px;"/>
            </g>
            <g id="b2" transform="matrix(0.948148,0,0,1.21581,0,0)">
                <path d="M710,385L706,450L854,527L1205,360L1206,288L1061,214L710,385Z" style="fill:rgb(136,127,127);stroke:black;stroke-width:1px;"/>
            </g>
            <g id="b3" transform="matrix(0.948148,0,0,1.21581,0,0)">
                <path d="M910,573L675,448L692,436L688,406L650,385L616,404L566,370.5L493,295L461,273L412,269L292,327L287,370.5L244,399L751,654L910,573Z" style="fill:rgb(136,127,127);stroke:black;stroke-width:1px;"/>
            </g>
        </g>
    </g>
</svg>
1 Like

I think that is very close to what they’ve done as I’ve seen this "<g>" in their code, too.
I’ll think about what will be the best way going forward, but at the moment I’m thinking about trying all the different methods myself, just to learn how they work and what there pros and cons are.

Was more hinting towards the use of jQuery because you kinda scolded WF for still using it, so I was wondering if you could give me some insight as to why that might not be the most noble solution ;D

I know that many companies in legacy code still use jQuery and this is totally fine as jQuery is still maintained. The only reason not to learn jQuery is why was jQuery created. In short, a decade ago jQuery was able to handle differences between browsers on how rules were applied in an elegant way so you had to write less code and not care about edge cases.

These days how browsers apply rules is more unified (they all agree that something should work this way) and implementing new rules and specifications is much faster. So IMO jQuery is outdated and not needed anymore.

The better way is IMO learn and understand javaScript. But you will find many developers who will disagree.

1 Like

As you tend to use chatGPT here is why developers should think twice about it as AI tell lies even on a basic question without shame. :rofl:

1 Like

The non-chalant boldness and confidence , with which it lies / halluzinates is astonishing, haha :smiley:

And I see your point. Someone with no basic knowledge would have a tough time destinguishing fiction from reality.

As this was ChatGPT 3.5 with which you tested this, how about the 4.0 version which has better reasoning capabilities?

Just out of curiosity, I’ll try to replicate it. [EDIT → ]


Looks like it’s getting better with ChatGPT4 as I see it, it knows to not put a element inside a element but was referring to headings :stuck_out_tongue:

By the way, I haven’t come any further yet, as I was moving home from Malta to Budapest, but now finally settled in and will approach this problem with the image map once again. During the moving I tried the responsive image-map, but even the basic image-map doesn’t work as I expect it. The areas are overlapping even in the standard dimension of the browser and I thought it might be due to my 125% scaling, but to no avail does that change anything.

I think I might try your approach with creating the svg overlay for the areas instead, as I couldn’t really get the jQuery library to load (it always gave me some load errors in the dev-inspect) My lack of coding knowledge really shows with this project, and I fear that I cannot catch up in time with others to really make use of my ideas and creatiivity and it’s holding me back big time. How would you recommend to learn HTML/CSS/JS in an effective way?