<div id="root"></div>
.container {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    height: 90vh;
    width: 100%;
  }
  .center {
    align-self: center;
  }
  .top-left {
    align-self: flex-start;
  }
  .bot-right {
    align-self: flex-end;
  }
  .image {
    width: 150px;
    height: 130px;
  }

  .flip {
      transform: rotate(0.5turn);
  }
  
  .force-moveX {
    transition: transform 1s;
    transform: translate(0, 0) !important;
  }
  .force-moveY {
    transition: transform 1s;
    transition-delay: 1s;
    transform: translateY(0) !important;
  }
  
const FarmFig = ({ image, handleClick = null, setRef, locs, animClass }) => {
  return (
    <div
      className={`${animClass}X`}
      style={{
        transform: `translate(${locs[1]}px`,
      }}
    >
      <div
        className={`${animClass}Y`}
        style={{
          transform: `translateY(${locs[0]}px)`,
        }}
      >
        <img
          className={`image ${animClass}`}
          src={image}
          ref={setRef}
          onClick={handleClick}
        />
      </div>
    </div>
  );
};

class App extends React.Component {
  constructor() {
    super();
    this.center = React.createRef();
    this.state = {
      images: {
        tl:
     "https://lh3.googleusercontent.com/proxy/4CqxhghbTJ5NP49WTvdRtMRdR1DqiAVYesY0MvqqwmaGl_Vq9uwFhxKHb_Zh4pmzPIq8g5WkZmzD1ja3k_fc_DSDTZejwvE",
        c:
          "https://lh3.googleusercontent.com/proxy/Erix2ztSUVwc7gKZLH5i9T2gCWLhEuxF-Ix2J0Dfdx1hJpjQBBsQOgcrgIlxAu5D9L_zMHGykyFLhFx-10eZYVzzE_PK7Zg",
        br:
          "https://pngarchive.com/public/uploads/small/11559054782q4dsokodad1svijk1zzlyrjdwtmlygkkaxxvooeqevdyrbomu3b5vwcwst0ndcidr89gdf0nyleyffoncphgazeqmnpmdubfypow.png",
      },
      animate: true,
      transition: {
        center: {
          startTop: 0,
          startRight: 0,
        },
        corner: {
          farmItem: null,
          startTop: 0,
          startRight: 0,
        },
      },
    };
  }
  //find locatin of center image
  getCenterLoc = () => {
    const imageEndTop =
      this.center.current.getBoundingClientRect().top +
      document.documentElement.scrollTop;

    const imageEndRight =
      this.center.current.getBoundingClientRect().right +
      document.documentElement.scrollLeft;
    return [imageEndTop, imageEndRight];
  };

  handleClick = ({ target }) => {
    // find location of clicked image
    const imageStartTop =
      target.getBoundingClientRect().top + document.documentElement.scrollTop;

    const imageStartRight =
      target.getBoundingClientRect().right +
      document.documentElement.scrollLeft;

    //find ending location of clicked image
    let endLoc = this.getCenterLoc();
    let selectedImage;
    this.setState((prevState) => {
      //switch clicked image with the center image
      if (prevState.images.tl === target.src) {
        selectedImage = "tl";
        prevState.images.tl = prevState.images.c;
        prevState.images.c = target.src;
      } else {
        selectedImage = "br";
        prevState.images.br = prevState.images.c;
        prevState.images.c = target.src;
      }
      return {
        images: prevState.images,
        animate: false,
        transition: {
          center: {
            startTop: imageStartTop - endLoc[0],
            startRight: imageStartRight - endLoc[1],
          },
          corner: {
            farmItem: selectedImage,
            startTop: endLoc[0] - imageStartTop,
            startRight: endLoc[1] - imageStartRight,
          },
        },
      };
    });
    setTimeout(() => this.triggerAnim(), 200);
  };

  triggerAnim = () => {
    this.setState({ animate: true });
  };

  getOldLoc = (loc) => {
    const { corner } = this.state.transition;
    let top, right;
    if (corner.farmItem === loc) {
      top = corner.startTop;
      right = corner.startRight;
    } else {
      top = 0;
      right = 0;
    }
    return [top, right];
  };

  render() {
    const { tl, c, br } = this.state.images;
    const { center } = this.state.transition;
    const animClass = this.state.animate ? "force-move" : "";
    return (
      <div
        className="container"
        onClick={(e) => console.log(e.clientX, e.clientY)}
      >
        <div className="top-left">
          <FarmFig
            image={tl}
            handleClick={this.handleClick}
            locs={this.getOldLoc("tl")}
            animClass={animClass}
          />
        </div>
        <div className="center">
          <FarmFig
            image={c}
            setRef={this.center}
            locs={[center.startTop, center.startRight]}
            animClass={animClass}
          />
        </div>
        <div className="bot-right">
          <FarmFig
            image={br}
            handleClick={this.handleClick}
            locs={this.getOldLoc("br")}
            animClass={animClass}
          />
        </div>
      </div>
    );
  }
}
ReactDOM.render(<App />, document.getElementById("root"));
View Compiled

External CSS

  1. https://cdnjs.cloudflare.com/ajax/libs/bulma/0.0.16/css/bulma.min.css
  2. https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.1/css/bulma.min.css

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/react/16.8.1/umd/react.production.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.1/umd/react-dom.production.min.js
  3. https://cdnjs.cloudflare.com/ajax/libs/react-is/17.0.1/umd/react-is.production.min.js