Перетаскивание не обнаруживает падение, когда холст становится отзывчивым

В Animate CC и с помощью API CreateJS/EaselJS я создал значительное количество различных холстов HTML5, каждый из которых содержит элементы перетаскивания, каждый раз с прогрессивными функциями.

Чтобы создать взаимодействие перетаскивания, я добавил в Drag MovieClip несколько EventListeners для событий mousedown, pressmove и pressup. Все они имеют связанные функции.

(Часть) Код действий для мувиклипа Drag

/* this refers to the Drag MovieClip */ 
root = this;

/* Mousedown Events */

/* removingFromDrop: Detects when a Drag is removed from certain Drop */
root.on("mousedown", removingFromDrop);

/* Pressmove Events */ 

/* onPressMove: Moves the Drag on pressmove */ 
root.on("pressmove", onPressMove);

/* detectDrop: While pressmoving, detects if the Drag is over a Drop */ 
root.on("pressmove", detectDrop); 

/* Pressup events */

/* setDragOverDrop: Releasing the left button of the mouse, 
   if a Drag is over a Drop, the Drag is positioned over the Drop */ 
root.on("pressup", setDragOverDrop); 

Как я уже сказал, все функции перетаскивания были реализованы прогрессивным образом, поэтому на некоторых холстах перетаскивание не обнаруживает капли (намеренно), в других к перетаскиванию применяется прозрачность (альфа), когда они находятся над холстом. падение, в других перетяжка должна быть наложена на каплю или вернуться в исходное положение, в других перетаскивание при надевании на каплю, ее нельзя сбрасывать в другие положения; и Т. Д.

Что не меняется почти во всех этих реализациях, так это то, как перетаскивание перемещается по событию pressmove...

Функция onPressMove

function onPressMove(event) {
    // There is more code here, but for effects 
    // of this question, it's irrelevant

    /* In layer terms, drag must be over the drop  */ 
    root.parent.setChildIndex(event.currentTarget, root.parent.numChildren-1);

    /* Drag takes the actual position of the mouse pointer  */ 
    var point = stage.globalToLocal(event.stageX, event.stageY); 
    event.currentTarget.x = point.x;
    event.currentTarget.y = point.y; 
}

...и как он обнаруживает падение, когда оно ниже, также в событии pressmove.

функция обнаружения падения

function detectDrop(event){
    /* The original function is more complex than this. For example, the drop detection 
       in the original function is being done against all the available drops. 
       For effects of this question, I'm simplyfying this function, doing the detection 
       over a single drop */

    /* Initial variables */
    var dropLocation;       //  Drop Location
    var point;              //  Point for the collision comparison
    var dropFound = false;  //  Drop is found? By default, no. 

    /* Drop is cloned. For effects of this question, the drop is a global variable. */
    dropLocation = drop.clone();

    /* Position of the drop is converted to local using the mouse pointer position */   
    point = dropLocation.globalToLocal(event.stageX, event.stageY);

    /* In local coordinates, the drag intersects with the point defined before? */  
    if (event.currentTarget.hitTest(point.x,point.y)) {   
        /* If yes, the drop was found */ 
        dropFound = true;                      
    }

    if (dropFound) {  
        // Irrelevant for effects of this question 
    }
}

Существует только один случай, когда взаимодействие перетаскивания не работает должным образом, и это случай, когда холст сделали отзывчивым.

Нет проблем, когда холст расположен в центре, и перетаскивание, и обнаружение падения работают нормально.

Но когда холст сделан отзывчивым, движение перетаскивания работает нормально, но падение не обнаруживается, когда над ним перетаскивание. Как я тестировал до сих пор, перетаскивание обнаруживает определенное падение в другом положении, которое, очевидно, не является положением ранее упомянутого падения.


person cristiancajiaos    schedule 12.05.2017    source источник


Ответы (1)


После некоторых тестов, которые я провел для перетаскивания, подобных основной реализации, показанной выше, я пришел к решению, которое включает дополнительные преобразования в функции обнаружения падения.

Во-первых, переменная point теперь содержит текущую позицию мыши в координатном пространстве сцены:

var point = stage.globalToLocal(event.stageX, event.stageY);

Затем я использую эту точку для преобразования в координатное пространство капли. Это преобразование хранится в другой переменной точки:

var pointGTL = dropLocation.globalToLocal(point.x, point.y); 

Тест пересечения в локальных координатах выполняется с переменной точки, определенной ранее:

event.currentTarget.hitTest(pointGTL.x,pointGTL.y) 

Теперь функция обнаружения падения выглядит так:

функция обнаружения падения

function detectDrop(event){
    /* Initial variables */
    var dropLocation;       //  Drop Location
    var point, pointGTL;    //  Points for the collision comparison
    var dropFound = false;  //  Drop is found? By default, no. 

    /* Drop is cloned */
    dropLocation = drop.clone();

    /* Position of the stage is converted to local 
       using the mouse pointer position */  
    point = stage.globalToLocal(event.stageX, event.stageY);

    /* Then, the position of the drop is converted to local 
       using the point defined before */ 
    pointGTL = dropLocation.globalToLocal(point.x, point.y); 

    /* In local coordinates, the drag intersects with the point defined before? */  
    if (event.currentTarget.hitTest(pointGTL.x,pointGTL.y)) {   
        /* If yes, the drop was found */ 
        dropFound = true;                      
    }

    /* Rest of the code */
}

Перетаскивание отлично работает в обоих адаптивных режимах (Fit in view или Stretch to fit).

person cristiancajiaos    schedule 12.06.2017