React-dnd: كيف أحصل على إحداثيات العنصر الذي تم إسقاطه بالنسبة إلى حاوية هدف الإسقاط؟

تم إنشاؤها على ١٣ مايو ٢٠١٥  ·  15تعليقات  ·  مصدر: react-dnd/react-dnd

أنا أعمل مع 1.0.0-rc.

في drag-around-naive :

const boxTarget = {
  drop(props, monitor, component) {
    const item = monitor.getItem();
    const delta = monitor.getDifferenceFromInitialOffset();
    const left = Math.round(item.left + delta.x);
    const top = Math.round(item.top + delta.y);

    component.moveBox(item.id, left, top);
  }
};

في الوقت الحالي ، يبدو أنني بحاجة إلى الحصول على الإزاحة من صفحة العنصر الأصلي ، ثم يمكنني العثور على الإزاحة من الصفحة حيث أسقطت ، ثم أحتاج إلى العثور على إزاحة حاوية الإسقاط من الصفحة ، ثم فعل ذلك هذا الحساب ولدي الموضع النسبي في حاوية هدف الإسقاط.

يبدو أن هذا يتطلب الكثير من العمل لشيء شائع جدًا ...

enhancement

التعليق الأكثر فائدة

نعم أعتقد أنه يمكننا الحصول على هذا من أجل التماثل. في الوقت الحالي ، يمكنك فقط استخدام findDOMNode(component).getBoundingClientRect() ، لكنني لا أمانع في إضافة هذا إذا كان المزيد من الأشخاص يدعمون الصوت. دعونا نبقي هذا مفتوحًا ونرى ما يقوله الآخرون.

ال 15 كومينتر

يبدو أن getClientOffset يعيدني إلى الموضع المرتبط بإطار العرض. إذن كل ما علي فعله هو العثور على تعويض في هدف الإسقاط الخاص بي. هل تعتقد أنه لا يزال من المفيد وجود طريقة ملائمة تتعلق بإسقاط الهدف؟

نعم أعتقد أنه يمكننا الحصول على هذا من أجل التماثل. في الوقت الحالي ، يمكنك فقط استخدام findDOMNode(component).getBoundingClientRect() ، لكنني لا أمانع في إضافة هذا إذا كان المزيد من الأشخاص يدعمون الصوت. دعونا نبقي هذا مفتوحًا ونرى ما يقوله الآخرون.

أود شيء من هذا القبيل أيضا. أحتاج إلى الحصول على المستقيم / الإحداثيات المحيطية لهدف الإسقاط ، لذلك عندما أحوم فوق شيء ما يمكنني حساب ما إذا كان على الجانب الأيسر أو الأيمن أو العلوي أو السفلي داخل هدف الإسقاط.

يمكن أن تكون الإحداثيات النسبية مفيدة لحالات الاستخدام الأخرى. بالنسبة إلى تطبيق يشبه Trello ، عند سحب بطاقة فوق قائمة ، يتم تمرير القائمة إلى أسفل عند التمرير بالقرب من أسفل منطقة الإفلات ، ويتم التمرير لأعلى عند التمرير بالقرب من الجزء العلوي.

تافهة لتنفيذ على مساحة المستخدم مع ذلك.

أيضًا ، أتذكر قراءة غامضة أن الوصول إلى المستطيل المحيط يؤدي إلى إعادة التدفق في المتصفحات وهو مكلف إلى حد ما. لست متأكدا إذا كان هذا لا يزال هو الحال.

لا أعتقد أن هناك طريقة للقيام بذلك دون الوصول فعليًا إلى getBoundingClientRect لأنك لا تعرف أبدًا ما إذا كان العنصر قد تم نقله أم لا.

بالنسبة إلى تطبيق يشبه Trello ، عند سحب بطاقة فوق قائمة ، يتم تمرير القائمة إلى أسفل عند التمرير بالقرب من أسفل منطقة الإفلات ، ويتم التمرير لأعلى عند التمرير بالقرب من الجزء العلوي.

هذه حالة استخدام رائعة.

تعتبر عقوبة الأداء مهمة بالفعل ، وسيتم إهدارها إذا تمت إضافتها إلى React DnD ولكن تطبيقك لا يستخدمها. لذلك ، لا أريد إضافة هذا إلى React DnD.

من السهل تنفيذه في userland ، وستكون قادرًا على القيام بأشياء مثل خنق المكالمات getBoundingClientRect ، أو وضع رمز التمرير ذي الصلة في إطار الرسوم المتحركة.

أنا منفتح على إضافة "التمرير عند التمرير في الأسفل" _ كمثال_ إلى اختبار الإجهاد القابل للفرز . قد يتضمن ذلك إضافة هدف إسقاط آخر على مستوى الحاوية يستمع فقط إلى hover والتمرير داخل إطار الرسوم المتحركة.

