Looking for assistance with resizing and repositioning an image within a viewport?

The JSFiddle code can be found at this link - https://jsfiddle.net/pmi2018/smewua0k/211/

Javascript

$('#rotate').click(function(e) {
  updateImage(90, 0)
  console.log("rotation");
});

$('#zoom-in').click(function() {
  updateImage(0, 0.1);
  console.log("Zoomed in");
});

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

var zoomLevel = 1;
var rotation = 0;

var updateImage = function(angle, zoom) {
  zoomLevel += zoom;
  var img_scale = ' scale(' + zoomLevel + ') ';

  rotation += angle;
  if (rotation == 360) {
    rotation = 0;
  }
  var str_rotation = ' rotate(' + rotation + 'deg) ';
  console.log("rotation=" + str_rotation + " scale=" + img_scale);
  var img = document.getElementById('sam');
  img.style.transform = img_scale + str_rotation
}

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<button type="button" id="zoom-in">zoom in</button> <button type="button" id="zoom-out">zoom out</button> 

<div id=imageblock>
  <img  id="sam" src="http://placekitten.com/g/250/250" />
</div>
<div>
  <a id="rotate" href="#">Rotate 90 degrees</a>
</div>

CSS

#imageblock {
  width: 300px;
  height: 300px;
  border: 1px solid #000000;
  overflow: auto;
  display: block;
}

#sam {
  transform-origin: center, center;
}

In order to keep the scaled image within the box, the origin must be set to upper left corner, and for rotating it has to be center, center. However, applying both rotation and scaling separately does not work as only the first transformation is applied.

How can I achieve both rotation and scaling of the image in the #imagebox?

Thank you!

Mark

Answer №1

When it comes to why certain transformations work well together, the key lies in understanding that the transform property can only have one origin. This means that if you apply multiple transformations to a single object, they will all share the same origin.

To address this issue, a simple solution is to place the image within a div element. From there, you can utilize zoom on the div and rotation on the image separately, allowing them to have different origins.

$('#rotate').click(function(e) {
  updateImage(90, 0)
});

$('#zoom-in').click(function() {
  updateImage(0, 0.1);
});

$('#zoom-out').click(function() {
  updateImage(0, -0.1);
});

var zoomLevel = 1;
var rotation = 0;

var updateImage = function(angle, zoom) {
  zoomLevel += zoom;
  var img_scale = ' scale(' + zoomLevel + ') ';

  rotation += angle;
  if (rotation == 360) {
    rotation = 0;
  }
  var str_rotation = ' rotate(' + rotation + 'deg) ';

  // Some modifications were made here, utilizing JQuery methods instead of pure JavaScript
  // The image's rotate property is updated first, followed by the div's scale property
  $('#sam').css('transform',str_rotation)
  $('#zoom').css('transform', img_scale);
}
#imageblock {
  width: 300px;
  height: 300px;
  border: 1px solid #000000;
  overflow: auto;
  display: block;
  overflow: hidden; /* To hide the scrollbar when you zoom in */
}

#zoom {
  transform:scale(1);
  transform-origin:top left;
}

#sam {
  transform: rotate(0deg)
  transform-origin: center center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<button type="button" id="zoom-in">zoom in</button> <button type="button" id="zoom-out">zoom out</button> 

<div id=imageblock>
  <div id="zoom"> <!-- I added this div -->
    <img  id="sam" src="http://placekitten.com/g/250/250" />
  </div>
</div>
<div>
  <a id="rotate" href="#">Rotate 90 degrees</a>
</div>

It's worth noting that there shouldn't be a comma in transform-origin: center center;.

If you have any questions, feel free to ask. Hopefully, this explanation has been helpful!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Runtime Error: Invalid source property detected - Firebase and Next.js collaboration issue

Currently, I am developing a Next.js application that retrieves data from a Firestore database. The database connection has been successfully established, and the data is populating the app. However, I am facing an issue with displaying the image {marketpl ...

Top solution for live chat between server and client using jQuery, Java, and PHP on a localhost setup

Seeking recommendations for the best chat solution to facilitate communication between client PCs and a server in my private network. Specifically interested in an Ajax/Java solution similar to the chat support feature found in GMail. ...

activated by selecting a radio button, with a bootstrap dropdown menu

I'm having trouble triggering the dropdown in Bootstrap by clicking on a radio button. It seems like a simple task, but I've been struggling with it all day. According to Bootstrap documentation, you can activate the dropdown using a hyperlink o ...

Python-JavaScript Integration Problem

I'm a beginner when it comes to Javascript, Python, and PHP. In my Javascript program, I have a button that triggers a Python script and displays the returned value on the screen. My goal is to steer clear of using Jquery and Json. Here are the snipp ...

Node.js - Creating seamless integration between Sequelize model JS and controller TS

Having trouble making my User.js model recognized inside my UserController.ts with sequelize in TypeScript. Edit: Unable to change the file extensions for these files. In the await User.findAll() part, an error occurs when running on the server, stating ...

Customize the theme of Ant Design for VueJS

I have successfully set up my Vue3 application with Tailwind and Ant Design. However, I am facing issues with customizing the Ant Design theme. I have been referring to this guide. When trying to customize the theme, I encountered the following error: Err ...

Aligning a element at the center is not functioning properly when using margin: 0 auto;

I'm having trouble aligning elements to the center when applying margin: 0 auto. You can view the code here: https://jsfiddle.net/helloworld123/vhhx1o7n/ The goal is to align the elements in the center of the page (.entry-wrap should be centered) and ...

Creating a custom route that is specific to a single ejs file

I'm trying to set up a URL like localhost:3000/hh234due with a unique ID that routes to a specific page. However, my current implementation is conflicting with other routes. How can I make the /:id route unique to one view? module.exports = fun ...

Having trouble with Angular UI Select functionality?

I have integrated the angular ui select library from https://github.com/angular-ui/ui-select into my project. Instead of using the traditional select element, I am now utilizing the ui-select directive. This is a snippet of my code: <select class=" ...

Ensure that the footer remains at the bottom of the page without being fixed to the bottom

I am currently working on configuring the footer placement on pages of my website that contain the main body content class ".interior-health-main". My goal is to have a sticky footer positioned at the very bottom of these pages in order to eliminate any wh ...

Displaying database values in an array within an HTML format

I need help displaying database values by replacing the $view['time'] with %time% using an array. For example, if $view['time']='8:00 pm';, then when I write %time% it should display 8:00 pm. It works for a single row, but w ...

Tips for submitting multiple radio button values in a tabular format

HTML Code: <div class="tab"><h4>Zip Code</h4> <p><input type="text" class="text1" placeholder="Enter zip code..." oninput="this.className = ''" name="zipcode"></p> </div> <div class="tab">& ...

Trouble displaying images from JSON file in AngularJS using ng-src - need help with image loading

While utilizing AngularJS to extract image data from a JSON file, everything seems to work fine for other types of data except images. Why is the ng-src not retrieving any images? I am attempting to load all the images into the div and set the src, alt, a ...

Google/StackExchange Menu Tab

I am interested in creating a navigation bar similar to Google's or StackExchange's new one, where it is always positioned at the top. It does not need to be fixed there, but I would like it to have links only. How can I achieve this layout with ...

Hover activates a CSS animation where elements pop over other elements

I want to design a menu that resembles those "apps panels" we often see. My menu consists of 6 elements, arranged side-by-side with no space between them. When I hover over an element, it slightly pops as shown in the code snippet below: #account-bub ...

The leaking of angular-material CSS onto other divs is causing unexpected styling

I am having trouble incorporating Angular Material's md-autocomplete into my angular application. I have already customized the CSS being used in my application, but when I add the Angular Material CSS, it messes up the entire page. Even when I tried ...

Steps for setting the value of a textbox within a bootstrap popover

When a user clicks on an Anchor element, I am displaying a Bootstrap popover using the following JQuery code. Jquery $("[data-toggle=popover]").popover({ trigger: 'click', placement: "top", html: true, ...

You are able to use a null type as an index in angular.ts(2538) error message occurred

onClick() { let obj = { fName: "ali", LName: "sarabi", age: "19", } let fieldName = prompt("field"); alert(obj[fieldName]); } I encountered an issue with the code above where alert(obj[fieldName] ...

divs placed next to each other

I'm facing an issue with 4 divs within a parent div. I've used float:left in the style of all 4 divs to display them side by side. Although the divs are appearing next to each other, the height of the parent div is not adjusting to accommodate th ...

What is the process for adding text before and after a Bootstrap progress bar?

I want to customize the bootstrap progress bar with text at the beginning and end, like this: 5 star ----------------------------------------------- 70% Here is my attempt to achieve this: <link rel="stylesheet" href="https ...