Crear una galería de imágenes (carrusel) infinita con React

Tiempo de lectura: 2 minutos

Voy a compartir con todos un componente de Galería Infinita de imágenes o carrusel.

Lo llamaremos «InfiniteGallery». Muestra imágenes de manera infinita en una galería. Además, incorpora la capacidad de arrastrar y soltar las imágenes para reorganizarlas. Este componente utiliza las bibliotecas react-dnd y react-dnd-html5-backend para la funcionalidad de arrastrar y soltar.

Primero hay que instalar las bibliotecas:

npm install react-dnd react-dnd-html5-backend --save

Ahora creamos nuestro componente, al que llamamos InfiniteGallery.tsx

import React, { useState } from 'react';
import { useDrag, useDrop, DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';

interface Image {
  id: number;
  src: string;
}

interface InfiniteGalleryProps {
  images: Image[];
}

const DraggableImage: React.FC<{
  image: Image;
  index: number;
  moveImage: (dragIndex: number, hoverIndex: number) => void;
}> = ({ image, index, moveImage }) => {
  const [, drag] = useDrag({
    item: { type: 'IMAGE', index },
  });

  const [, drop] = useDrop({
    accept: 'IMAGE',
    hover: (draggedItem: { index: number }) => {
      if (draggedItem.index !== index) {
        moveImage(draggedItem.index, index);
        draggedItem.index = index;
      }
    },
  });

  return (
    <div ref={(node) => drag(drop(node))} style={{ width: '100px', margin: '5px', cursor: 'move' }}>
      <img src={image.src} alt={`Image ${image.id}`} style={{ width: '100%', height: '100%' }} />
    </div>
  );
};

const InfiniteGallery: React.FC<InfiniteGalleryProps> = ({ images }) => {
  const [galleryImages, setGalleryImages] = useState(images);

  const moveImage = (dragIndex: number, hoverIndex: number) => {
    const updatedImages = [...galleryImages];
    const draggedImage = updatedImages[dragIndex];

    updatedImages.splice(dragIndex, 1);
    updatedImages.splice(hoverIndex, 0, draggedImage);

    setGalleryImages(updatedImages);
  };

  return (
    <DndProvider backend={HTML5Backend}>
      <div style={{ display: 'flex', flexWrap: 'wrap' }}>
        {galleryImages.map((image, index) => (
          <DraggableImage key={image.id} image={image} index={index} moveImage={moveImage} />
        ))}
      </div>
    </DndProvider>
  );
};

export default InfiniteGallery;

Si queremos el componente en Javascript, lo llamaremos InfiniteGallery.js

import React, { useState } from 'react';
import { useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';

const DraggableImage = ({ image, index, moveImage }) => {
  const [, drag] = useDrag({
    item: { type: 'IMAGE', index },
  });

  const [, drop] = useDrop({
    accept: 'IMAGE',
    hover: (draggedItem) => {
      if (draggedItem.index !== index) {
        moveImage(draggedItem.index, index);
        draggedItem.index = index;
      }
    },
  });

  return (
    <div ref={(node) => drag(drop(node))} style={{ width: '100px', margin: '5px', cursor: 'move' }}>
      <img src={image.src} alt={`Image ${image.id}`} style={{ width: '100%', height: '100%' }} />
    </div>
  );
};

const InfiniteGallery = ({ images }) => {
  const [galleryImages, setGalleryImages] = useState(images);

  const moveImage = (dragIndex, hoverIndex) => {
    const updatedImages = [...galleryImages];
    const draggedImage = updatedImages[dragIndex];

    updatedImages.splice(dragIndex, 1);
    updatedImages.splice(hoverIndex, 0, draggedImage);

    setGalleryImages(updatedImages);
  };

  return (
    <div style={{ display: 'flex', flexWrap: 'wrap' }}>
      {galleryImages.map((image, index) => (
        <DraggableImage key={image.id} image={image} index={index} moveImage={moveImage} />
      ))}
    </div>
  );
};

export default InfiniteGallery;

Este componente te permite pasar una lista de imágenes y luego organizarlas a través de la funcionalidad de arrastrar y soltar. Puedes usarlo de la siguiente manera:

import React from 'react';
import InfiniteGallery from './InfiniteGallery'; // Ajusta la ruta según tu estructura de archivos

const App: React.FC = () => {
  const images = [
    { id: 1, src: 'image1.jpg' },
    { id: 2, src: 'image2.jpg' },
    { id: 3, src: 'image3.jpg' },
    // Agrega más imágenes según sea necesario
  ];

  return (
    <div>
      <h1>¡Galería Infinita Impresionante!</h1>
      <InfiniteGallery images={images} />
    </div>
  );
};

export default App;

Este componente utiliza la biblioteca react-dnd para facilitar el arrastrar y soltar.

Deja un comentario