Center the popover over the element

I am in the process of creating a resource map using SVGs. My goal is to display a popover in the center of the element when a user clicks on it. However, due to CSS rotation of the map, the traditional techniques such as the one mentioned here have not been successful.

Below is the javascript code I am using:

Map.popup = function(e) {
    var rect = $(this);
    var offset = $(this).offset();

    var rectWidth = $(this).attr('width').replace(/[^-\d\.]/g, '');
    var rectHeight = $(this).attr('height').replace(/[^-\d\.]/g, '');

    var centerX = offset.left - rectWidth/2;
    var centerY = offset.top - rectHeight/2;

    $('.popup').css({
       'top' : centerY,
       'left' : centerX,
    });
}

Here is the markup:

    <div id="map">
    <svg width="1088px" height="1088px" xmlns="http://www.w3.org/2000/svg">
        <g transform="translate(288.0 32.0) rotate(45 256.0 512.0)">
            <!-- Add your rects here -->
        </g>
    </svg>
</div>

You can view the map and its positioning issue here.

If you have any suggestions on more accurate targeting of the center of each element, I would greatly appreciate it.

Answer №1

Pointed out by @sjm, there is a way to get the "real" height/width using getBoundingCliendRect(), but it may not work when applied on $(this).

Map.popup = function(e) {    
  var rect          = $(this);
      offset        = $(this).offset(),
      canvas        = document.getElementById(rect.prop('id')),
      rectWidth     = canvas.getBoundingClientRect().width,
      rectHeight    = canvas.getBoundingClientRect().height,
      popoverWidth  = 250,
      popoverHeight = $('.popup').height(),
      centerX       = offset.left - popoverWidth + rectWidth/2,
      centerY       = offset.top + rectHeight/2;

  $('.popup').css({
     'top' : centerY,
     'left' : centerX,
  });
}

Additionally, the calculations for centerX and centerY were incorrect. I've made the necessary corrections.

Cheers!

Answer №2

To start, it is essential to utilize getBoundingClientRect() method in order to obtain the precise width of the bounding region of the selected SVG Element following its rotation. Next, instead of subtracting, you should add half of this value to your offsets to ensure that the top left corner of your popup aligns with the center of the SVG element that was clicked.

In addition, by subtracting 250px (the width of the Popup Element) from the centerX calculation, the popup Arrow point (located at the top right) will properly center in the middle of the clicked element.

Updated code:

Map.popup = function(e) {
 var rect = $(this);
 var offset = $(this).offset();

 var rectWidth = $(this)[0].getBoundingClientRect().width;
 var rectHeight = $(this)[0].getBoundingClientRect().height;

 var centerX = offset.left + rectWidth/2 - 250;
 var centerY = offset.top + rectHeight/2;

 $('.popup').css({
   'top' : centerY,
   'left' : centerX,
 });
}

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

Utilizing preg_match in PHP to validate a textarea for alphanumeric characters, numeric values, and spaces

I've almost got everything working, but I'm stuck on how to utilize preg_match. I checked the manual here http://php.net/manual/en/function.preg-match.php, but it doesn't clearly explain the syntax for creating my own validation. For example ...

Accessing Rails controller information via a JavaScript AJAX request

In the process of developing a rails application, I have implemented code within the controller to interact with an API. Initially, I call the inventories endpoint, followed by separate calls to two other id endpoints (store_id and product_id) in order to ...

Using Styled Components to achieve full width for input tag in relation to its parent

I am working with an input field that has a specific width set. My goal is to increase the width of this input field to 100% by selecting it from its parent component. Is there a way to achieve this without passing an explicit width prop in the styled c ...

Developing a custom CSS for React using clamp and focus attributes

