How to Zoom in an Image and Center It

How to zoom in a background image to the center of it

I have been playing around with this a bit. This is what I ended up with.

Here is the logic that I used figuring this out:

  • An image rotates around its center.
  • If I put the image in a container it will cut a part of the image off. The image will still rotate around the center of the image....But that is not the center of the container anymore.
  • Solution: I made the image behave like background: cover; by using min-width: 100%; and min-height: 100%;
  • Solution: I centered the image in the container using flexbox.

Another way of centering might be preferable, since the flexbox also affects other children of the container. So any improvements/comments about that would be welcome :).

html

<div id="wrapper">
<img src="data:image/png;base64,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" id="image"/>
</div>

css

@keyframes zoom-effect {
0% {
transform: scale(1) rotate(0deg);}
100% {
transform: scale(4) rotate(360deg);}
}
#wrapper{
height: 250px;
width: 350px;
border: 2px solid green;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}
#image{
z-index: -100;
min-height: 100%;
min-width: 100%;
animation-name: zoom-effect;
animation-duration: 9s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}

Hope it helps :)

How to zoom image from center without using exact position

You can adjust the top and left position at the same time as you enlarge.

-1rem seems to fit nicely.

let image = $('#navigation_bar img');
$('#menu-item-948').hover(function() {
// alert("top :"+position.top +" left : "+ position.left +" right: "+ position.right +" bottom: "+ position.bottom); $(image) .attr("src", "https://matiloos.dts.company/wp-content/uploads/2018/11/Asset-6.png") .animate({ width: "5rem", height: "5rem", top: "-1rem", left: "-1rem" }, 150); $('#menu-item-948').append('<p id="text" >text</p>'); $('#text').css('color', '#55EA00');
}, function() { $(image) .attr("src", "https://matiloos.dts.company/wp-content/uploads/2018/11/Asset-5.png") .animate({ width: "2.5rem", height: "2.5rem", top: 0, left: 0, }, 300); $('#text').remove();});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><div class="flex-col hide-for-medium flex-center" style="margin-left: 50%; margin-top: 10%">  <ul id="navigation_bar" class="nav header-nav header-bottom-nav nav-center  nav-divided nav-uppercase text-center ">    <li id="menu-item-948" class="menu-item menu-item-type-post_type menu-item-object-page  menu-item-948">      <a href="https://matiloos.dts.company/demos/shop-demos/big-sale/" class="nav-top-link"><img id="pic1" src="https://matiloos.dts.company/wp-content/uploads/2018/11/Asset-5.png" style="position:relative;width: 2.5rem; height: 2.5rem"></a>    </li>  </ul>

How to zoom in an image and center it?

