Элегантный способ позиционирования двух прямоугольников - PullRequest
6 голосов
/ 16 апреля 2011

У меня есть прямоугольник (называемый target ) и я хочу разместить рядом другой прямоугольник (называемый satellite ). Спутник имеет позицию (сверху, снизу, слева, справа), которая определяет край размещения относительно цели. Он также имеет выравнивание , которое (слева, в центре, справа для верхнего и нижнего положения, сверху, в середине и снизу для левого и правого положения).

Пример:

+----------+----------------------------+
|          |                            |
|  Target  | Satellite, Position=RIGHT, |
|          | Align=TOP                  |
|          |                            |
|          |----------------------------+
|          |
+----------+

Я знаю верхние левые координаты цели, а также ее ширина и высота . Я также знаю ширину и высоту спутника и хочу вычислить его верхние левые координаты. Я мог бы сделать это как серию из 12 if предложений, но, возможно, есть более элегантный, математический или алгоритмический способ сделать это. Есть ли альтернативный путь к этому:

# s = satellite, t = target
if pos == "top" && align == "left"
  s.x = t.x
  s.y = t.y - s.height
else if pos == "top" && align == "center"
  s.x = t.x + t.width / 2 - s.width / 2
  s.y = t.y - s.height
# etc, etc

Какие-нибудь хорошие решения в Ruby или JavaScript?

Ответы [ 3 ]

1 голос
/ 16 апреля 2011

Мне нравится другой ответ, но вот как это сделать без необходимости что-либо хранить. Вся математика и логика с использованием трюка, который в javascript true оценивается как 1, а false оценивается в 0, когда применяются арифметические операторы:

p.s. (проверьте рабочий jsfiddle: http://jsfiddle.net/vQqSe/52/)

var t = {
    jq: $('#target'),
    width: parseInt($('#target').css('width')),
    height: parseInt($('#target').css('height')),
    top: parseInt($('#target').css('top')),
    left: parseInt($('#target').css('left'))
};
var s = {
    jq: $('#satellite'),
    width: parseInt($('#satellite').css('width')),
    height: parseInt($('#satellite').css('height'))
};

// start with it top left and add using javascript tricks
s.jq.css('top', t.top - s.height +
    s.height * (a == 'top') +
    (t.height/2 + s.height/2) * (a == 'middle') +
    t.height * (a == 'bottom') +
    (t.height + s.height) * (p == 'bottom')
);        

s.jq.css('left', t.left - s.width +
    t.width * (a == 'left') +
    s.width * (a == 'right') +
    (s.width/2 + t.width/2) * (a == 'center') +
    (s.width + t.width) * (p == 'right')
);
0 голосов
/ 16 апреля 2011
def vector pos, align, hash
  case hash[pos]
  when -1;     [0.0, -1.0]
  when 1;      [1.0, 0.0]
  else
    case hash[align]
    when -1;   [0.0, 0.0]
    when 1;    [1.0, -1.0]
    else       [0.5, -0.5]
    end
  end
end

y_t, y_s = vector(pos, align, "top" => -1, "bottom" => 1)
x_t, x_s = vector(pos, align, "left" => -1, "right" => 1)
s.y = t.y + y_t*t.height + y_s*s.height
s.x = t.x + x_t*t.width + x_s*s.width

или

def vector pos, align, head, tail
  case pos
  when head;   [0.0, -1.0]
  when tail;   [1.0, 0.0]
  else
    case align
    when head; [0.0, 0.0]
    when tail; [1.0, -1.0]
    else       [0.5, -0.5]
    end
  end
end

y_t, y_s = vector(pos, align, "top", "bottom")
x_t, x_s = vector(pos, align, "left", "right")
s.y = t.y + y_t*t.height + y_s*s.height
s.x = t.x + x_t*t.width + x_s*s.width
0 голосов
/ 16 апреля 2011

Если вы использовали серию объектов, то добьетесь цели:

var positions = {

    top: {left:{x:t.x, y:y.y-s.height}, center:{x:tx.x + t.width/2- s.width/2, y:t.y-s.height}}
    //etc....
}
//then to get the position you can simply
var pos = positions[pos][align])

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