SnapUtil.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. var abs = Math.abs,
  2. round = Math.round;
  3. /**
  4. * Snap value to a collection of reference values.
  5. *
  6. * @param {Number} value
  7. * @param {Array<Number>} values
  8. * @param {Number} [tolerance=10]
  9. *
  10. * @return {Number} the value we snapped to or null, if none snapped
  11. */
  12. export function snapTo(value, values, tolerance) {
  13. tolerance = tolerance === undefined ? 10 : tolerance;
  14. var idx, snapValue;
  15. for (idx = 0; idx < values.length; idx++) {
  16. snapValue = values[idx];
  17. if (abs(snapValue - value) <= tolerance) {
  18. return snapValue;
  19. }
  20. }
  21. }
  22. export function topLeft(bounds) {
  23. return {
  24. x: bounds.x,
  25. y: bounds.y
  26. };
  27. }
  28. export function mid(bounds, defaultValue) {
  29. if (!bounds || isNaN(bounds.x) || isNaN(bounds.y)) {
  30. return defaultValue;
  31. }
  32. return {
  33. x: round(bounds.x + bounds.width / 2),
  34. y: round(bounds.y + bounds.height / 2)
  35. };
  36. }
  37. export function bottomRight(bounds) {
  38. return {
  39. x: bounds.x + bounds.width,
  40. y: bounds.y + bounds.height
  41. };
  42. }
  43. /**
  44. * Retrieve the snap state of the given event.
  45. *
  46. * @param {Event} event
  47. * @param {String} axis
  48. *
  49. * @return {Boolean} the snapped state
  50. *
  51. */
  52. export function isSnapped(event, axis) {
  53. var snapped = event.snapped;
  54. if (!snapped) {
  55. return false;
  56. }
  57. if (typeof axis === 'string') {
  58. return snapped[axis];
  59. }
  60. return snapped.x && snapped.y;
  61. }
  62. /**
  63. * Set the given event as snapped.
  64. *
  65. * This method may change the x and/or y position of the shape
  66. * from the given event!
  67. *
  68. * @param {Event} event
  69. * @param {String} axis
  70. * @param {Number|Boolean} value
  71. *
  72. * @return {Number} old value
  73. */
  74. export function setSnapped(event, axis, value) {
  75. if (typeof axis !== 'string') {
  76. throw new Error('axis must be in [x, y]');
  77. }
  78. if (typeof value !== 'number' && value !== false) {
  79. throw new Error('value must be Number or false');
  80. }
  81. var delta,
  82. previousValue = event[axis];
  83. var snapped = event.snapped = (event.snapped || {});
  84. if (value === false) {
  85. snapped[axis] = false;
  86. } else {
  87. snapped[axis] = true;
  88. delta = value - previousValue;
  89. event[axis] += delta;
  90. event['d' + axis] += delta;
  91. }
  92. return previousValue;
  93. }