JavaScript Image Overlay Over a Specified Div

How can I display an image overlay on all other images that are not currently being hovered over?

Update

I've added a CSS filter with a short transition as an idea for a straightforward overlay, in place of changing opacity.


At the risk of oversimplifying this, you can use CSS negation to handle this task.

From MDN:

The :not() CSS pseudo-class represents elements that do not match a
list of selectors. Since it prevents specific items from being
selected, it is known as the negation pseudo-class.

.thumbnail-photos-wrapper:hover .thumbnail-image-wrapper:not(:hover) {  filter: brightness(.33);}
.thumbnail-image-wrapper { transition: filter 0.3s ease-in-out;}
/* For styling puroses only — ignore */.thumbnail-photos-wrapper { display: inline-block; }
<div class="thumbnail-photos-wrapper">  <div class="thumbnail-image-wrapper">    <img src=http://placekitten.com/50/50 alt="Thumbnail photo" />  </div>  <div class="thumbnail-image-wrapper">    <img src=http://placekitten.com/50/50 alt="Thumbnail photo" />  </div>  <div class="thumbnail-image-wrapper">    <img src=http://placekitten.com/50/50 alt="Thumbnail photo" />  </div></div>

How to overlay a dynamically selected image over a dynamically populated div

Actually I think the best solution is not to add a background-image to the div elements in which you put your text, but rather to create a child div for each div you created, and work with the image inside the child.

careerstage_td.selectAll('div')
.data(dataset)
.enter().append('div')
.attr("class", "career-count")
.text(function(d){return d;})
.style("color", function(d){return d.color;})
.append('div')
.attr("class", "childClass")
.style("background-image", function(d){return "url('images/" + d.icon + "')";})
.style("background-repeat", "no-repeat")
.style("background-position", "center center");

In the given code, I generate my divs thanks to the data, and for each div I append a new div (classnames "childClass"). Now I can play on this childClass.

See the jsfiddle for an example. (note that I used a simplified dataset so I pushed always the image as a background, and the same text color).

The trick to ensure that the icon displays in the middle of the parent node is to define the parent as position:relative and the children as absolute with a width and height of 100%. Centering the background both on x and y does the job.

How can I add a transparent image overlay on top of a video?

I'd throw them both in a position:relative div with a class that hides a contained img on hover. You still have to tell the img where to be within the div.

<style>
.gone:hover img{display:none;}
</style>

<a href=/districtvision>
<div class="gone" style="position:relative;">
<img src="yourImage.png" style="position:absolute;z-index:1;">
<video onmouseover="this.play();" onmouseout="this.pause();" loop muted width="100%">
<source src="https://topspinstudios.com/s/DV-Loop.mp4" type="video/mp4">
</video>
</div>
</a>

Keep div overlay relative to background image regardless of window size

EDIT: Added js alternative

I was convinced that this could be done with css and almost gave up, but then I remembered the new(ish) css units vh and vw....

jsfiddle

CSS

