The image will be displayed at the center of its container. In case users zoom in the image to the level which makes the image bigger than its container, then we'll hide the outside parts.
Having that imagination, the container could be styled as below:
.image-container {
/* Center the content */
align-items: center;
display: flex;
justify-content: center;
overflow: hidden;
width: 100%;
}
Initially, we want the image to be fit within its container. To do that, we clone the image and handle the load
event to determine the size of image:
// Query the element
const image = document.getElementById('image');
// Create new image element
const cloneImage = new Image();
cloneImage.addEventListener('load', function (e) {
// Get the natural size
const width = e.target.naturalWidth;
const height = e.target.naturalHeight;
// Set the size for image
image.style.width = `${width}px`;
image.style.height = `${height}px`;
});
// Clone it
cloneImage.src = image.src;
The initial scale can be determined based on the widths of container and image:
cloneImage.addEventListener('load', function(e) {
...
// The initial scale
const scale = image.parentNode.getBoundingClientRect().width / width;
});
Now we scale the image to that value by setting the transform
style:
cloneImage.addEventListener('load', function(e) {
...
image.style.transform = `scale(${scale}, ${scale})`;
});
You can take a look at the Create a range slider post for more details. Initially, we want to set the slider range based on the scale calculated in the previous section.
First, we define the minimum and maximum scales and calculate the range step:
const minScale = 0.1;
const maxScale = 2;
const step = (maxScale - minScale) / 100;
It's also possible to set the lower and upper values based on the initial scale. I set constant values to make this post simple
The slider can update the value via the width of left part:
// Query the elements
const knob = document.getElementById('knob');
const leftSide = knob.previousElementSibling;
cloneImage.addEventListener('load', function(e) {
...
leftSide.style.width = `${(scale - minScale) / step}%`;
});
In the previous section, we set the initial value for the slider based on the scale. It's the time to do the other part, update the scale based on the slider's value.
It happens when user drags the knob:
const mouseMoveHandler = function (e) {
// Calculate the width for the left part
// ...
let newLeftWidth = ((leftWidth + dx) * 100) / containerWidth;
// Set the width
leftSide.style.width = `${newLeftWidth}%`;
// Calculate the scale
const scale = minScale + newLeftWidth * step;
image.style.transform = `scale(${scale}, ${scale})`;
};
Enjoy the demo!
Photo by Pedro Lastra on Unsplash