fixed the offset issue

This commit is contained in:
paul
2025-03-05 14:41:56 +05:30
parent b1c707a21d
commit 4d0ea22af6
5 changed files with 92 additions and 43 deletions

View File

@@ -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">
{

View File

@@ -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()}}

View File

@@ -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
`}>

View File

@@ -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>
}

View File

@@ -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>