Try implementing transform translate with absolute coordinates when positioning elements on a webpage

If I wanted to create a box that moves along with the mouse cursor, I could achieve that using the code below.

document.addEventListener('mousemove', (e) => {
    document.documentElement.style.setProperty('--mouse-x', e.clientX + 'px');
    document.documentElement.style.setProperty('--mouse-y', e.clientY + 'px');
});
.box {
  width: 50px;
  height: 50px;
  
  background-color: blue;
  
  transform: translate(calc(var(--mouse-x) - 50%), calc(var(--mouse-y) - 50%));
}
<div class="box"></div>

However, if the element is not positioned at the top left corner, this method will no longer work as expected.

document.addEventListener('mousemove', (e) => {
    document.documentElement.style.setProperty('--mouse-x', e.clientX + 'px');
    document.documentElement.style.setProperty('--mouse-y', e.clientY + 'px');
});
.box {
  width: 50px;
  height: 50px;
  
  margin-left: 150px;
  
  background-color: blue;
  
  transform: translate(calc(var(--mouse-x) - 50%), calc(var(--mouse-y) - 50%));
}
<div class="box"></div>

I am looking for a way to use absolute coordinates in conjunction with a CSS transform without disrupting the flow of elements. One approach could be to calculate the central position of the element dynamically through JavaScript.

document.addEventListener('mousemove', (e) => {
    document.documentElement.style.setProperty('--mouse-x', e.clientX + 'px');
    document.documentElement.style.setProperty('--mouse-y', e.clientY + 'px');
});

window.addEventListener('load', (e) => {
    const box = document.querySelector('.box');
    const rect = box.getBoundingClientRect();
    box.setAttribute('style', `
      --center-x: ${rect.left + (rect.width / 2)}px;
      --center-y: ${rect.top + (rect.height / 2)}px;
    `);
});
.box {
  width: 50px;
  height: 50px;
  
  margin-left: 150px;
  
  background-color: blue;
  
  transform: translate(calc(var(--mouse-x) - var(--center-x)), calc(var(--mouse-y) - var(--center-y)));
}
<div class="box"></div>

Although this solution works, it is not perfect and can easily be disrupted by changes on the page. Additionally, performance may suffer when multiple elements are involved. Is there a more efficient method to accomplish this task using CSS or Vanilla JS?

Answer №1

Instead of using translate(), I suggest utilizing the left and top properties in CSS to position an element based on coordinates.

window.addEventListener('load', (e) => {
    const box = document.querySelector('.box');
    const rect = box.getBoundingClientRect();
    document.addEventListener('mousemove', (e) => {
    box.style.left = e.pageX + 'px';
    box.style.top = e.pageY + 'px';
});
});
.box {
  width: 50px;
  height: 50px;
  position:absolute;
  transform:translate(-50%,-50%);
  background-color: blue;
}
<div class="box"></div>

The transform: translate() property adjusts relative to the size of the box, whereas the left and top properties do not. Additionally, using left and top can be more efficient as it avoids unnecessary calculations that were present in your previous code. This method offers a simpler and faster solution.

Answer №2

Utilizing the requestAnimationFrame() function can be a helpful solution. This method informs the browser of your intention to execute an animation, prompting the browser to call a specified function for updating an animation before the next repaint. With higher refresh rate monitors, this function will be executed more frequently to align with the monitor's refresh rate.

For more details, visit this link

Here is the functional implementation:

const box = document.querySelector('.box');
const rect = box.getBoundingClientRect();
let mouseX = 0;
let mouseY = 0
document.addEventListener('mousemove', (e) => {
  mouseX = e.pageX + 'px';
  mouseY = e.pageY + 'px';
})

function mouseMove() {
  box.style.left = mouseX;
  box.style.top = mouseY;
  requestAnimationFrame(mouseMove)
};
mouseMove()
.box {
  width: 50px;
  height: 50px;
  position: absolute;
  transform: translate(-50%, -50%);
  background-color: blue;
}
<div class="box"></div>

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

Rotating Social Media Symbols - bootstrap 4

