Переместить объект по кругу в ткани - PullRequest
0 голосов
/ 10 мая 2018

В настоящее время я использую fabricjs для рисования на холсте.

У меня есть один большой полукруг и маленький круг. Я хочу, чтобы пользователь мог перемещать маленький круг по внешней линии большого полукруга. Но как я могу предотвратить, чтобы круг покинул свой путь? Математика не проблема;)

РЕДАКТИРОВАТЬ: Здесь у меня есть код, который показывает вам, что я хочу.

            deltaLeft = p.left - centerPointX;
            deltaTop = p.top - centerPointY;
            length = Math.sqrt(deltaLeft * deltaLeft + deltaTop * deltaTop);

            console.log(length);
            if((length <= centerRadius + 5) && (length >= centerRadius - 5) ){
                handleNewX = p.left;
                handleNewY = p.top;
            }else{
                p.left = handleNewX;
                p.top = handleNewY;
            }

https://jsfiddle.net/g1h2gL88/

Проблема в том, что неестественно двигать ручкой

1 Ответ

0 голосов
/ 10 мая 2018

Проблема в математике, если вы хотите ограничить момент объекта на окружности, он вычислит угол вектора от центра к положению мыши. А затем вы рассчитываете новую позицию, используя угол и centerRadius. Вы в основном помещаете прямую бесконечную линию, начинающуюся в центре мышки, а затем вычисляете пересечение линии с окружностью.

deltaLeft = p.left - centerPointX;
deltaTop = p.top - centerPointY;

var radians = Math.atan2(deltaTop, deltaLeft)
p.left = Math.cos(radians) * centerRadius + centerPointX
p.top = Math.sin(radians) * centerRadius + centerPointY

jsfiddle demo

Если вы действительно хотите иметь диапазон от centerRadius - 5 до centerRadius + 5, то это можно легко расширить до:

var length = Math.sqrt(deltaLeft * deltaLeft + deltaTop * deltaTop);

// change the position only if mouse is outside if the centerRadius +/- 5 range
if (length <= centerRadius - 5 || length >= centerRadius + 5) {
  var radians = Math.atan2(deltaTop, deltaLeft)

  if (length < centerRadius) {
    length = centerRadius - 5;
  } else {
    length = centerRadius + 5;
  }
  p.left = Math.cos(radians) * length + centerPointX
  p.top = Math.sin(radians) * length + centerPointY
}

демонстрация скрипки

...