I have a tricky question: I have a fullsize background over the site I\'m working on. Now I want to attach a div to a certain position on the image and also that the div sc
Relying on css transforms and applying it to a single element gives you much better performance regardless of the number of hotspots (fewer DOM manipulations and much fewer re-flows). Hardware acceleration is also a nice-to-have :)
First, meta-code:
Create a .hot-spot--container inside your image .container
Create .hot-spot and position/size them within the .hot-spot--container
Transform .hot-spot--container mimicking background-size: cover behaviour
Repeat #3 whenever there's a re-size
Calculate your bg image ratio:
var bgHeight = 1368;
var bgWidth = 1920;
var bgRatio = bgHeight / bgWidth;
Whenever the window is re-sized, re-calculate container ratio:
var containerHeight = $container.height();
var containerWidth = $container.width();
var containerRatio = containerHeight / containerWidth;
Calculate scale factors to mimic background-size: cover behaviour...
if (containerRatio > bgRatio) {
//fgHeight = containerHeight
//fgWidth = containerHeight / bgRatio
xScale = (containerHeight / bgRatio) / containerWidth
} else {
//fgHeight = containerWidth / bgRatio
//fgWidth = containerWidth
yScale = (containerWidth * bgRatio) / containerHeight
}
...and apply the transform to the hot spot container element, essentially re-sizing and re-positioning it "in sync" with the background:
var transform = 'scale(' + xScale + ', ' + yScale + ')';
$hotSpotContainer.css({
'transform': transform
});
Fiddled: https://jsfiddle.net/ovfiddle/a3pdLodm/ (you can play with the preview window pretty effectively. Note the code can be adjusted to take pixel-based dimensions and positioning for hot spots, you'll just have to consider container and image sizes when calculating scale values)
Update: the background-size: contain behaviour uses the same calculation except when the containerRatio is smaller than the bgRatio. Updating the background css and flipping the sign around is enough.