draggable.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /**
  2. * Simple draggable tool, just for demo or testing.
  3. * Use jquery.
  4. */
  5. (function (global) {
  6. var BORDER_WIDTH = 4;
  7. var $ = global.jQuery;
  8. global.draggable = {
  9. /**
  10. * @param {HTMLElement} mainEl
  11. * @param {module:echarts/echarts~EChart} chart
  12. * @param {Object} [opt] {width: ..., height: ...}
  13. * @param {number} [opt.width] If not specified, use mainEl current width.
  14. * @param {number} [opt.height] If not specified, use mainEl current height.
  15. * @param {boolean} [opt.lockX=false]
  16. * @param {boolean} [opt.lockY=false]
  17. * @param {number} [opt.throttle=false]
  18. * @return {type} description
  19. */
  20. init: function (mainEl, chart, opt) {
  21. opt = opt || {};
  22. var chartResize = chart ? $.proxy(chart.resize, chart) : function () {};
  23. if (opt.throttle) {
  24. chartResize = throttle(chartResize, opt.throttle, true, false);
  25. }
  26. var mainEl = $(mainEl);
  27. var id = mainEl.attr('data-draggable-id');
  28. if (id == null) {
  29. id = +Math.random();
  30. mainEl.attr('data-draggable-id', id);
  31. }
  32. else {
  33. $('.draggable-control[data-draggable-id=' + id + ']').remove();
  34. }
  35. var controlEl = $(
  36. '<div class="draggable-control">DRAG<span class="draggable-label"></span></div>'
  37. );
  38. controlEl.css({
  39. 'position': 'absolute',
  40. 'border-radius': '30px',
  41. 'width': '60px',
  42. 'height': '60px',
  43. 'line-height': '60px',
  44. 'text-align': 'center',
  45. 'background': '#333',
  46. 'color': '#fff',
  47. 'cursor': 'pointer',
  48. 'font-size': '18px',
  49. 'box-shadow': '0 0 5px #333',
  50. '-webkit-user-select': 'none',
  51. 'user-select': 'none'
  52. });
  53. var label = controlEl.find('.draggable-label');
  54. label.css({
  55. 'display': 'block',
  56. 'position': 'absolute',
  57. 'color': '#000',
  58. 'font-size': '12px',
  59. 'text-align': 'center',
  60. 'left': 0,
  61. 'top': '65px',
  62. 'width': '60px',
  63. 'line-height': 1
  64. });
  65. mainEl.css({
  66. 'position': 'absolute',
  67. 'left': mainEl[0].offsetLeft + 'px',
  68. 'top': mainEl[0].offsetTop + 'px',
  69. 'width': mainEl[0].offsetWidth + 'px',
  70. 'height': mainEl[0].offsetHeight + 'px',
  71. 'border-style': 'solid',
  72. 'border-color': '#ddd',
  73. 'border-width': BORDER_WIDTH + 'px',
  74. 'padding': 0,
  75. 'margin': 0
  76. });
  77. mainEl.parent().append(controlEl);
  78. var controlSize = controlEl[0].offsetWidth;
  79. var boxSizing = mainEl.css('box-sizing');
  80. var borderBoxBroder = boxSizing === 'border-box' ? 2 * BORDER_WIDTH : 0;
  81. var mainContentWidth = opt.width || (mainEl.width() + borderBoxBroder);
  82. var mainContentHeight = opt.height || (mainEl.height() + borderBoxBroder);
  83. var mainOffset = mainEl.offset();
  84. resize(
  85. mainOffset.left + mainContentWidth + BORDER_WIDTH,
  86. mainOffset.top + mainContentHeight + BORDER_WIDTH,
  87. true
  88. );
  89. var dragging = false;
  90. controlEl.on('mousedown', function () {
  91. dragging = true;
  92. });
  93. $(document).on('mousemove', function (e) {
  94. if (dragging) {
  95. resize(e.pageX, e.pageY);
  96. }
  97. });
  98. $(document).on('mouseup', function () {
  99. dragging = false;
  100. });
  101. function resize(x, y, isInit) {
  102. var mainOffset = mainEl.offset();
  103. var mainPosition = mainEl.position();
  104. var mainContentWidth = x - mainOffset.left - BORDER_WIDTH;
  105. var mainContentHeight = y - mainOffset.top - BORDER_WIDTH;
  106. if (isInit || !opt.lockX) {
  107. controlEl.css(
  108. 'left',
  109. (mainPosition.left + mainContentWidth + BORDER_WIDTH - controlSize / 2) + 'px'
  110. );
  111. mainEl.css(
  112. 'width',
  113. (mainContentWidth + borderBoxBroder) + 'px'
  114. );
  115. }
  116. if (isInit || !opt.lockY) {
  117. controlEl.css(
  118. 'top',
  119. (mainPosition.top + mainContentHeight + BORDER_WIDTH - controlSize / 2) + 'px'
  120. );
  121. mainEl.css(
  122. 'height',
  123. (mainContentHeight + borderBoxBroder) + 'px'
  124. );
  125. }
  126. label.text(Math.round(mainContentWidth) + ' x ' + Math.round(mainContentHeight));
  127. chartResize();
  128. }
  129. }
  130. };
  131. function throttle(fn, delay, trailing, debounce) {
  132. var currCall = (new Date()).getTime();
  133. var lastCall = 0;
  134. var lastExec = 0;
  135. var timer = null;
  136. var diff;
  137. var scope;
  138. var args;
  139. var isSingle = typeof fn === 'function';
  140. delay = delay || 0;
  141. if (isSingle) {
  142. return createCallback();
  143. }
  144. else {
  145. var ret = [];
  146. for (var i = 0; i < fn.length; i++) {
  147. ret[i] = createCallback(i);
  148. }
  149. return ret;
  150. }
  151. function createCallback(index) {
  152. function exec() {
  153. lastExec = (new Date()).getTime();
  154. timer = null;
  155. (isSingle ? fn : fn[index]).apply(scope, args || []);
  156. }
  157. var cb = function () {
  158. currCall = (new Date()).getTime();
  159. scope = this;
  160. args = arguments;
  161. diff = currCall - (debounce ? lastCall : lastExec) - delay;
  162. clearTimeout(timer);
  163. if (debounce) {
  164. if (trailing) {
  165. timer = setTimeout(exec, delay);
  166. }
  167. else if (diff >= 0) {
  168. exec();
  169. }
  170. }
  171. else {
  172. if (diff >= 0) {
  173. exec();
  174. }
  175. else if (trailing) {
  176. timer = setTimeout(exec, -diff);
  177. }
  178. }
  179. lastCall = currCall;
  180. };
  181. /**
  182. * Clear throttle.
  183. * @public
  184. */
  185. cb.clear = function () {
  186. if (timer) {
  187. clearTimeout(timer);
  188. timer = null;
  189. }
  190. };
  191. return cb;
  192. }
  193. }
  194. })(window);