Положение мыши в dragBoundFunc

Я использую kineticjs для рисования виджета на холсте. Этот виджет имеет ширину 600 пикселей и состоит из нескольких прямоугольников (по умолчанию 24). На этот прямоугольник можно перетащить другой, назовем его «курсор».

Вместо плавного перетаскивания я хочу, чтобы курсор переходил к другим прямоугольникам только тогда, когда моя мышь находится достаточно далеко (например, ступенчатое перетаскивание, если хотите).

Например, если курсор находится на 0,0, а у меня всего 24 прямоугольника, я хочу, чтобы мой курсор перемещался к следующему прямоугольнику только тогда, когда моя мышь находится на 25,0 (600 пикселей / 24 прямоугольника = 25 пикселей).

Итак, чтобы сделать это, я реализовал:

cursor.setDragBoundFunc(function(pos){
    var caseSize = WIDTH / caseNum;
    var posX = Math.round(pos.x/caseNum) * caseSize;
    if(posX > (WIDTH - caseSize)) {
        posX = WIDTH - caseSize;
    }

    if(posX < 0 ) {
        posX = 0;
    }

    return {
        x: posX, 
        y: cursor.getAbsolutePosition().y
    }
});

Проблема в том, что pos.x представляет не положение мыши на холсте, а положение мыши с начала события перетаскивания (pos будет равно 0,0, даже если я начну перетаскивание с середины холста).

Вот пример проблемы: http://jsfiddle.net/H9rpz/

Как я могу получить положение мыши на холсте в setDragBoundFunc()?

Спасибо


person grunk    schedule 14.11.2012    source источник
comment
Можете ли вы настроить jsFiddle, демонстрирующий проблему?   -  person Shmiddty    schedule 14.11.2012
comment
console.log(pos) для регистрации содержимого pos в вашем браузере. Затем вы можете осмотреть объект и посмотреть, содержит ли он то, что вам нужно.   -  person Jan    schedule 14.11.2012
comment
@Shmiddty: Вот скрипка: jsfiddle.net/H9rpz. посмотрите консоль, чтобы увидеть значение pos.x. если вы начнете перетаскивать синий прямоугольник, щелкнув в его правой части, pos.x будет равен 0   -  person grunk    schedule 14.11.2012
comment
Я хотел зарегистрировать весь объект pos на случай, если он содержит больше переменных. Но это не так, просто х и у...   -  person Jan    schedule 14.11.2012
comment
Кроме того, похоже, что вы создаете новый слой каждый раз, когда вызываете draw, что приводит к созданию нового холста в DOM.   -  person Shmiddty    schedule 14.11.2012
comment
@Shimiddty, спасибо за совет о слоях!   -  person grunk    schedule 16.11.2012


Ответы (3)


Кажется, что функция setDragBoundFunc принимает два аргумента, а второй — это объект event, который может содержать то, что вам нужно:

cursor.setDragBoundFunc(function(pos, event){
   var posX = event.offsetX;
   ....
});

У вас также есть математическая логическая ошибка в начале функции. Следует читать:

cursor.setDragBoundFunc(function(pos, event){
   var caseSize = WIDTH / caseNum;
   var posX = event.offsetX;
   posX = Math.floor(posX /  caseSize) *  caseSize; // This right here
   ...
});

Рабочий пример: http://jsfiddle.net/H9rpz/3/

person Jan    schedule 14.11.2012
comment
floor, вероятно, более подходит, чем round - person Shmiddty; 14.11.2012

Именно эта функция была реализована в ручном тесте KineticJS. Вот код, который вы ищете:

https://github.com/ericdrowell/KineticJS/blob/master/tests/js/manualTests.js#L1004

Попробуйте :)

person Eric Rowell    schedule 16.11.2012
comment
Жаль, что я не видел этого раньше ^_^, я поищу больше в репозитории github, спасибо. - person grunk; 16.11.2012

В дополнение к ответу @Jan ваша математика немного неверна:

cursor.setDragBoundFunc(function(pos, event){
    var posX = event.offsetX;
    posX = Math.floor(posX/WIDTH * caseNum) * caseWidth;
    ...
person Shmiddty    schedule 14.11.2012