I am looking to incorporate a Social Button Footer similar to the one in this CodePen example: (https://codepen.io/vpdemo/pen/WbMNJv). However, my buttons are not appearing as circles. How can I rectify this? a, a:hover { text-decoration: none; } .soc ...

Exploring Navigation in AngularJS with ui-router

I've encountered an issue with ui-router functionality in my code. Here's a breakdown of the problem: Within my index.html file <li> <a ui-sref="day2">Day 2</a> </li> <li><a ui-sref="day3">Day 3</a& ...

How can you use JavaScript to retrieve the position of an element on a webpage?

As mentioned in the title, I am looking for a way to retrieve the x and y positions of an element relative to its location on the webpage and based on its positioning schemes such as absolute or relative. ...

Having trouble with accessing properties like `d3.svg()`, `d3.scale()` and other features of d3js within an Angular 2 environment

Struggling to incorporate d3.js into angular2. Below is the command I used to install d3 in Angular2: npm install --save d3 install --save-dev @types/d3 This is how my package.json appears: { "name": "my-app", "version": "0.0.0", "license": "M ...

error : failed to establish a connection to the MongoDB database

Ensure that the first parameter passed to mongoose.connect() or mongoose.createConnection() is a string. MongooseError: The uri parameter for openUri() must be a string, but it was "undefined". Double check that the initial parameter for mongoose.connect() ...

Tips for executing a jQuery function on multiple sets of elements

Currently, I have a list with all items sharing the same class name. There is a jQuery plugin that identifies the tallest element and sets the height of all list items to match the tallest one. My goal is to run this method for each UL group individually. ...

Interactive Gridview feature enables users to rearrange data elements easily by dragging and dropping them into desired

Currently, I am working on a sample project involving the drag and drop functionality of a grid view that allows users to reorder data. My main challenge is figuring out how to retrieve the data from the first column in the order that the user has changed ...

I am attempting to retrieve the information entered into the textbox, search for it within my database, and display the results beneath the textbox for reference

<!----- fetchCedulaData.php This script retrieves data from the database and performs a search to return results ---------------------------- - --> <?php require("connection.php"); $cedula=$_REQUEST["cedula"]; //$cedula="0922615646"; echo $cedu ...

Validation of nested phone numbers using jQuery

I'm trying to figure out how to incorporate the jQuery validation plug-in into a multi-step form where validation occurs on each step as the user progresses. I know that typically, the validation plug-in is triggered by a submit request, but in this c ...

Is there a way to rearrange html elements using media queries?

Here is a snippet of code showcasing how my website is structured for both desktop and mobile views. Display on Desktop <body> <div> <header> <div>example</div> <a><img src"my logo is here"/& ...

Why does it display 'Undefined' when I attempt to access an object in an array in Next.js?

I am currently working on a way to display sub Products related to the main product. I have attempted to extract the product code from the URL and then retrieve sub-products that correspond to the main product code. List of Products and Sub products const ...

What's the trick to making a column that's 2/3 wide in a 34grid layout?

Is it possible to use the 34 Responsive Grid system to create a column that takes up two-thirds of the full width? Although the Grid System has equal columns settings, I'm curious how to combine or merge two columns together? <div class="containe ...

Implementing a click event listener on an iframe that has been dynamically generated within another iframe

Below is the code I used to attach a click event to an iframe: $("#myframe").load(function() { $(this.contentWindow.document).on('click', function() { alert("It's working properly"); }); }) Everything seems to be working co ...

Browser fails to display input value when altered

I have noticed that when the value of the Input element changes, the browser does not display the updated value. However, you can verify this change by inspecting the DevTools in the browser. I am curious as to why the actual value of the Input element is ...

Menu items on the responsive design are vanishing

I am facing an issue with my sample menu layout. It appears fine on desktop view, but when I switch to a smaller window size of 480px, the items from About to Contact disappear when I hover away from the last item in the .has-children class. It seems like ...

Ensuring that the content fits perfectly inside a div using either Bootstrap or

I am facing an issue with two nested divs. One of them has a button that I want to stick to the bottom of the parent div, while the other contains text or a list of persons. The problem arises when the text is lengthy, causing it to overflow the div. I am ...

Modify CSS image according to the user interface language in asp.net

Is there a way to dynamically change the image based on different cultures in my ASP.NET webpage? I have successfully been able to switch strings using a resource file, but I am unsure how to handle images. Currently, I have an A tag with a specific clas ...

Is it possible to incorporate a combination of es5 and es2015 features in an AngularJS application?

In my workplace, we have a large AngularJS application written in ES5 that is scheduled for migration soon. Rather than jumping straight to a new JS framework like Angular 2+ or React, I am considering taking the first step by migrating the current app to ...

Using AngularJS to extract values from deeply nested JSON structures

I'm currently navigating through a nested JSON object and I'm facing challenges in accessing the sub items within it. Below is a snippet of the JSON file I'm working with. It has successfully passed the JSONLint test, so it should be in pro ...

What is the functionality of Vue plugins in Vite MPAs?

I have developed a Vite application and I am trying to implement multiple pages. I followed the documentation on how to achieve this (link here), but when I start the server, all I see is a blank page. This is what my vite.config.js file looks like: impor ...