Coordinates of HTML elements corners after rotation

Seeking to obtain the XY coordinates of an HTML element in order to accurately calculate the physical distance, in pixels, from the corners of a rotated element relative to another element.

In this code snippet, I am attempting to determine the distance from the top-left corner of the inner div to the center of the outer div. However, I only have access to the Left and Top values of a non-rotated div. Is there a way to retrieve these coordinates for the rotated div, either in relation to the viewport or another element?

I have experimented with using getBoundingClientRect(), but it provides a larger rectangle and incorrect coordinates as it encompasses the complete rotated div vertically.

Therefore, I am seeking guidance on how to accurately retrieve these coordinates.

document.getElementById('outRotated').innerHTML = clacDistancCornerCenter() + "  Rotated distance of corner to center: "


function clacDistancCornerCenter() {
  var outer = document.getElementById('outer');
  var inner = document.getElementById('inner');

  var centerX = outer.offsetWidth / 2;
  var centerY = outer.offsetHeight / 2;


  var innersCornerX = outer.offsetLeft;
  var innersCornerY = outer.offsetTop;

  //distance formula -> d = sqrt( pow( x2 - x1)  + pow( y2 - y1) )

  var distance = Math.sqrt(Math.pow(centerX - innersCornerX, 2) + Math.pow(centerY - innersCornerY, 2));

  return distance;
}

