fisheye.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /* eslint-disable @typescript-eslint/no-unused-vars */
  2. // https://github.com/d3/d3-plugins/blob/master/fisheye/fisheye.js
  3. import { Linear } from '@antv/scale';
  4. function fisheyeTransform(x, focus, distortion, min, max) {
  5. var left = x < focus;
  6. var m = (left ? focus - min : max - focus) || max - min;
  7. var f = left ? -1 : 1;
  8. return (f * m * (distortion + 1)) / (distortion + m / ((x - focus) * f)) + focus;
  9. }
  10. function fisheyeUntransform(tx, focus, distortion, min, max) {
  11. var left = tx < focus;
  12. var m = (left ? focus - min : max - focus) || max - min;
  13. var f = left ? -1 : 1;
  14. return m / ((m * (distortion + 1)) / (tx - focus) - distortion * f) + focus;
  15. }
  16. /**
  17. * Map actual visual point to abstract focus point(0, 1)
  18. */
  19. function normalize(focus, length, isVisual) {
  20. if (!isVisual)
  21. return focus;
  22. var s = new Linear({
  23. range: [0, 1],
  24. domain: [0, length],
  25. });
  26. return s.map(focus);
  27. }
  28. /**
  29. * Applies cartesian fisheye transforms for the first dimension of vector2.
  30. * @param params [focus, distortion]
  31. * @param x x of the the bounding box of coordinate
  32. * @param y y of the the bounding box of coordinate
  33. * @param width width of the the bounding box of coordinate
  34. * @param height height of the the bounding box of coordinate
  35. * @returns transformer
  36. */
  37. export var fisheyeX = function (params, x, y, width, height) {
  38. var _a = params, focus = _a[0], distortion = _a[1], _b = _a[2], isVisual = _b === void 0 ? false : _b;
  39. var normalizedFocusX = normalize(focus, width, isVisual);
  40. return {
  41. transform: function (vector) {
  42. var vx = vector[0], vy = vector[1];
  43. var fx = fisheyeTransform(vx, normalizedFocusX, distortion, 0, 1);
  44. return [fx, vy];
  45. },
  46. untransform: function (vector) {
  47. var fx = vector[0], vy = vector[1];
  48. var vx = fisheyeUntransform(fx, normalizedFocusX, distortion, 0, 1);
  49. return [vx, vy];
  50. },
  51. };
  52. };
  53. /**
  54. * Applies cartesian fisheye transforms for the second dimension of vector2.
  55. * @param params [focus, distortion]
  56. * @param x x of the the bounding box of coordinate
  57. * @param y y of the the bounding box of coordinate
  58. * @param width width of the the bounding box of coordinate
  59. * @param height height of the the bounding box of coordinate
  60. * @returns transformer
  61. */
  62. export var fisheyeY = function (params, x, y, width, height) {
  63. var _a = params, focus = _a[0], distortion = _a[1], _b = _a[2], isVisual = _b === void 0 ? false : _b;
  64. var normalizedFocusY = normalize(focus, height, isVisual);
  65. return {
  66. transform: function (vector) {
  67. var vx = vector[0], vy = vector[1];
  68. var fy = fisheyeTransform(vy, normalizedFocusY, distortion, 0, 1);
  69. return [vx, fy];
  70. },
  71. untransform: function (vector) {
  72. var vx = vector[0], fy = vector[1];
  73. var vy = fisheyeUntransform(fy, normalizedFocusY, distortion, 0, 1);
  74. return [vx, vy];
  75. },
  76. };
  77. };
  78. /**
  79. * Applies cartesian fisheye transforms for both dimensions of vector2.
  80. * @param params [focusX, focusY, distortionX, distortionY]
  81. * @param x x of the the bounding box of coordinate
  82. * @param y y of the the bounding box of coordinate
  83. * @param width width of the the bounding box of coordinate
  84. * @param height height of the the bounding box of coordinate
  85. * @returns transformer
  86. */
  87. export var fisheye = function (params, x, y, width, height) {
  88. var _a = params, focusX = _a[0], focusY = _a[1], distortionX = _a[2], distortionY = _a[3], _b = _a[4], isVisual = _b === void 0 ? false : _b;
  89. var normalizedFocusX = normalize(focusX, width, isVisual);
  90. var normalizedFocusY = normalize(focusY, height, isVisual);
  91. return {
  92. transform: function (vector) {
  93. var vx = vector[0], vy = vector[1];
  94. var fx = fisheyeTransform(vx, normalizedFocusX, distortionX, 0, 1);
  95. var fy = fisheyeTransform(vy, normalizedFocusY, distortionY, 0, 1);
  96. return [fx, fy];
  97. },
  98. untransform: function (vector) {
  99. var fx = vector[0], fy = vector[1];
  100. var vx = fisheyeUntransform(fx, normalizedFocusX, distortionX, 0, 1);
  101. var vy = fisheyeUntransform(fy, normalizedFocusY, distortionY, 0, 1);
  102. return [vx, vy];
  103. },
  104. };
  105. };
  106. /**
  107. * Applies circular fisheye transforms.
  108. * @param params [focusX, focusY, radius, distortion, isVisual?]
  109. * @param x x of the the bounding box of coordinate
  110. * @param y y of the the bounding box of coordinate
  111. * @param width width of the the bounding box of coordinate
  112. * @param height height of the the bounding box of coordinate
  113. * @returns transformer
  114. */
  115. export var fisheyeCircular = function (params, x, y, width, height) {
  116. var _a = params, focusX = _a[0], focusY = _a[1], radius = _a[2], distortion = _a[3], _b = _a[4], isVisual = _b === void 0 ? false : _b;
  117. var scaleX = new Linear({
  118. range: [0, width],
  119. });
  120. var scaleY = new Linear({
  121. range: [0, height],
  122. });
  123. // focus point => visual point
  124. var nx = isVisual ? focusX : scaleX.map(focusX);
  125. var ny = isVisual ? focusY : scaleY.map(focusY);
  126. return {
  127. transform: function (vector) {
  128. var x = vector[0], y = vector[1];
  129. // focus point => visual point
  130. var dx = scaleX.map(x) - nx;
  131. var dy = scaleY.map(y) - ny;
  132. var dd = Math.sqrt(dx * dx + dy * dy);
  133. if (dd > radius)
  134. return [x, y];
  135. var r = fisheyeTransform(dd, 0, distortion, 0, radius);
  136. var theta = Math.atan2(dy, dx);
  137. var fx = nx + r * Math.cos(theta);
  138. var fy = ny + r * Math.sin(theta);
  139. // visual point => focus point
  140. return [scaleX.invert(fx), scaleY.invert(fy)];
  141. },
  142. untransform: function (vector) {
  143. var tx = vector[0], ty = vector[1];
  144. var dx = scaleX.map(tx) - nx;
  145. var dy = scaleY.map(ty) - ny;
  146. var dd = Math.sqrt(dx * dx + dy * dy);
  147. if (dd > radius)
  148. return [tx, ty];
  149. var x = fisheyeUntransform(dd, 0, distortion, 0, radius);
  150. var theta = Math.atan2(dy, dx);
  151. var fx = nx + x * Math.cos(theta);
  152. var fy = ny + x * Math.sin(theta);
  153. return [scaleX.invert(fx), scaleY.invert(fy)];
  154. },
  155. };
  156. };
  157. //# sourceMappingURL=fisheye.js.map