JSFiddle - React, Tailwind, and code Playground

HTML

<div id="cntnt" class="grid" style="10000px;">
<textarea id="txt" onchange="build()" style="width: 90vw; height: 90vh;">
$( '.post__image-link' ).toArray().map( a => a.href ).join(', ')

В консоли браузера на странице Нуботреда выполнить вон ту ⬆ строку и скопировать сюда полученный текст — массив ссылок на картинки, почистить от ненужных ссылок.
Потом щёлкнуть мимо текстового поля ввода.
Двумя щелчками картинки перемещаются в конец.
</textarea>
</div>

CSS

*{transition:all 0.2s linear;}
.group{
  display: inline-block;
  box-shadow: inset 0 0 20px #004;
  text-align: center;
}
.selected{
  transform: scale(0.8);
  box-shadow: 0 0 20px 3px #800;
}
img{
  height: 400px;
  margin: 5px;
}
.grid img{
  margin: 0;
}

JavaScript

function qf( s, f, n ) { return s=[...(n||document).querySelectorAll(s)],f?s.map(f):s }
function qs( s, n ) { return (n||document).querySelector(s) }
function wr( e, t ) { e.innerHTML = t }
function debounce( f, delay = 50, ...b ) {
  let t;
  return function( ...a ) {
    clearTimeout( t );
    t = setTimeout( f, delay, ...b, ...a );
  }
}
function delayed( f, ...b ) {
  let t;
  return function( delay = 50, ...a ) {
    clearTimeout( t );
    t = setTimeout( f, delay, ...b, ...a );
  }
}
function getel( ev, tag = 'IMG' ) { return ev?.target.tagName === tag && ev.target }
function moveve( c, a, b ) {
  if( !c ) return;
  a.forEach( a => {
    if( ! a?.tagName ) return;
    let p = a.parentNode;
    if( p?.parentNode === b ) b.insertBefore( a, p );
    else if( c !== b ) c.append( a );
    if( p.childNodes.length === 0 ) p.remove();
  } );
}
function wrapel( e ) {
  let p = e.parentNode;
  if( !p ) return;
  if( !p.classList.contains( 'group' ) ) {
    const d = document.createElement( 'div' );
    d.className = "group";
    p.insertBefore( d, e );
    d.append( e );
    p = d;
  }
  return p;
}
function build() {
  wr(
    cntnt,
    qs('#txt').value.replace( /^\W+|\W+$/g, '').split(',')
      .map(s=>'<img src="'+s+'" class="grid-item">').join('')
  );
}

const { body } = document;
const images = new Set();
const cntnt = qs('#cntnt');
let droponimg, dropondiv;
body.ondblclick = ev => {
  ev = getel( ev );
  ( ev.parentNode === body ? cntnt : body ).append( ev );
}
body.ondragstart = ev => {
  holdsel();
}
body.ondragenter = ev => {
  droponimg = getel( ev );
  dropondiv = getel( ev, 'DIV' );
}
body.ondragend = ev => {
  images.add( getel( ev ) );
  moveve( wrapel( droponimg ) || dropondiv, images, dropondiv );
  images.forEach( imgsel );
}
const holdsel = delayed( imgsel );
body.onmousedown = ev => holdsel( 200, getel( ev ) );
body.onmouseup = ev => holdsel();
function imgsel( e ) {
  if( !e ) return;
  if( images.has( e ) ) {
    images.delete( e );
  }else{
 ...