fixed the offset issue
This commit is contained in:
@@ -665,9 +665,9 @@ class Canvas extends React.Component {
|
||||
* Handles drop event to canvas from the sidebar and on canvas widget movement
|
||||
* @param {DragEvent} e
|
||||
*/
|
||||
handleDropEvent = (e, draggedElement, widgetClass = null, initialPos={x: 0, y: 0}) => {
|
||||
handleDropEvent = (e, draggedElement, widgetClass = null, initialOffset={x: 0, y: 0}) => {
|
||||
|
||||
console.log("event: ", e, draggedElement, widgetClass, initialPos)
|
||||
console.log("event: ", e, draggedElement, widgetClass, initialOffset)
|
||||
|
||||
// e.preventDefault()
|
||||
|
||||
@@ -690,17 +690,18 @@ class Canvas extends React.Component {
|
||||
|
||||
const { clientX, clientY } = e.nativeEvent
|
||||
|
||||
const { initial } = e.operation.shape
|
||||
const { transform } = e.operation
|
||||
console.log("event: ", e)
|
||||
// const { x: clientX, y: clientY} = e.delta;
|
||||
// const {clientX: draggedElementInitialX, clientY: draggedElementInitialY} = e.activatorEvent
|
||||
const {clientX: draggedElementInitialX, clientY: draggedElementInitialY} = e.operation.activatorEvent
|
||||
const { initial, current } = e.operation.shape
|
||||
|
||||
// console.log("wirking: ", clientX, clientY, e, draggedElementInitialX, draggedElementInitialY)
|
||||
console.log("wirking: ", transform)
|
||||
|
||||
// TODO: + initial cursor position - final cursor position
|
||||
let finalPosition = {
|
||||
x: ((clientX - canvasRect.left) / this.state.zoom) - (initial.left) / this.state.zoom,
|
||||
y: ((clientY - canvasRect.top) / this.state.zoom) - (initial.top) / this.state.zoom,
|
||||
x: ((clientX - canvasRect.left) / this.state.zoom),
|
||||
y: ((clientY - canvasRect.top) / this.state.zoom),
|
||||
}
|
||||
|
||||
console.log("container: ", container)
|
||||
@@ -726,6 +727,11 @@ class Canvas extends React.Component {
|
||||
// y: (clientY - canvasRect.top) / this.state.zoom - (elementHeight / 2) / this.state.zoom,
|
||||
// }
|
||||
|
||||
finalPosition = {
|
||||
x: finalPosition.x - initialOffset.x,
|
||||
y: finalPosition.y - initialOffset.y
|
||||
}
|
||||
console.log(initial, current)
|
||||
let widgetId = draggedElement.getAttribute("data-widget-id")
|
||||
|
||||
const widgetObj = this.getWidgetById(widgetId)
|
||||
@@ -1083,6 +1089,7 @@ class Canvas extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
// FIXME: inner canvas not recognized as droppable or some thing
|
||||
|
||||
return (
|
||||
<div className="tw-relative tw-overflow-hidden tw-flex tw-w-full tw-h-full tw-max-h-[100vh]">
|
||||
@@ -1120,7 +1127,7 @@ class Canvas extends React.Component {
|
||||
<div className="tw-w-full tw-h-full tw-outline-none tw-flex tw-relative tw-bg-[#f2f2f2] tw-overflow-hidden"
|
||||
ref={this.canvasContainerRef}
|
||||
style={{
|
||||
transition: " transform 0.3s ease-in-out",
|
||||
// transition: " transform 0.3s ease-in-out",
|
||||
backgroundImage: `url(${DotsBackground})`,
|
||||
backgroundSize: 'cover', // Ensure proper sizing if needed
|
||||
backgroundRepeat: 'no-repeat',
|
||||
@@ -1135,7 +1142,7 @@ class Canvas extends React.Component {
|
||||
}}
|
||||
/>
|
||||
{/* Canvas */}
|
||||
<div data-canvas className="tw-w-full tw-h-full tw-absolute tw-top-0 tw-select-none"
|
||||
<div data-canvas className="tw-w-full tw-h-full tw-absolute tw-bg-transparent tw-top-0 tw-select-none"
|
||||
ref={this.canvasRef}>
|
||||
<div className="tw-relative tw-w-full tw-h-full">
|
||||
{
|
||||
|
||||
@@ -805,7 +805,7 @@ class Widget extends React.Component {
|
||||
|
||||
handleDragStart = (e, ) => {
|
||||
// NOTE: this line will prevent problem's such as self-drop or dropping inside its own children
|
||||
setTimeout(this.disablePointerEvents, 1)
|
||||
// setTimeout(this.disablePointerEvents, 1)
|
||||
|
||||
this.setState({ isDragging: true })
|
||||
}
|
||||
@@ -972,7 +972,8 @@ class Widget extends React.Component {
|
||||
|
||||
handleDragEnd = () => {
|
||||
this.setState({ isDragging: false })
|
||||
this.enablePointerEvents()
|
||||
// this.enablePointerEvents()
|
||||
// console.log("enable pointer events: ")
|
||||
// this.props.onWidgetDragEnd(this.elementRef?.current)
|
||||
}
|
||||
|
||||
@@ -1062,15 +1063,14 @@ class Widget extends React.Component {
|
||||
}
|
||||
|
||||
// const boundingRect = this.getBoundingRect
|
||||
// TODO: rewrite Drag and drop
|
||||
// FIXME: if the parent container has tw-overflow-none, then the resizable indicator are also hidden
|
||||
// FIXME: renable pointer events
|
||||
// FIXME: re-enable pointer events
|
||||
return (
|
||||
|
||||
// <DragContext.Consumer>
|
||||
<DragContext.Consumer>
|
||||
{
|
||||
({ draggedElement, widgetClass }) => {
|
||||
({ draggedElement, widgetClass, setInitialOffset }) => {
|
||||
|
||||
|
||||
return (
|
||||
@@ -1081,7 +1081,7 @@ class Widget extends React.Component {
|
||||
dragElementType={this.getWidgetType()}
|
||||
droppableTags={this.droppableTags}
|
||||
className="tw-shadow-xl tw-w-fit tw-h-fit"
|
||||
initialPos={{ ...this.state.pos }}
|
||||
currentPos={{ ...this.state.pos }}
|
||||
onDragStart={this.handleDragStart}
|
||||
onDragOver={(e) => {this.handleDragOver(e, draggedElement)}}
|
||||
onDragEnd={(e) => this.handleDragEnd()}
|
||||
@@ -1090,6 +1090,8 @@ class Widget extends React.Component {
|
||||
onDragEnter={(e) => this.handleDragEnter(e, draggedElement)} // this is by droppable
|
||||
widgetRef={this.elementRef}
|
||||
|
||||
canvas={this.canvas}
|
||||
|
||||
// onDragOver={(e) => this.handleDragOver(e, draggedElement)}
|
||||
// onDrop={(e) => {this.handleDropEvent(e, draggedElement, widgetClass); onDragEnd()}}
|
||||
|
||||
|
||||
@@ -2,21 +2,25 @@ import React, { useEffect, useRef, useState } from 'react'
|
||||
import { useDragDropManager, useDroppable, useDraggable } from '@dnd-kit/react'
|
||||
import { useDragContext } from '../../components/draggable/draggableContext'
|
||||
import WidgetContainer from '../constants/containers'
|
||||
import { useSortable } from '@dnd-kit/react/sortable'
|
||||
|
||||
|
||||
// FIXME: widget class is null
|
||||
function WidgetDnd({widgetId, widgetRef, droppableTags, onDrop, onDragStart,
|
||||
onDragEnd, onDragEnter, onDragOver, initialPos,
|
||||
function WidgetDnd({widgetId, canvas, widgetRef, droppableTags,onMousePress, onDrop, onDragStart,
|
||||
onDragEnd, onDragEnter, onDragOver, currentPos={x: 0, y: 0},
|
||||
...props}) {
|
||||
|
||||
const dndRef = useRef(null)
|
||||
|
||||
const {dragElementType} = props
|
||||
|
||||
const { draggedElement, setOverElement, widgetClass } = useDragContext()
|
||||
const { draggedElement, setOverElement, widgetClass, setInitialOffset } = useDragContext()
|
||||
|
||||
const { ref: dropRef, isDropTarget, droppable} = useDroppable({
|
||||
const [isDropDisabled, setIsDropDisabled] = useState(false);
|
||||
|
||||
const { ref: dropRef, droppable} = useDroppable({
|
||||
id: widgetId,
|
||||
disabled: isDropDisabled,
|
||||
// accept: (draggable) => {
|
||||
|
||||
// const allowDrop = (droppableTags && droppableTags !== null && (Object.keys(droppableTags).length === 0 ||
|
||||
@@ -37,6 +41,8 @@ function WidgetDnd({widgetId, widgetRef, droppableTags, onDrop, onDragStart,
|
||||
// data: { title: props.children }
|
||||
})
|
||||
|
||||
|
||||
// const sortable = useSortable()
|
||||
|
||||
const manager = useDragDropManager()
|
||||
|
||||
@@ -45,6 +51,18 @@ function WidgetDnd({widgetId, widgetRef, droppableTags, onDrop, onDragStart,
|
||||
const [allowDrop, setAllowDrop] = useState(false) // indicator if the draggable can be dropped on the droppable
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
if (draggable.isDragging){
|
||||
setIsDropDisabled(true)
|
||||
}else{
|
||||
setIsDropDisabled(false)
|
||||
}
|
||||
|
||||
}, [draggable.isDragging])
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
canvas?.addEventListener("mousedown", handleInitialPosOffset)
|
||||
|
||||
manager?.monitor?.addEventListener("dragstart", handleDragEnter)
|
||||
manager?.monitor?.addEventListener("dragend", handleDropEvent)
|
||||
@@ -55,8 +73,10 @@ function WidgetDnd({widgetId, widgetRef, droppableTags, onDrop, onDragStart,
|
||||
manager?.monitor?.removeEventListener("dragstart", handleDragEnter)
|
||||
manager?.monitor?.removeEventListener("dragend", handleDropEvent)
|
||||
manager?.monitor?.removeEventListener("dragmove", handleDragOver)
|
||||
canvas?.removeEventListener("mousedown", handleInitialPosOffset)
|
||||
|
||||
}
|
||||
}, [manager, draggedElement, widgetClass])
|
||||
}, [manager, draggedElement, widgetClass, canvas])
|
||||
|
||||
|
||||
const handleRef = (node) => {
|
||||
@@ -66,15 +86,32 @@ function WidgetDnd({widgetId, widgetRef, droppableTags, onDrop, onDragStart,
|
||||
dragRef(node)
|
||||
}
|
||||
|
||||
const handleInitialPosOffset = (e) => {
|
||||
|
||||
console.log("canvas bounding rect: ", canvas.getBoundingClientRect())
|
||||
|
||||
const {clientX, clientY} = e
|
||||
|
||||
const canvasBoundingRect = canvas.getBoundingClientRect()
|
||||
|
||||
const initialOffset = {
|
||||
x: clientX - (currentPos.x + canvasBoundingRect.left),
|
||||
y: clientY - (currentPos.y + canvasBoundingRect.top)
|
||||
}
|
||||
|
||||
setInitialOffset(initialOffset)
|
||||
console.log("initial position calc: ", initialOffset, clientX, clientY)
|
||||
|
||||
}
|
||||
|
||||
const handleDragEnter = (e) => {
|
||||
|
||||
|
||||
if (draggable.isDragSource){
|
||||
|
||||
console.log("widget class: ", widgetClass)
|
||||
|
||||
|
||||
// if the current widget is being dragged
|
||||
onDragContextStart(dndRef?.current, widgetClass, {}, initialPos)
|
||||
onDragContextStart(dndRef?.current, widgetClass, {})
|
||||
|
||||
dndRef.current.style.zIndex = 10
|
||||
|
||||
@@ -121,7 +158,7 @@ function WidgetDnd({widgetId, widgetRef, droppableTags, onDrop, onDragStart,
|
||||
(droppableTags.exclude?.length > 0 && !droppableTags.exclude?.includes(dragElementType))
|
||||
))
|
||||
|
||||
|
||||
console.log("Drop allowed: ", dropAllowed, dragElementType )
|
||||
setAllowDrop(dropAllowed)
|
||||
|
||||
onDragOver(e)
|
||||
@@ -136,7 +173,7 @@ function WidgetDnd({widgetId, widgetRef, droppableTags, onDrop, onDragStart,
|
||||
onDragEnd(e)
|
||||
|
||||
}else if (droppable.isDropTarget){
|
||||
setAllowDrop(false)
|
||||
// setAllowDrop(false)
|
||||
|
||||
|
||||
if (!draggedElement || !draggedElement.getAttribute("data-drag-start-within")) {
|
||||
@@ -167,14 +204,14 @@ function WidgetDnd({widgetId, widgetRef, droppableTags, onDrop, onDragStart,
|
||||
data-widget-id={widgetId}
|
||||
data-container={WidgetContainer.CANVAS}
|
||||
data-draggable-type={dragElementType}
|
||||
className={`${props.className || ''} tw-relative tw-h-max tw-w-max tw-outline-none`}
|
||||
className={`${props.className || ''} ${draggable.isDragging && "tw-pointer-events-none"} tw-relative tw-h-max tw-w-max tw-outline-none`}
|
||||
>
|
||||
|
||||
{props.children}
|
||||
|
||||
{
|
||||
(droppable.isDropTarget && !draggable.isDragSource) &&
|
||||
<div className={`${allowDrop.allow ? "tw-bg-[#82ff1c55]" : "tw-bg-[#eb5d3662]"}
|
||||
<div className={`${allowDrop ? "tw-bg-[#82ff1c55]" : "tw-bg-[#eb5d3662]"}
|
||||
tw-absolute tw-top-0 tw-left-0 tw-w-full tw-h-full tw-z-[3]
|
||||
tw-border-2 tw-border-dashed tw-rounded-lg tw-pointer-events-none
|
||||
`}>
|
||||
|
||||
@@ -8,7 +8,7 @@ function Droppable(props) {
|
||||
const droppableRef = useRef(null)
|
||||
const { droppableTags, onDrop } = props
|
||||
|
||||
const { draggedElement, setOverElement, widgetClass, initialPosition } = useDragContext()
|
||||
const { draggedElement, setOverElement, widgetClass, initialOffset } = useDragContext()
|
||||
|
||||
const { ref, isDropTarget, droppable} = useDroppable({
|
||||
id: props.id,
|
||||
@@ -40,7 +40,7 @@ function Droppable(props) {
|
||||
manager?.monitor?.removeEventListener("dragend", handleDragLeave)
|
||||
manager?.monitor?.removeEventListener("dragmove", handleDragOver)
|
||||
}
|
||||
}, [manager, draggedElement, widgetClass, initialPosition])
|
||||
}, [manager, draggedElement, widgetClass, initialOffset])
|
||||
|
||||
|
||||
const handleRef = (node) => {
|
||||
@@ -117,9 +117,6 @@ function Droppable(props) {
|
||||
return
|
||||
}
|
||||
|
||||
setAllowDrop({allow: false, show: false})
|
||||
|
||||
|
||||
if (!draggedElement || !draggedElement.getAttribute("data-drag-start-within")) {
|
||||
// if the drag is starting from outside (eg: file drop) or if drag doesn't exist
|
||||
return
|
||||
@@ -135,18 +132,21 @@ function Droppable(props) {
|
||||
(droppableTags.exclude?.length > 0 && !droppableTags.exclude?.includes(dragElementType))
|
||||
))
|
||||
|
||||
console.log("initial POs: ", initialPosition)
|
||||
console.log("initial POs: ", initialOffset)
|
||||
if (onDrop && dropAllowed) {
|
||||
onDrop(e, draggedElement, widgetClass, initialPosition)
|
||||
onDrop(e, draggedElement, widgetClass, initialOffset)
|
||||
}
|
||||
|
||||
setTimeout(() => setAllowDrop({allow: true, show: false}), 10)
|
||||
|
||||
}
|
||||
|
||||
|
||||
const handleDragLeave = (e) => {
|
||||
|
||||
const {target} = e.operation
|
||||
// const {target} = e.operation
|
||||
|
||||
if (target && target.id === props.id){
|
||||
if (droppable.isDropTarget){
|
||||
handleDropEvent(e)
|
||||
}else{
|
||||
setAllowDrop({allow: false, show: false})
|
||||
@@ -161,11 +161,15 @@ function Droppable(props) {
|
||||
{props.children}
|
||||
|
||||
{
|
||||
allowDrop.show &&
|
||||
<div className={`${allowDrop.allow ? "tw-bg-[#82ff1c31]" : "tw-bg-[#eb5d3646]"}
|
||||
tw-absolute tw-top-0 tw-left-0 tw-w-full tw-h-full tw-z-[0]
|
||||
droppable.isDropTarget &&
|
||||
<div className={`
|
||||
tw-absolute tw-top-0 tw-left-0 tw-w-full tw-h-full tw-z-[0] tw-p-3
|
||||
tw-border-2 tw-border-dashed tw-rounded-lg tw-pointer-events-none
|
||||
`}>
|
||||
|
||||
<div className={`${allowDrop.allow ? "tw-bg-[#82ff1c31]" : "tw-bg-[#eb5d3646]"} tw-w-full tw-h-full tw-pointer-events-none`}>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ export const DragProvider = ({ children }) => {
|
||||
const [draggedElement, setDraggedElement] = useState(null)
|
||||
const [overElement, setOverElement] = useState(null) // the element the dragged items is over
|
||||
|
||||
const [initialPosition, setInitialPosition] = useState({x: 0, y: 0})
|
||||
const [initialOffset, setInitialOffset] = useState({x: 0, y: 0})
|
||||
|
||||
const [dragElementMetaData, setDragElementMetaData] = useState({})
|
||||
|
||||
@@ -20,11 +20,10 @@ export const DragProvider = ({ children }) => {
|
||||
|
||||
const [isDragging, setIsDragging] = useState(false)
|
||||
|
||||
const onDragStart = (element, widgetClass=null, metaData={}, initialPos={x: 0, y: 0}) => {
|
||||
const onDragStart = (element, widgetClass=null, metaData={}) => {
|
||||
|
||||
setDraggedElement(element)
|
||||
setIsDragging(true)
|
||||
setInitialPosition(initialPos)
|
||||
setDragElementMetaData(metaData)
|
||||
|
||||
if (widgetClass && !isSubClassOfWidget(widgetClass))
|
||||
@@ -48,7 +47,7 @@ export const DragProvider = ({ children }) => {
|
||||
<DragContext.Provider value={{ draggedElement, overElement, setOverElement,
|
||||
widgetClass, onDragStart, onDragEnd, isDragging,
|
||||
dragElementMetaData, setDragElementMetaData,
|
||||
initialPosition
|
||||
initialOffset, setInitialOffset
|
||||
}}>
|
||||
{children}
|
||||
</DragContext.Provider>
|
||||
|
||||
Reference in New Issue
Block a user