Elegant way to place two rectangles

I have a rectangle (called target ) and you want to place another rectangle (called satellite ). The satellite has a position (upper, lower, left, right) that defines the edge of the location relative to the target. It also has an alignment that is (left, center, right top and bottom positions, top, middle and bottom for left and right).

Example:

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

I know the upper left coordinates of the target, as well as its width and height . I also know the width and height of the satellite and want to calculate the upper left coordinates. I could do this as a series of 12 if sentences, but maybe there is a more elegant, mathematical or algorithmic way to do this. Is there an alternative way:

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

Any good solutions in Ruby or JavaScript?

+6
source share
3 answers

I like the other answer, but here's how to do it without having to store anything. All math and logic using a trick that in javascript evaluates to 1 and false evaluates to 0 when using arithmetic operators:

ps (check working 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') ); 
+1
source

If you used a series of objects, this will do the trick:

  var positions = {

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

0
source
 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) sy = ty + y_t*t.height + y_s*s.height sx = tx + x_t*t.width + x_s*s.width 

or

 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") sy = ty + y_t*t.height + y_s*s.height sx = tx + x_t*t.width + x_s*s.width 
0
source

Source: https://habr.com/ru/post/886018/


All Articles