ومع ذلك ، لن أضيف طرق تنسيق DOM إلى React DnD للأسباب الموضحة أعلاه.

gaearon أنا مهتم بالحل المعمم. كيف يمكننا استخدام react-dnd-html5-backend بدلاً من getBoundingClientRect مباشرةً؟

لقد قمت بحل هذا عن طريق تمرير الدالتين DropTargetMonitor getInitialSourceClientOffset و getSourceClientOffset إلى وظيفة رد الاتصال داخل حدث onDrop . بهذه الطريقة ، يمكن لوظيفة رد الاتصال الخاصة بي حساب الإحداثيات الصحيحة المتعلقة بمنفذ العرض.

// some code before...

const [, dropRef] = useDrop({
    accept: 'STICKY',
    drop(item, monitor) {
      move(
        item.id,
        monitor.getInitialSourceClientOffset(),
        monitor.getSourceClientOffset()
      );
    },
  });

// I'm updating my state with npm immer (immutable helper) throuthg the produce function...

const move = (id, initialPosition, finalPosition) => {
    setList(
      produce(list, draft => {
        list.map(item => {
          if (item.id === id) {
            item.position = getCorrectDroppedOffsetValue(
              initialPosition,
              finalPosition
            );
          }
          return item;
        });
      })
    );
  };

// and finally, my getCorrectDroppedOffsetValue function
const getCorrectDroppedOffsetValue = (initialPosition, finalPosition) => {
    // get the container (view port) position by react ref...
    const dropTargetPosition = ref.current.getBoundingClientRect();

    const { y: finalY, x: finalX } = finalPosition;
    const { y: initialY, x: initialX } = initialPosition;

    // calculate the correct position removing the viewport position.
   // finalY > initialY, I'm dragging down, otherwise, dragging up
    const newYposition =
      finalY > initialY
        ? initialY + (finalY - initialY) - dropTargetPosition.top
        : initialY - (initialY - finalY) - dropTargetPosition.top;

    const newXposition =
      finalX > initialX
        ? initialX + (finalX - initialX) - dropTargetPosition.left
        : initialX - (initialX - finalX) - dropTargetPosition.left;

    return {
      x: newXposition,
      y: newYposition,
    };
  };

findDOMNode لا يعمل مع المكون الوظيفي ، و useDrop#drop لا يمرر أي component . الآن إذا أردت الحصول على ref للمكون الخاص بي لتخزينه بشكل منفصل واستدعاء موصل الإسقاط يدويًا لتمريره. هل هناك طريقة أكثر إيجازًا للقيام بذلك؟

function useCustomDrop(onDrop: (info: unknown, xy: Point) => void) {

    const ref = useRef<Element>();

    const [, dropTarget] = useDrop<any, void, unknown>({
        accept: 'item-type',
        drop(item, monitor) {
            const offset = monitor.getSourceClientOffset();
            if (offset && ref.current) {
                const dropTargetXy = ref.current.getBoundingClientRect();
                onDrop(item.data, {
                    x: offset.x - dropTargetXy.left,
                    y: offset.y - dropTargetXy.top,
                });
            }
        }
    });

    return (elem) => {
        ref.current = elem;
        dropTarget(ref);
    };
}

quanganhtran ، هل لديك أي عينات أكواد كاملة ترغب في مشاركتها ، من فضلك؟

تضمين التغريدة

مثال مفتعل: https://codesandbox.io/s/elastic-liskov-00ldf

تكون واجهة برمجة التطبيقات أجمل عندما لا نضطر إلى تخزين ref بأنفسنا ( useGlobalDrop مقابل useLocalDrop ). الآن إذا كان فقط ref ، الذي أفترض أن react-dnd بالفعل ، تم إرفاقه ~ بالعنصر monitor ~ في مكان ما (يمكن الوصول إليه بـ drop ، ليس لدي رأي أين) ، فإنه سيحل هذا.

هذا الحل غير موثوق به خاصة عند تكبير المتصفح أو تغيير دقة الجهاز. اي فكرة؟

لدي نفس السؤال @ sepehr09

مجرد مرور بعد بضع عمليات بحث على google ... أي تحديث على السؤال الأصلي؟ (الحصول على x / y لعنصر تم إسقاطه بالنسبة إلى هدف الإسقاط)

أعتقد أنني سأشارك في قائمة أولئك الذين يحتاجون إلى هذا. اي مساعدة من فضلك؟

أعتقد أن هذه الميزة ضرورية للغاية ، ويجب إضافتها في المكتبة. الآن ، أي شخص عمل معها ، الرجاء مساعدتنا!

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات