Scale element proportional to Background Cover with jQuery

前端 未结 6 1751
情话喂你
情话喂你 2020-11-28 10:11

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

6条回答
  •  暗喜
    暗喜 (楼主)
    2020-11-28 10:38

    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:

    1. Create a .hot-spot--container inside your image .container

    2. Create .hot-spot and position/size them within the .hot-spot--container

    3. Transform .hot-spot--container mimicking background-size: cover behaviour

    4. 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.

提交回复
热议问题