I'm currently working on creating an object to be used in inline style, but I'm having trouble figuring out how to correctly write `clamp` and `after`. const PhoneInputStyle = { fontSize: clamp("13px", "1.111vw", "16px"), /*this particular ...

Tips for adjusting the position of an infowindow in ArcGIS

I have implemented the use of infowindow in arcgis to display certain information. https://i.sstatic.net/Dnpas.jpg Currently, the infowindow is appearing directly over my icon. Is there a way to adjust its position if it covers the icon? ...

Bootstrap for a more streamlined container

https://i.sstatic.net/fJ8nt.png My Bootstrap setup includes a container-fluid with multiple cards inside. I want to adjust the container layout to stack the cards more closely together in a vertical direction, instead of being displayed in a grid format. ...

Resize a div within another div using overflow scroll and centering techniques

Currently, I am working on implementing a small feature but am facing difficulties with the scroll functionality. My goal is to zoom in on a specific div by scaling it using CSS: transform: scale(X,Y) The issue I am encountering lies in determining the c ...

Is the z-index functioning properly for the header call-to-action text on mobile devices, but not on desktop?

The desktop header cta is functioning properly, but when I switch to mobile nothing happens. I attempted to increase the z-index number within the html instead of in the style sheet. This is where my CTA is located in the html: CALL TO ACTION surrounded ...

Troubleshooting techniques for resolving CSS issues with the video.js package in ReactJS

When using video.js in react to build a video player, I encountered an issue with the npm package not providing its inbuilt CSS. How can I add the inbuilt CSS of video.js? Instead of the control bar, I am getting something different than what is shown in t ...

Patience is key when waiting for the outcome of an async Javascript function in order to obtain a result (Could it be

Hey there, I've been searching for a solution to my problem even though it's been discussed before. I'm trying to achieve something simple: creating a string like distance is : " + CalculateDistance(position);. The desired result should look ...

Modifying the dimensions of media:thumbnail in Blogger's RSS Feed

I came across this post, but it seems like there have been updates in the past 4 years regarding how thumbnails are generated for Blogger posts. I've attempted various methods, but so far none of them have been successful. If anyone could assist me in ...

Steps for styling an AngularJS Popup:1. Determine the desired appearance for

I have some code that displays a popup when clicked, along with its automatically generated CSS. I want to be able to make changes to the CSS by adding IDs or classes to it. How can I assign IDs or classes to this element so that I can easily target them f ...

Is it possible to implement hierarchical validation within reactflow nodes?

I am currently utilizing reactflow to establish a network of sequences, each possessing their own unique "levels." My primary objective is to restrict connections between sequences based on their respective levels. For instance, a level 5 sequence should ...

What is the method to define a function in express js that is accessible from all views?

Is there a way to develop a function within my Express JS MVC web application that can be accessed from any view? How can I define this function in middleware so it can be directly called from a view? I envision being able to use this function like: < ...

Alignment of inner div within the footer

I'm struggling to align my footer navigation inline with my footer title. Check out this code snippet to see what I've tried so far: https://jsfiddle.net/nkzsufov/ I experimented with using absolute and relative positioning: .footerNav { margi ...

Mastering Vuex: effectively managing intricate data structures and dynamic state transformations

Let's say I'm utilizing an external API that interacts with Machine objects. With the API, you can create a Machine using createMachine, resulting in a complex object with various nested properties and functions to modify its state. The API inclu ...

JSdom, automation, web scraping, handling dynamic iframes

I am currently in the process of automating my tasks on the website provided at the link below: I need to fill out forms and submit them automatically. So far, I have been successful in automating using Greasemonkey and I am now considering switching to ...

Servlet question: What causes the XMLHttpRequest responseText to consistently appear empty?

I've been going crazy trying to figure out how to solve this issue. I have a servlet deployed in Tomcat running on localhost:8080 that looks like this: @WebServlet(urlPatterns = { "/createcon" }, asyncSupported = true) public class CreateCon extends ...

The module script failed to load due to an unexpected response from the server, which was MIME type of text/jsx instead of a javascript module script

I have recently set up an express server and created an API, as well as installed React using Vite for my frontend. However, when I attempt to connect or load my main HTML file to the server, an error is displayed in the console. This is all new to me as I ...

Verify that JavaScript is capable of performing mathematical operations such as addition and multiplication successfully

When dealing with a specific set of "Strings" that represent integers in an addition operation, how can one determine if the calculation is feasible in javascript? For example: 2 + 2 (certainly possible) 20000000000000000 - 1 (impossible) 2e50 + 2e60 (i ...