【发布时间】:2021-02-28 18:19:59
【问题描述】:
我正在尝试做一些类似 canva.com 的事情,您可以在其中从侧边栏中选择图像并将它们放在“div”中的任何位置,这样您就可以放置许多图像并且每个图像都有自己的位置。关键是当我尝试使用 setState(prevState=>{return [...prevState,{src:...,postitionX:...,positionY:...}]})这会在移动鼠标时为每个像素渲染一个 img。
所以问题是当我拖动时我有一个设置鼠标位置的函数,所以当位置改变时,useEffect 重新渲染并运行内部函数,我的目标是设置一个对象(img)具有当前 img 的所有属性,当我拖放另一个 img 时,每个 img 在放置区域中都有自己的位置。
import React, {useState,useEffect} from 'react'
import Img from "./img-card"
const DropImg=()=>{
//this state is for getImg, with this i save all the images of the input file (sidebar)
const [img,setImg]=useState([])
//this state is for the image shown in the editor
const[imgDrag,setImgDrag]=useState([])
//this saves the position of the element currently dragged,then it is passed to the state that has al the objects that contain all the images with its own data and properties.
const[position,setPosition]=useState({x:0,y:0})
//this state is for getting the src of the img that is been dragged in the drag zone
const [imgSelected,setImageSelected]=useState()
const getImg=(e)=>{
let img=e.target.files
for(let i=0;i<img.length;i++){
setImg((prevState)=>{return ( img? [...prevState,URL.createObjectURL(img[i])] : [...prevState]) })
}
}
const dragOver=(e)=>{
e.preventDefault()
//clientX and clientY are mouse events that show the position of the pointer
let xPosition=e.clientX
let yPosition=e.clientY
//set the positions to later send the data to the imgDrag that has all the data about the images
setPosition(()=>{return {["x"]:xPosition,["y"]:yPosition}})
}
useEffect(()=>{
setImgDrag( (prevState)=>{ return [...prevState, {src:imgSelected, x:position.x, y:position.y,...prevState}]})
},[position])
function drop(e){
e.preventDefault();
}
const dragStart=e=>{
setImageSelected(e.target.src)
}
return (
<div className="flex bg-gray-400">
<div className=" bg-gray-800 w-1/4 rem-width-25 px-5 pt-6 h-screen">
<div className="block">
<div className="relative bg-teal-500 border rounded py-12 m-auto text-center w-11/12 text-white ">
<input type="file" id="img" className="absolute top-0 m-auto left-0 cursor-pointer bg-gray-200 border border-gray-300 mb-3 outline-none py-10 px-5 rounded shadow-sm opacity-0" multiple onChange={getImg} />
Click Here Or Drop An Image
</div>
</div>
<div className="grid w-full grid-cols-3 gap-2 mt-10">
{(img? img.map((src,index)=>{return <Img key={index} id={index} draggable="true" onDragStart={dragStart} src={src}/>}):null)}
</div>
</div>
<div onDrop={drop} onDragOver={dragOver} className="w-9/12 h-screen relative">
{imgDrag? imgDrag.map((data)=>{return <Img src={data.src} style={{width:450,position: 'absolute',top:data.y-400,left:data.x-600}}/>}): null}
{img? null:<p id="drop-here" className="text-center">Drop Image Here!</p>}
</div>
</div>)
}
export default DropImg
【问题讨论】:
标签: javascript reactjs react-hooks