Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preview Image only works once, on the first drag. #3609

Open
EOMedvis opened this issue Dec 14, 2023 · 3 comments
Open

Preview Image only works once, on the first drag. #3609

EOMedvis opened this issue Dec 14, 2023 · 3 comments

Comments

@EOMedvis
Copy link

EOMedvis commented Dec 14, 2023

First of all, I would like to state I'm completely new the React development, and there are probably some really basic things I'm missing that is causing the problem I will show below. Please bare with my newbie ignorance if that is the case.

I have a draggable object defined below, that I created following the examples on the React DnD site:

import type { CSSProperties, FC } from "react";
import { DragPreviewImage, useDrag } from "react-dnd";
import { DraggableTypes } from "./DraggableTypes";

export interface CardProps {
  cardData: CardType;
}

export const mainCardStyle: CSSProperties = {  
  border: '12px solid white',
  outline: '3px solid white',
  outlineOffset: '-20px',
  borderRadius: '25px',
  width: '65%',
  height: '100%',
  minWidth: '120px',
  minHeight: '320px',
  textAlign: 'center',
  color: 'white',
  backgroundImage: 'linear-gradient(to top, #396BE5, #ACA9E4)',  
  marginRight: '10px',
  marginBottom: '10px',
  cursor: 'move',
  float: 'left',
  boxShadow: '0px 5px 8px grey'
};

const innerDivStyle: CSSProperties = {margin: '10px'};
const imageDivStyle: CSSProperties = {marginTop: '40px',marginBottom: '20px'};
const titleDivStyle: CSSProperties = {marginBottom: '10px'};

function collectHandler(monitor: any) {
  return {
    isDragging: monitor.isDragging(),
    handlerId: monitor.getHandlerId(),
  };
}

export const DraggableCard: FC<CardProps> = function Card({ cardData }) {
  const [{isDragging}, drag, preview] = useDrag(
    function () 
    {
      return {
        type: DraggableTypes.Card,
        item: { cardData },
        collect: collectHandler,
        //end: (item, monitor) => { preview(null, { captureDraggingState: true });}, <== unsure about this.              
      };
    },
    [cardData]
  );

  const opacity = isDragging ? 0.4 : 1;
  
  return (    
    <>
      <DragPreviewImage connect={preview} src={cardData.image + ".png"} />
      <div ref={drag} style={{ ...mainCardStyle, opacity }}>
        <div style={innerDivStyle}>
          <div style={imageDivStyle}>
            <img src="placeHolder.png" alt="IconPlaceholder" /> 
          </div>
          <div style={titleDivStyle}>
            <strong>{cardData.title}</strong>
          </div>
          <div>            
            {cardData.description}
          </div>
        </div>        
      </div>
    </>
  );
};

It's working, for the most part. I can drag it into a drop target and have stuff happened as I expected. The only problem is that if I drag the object, and let go without dropping it into the drop target, the next time I drag it, the preview image no longer works. Instead i just get a transparent copy of the draggable object that moves with my cursor, instead of the assigned preview image, as if I never assigned the preview image at all (it works as if this line: <DragPreviewImage connect={preview} src={cardData.image + ".png"} />, was completely removed from the code).

The draggable object is dynamically created from an array of data. So I'm not sure if Im supposed to clear data first each time I drop. I've asked Chat GPT for some insights and it told me I have to clear the preview and gave me the line I liked with the "<==". That hasn't fixed the issue, though.

I know React has some strangeness where if the data doesn't change, things don't rerender sometimes. I'm not sure if this is the issue. Am I doing something wrong, or is there some limitation in React DnD I'm not aware of? Thank you for your time. :)

@deepak-penaganti
Copy link

@EOMedvis Please use key property on <DragPreviewImage key={new Date().getTime()} /> this will ensure the rerender on every drag

@EOMedvis
Copy link
Author

EOMedvis commented Jan 2, 2024

Oh. Awesome. Thank you for the solution!

I'm running into a second somewhat related problem. I am using an image for the preview and would like to scale it, but DragPreviewImage doesn't accept a CSS Style property (e.g. <DragPreviewImage style={{...style props}}>). Is there a way to scale the preview image without just editing the raw image itself? Or is there a better/different solution than using DragPreviewImage for a preview?

@EOMedvis
Copy link
Author

EOMedvis commented Jan 2, 2024

Actually, I think I fixed the PreviewImg not being scaled. I can scale and store an image as a src before feeding it to the DragPreviewImage and it seems to work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants