Skip to main content
corrected mixed up x and y coordinates, removed unnecessary pieces
Source Link
gravity = (coords, height, width) ->
    center =
      x: (page_width = testEl().width) / 2
     , y: testEl().height / 2
    el_centerpage_height =
      x: coords.width / 2
      y: coordstestEl().height) / 2
    box_center =
      x: width / 2
     , y: height / 2
 
    points = [] 

    for x in [coords.left..(coords.right + width)] by 2030
      points.push([x - width, coords.top - height])
      points.push([x - width, coords.bottom])

    for y in [coords.top..(coords.bottom + height)] by 2030
      points.push([coords.left - width, y - height])
      points.push([coords.right, y - height])

    sort = (a, b) ->
      for ary in [[a, obja = {}], [b, objb = {}]]
        x = ary[0][0]
        y = ary[0][1]
        ary[1]['diffx']ary[1].diffx = if (dax = (x + box_center.x)) > center.x then dax - center.x else center.x - dax
        ary[1]['diffy']ary[1].diffy = if (day = (y + box_center.y)) > center.y then day - center.y else center.y - day
        ary[1]['diff']ary[1].diff = ary[1]['diffx']ary[1].diffx + ary[1]['diffy']ary[1].diffy
        if x < 0 || x + width > testEl().widthpage_width then ary[1]['diff']ary[1].diff =+ 10000
        if y < 0 || y + height > testEl().heightpage_height then ary[1]['diff']ary[1].diff =+ 10000
      obja.diff - objb.diff

    points.sort(sort)
    x: if (x = points[0][0]
 ) < 0 || yx =+ points[0][1]
width > page_width then pointscenter.x =- nullbox_center.x else x
    xy: if (y
  = points[0][1]) < 0 || y: x+ height > page_height then center.y - box_center.y else y
gravity = (coords, height, width) ->
    center =
      x: testEl().width / 2
      y: testEl().height / 2
    el_center =
      x: coords.width / 2
      y: coords.height / 2
    box_center =
      x: width / 2
      y: height / 2
 
    points = []
    for x in [coords.left..(coords.right + width)] by 20
      points.push([x - width, coords.top - height])
      points.push([x - width, coords.bottom])

    for y in [coords.top..(coords.bottom + height)] by 20
      points.push([coords.left - width, y - height])
      points.push([coords.right, y - height])

    sort = (a, b) ->
      for ary in [[a, obja = {}], [b, objb = {}]]
        x = ary[0][0]
        y = ary[0][1]
        ary[1]['diffx'] = if (dax = (x + box_center.x)) > center.x then dax - center.x else center.x - dax
        ary[1]['diffy'] = if (day = (y + box_center.y)) > center.y then day - center.y else center.y - day
        ary[1]['diff'] = ary[1]['diffx'] + ary[1]['diffy']
        if x < 0 || x + width > testEl().width then ary[1]['diff'] =+ 10000
        if y < 0 || y + height > testEl().height then ary[1]['diff'] =+ 10000
      obja.diff - objb.diff

    points.sort(sort)
    x = points[0][0]
     y = points[0][1]
    points = null
    x: y
     y: x
gravity = (coords, height, width) ->
    center = x: (page_width = testEl().width) / 2, y: (page_height = testEl().height) / 2
    box_center = x: width / 2, y: height / 2
    points = [] 

    for x in [coords.left..(coords.right + width)] by 30
      points.push([x - width, coords.top - height])
      points.push([x - width, coords.bottom])

    for y in [coords.top..(coords.bottom + height)] by 30
      points.push([coords.left - width, y - height])
      points.push([coords.right, y - height])

    sort = (a, b) ->
      for ary in [[a, obja = {}], [b, objb = {}]]
        x = ary[0][0]
        y = ary[0][1]
        ary[1].diffx = if (dax = (x + box_center.x)) > center.x then dax - center.x else center.x - dax
        ary[1].diffy = if (day = (y + box_center.y)) > center.y then day - center.y else center.y - day
        ary[1].diff = ary[1].diffx + ary[1].diffy
        if x < 0 || x + width > page_width then ary[1].diff =+ 10000
        if y < 0 || y + height > page_height then ary[1].diff =+ 10000
      obja.diff - objb.diff

    points.sort(sort)
    x: if (x = points[0][0]) < 0 || x + width > page_width then center.x - box_center.x else x
    y: if (y = points[0][1]) < 0 || y + height > page_height then center.y - box_center.y else y
updated answer to provide details about the changes
Source Link

Instead of identifying specific points (top-left, bottom-right, middle-left, etc...) the new code pushes every possible point in steps (set to 20 but could be higher for performance purposes) into an array. Then the array is sorted by the combined x and y difference of the point to page center. Giving us the closest possible points to page center while remaining attached to the element.

One note, be careful not to set the steps too low as that will impact performance. Even in 20px steps the movement is relatively fluid.

Instead of identifying specific points (top-left, bottom-right, middle-left, etc...) the new code pushes every possible point in steps (set to 20 but could be higher for performance purposes) into an array. Then the array is sorted by the combined x and y difference of the point to page center. Giving us the closest possible points to page center while remaining attached to the element.

One note, be careful not to set the steps too low as that will impact performance. Even in 20px steps the movement is relatively fluid.

removed mention of further review
Source Link

Okay, I think I got it. Yay! This one has haunted me for awhile. The new gravity function is completely fluid, way more concise, and accurate.

Still open to improvement suggestions, but I'm pretty happy with the outcome.

gravity = (coords, height, width) ->
    center =
      x: testEl().width / 2
      y: testEl().height / 2
    el_center =
      x: coords.width / 2
      y: coords.height / 2
    box_center =
      x: width / 2
      y: height / 2

    points = []
    for x in [coords.left..(coords.right + width)] by 20
      points.push([x - width, coords.top - height])
      points.push([x - width, coords.bottom])

    for y in [coords.top..(coords.bottom + height)] by 20
      points.push([coords.left - width, y - height])
      points.push([coords.right, y - height])

    sort = (a, b) ->
      for ary in [[a, obja = {}], [b, objb = {}]]
        x = ary[0][0]
        y = ary[0][1]
        ary[1]['diffx'] = if (dax = (x + box_center.x)) > center.x then dax - center.x else center.x - dax
        ary[1]['diffy'] = if (day = (y + box_center.y)) > center.y then day - center.y else center.y - day
        ary[1]['diff'] = ary[1]['diffx'] + ary[1]['diffy']
        if x < 0 || x + width > testEl().width then ary[1]['diff'] =+ 10000
        if y < 0 || y + height > testEl().height then ary[1]['diff'] =+ 10000
      obja.diff - objb.diff

    points.sort(sort)
    x = points[0][0]
    y = points[0][1]
    points = null
    x: y
    y: x

Okay, I think I got it. Yay! This one has haunted me for awhile. The new gravity function is completely fluid, way more concise, and accurate.

Still open to improvement suggestions, but I'm pretty happy with the outcome.

gravity = (coords, height, width) ->
    center =
      x: testEl().width / 2
      y: testEl().height / 2
    el_center =
      x: coords.width / 2
      y: coords.height / 2
    box_center =
      x: width / 2
      y: height / 2

    points = []
    for x in [coords.left..(coords.right + width)] by 20
      points.push([x - width, coords.top - height])
      points.push([x - width, coords.bottom])

    for y in [coords.top..(coords.bottom + height)] by 20
      points.push([coords.left - width, y - height])
      points.push([coords.right, y - height])

    sort = (a, b) ->
      for ary in [[a, obja = {}], [b, objb = {}]]
        x = ary[0][0]
        y = ary[0][1]
        ary[1]['diffx'] = if (dax = (x + box_center.x)) > center.x then dax - center.x else center.x - dax
        ary[1]['diffy'] = if (day = (y + box_center.y)) > center.y then day - center.y else center.y - day
        ary[1]['diff'] = ary[1]['diffx'] + ary[1]['diffy']
        if x < 0 || x + width > testEl().width then ary[1]['diff'] =+ 10000
        if y < 0 || y + height > testEl().height then ary[1]['diff'] =+ 10000
      obja.diff - objb.diff

    points.sort(sort)
    x = points[0][0]
    y = points[0][1]
    points = null
    x: y
    y: x

Okay, I think I got it. Yay! This one has haunted me for awhile. The new gravity function is completely fluid, way more concise, and accurate.

gravity = (coords, height, width) ->
    center =
      x: testEl().width / 2
      y: testEl().height / 2
    el_center =
      x: coords.width / 2
      y: coords.height / 2
    box_center =
      x: width / 2
      y: height / 2

    points = []
    for x in [coords.left..(coords.right + width)] by 20
      points.push([x - width, coords.top - height])
      points.push([x - width, coords.bottom])

    for y in [coords.top..(coords.bottom + height)] by 20
      points.push([coords.left - width, y - height])
      points.push([coords.right, y - height])

    sort = (a, b) ->
      for ary in [[a, obja = {}], [b, objb = {}]]
        x = ary[0][0]
        y = ary[0][1]
        ary[1]['diffx'] = if (dax = (x + box_center.x)) > center.x then dax - center.x else center.x - dax
        ary[1]['diffy'] = if (day = (y + box_center.y)) > center.y then day - center.y else center.y - day
        ary[1]['diff'] = ary[1]['diffx'] + ary[1]['diffy']
        if x < 0 || x + width > testEl().width then ary[1]['diff'] =+ 10000
        if y < 0 || y + height > testEl().height then ary[1]['diff'] =+ 10000
      obja.diff - objb.diff

    points.sort(sort)
    x = points[0][0]
    y = points[0][1]
    points = null
    x: y
    y: x
Source Link
Loading