Nathan
Nathan

Reputation: 666

Content being cropped when scaling a div

I'm trying to make a div that can be zoomed in on using the 'scale' property. However, when I scale up an image, it scales fine, however the outsides of the image are being cropped and I can't scroll around the page to see the rest of the image for some reason.

Example on codepen:

http://codepen.io/anon/pen/xLGFl

So if you look at Greenland for example, and then you click the 'in' button, you'll see after the image has been scaled, 90% of Greenland disappears and you cannot scroll back up to view the missing part of Greenland or anywhere else on the map, which is what I want to be able to do.

I've tried things like adding background-size:cover and 100% 100%, I've tried adding overflow:auto, I've tried putting the image in an image tag within the map-container div and I've tried putting another div around the map-container div that has a fixed width and height with overflow:auto on it but I'm getting the same results every time.

Any help with this is much appreciated!

EDIT WITH SOLUTION:

To fix it, I used Candlejack's solution and change my zoomIn() function by setting a variable to change the top/left position depending on how far it was zoomed in. I had to do trial/error to get the right values for my site. I also had to use the same code below (with zoomMargin changes in the switch statement) in my zoomOut() function to change back to the previous zoomMargin value.

var zoomMargin = 0;
function zoomIn(){
    //get the id of the element to be scaled and scale it using GSAP
    var mapContainer = document.getElementById("map-container");
    TweenMax.set(mapContainer,{transformOrigin: "50% 50%"});
    TweenMax.to(mapContainer, 0.4, { scale: "+=1"});
    console.log("scale: "+mapContainer._gsTransform.scaleX);
    //switch between the scale value (the scale value in my switch statement is from the GSAP library)
    switch(mapContainer._gsTransform.scaleX){
        case 1:
            zoomMargin = 24.9;
        break;
        case 2:
            zoomMargin = 33.3;
        break;
        case 3:
            zoomMargin = 37.5;
        break;
        case 4:
            zoomMargin = 39.9;
        break;
        case 5:
            zoomMargin = 41.6;
        break;
    }
    $('#map-inner-container').css( "top", zoomMargin+"%" );
    $('#map-inner-container').css( "left", zoomMargin+"%" );
}

HTML:

<div id="map-container">
    <div id="map-inner-container">
        <img src="map-url.png" style="z-index:-9999;">
    </div>
</div>

Upvotes: 1

Views: 505

Answers (1)

Candlejack
Candlejack

Reputation: 445

I took the background image out of your #map-container and placed it in the markup as an img - as shown here.

This allows scrolling to the full extent of the image, regardless of zoomed level.

You may need to tweak the image styling to resemble your original design, but this should at least solve the immediate scrolling issue.

EDIT:

New version here: http://codepen.io/anon/pen/eHDmG

Added position: relative to the img CSS, and then altered the top rule in the JS functions for zoomIn/zoomOut.

So far I've used static values of 20% and 0% to demonstrate the point - it only really looks good the first time you zoom in. Ideally these values should be set dynamically depending on which zoom depth you are at. You could set a variable to store an integer which increments every time the user zooms in and decrements every time the user zooms out, and then calculate an appropriate top position value depending on this variable.

Upvotes: 1

Related Questions