As I said in my comment above, I would avoid the zoom css property and stick to just javascript. I managed to throw together the following code which works pretty well for the first click, really all it needs is a little more dynamically (even a word?).

        <html>              <head>                <script type="text/javascript">               function resizeImg (img)               {              var resize = 150; // resize amount in percentage              var origH  = 200;  // original image height              var origW  = 200; // original image width              var mouseX = event.x;              var mouseY = event.y;              var newH   = origH * (resize / 100) + "px";              var newW   = origW * (resize / 100) + "px";                              // Set the new width and height              img.style.height = newH;              img.style.width  = newW;                            var c = img.parentNode;                            // Work out the new center              c.scrollLeft = (mouseX * (resize / 100)) - (newW / 2) / 2;              c.scrollTop  = (mouseY * (resize / 100)) - (newH / 2) / 2;               }             </script>             <style type="text/css">               #Container {                 position:relative;                 width:200px;                    height:200px;                 overflow:hidden;               }             </style>              </head>              <body>                <div id="Container">                  <img alt="Click to zoom" onclick="resizeImg(this)"                     src="https://picsum.photos/200" />                </div>              </body>            </html>

How to re-center an image once it has been dragged and zoomed in or out

Instead of re-centering the content after scale, use the center point of the content as the scale pivot.
In other words, scale around the center of the content.

Introduce a simple method to calculate the center:

private Point2D getContentCenter() {
Bounds contentBounds = CONTENT.getBoundsInLocal();
return new Point2D(contentBounds.getCenterX(), contentBounds.getCenterY());
}

And scale around it:

private void zoom(ScrollEvent scrollEvent) {
// adds or subtracts to the image's scale based on
// whether user is scrolling backwards or forwards
final double dScale = scrollEvent.getDeltaY() > 0 ? 0.1 : -0.1;
scale += dScale;
Point2D target = getContentCenter();
// applies the zoom to the image
applyZoom(1 + dScale, target);
}

EDIT:
The following ZoomController implements scaling around mouth positions and recentering of the content when the pane is resized :

class ZoomController{

// the plane on which the node is being dragged
private final AnchorPane PLANE;
// the node I want to zoom and drag
private final Node CONTENT;

// the total amount of scaling applied to the CONTENT node
private int scale = 1;

private Point2D lastMousePosition = new Point2D(0, 0);

public ZoomController( AnchorPane plane, Node content ) {
PLANE = plane;
CONTENT = content;

PLANE.heightProperty().addListener((obs, number, t1) -> centerView());
PLANE.widthProperty().addListener((obs, number, t1) -> centerView());

// saves the mouse's position whenever the mouse moves
PLANE.setOnMousePressed(event -> updateMousePosition(event));
PLANE.setOnMouseDragged(drag());

PLANE.setOnScroll(handleScroll());
}

private void updateMousePosition(MouseEvent mouseEvent) {
lastMousePosition = new Point2D(mouseEvent.getX(), mouseEvent.getY());
}

private EventHandler<ScrollEvent> handleScroll() {
return scrollEvent -> {
// filters out the mouse stopping to scroll
if (scrollEvent.getDeltaX() == 0 && scrollEvent.getDeltaY() == 0) return;
// starts zooming
if (scrollEvent.isControlDown()) {
zoom(scrollEvent);
}
};
}

private void zoom(ScrollEvent scrollEvent) {

// adds or subtracts to the image's scale based on
// whether user is scrolling backwards or forwards
final double dScale = scrollEvent.getDeltaY() > 0 ? 0.1 : -0.1;
scale += dScale;

// scale around mouse position
Point2D pivot = CONTENT.parentToLocal(new Point2D(scrollEvent.getX(), scrollEvent.getY()));

//applies the zoom to the image
applyZoom(1 + dScale, pivot);
}

private void applyZoom(final double zoomAmount, Point2D target) {
// applies the necessary scaling to the image...
Scale zoom = new Scale(zoomAmount, zoomAmount);
// ...and centers the scaling to the point where the mouse is located at
zoom.setPivotY(target.getY());
zoom.setPivotX(target.getX());
CONTENT.getTransforms().add(zoom);
}

private EventHandler<MouseEvent> drag() {
return mouseEvent -> {

// calculates the path taken by the mouse...
Point2D newMousePosition = new Point2D(mouseEvent.getX(), mouseEvent.getY());
Point2D mouseTranslation = lastMousePosition.subtract(newMousePosition);
// ...and saves its new position
updateMousePosition(mouseEvent);

// applies the drag
applyDrag(mouseTranslation);
};
}

private void applyDrag(Point2D dragAmount) {
// applies the necessary translation to the image...
Translate drag = new Translate();
// ...based on the mouse's movement
drag.setX(-dragAmount.getX());
drag.setY(-dragAmount.getY());
CONTENT.getTransforms().add(drag);
}

private void centerView() {

// gets the coordinates we need to place the image at for it to be centered
Point2D centerPosition = CONTENT.parentToLocal(getCenterEdge());
Point2D position = getContentPosition();

Point2D translation = centerPosition.subtract(position);
// applies the necessary translation to the image...
Translate translateToCenter = new Translate();
translateToCenter.setX(translation.getX());
translateToCenter.setY(translation.getY());
CONTENT.getTransforms().add(translateToCenter);
}

private Point2D getContentPosition() {
// gets the minimal coordinates of the bounds around the image
// ie: the image's coordinates
Bounds contentBounds = CONTENT.getBoundsInLocal();
return new Point2D(contentBounds.getMinX(), contentBounds.getMinY());
}

private Point2D getCenterEdge() {
// gets the size of the image and the anchor pane it is in...
Point2D contentSize = getContentSize();
Point2D parentSize = getParentSize();
// ...to determine the coordinates at which to place the image for it to be centered
return new Point2D(
(parentSize.getX() - contentSize.getX()) / 2,
(parentSize.getY() - contentSize.getY()) / 2
);
}

private Point2D getContentSize() {
//BoundsInParent: rectangular bounds of this Node which include its transforms
Bounds contentBounds = CONTENT.getBoundsInParent();
return new Point2D(contentBounds.getWidth(), contentBounds.getHeight());
}

private Point2D getParentSize() {//renamed from getAvailableSpace()
// gets the size of the Anchorpane the image is inn
return new Point2D(PLANE.getWidth(), PLANE.getHeight());
}
}


Related Topics



Leave a reply



Submit