Solution for background-size:cover
I am trying to give you solution(or consider as an idea). You can check working demo here. Resize the window to see the result.
First,I didn't understand why you are using transform
,top:50%
and left:50%
for hotspot. So I tried to solve this using minimal use-case and adjusted your markup and css for my convenience.
Here rImage
is the aspect ratio of the original image.
var imageWidth = 1920;
var imageHeight = 1368;
var h = {
x: imageWidth / 2,
y: imageHeight / 2,
height: 100,
width: 50
};
var rImage= imageWidth / imageHeight;
In window resize handler,calculate the aspect ration of viewport r
.
Next,the trick is to find the dimensions of the image when we resize the window. But,viewport will clip the image to maintain aspect ratio. So to calculate the image dimensions we need some formula.
When using background-size:cover
to calculate the dimensions of image,below formulas are used.
if(actual_image_aspectratio <= viewport_aspectratio)
image_width = width_of_viewport
image_height = width_ofviewport / actual_image_aspectratio
And
if(actual_image_aspectratio > viewport_aspectratio)
image_width = height_of_viewport * actual_image_aspectratio
image_height = height_of_viewport
You can refer this URL for more understanding on image dimensions calculation when using background-size:cover
.
After getting the dimensions of the image, we need to plot the hot-spot coordinates from actual image to new image dimensions.
To fit the image in viewport image will be clipped on top & bottom / left & right of the image. So we should consider this clipped image size as an offset while plotting hotspots.
offset_top=(image_height-viewport_height)/2
offset_left=(image_width-viewport_width)/2
add this offset values to each hotspot's x,y
coordnates
var imageWidth = 1920;
var imageHeight = 1368;
var hotspots = [{
x: 100,
y: 200,
height: 100,
width: 50
}, {
x: 300,
y: 500,
height: 200,
width: 100
}, {
x: 600,
y: 600,
height: 150,
width: 100
}, {
x: 900,
y: 550,
height: 100,
width: 25
}];
var aspectRatio = imageWidth / imageHeight;
$(window).resize(function() {
positionHotSpots();
});
var positionHotSpots = function() {
$('.hotspot').remove();
var wi = 0,
hi = 0;
var r = $('#image').width() / $('#image').height();
if (aspectRatio <= r) {
wi = $('#image').width();
hi = $('#image').width() / aspectRatio;
} else {
wi = $('#image').height() * aspectRatio;
hi = $('#image').height();
}
var offsetTop = (hi - $('#image').height()) / 2;
var offsetLeft = (wi - $('#image').width()) / 2;
$.each(hotspots, function(i, h) {
var x = (wi * h.x) / imageWidth;
var y = (hi * h.y) / imageHeight;
var ww = (wi * (h.width)) / imageWidth;
var hh = (hi * (h.height)) / imageHeight;
var hotspot = $('<div>').addClass('hotspot').css({
top: y - offsetTop,
left: x - offsetLeft,
height: hh,
width: ww
});
$('body').append(hotspot);
});
};
positionHotSpots();
html,
body {
height: 100%;
padding: 0;
margin: 0;
}
#image {
height: 100%;
width: 100%;
background: url('https://upload.wikimedia.org/wikipedia/commons/thumb/0/08/Alexanderplatz_Stadtmodell_1.jpg/1920px-Alexanderplatz_Stadtmodell_1.jpg');
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
.hotspot {
position: absolute;
z-index: 1;
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='image'></div>
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…