html, body{
height: 100%;
width: 100%;
}
.cat {
height: 100%;
width: 100%;
position: relative;
background:url(http://placekitten.com/g/800/400) no-repeat center center / cover;
}
.place-on-eye {
position: absolute;
color: #fff;
margin:0;
}

@media (min-aspect-ratio: 2/1) {
.place-on-eye {
bottom: 50%;
left: 46.875%;
margin-bottom: 1.25vw;
}
}

@media (max-aspect-ratio: 2/1) {
.place-on-eye {
bottom: 52.5%;
left: 50%;
margin-left: -6.25vh;
}
}

Explanation

So the left eye is at approx 375, 190, and since the image is centered, we will also want to know how far off the center it is, so 25, 10. Since the image is covering, the size of the image will change based on whether the aspect ratio of the viewport is greater or less than the aspect ratio of the background image. Knowing this, we can use media queries to position the text.

The image is 2:1, so when the viewport aspect ratio is > 2:1, we know that the width of the image is the width of the viewport, so the left position of the <p> should always be 46.867% (375/800). The bottom position is going to be more difficult because the image extends beyond the viewport top and bottom. We know that the image is centered, so first move the <p> to the middle, then push it up by 2.5% (10/400) of the height of the image. We don't know the height of the image, but we do know the image aspect ratio and that the width of the image is equal to the width of the viewport, so 2.5% of the height = 1.25% width. So we have to move the bottom up by 1.25% width, which we can do by setting margin-bottom:1.25vw. Incidentally, we can do this without vw in this case because padding is always calculated relative to the width, so we could have set padding-bottom:1.25%, however this won't work in the next case where you have to position the left relative to the height.

The case when the aspect ratio is < 2:1 is analogous. The height of the image is the height of the viewport, so the bottom position should always be 52.5% (210/400) and the left is calculated similar to above. Move it over to center, then back it up by 3.125% (25/800) the width of the image, which is equal to 6.25% the height of the image, which is equal to the viewport height, so margin-left:-6.25vh.

Hopefully this is correct and helps you out!

JS Alternative

jsfiddle

Here's an alternative that uses js. It uses some features like forEach and bind that might cause problems depending on how old a browser you need it to work on, but they are easily replaceable. With js you can directly calculate the scaled dimensions of the bg image which makes the positioning easier. Not the most elegant code, but here goes:

//elem:     element that has the bg image
//features: array of features to mark on the image
//bgWidth: intrinsic width of background image
//bgHeight: intrinsic height of background image
function FeatureImage(elem, features, bgWidth, bgHeight) {
this.ratio = bgWidth / bgHeight; //aspect ratio of bg image
this.element = elem;
this.features = features;
var feature, p;
for (var i = 0; i < features.length; i++) {
feature = features[i];
feature.left = feature.x / bgWidth; //percent from the left edge of bg image the feature resides
feature.bottom = (bgHeight - feature.y) / bgHeight; //percent from bottom edge of bg image that feature resides
feature.p = this.createMarker(feature.name);
}
window.addEventListener("resize", this.setFeaturePositions.bind(this));
this.setFeaturePositions(); //initialize the <p> positions
}

FeatureImage.prototype.createMarker = function(name) {
var p = document.createElement("p"); //the <p> that acts as the feature marker
p.className = "featureTag";
p.innerHTML = name;
this.element.appendChild(p);
return p
}

FeatureImage.prototype.setFeaturePositions = function () {
var eratio = this.element.clientWidth / this.element.clientHeight; //calc the current container aspect ratio
if (eratio > this.ratio) { // width of scaled bg image is equal to width of container
this.scaledHeight = this.element.clientWidth / this.ratio; // pre calc the scaled height of bg image
this.scaledDY = (this.scaledHeight - this.element.clientHeight) / 2; // pre calc the amount of the image that is outside the bottom of the container
this.features.forEach(this.setWide, this); // set the position of each feature marker
}
else { // height of scaled bg image is equal to height of container
this.scaledWidth = this.element.clientHeight * this.ratio; // pre calc the scaled width of bg image
this.scaledDX = (this.scaledWidth - this.element.clientWidth) / 2; // pre calc the amount of the image that is outside the left of the container
this.features.forEach(this.setTall, this); // set the position of each feature marker
}
}

FeatureImage.prototype.setWide = function (feature) {
feature.p.style.left = feature.left * this.element.clientWidth + "px";
feature.p.style.bottom = this.scaledHeight * feature.bottom - this.scaledDY + "px"; // calc the pixels above the bottom edge of the image - the amount below the container
}

FeatureImage.prototype.setTall = function (feature) {
feature.p.style.bottom = feature.bottom * this.element.clientHeight + "px";
feature.p.style.left = this.scaledWidth * feature.left - this.scaledDX + "px"; // calc the pixels to the right of the left edge of image - the amount left of the container
}

var features = [
{
x: 375,
y: 190,
name: "right eye"
},
{
x: 495,
y: 175,
name: "left eye"
},
{
x: 445,
y: 255,
name: "nose"
},
{
x: 260,
y: 45,
name: "right ear"
},
{
x: 540,
y: 20,
name: "left ear"
}
];

var x = new FeatureImage(document.getElementsByClassName("cat")[0], features, 800, 400);

Position div over particular region of variable height image

This can be achieved with CSS and a few changes to your markup

The image in your example is scaled in relation to the height of the viewport - the height is always 100% and the width is calculated on the fly by the browser to keep the aspect ratio.

To position the overlay the same scaling will need to apply. To do this a container can be added which will fit the viewport height and scale to the width of the image, this will then allow for the overlay to be positioned relatively to it and scale in proportion to the image.

The following modifications are required:

  • Wrap .background and .overlay in a container (called #container in this instance)
  • Set #container with the following properties:

    • height: 100vh; - This will make it fill the entire viewport height
    • margin-top: -61px; - Carried over from your example
    • position: relative; - To ensure that .overlay is positioned in relation to this container
    • width: 570vh; - This will ensure that the container scales at the same rate as the image. This is calculated by finding the aspect ratio of your existing image - 1140 x 200 is an aspect ratio of 57 : 10 so 200(px) * 5.7 = 1140(px) translates to 100(vh) * 5.7 = 570(vh)
  • Set .background with the following properties:

    • height: 100%; - To ensure it resizes in a similar manner to your example, it will fill the entire height of the viewport. The width will scale in relation to this
  • Set .overlay with the following properties:

    • background: red; - Carried over from your example
    • height: 6vh; - As the image is scaled in relation to the viewport height this will ensure that the overlay scales at the same rate
    • left: 18.3%; - Positions the overlay at the designated area over the registered symbol
    • position: absolute; - Positions the overlay relative to the container
    • top: 29%; - Positions the overlay at the designated area over the registered symbol
    • width: 6vh; - As the image is scaled in relation to the viewport height this will ensure that the overlay scales at the same rate

$(".overlay").click(function() {  alert("Clicked")});
#container {  height: 100vh;  margin-top: -61px;  position: relative;  width: 570vh;}.background {  height: 100%;}.overlay {  background: red;  height: 6vh;  left: 18.3%;  position: absolute;  top: 29%;  width: 6vh;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><div id="container">  <img alt="" class="background" src="http://cisloandthomas.com/wp-content/uploads/2015/12/Shrunken-Banner-Wide-Ends-1140x200.jpg">  <div class="overlay"></div></div>


Related Topics



Leave a reply



Submit