Search code examples
javascripthtmlcssscale

Need help scaling an image inside a viewport


I have a Django site that displays an image and I need to zoom in and zoom out using a button while keeping the viewport relatively the same size and use scroll bars to move the image when it is zoomed in. I am not a CSS nor javascript guy, so this attempt is based on a lot of google help.

$(document).ready(function() {
  console.log("Zoom START");
  $('#zoom-in').click(function() {
    updateZoom(0.1);
    console.log("Zoomed in");
  });

  $('#zoom-out').click(function() {
    updateZoom(-0.1);
    console.log("Zoomed out");
  });


  zoomLevel = 1;

  var updateZoom = function(zoom) {
    zoomLevel += zoom;
    $('#imageblock').css({
      zoom: zoomLevel,
      '-moz-transform': 'scale(' + zoomLevel + ')',
      /* Firefox */
      'transform': 'scale(' + zoomLevel + ')',
      //'-ms-transform': 'scale(' + zoomLevel + ')', /* IE 9 */
      '-webkit-transform': 'scale(' + zoomLevel + ')',
      /* Safari and Chrome */
      //'-o-transform': 'scale(' + zoomLevel + ')', /* Opera */

    });
    console.log("updated imageblock css");
  }
});
#imageblock {
  max-height: 600px;
  max-width: 800px;
  transform-origin: top left;
  overflow: hidden;
}

#imageblock img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label>Image:</label>
<div class="readonly">
  <div>
    <b>Click to tag people, Ctrl-click to tag animals</b>
    <button type="button" id="zoom-in">zoom in</button> <button type="button" id="zoom-out">zoom out</button>
  </div>
  <div id="imageblock">
    <img src="https://i.imgur.com/v38pV.jpg" id="img1" doc_id="394" style="height:600px" />
  </div>
  <div>
    <a id="rotate" href="#">Rotate 90 degrees</a>
  </div>
</div>

The image zooms, but also grows to fill the page without any scrollbars, and does not stay within a viewport (image block). Thanks for any assistance/direction you can give me!

Mark


Solution

  • You might want to use an approach like this with a couple bounding elements to control the clipping and scrolling. See below:

    $('input').on('change', function() {
      $('img').css('transform', `scale(${$(this).val()})`);
    });
    div {
      width: 300px;
      height: 300px;
      border: 1px solid #000000;
      overflow: scroll;
      display: block;
    }
    
    img {
      transform-origin: 0 0;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <input type="number" step="0.1" value="1" min="0" />
    
    <div>
      <img src="http://placekitten.com/g/250/250" />
    </div>