What is the best way to smoothly move a fixed-size div from one container to another during a re-render process?

Introduction

Anticipated change

Similar, though not identical to my scenario:

  1. Situation 0: Imagine you have a container (chessboard with divs for game pieces) and a dead-pieces-view (container for defeated pieces). The positioning of these containers is determined by CSS rules and device/media parameters, managed by the browser.
  2. Situation 1: A piece is captured and needs to be smoothly transitioned from the board to the dead-pieces view in the correct location.

I can accurately identify the moving divs using unique ids/keys.

Additional Requirements: I am using React, so I anticipate that the smooth transition can be achieved simply by updating the rendering from State0 to State1. (Or, at the very least, with minimal imperative code additions)

Here is a link to my sandbox project: https://codesandbox.io/s/crazy-pasteur-lr4ku

Prior Attempts:

  1. I experimented with using react keys and ids to track the moving div. However, the issue was not specific to React; even manual movement of the div using pure JS (appendChild) did not result in a smooth transition.
  2. I also attempted to use react-pose as it seemed like a potential solution. Unfortunately, it appeared to be limited to animating ul/li elements exclusively, while other animated elements on the page remained independent from one another (or perhaps I did not fully explore the framework's capabilities).

Answer №1

I stumbled upon a concept that seems like it could be a good fit for my needs.

Abstract:

When div1 changes position to div1', I immediately kill div1 while smoothly animating the transition of div1' from its last known place using keyframes, with 1 iteration.

Technical:

In React: componentWillUnmount saves the current position of the uniquely identified element.

In React: componentDidMount calculates the difference, creates an animation on the fly, and uses setState to re-render with the animation.

Unfortunately, this approach requires some global states and other anti-patterns, but it does the trick.

Working example(based on question): https://codesandbox.io/s/muddy-hill-ti6bs

Key points:

  1. No absolute positioning is used anywhere
  2. The containers resize according to CSS properties when the page/browser/viewport is resized
  3. The target div smoothly moves to its new spot upon re-render, even if the previous animation was interrupted.

Answer №2

It is important to:

  • Maintain consistency in the parent element during re-renders in order to prevent React from creating/deleting a new child. To achieve this, the parent container must have a persistent key value such as
    key: idx === parentContainer ? "withBlock" : idx
    .
  • Ensure there is a transitionable property available, like setting position: absolute in the styles and allowing modification of the top value.

Once these conditions are met, you can update the transitionable property after each render by utilizing the following code snippet:

const Block = () => {
  const ref = useRef();
  useEffect(() => {
    if (!ref.current) {
      return;
    }
    const el = ref.current;
    const {top} = el.parentNode.getBoundingClientRect();
    el.style.top = `${top + border}px`;
  });
  return <div className="block" ref={ref} />;
};

https://codesandbox.io/s/busy-mendeleev-7s2zg

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

There seems to be an issue with npm displaying an inaccurate version number for my

In brief: The version of my module on npmjs.org doesn't match the version in package.json. Why? I have a JavaScript module that I released on npm and bower: https://github.com/Offirmo/network-constants.js It has a package.json for npm and a bower.js ...

Javascript Google Maps API is not working properly when trying to load the Gmap via a Json

Trying to display a map using Gmaps and Jquery Ajax through JSON, but encountering difficulty in getting the map to appear on the page. The correct coordinates are being retrieved as confirmed by testing in the console. Puzzled by why it's not showin ...

Exploring React-Query's Search Feature

Looking for guidance on optimizing my Product search implementation using react-query. The current solution is functional but could be streamlined. Any suggestions on simplifying this with react-query would be greatly appreciated. import { useEffect, use ...

Smooth scrolling in JavaScript can lead to unexpected jumps when using scroll-margin-top

I am currently working on implementing smooth scrolling into my website using JavaScript. However, I have run into a problem with CSS property scroll-margin-top causing a sudden jump at the end. The CSS I am using for scroll margins looks like this: class ...

Arranging column contents neatly on small screens

Although there are similar answers available, I want to address those who are trying to prevent their columns from stacking on XS display. Despite having two columns, the content is still stacking at certain displays. This issue is occurring while using B ...

Issues with Ajax calls not functioning properly within CakePHP

I'm attempting to make an AJAX request in CakePHP. The submit button is marked as #enviar and the action as pages/contato. This is the code for my AJAX request: $(document).ready(function() { $('#enviar').click(function(){ $. ...

What is the process to subscribe and obtain data from a server-to-user channel using pusher-js?

I am currently hosting my application using next.js on Vercel. I want to integrate Pusher to provide real-time messages to users in a private and secure manner. Despite successful log entries, I am facing challenges in subscribing to the channel and retrie ...

"I'm curious about how to reset a form in reactjs hooks after it has been submitted

Just dipped my toes into the world of hooks and I'm stumped on how to clear input fields post-submit. Tried form.reset() but it's not doing the trick. import { useForm } from "react-hook-form"; import.... export default function AddUse ...

What is the best way to toggle the visibility of a dynamically created HTML element in ASP.NET?

I'm working on a program that displays two different prices depending on whether the user is registered or not. Registered users will see both the normal price and the discounted price, while unregistered users will only see the normal price. I need t ...

I am unable to access the state after setting it in useEffect in React. Why is this happening?

After rendering the component, I utilize socket io to send a socket emit in order to fetch data within the useEffect hook. Subsequently, I also listen for the data that is returned. However, upon receiving the data back from the socket, I update the stat ...

Ensuring proper alignment of images and text in HTML when resizing

Trying to show an image and text side by side, I'm using the following code: div.out { background-color: silver; border: 1px solid black; padding: 10px; display: flex; } div.right { order: 1; background-color: white; border: 1px soli ...

What is the best way to implement fontSize on CardHeader title using Material UI?

I am facing an issue where I am trying to adjust the font size of the title within CardHeader to 16px. Despite my attempts to modify the theme in App.js, it doesn't seem to have any effect. const theme = createMuiTheme({ typography: { useNextVar ...

Looking to create cascading dropdown options

I am working on a form that includes 3 dropdowns with the same options listed below: <select id="one"> <option value="1">Select</option> <option value="1">One</option> <option value="2">Two</option> <option val ...

Issue encountered while incorporating a PHP file into Javascript code

I'm facing a particular issue where I have a PHP file that is supposed to provide me with a JSON object for display in my HTML file. Everything seems to be working fine as I am receiving an output that resembles a JSON object. Here's the PHP file ...

Resetting ajax success message when modal is closed

Currently utilizing w3.css and its modal feature, I am encountering an issue with clearing the message displayed after a successful ajax call once the window is closed. Even though I have implemented code to clear the message upon closing the window (by cl ...

Guide on integrating a php script into a react application

I'm currently in the process of setting up a functional contact form on my website by following the guidance provided in this article link. However, the tutorial includes a php script to manage the post data, and I am using create-react-app and unsure ...

Exploring CSS3 animations: customizing animations for individual elements based on scroll movements

Can you help me with CSS3 animations triggered by scrolling? I came across a code that reveals a DIV element as the user scrolls down: <script type="text/javascript"> $(document).ready(function() { /* Every time the window ...

Steps for populating a dropdown list with a JSON response

I'm facing a challenge in inserting server data into a dropdown list because each object name begins with a random ID. Here's what I'm attempting to achieve here: $("#CampaignOpenActionSubscriber_campaign_id").change(function() { var el ...

Adjust the dimensions of the MaterialUI Switch component manually

Struggling to resize a Material-UI Switch as the default size isn't suitable. Managed to increase the size, but now the behavior isn't ideal. It looks fine in its default state: However, when changing its state, it loses style: Unable to figu ...

The placement of term.js is always at the bottom of the body

Seeking help with JavaScript as a beginner, I am facing issues with placing an element in my project. Although I can easily open terminals and write to them, every time I create one, it gets appended at the end of the body. I referred to this example for ...