Skip to main content

How to drop image elements into a canvas with React?

You can use HTML drag-and-drop events to add images or other elements to a canvas.

import React from 'react';
import { Stage, Layer, Image } from 'react-konva';
import useImage from 'use-image';

const URLImage = ({ image, onChange }) => {
const [img] = useImage(image.src);
return (
<Image
image={img}
x={image.x}
y={image.y}
// Center the image on its stored position.
offsetX={img ? img.width / 2 : 0}
offsetY={img ? img.height / 2 : 0}
draggable
onDragEnd={(event) => {
onChange({ ...image, ...event.target.position() });
}}
/>
);
};

const App = () => {
const dragUrl = React.useRef();
const stageRef = React.useRef();
const nextImageId = React.useRef(0);
const [images, setImages] = React.useState([]);
return (
<div>
Try to drag and drop the image into the stage:
<br />
<img
alt="lion"
src="https://konvajs.org/assets/lion.png"
draggable="true"
onDragStart={(e) => {
dragUrl.current = e.target.src;
}}
/>
<div
onDrop={(e) => {
e.preventDefault();
// register event position
stageRef.current.setPointersPositions(e);
// add image
setImages((currentImages) =>
currentImages.concat([
{
id: nextImageId.current++,
...stageRef.current.getPointerPosition(),
src: dragUrl.current,
},
])
);
}}
onDragOver={(e) => e.preventDefault()}
>
<Stage
width={window.innerWidth}
height={window.innerHeight}
style={{ border: '1px solid grey' }}
ref={stageRef}
>
<Layer>
{images.map((image) => {
return (
<URLImage
key={image.id}
image={image}
onChange={(newAttributes) => {
setImages((currentImages) =>
currentImages.map((currentImage) =>
currentImage.id === newAttributes.id
? newAttributes
: currentImage
)
);
}}
/>
);
})}
</Layer>
</Stage>
</div>
</div>
);
};

export default App;