function calcDistHorizontal() {
  $('div').css('transform', 'rotate(0deg)');
  document.getElementById('outHorizontal').innerHTML = clacDistancCornerCenter()+ "  This Should be differnt when horizontal: ";
}
div {
  top: 15%;
  left: 20%;
  width: 50%;
  height: 50%;
  border: 1px solid black;
  position: absolute;
  display: block;
  transform: rotate(25deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="outRotated"> </p>
<p id="outHorizontal"> </p>

<button onclick="calcDistHorizontal()">Distance Horizontal</button>

<div id="outer">
  <div id="mid">
    <div id="inner">
    </div>
  </div>
</div>

Answer №1

My solution involves a straightforward approach without any additional mathematical calculations. I simply create a new element with a width of 0px to act as a reference point. Placing it in the desired corner, I then use getBoundingClientRect() to obtain the viewport coordinates. This method returns a rectangle object with top, bottom, left, and right values relative to the screen's viewport. Since the point element has 0 width and height, the top is equal to the bottom, and the left is equal to the right.

clacDistancCornerCenter();


function clacDistancCornerCenter() {
  var center = document.getElementById('center').getBoundingClientRect();
  var corner = document.getElementById('corner').getBoundingClientRect();

  //alert("left =" + center.left + "top =" + center.top + "right =" + center.right + "bottom =" + center.bottom);

  var centerX = center.left;
  var centerY = center.top;


  var innersCornerX = corner.left;
  var innersCornerY = corner.top;

  //distance formula -> d = sqrt( pow( x2 - x1)  + pow( y2 - y1) )

  var distance = Math.sqrt(Math.pow(centerX - innersCornerX, 2) + Math.pow(centerY - innersCornerY, 2));

  document.getElementById('outRotated').innerHTML = "Distance center to corner: "+ distance;
}

function horizontal() {

  $('div').css('transform', 'rotate(0deg)');

}


function relocate(top, left) {
  var point = document.getElementById('corner');
  if (top) {
    point.style.bottom = 'auto';
    point.style.top = 0;
  } else {
    point.style.top = 'auto';
    point.style.bottom = 0;

  }

  if (left) {
    point.style.right = 'auto';
    point.style.left = 0;
  } else {
    point.style.left = 'auto';
    point.style.right = 0;
  }
  clacDistancCornerCenter();
}
div {
  top: 15%;
  left: 20%;
  width: 50%;
  height: 50%;
  border: 1px solid black;
  position: absolute;
  display: block;
  transform: rotate(25deg);
}
.point {
  width: 7px;
  height: 7px;
  background-color: blue;
  //border:3px solid blue;
  position: absolute;
  display: block;
}
#center {
  left: 50%;
  top: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="outRotated"></p>
<p id="outRotated"> Set points width and height to 0 to get the actual correct distance. For now the points are large for easy understanding</p>

<br/>
<button onclick="relocate(true,true)">Top Left</button>-------
<button onclick="relocate(true,false)">Top Right</button>
<br/>
<button onclick="relocate(false,true)">Bottom Left</button>
<button onclick="relocate(false,false)">Bottom Right</button>
<br/>
<button onclick="horizontal()">Horizontal</button>

<div id="outer">
  <span id="center" class="point" onclick="outputXY()"></span>
  <div id="mid">
    <div id="inner">
      <span id="corner" class="point" onclick="outputXY()"></span>
    </div>
  </div>
</div>

Answer №2

One way to achieve this using any css 2d transform is by utilizing getComputedStyle and extracting the transformed coordinates from the transform matrix.

function calculateTransformedPoint(element, point)
{
    var style = getComputedStyle(element);
    var transformOrigin = style.transformOrigin.split(' ').map(function(item)
    {
        // Strip 'px' and convert to number
        return +item.slice(0,-2);
    });
    var p = [point[0] - transformOrigin[0], point[1] - transformOrigin[1]];
    var transform = style.transform;
    // Matrix
    var matrix = [];
    if(transform.slice(0,7) === 'matrix(')
        matrix = transform.slice(7,-1).split(',').map(function(item){ return +item; });
    else
    {
        // 'matrix3d('
        var temp = transform.slice(9,-1).split(',');
        matrix = [
            +temp[0],
            +temp[1],
            +temp[4],
            +temp[5],
            +temp[12],
            +temp[13]
        ];
    }
    // Matrix multiplication
    return [
        p[0] * matrix[0] + p[1] * matrix[2] + matrix[4] + transformOrigin[0],
        p[0] * matrix[1] + p[1] * matrix[3] + matrix[5] + transformOrigin[1]
    ];
}

Example of how to use this function

Answer №3

Geometry!

Imagine having a Vector class in your codebase with x and y properties. You could implement the following method to calculate the new XY coordinates after rotation:

vA.calculateRotatedVector = function(vB, angle){
   angle = angle*Math.PI/180;
   return new Vector( (Math.cos(angle) * (this.x - vB.x)
                     - Math.sin(angle) * (this.y - vB.y) + vB.x),
                      (Math.sin(angle) * (this.x - vB.x) 
                     + Math.cos(angle) * (this.y - vB.y) + vB.y) );
};

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

What is the best way to merge two interfaces and convert all of their fields to optional properties?

I have two unalterable interfaces: interface Person { name: string; age: number; } interface User { username: string; password: string; } I aim to merge them into a single interface called Player // please, adjust this code accordingly interfac ...

PHP for Calculating Time to Percentage

I have a question that may seem simple, but I'm unsure how to convert the time difference between two dates into a percentage. Currently, I am utilizing a JQuery plugin available at: The specific script on the page responsible for calculating the pe ...

Tips on transmitting form information from client-side JavaScript to server-side JavaScript with Node.js

Having created an HTML page with a form, my goal is to capture user input and store it in a JSON file. However, I've run into some confusion... In the process, I utilized the express module to set up a server. My mind is juggling concepts such as AJA ...

Append a constant string to the conclusion of the route parameter

Using React Router v6.4.1, I am aiming for a consistent conclusion to a series of dynamic routes. Specifically, I want my product detail routes to always end with "-product". For example, if the path is "/shaver-900-product", it should activate my Produc ...

Implement a feature in JSP that allows users to dynamically add or remove fields before submitting the data to the database

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http- ...

"Position the label on the left and input on the right for

Having trouble with label and input alignment - I've attempted: <div class="form-group"> <label class="control-label" for="" style="float: left;font-size: 20px;padding-right: 10px;">ID : </label> <input style= ...

Create a jQuery datatable row using data from an internal array

Received a JSON response from the server: { "data": [{ "id": 1, "apiKey": "test1", "name": [{ "identifier": "1", "status": "Online" }, { "identifier": "2", "status ...

Concealing a div based on empty textboxes using backbone and javascript

I need assistance with displaying or hiding a div based on the length of text boxes. My project is structured using Backbone, so I am unsure about where to insert the code.. Here is my current code; <input type="text" id="txtUsername" placeholder="use ...

Unable to generate this QUIZ (JavaScript, HTML)

Hi there, I'm working on a sample quiz and having trouble displaying the result. As a coding newbie, I could really use some help. In this quiz, users answer questions and based on their responses, I want to display whether they are conservative, agg ...

Populate List Items until Maximum Capacity is Reached and Increase the

Is there a way to make a ListItem fill the list vertically while also being able to overflow it if needed? I'm looking for a solution that would allow me to access the height of the empty space in the list, which I believe would be the minHeight. Som ...

eliminate the script and HTML comment from a designated division

Here is the default code that I need to modify using JavaScript to remove scripts, comments, and some text specifically from this div: I came across this script that removes all scripts, but I only want to remove specific ones from this div: $('scri ...

What is the best way to retrieve the value from a textarea and verify if it is blank or not?

I have successfully incorporated a textarea using simpleMde, but I am facing difficulty in retrieving the value and checking whether it is empty or not. var message = document.getElementById("simpleMde").value; console.log(message); <textarea class=" ...

Working with extensive amounts of HTML in JavaScript

Is there a way to dynamically load large amounts of HTML content in JavaScript? I'm struggling to figure out how to insert all the HTML content into the designated space within the JavaScript code. If anyone knows a different approach or solution, ple ...

Leveraging JavaScript code repeatedly

Apologies if this question has been asked before, as I couldn't find it. I have an HTML table with images used as buttons: <td> <button class="trigger"> <img src="D:\Elly Research\ CO2858\Presentation\Calypso ...

Internet Explorer does not recognize window.opener.location as valid, while there are no issues with Chrome

Response.Write("<script language='javascript'>alert(window.opener.location.pathname); if(window.opener.location.pathname.toString() == \"/page.aspx\"){window.opener.document.forms[0].submit();}</script>"); While this code w ...

Accessing the value of a hidden field within an ng-repeat loop when binding to an HTML table

I am working on a project where I have an HTML table with data being bound from AngularJS. The structure looks something like this: <tr ng-repeat="item in List| filter: { MachineType: 'Physical' }"> <td>{{item.MachineType}}< ...

Utilizing key values to access an array and generate a list of items in React.js

This marks my initiation on Stack Overflow, and I extend an apology in advance for any lack of clarity in my explanation due to unfamiliarity with the platform. My current task involves creating a resume with a dynamic worklist feature on my website. The ...

Blend express router by chaining the (.route) method with other HTTP methods like (.get, .post, etc) to create

Here is my code structure: let router = require( 'express' ).Router(); Later on, I define my routes like this: router .route( '/' ) .get( listMiddleware ); router .route( '/:id' ) .get( getOneByIdMiddleware ...

Adding the expanded search icon to a text box in Vuetify: A step-by-step guide

Recently, I integrated Vuetifyjs into my right-to-left (RTL) Vue 2 project. Within a card element, I inserted a table and included a search bar following the documentation. Now, I have two specific goals in mind: Relocate the "number of items to show" opt ...

Instructions on displaying the filename as the input for width and height dimensions

Running into an issue with Bootstrap 4 - whenever I try to upload a file with a long name, it ends up overflowing beyond the input field. ...