scrollbar.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.Scrollbar = exports.DEFAULT_THEME = void 0;
  4. var tslib_1 = require("tslib");
  5. var dom_util_1 = require("@antv/dom-util");
  6. var util_1 = require("@antv/util");
  7. var group_component_1 = require("../abstract/group-component");
  8. var DEFAULT_STYLE = {
  9. trackColor: 'rgba(0,0,0,0)',
  10. thumbColor: 'rgba(0,0,0,0.15)',
  11. size: 8,
  12. lineCap: 'round',
  13. };
  14. exports.DEFAULT_THEME = {
  15. // 默认样式
  16. default: DEFAULT_STYLE,
  17. // 鼠标 hover 的样式
  18. hover: {
  19. thumbColor: 'rgba(0,0,0,0.2)',
  20. },
  21. };
  22. var Scrollbar = /** @class */ (function (_super) {
  23. tslib_1.__extends(Scrollbar, _super);
  24. function Scrollbar() {
  25. var _this = _super !== null && _super.apply(this, arguments) || this;
  26. _this.clearEvents = util_1.noop;
  27. _this.onStartEvent = function (isMobile) { return function (e) {
  28. _this.isMobile = isMobile;
  29. e.originalEvent.preventDefault();
  30. var clientX = isMobile ? util_1.get(e.originalEvent, 'touches.0.clientX') : e.clientX;
  31. var clientY = isMobile ? util_1.get(e.originalEvent, 'touches.0.clientY') : e.clientY;
  32. // 将开始的点记录下来
  33. _this.startPos = _this.cfg.isHorizontal ? clientX : clientY;
  34. _this.bindLaterEvent();
  35. }; };
  36. _this.bindLaterEvent = function () {
  37. var containerDOM = _this.getContainerDOM();
  38. var events = [];
  39. if (_this.isMobile) {
  40. events = [
  41. dom_util_1.addEventListener(containerDOM, 'touchmove', _this.onMouseMove),
  42. dom_util_1.addEventListener(containerDOM, 'touchend', _this.onMouseUp),
  43. dom_util_1.addEventListener(containerDOM, 'touchcancel', _this.onMouseUp),
  44. ];
  45. }
  46. else {
  47. events = [
  48. dom_util_1.addEventListener(containerDOM, 'mousemove', _this.onMouseMove),
  49. dom_util_1.addEventListener(containerDOM, 'mouseup', _this.onMouseUp),
  50. // 为了保证划出 canvas containerDom 时还没触发 mouseup
  51. dom_util_1.addEventListener(containerDOM, 'mouseleave', _this.onMouseUp),
  52. ];
  53. }
  54. _this.clearEvents = function () {
  55. events.forEach(function (e) {
  56. e.remove();
  57. });
  58. };
  59. };
  60. // 拖拽滑块的事件回调
  61. // 这里是 dom 原生事件,绑定在 dom 元素上的
  62. _this.onMouseMove = function (e) {
  63. var _a = _this.cfg, isHorizontal = _a.isHorizontal, thumbOffset = _a.thumbOffset;
  64. e.preventDefault();
  65. var clientX = _this.isMobile ? util_1.get(e, 'touches.0.clientX') : e.clientX;
  66. var clientY = _this.isMobile ? util_1.get(e, 'touches.0.clientY') : e.clientY;
  67. // 鼠标松开的位置
  68. var endPos = isHorizontal ? clientX : clientY;
  69. // 滑块需要移动的距离, 由于这里是对滑块监听,所以移动的距离就是 diffDis, 如果监听对象是 container dom,则需要算比例
  70. var diff = endPos - _this.startPos;
  71. // 更新 _startPos
  72. _this.startPos = endPos;
  73. _this.updateThumbOffset(thumbOffset + diff);
  74. };
  75. _this.onMouseUp = function (e) {
  76. e.preventDefault();
  77. _this.clearEvents();
  78. };
  79. // 点击滑道的事件回调,移动滑块位置
  80. _this.onTrackClick = function (e) {
  81. var _a = _this.cfg, isHorizontal = _a.isHorizontal, x = _a.x, y = _a.y, thumbLen = _a.thumbLen;
  82. var containerDOM = _this.getContainerDOM();
  83. var rect = containerDOM.getBoundingClientRect();
  84. var clientX = e.clientX, clientY = e.clientY;
  85. var offset = isHorizontal ? clientX - rect.left - x - thumbLen / 2 : clientY - rect.top - y - thumbLen / 2;
  86. var newOffset = _this.validateRange(offset);
  87. _this.updateThumbOffset(newOffset);
  88. };
  89. _this.onThumbMouseOver = function () {
  90. var thumbColor = _this.cfg.theme.hover.thumbColor;
  91. _this.getElementByLocalId('thumb').attr('stroke', thumbColor);
  92. _this.draw();
  93. };
  94. _this.onThumbMouseOut = function () {
  95. var thumbColor = _this.cfg.theme.default.thumbColor;
  96. _this.getElementByLocalId('thumb').attr('stroke', thumbColor);
  97. _this.draw();
  98. };
  99. return _this;
  100. }
  101. Scrollbar.prototype.setRange = function (min, max) {
  102. this.set('minLimit', min);
  103. this.set('maxLimit', max);
  104. var curValue = this.getValue();
  105. var newValue = util_1.clamp(curValue, min, max);
  106. if (curValue !== newValue && !this.get('isInit')) {
  107. this.setValue(newValue);
  108. }
  109. };
  110. Scrollbar.prototype.getRange = function () {
  111. var min = this.get('minLimit') || 0;
  112. var max = this.get('maxLimit') || 1;
  113. return { min: min, max: max };
  114. };
  115. Scrollbar.prototype.setValue = function (value) {
  116. var range = this.getRange();
  117. var originalValue = this.getValue();
  118. this.update({
  119. thumbOffset: (this.get('trackLen') - this.get('thumbLen')) * util_1.clamp(value, range.min, range.max),
  120. });
  121. this.delegateEmit('valuechange', {
  122. originalValue: originalValue,
  123. value: this.getValue(),
  124. });
  125. };
  126. Scrollbar.prototype.getValue = function () {
  127. return util_1.clamp(this.get('thumbOffset') / (this.get('trackLen') - this.get('thumbLen')), 0, 1);
  128. };
  129. Scrollbar.prototype.getDefaultCfg = function () {
  130. var cfg = _super.prototype.getDefaultCfg.call(this);
  131. return tslib_1.__assign(tslib_1.__assign({}, cfg), { name: 'scrollbar', isHorizontal: true, minThumbLen: 20, thumbOffset: 0, theme: exports.DEFAULT_THEME });
  132. };
  133. Scrollbar.prototype.renderInner = function (group) {
  134. this.renderTrackShape(group);
  135. this.renderThumbShape(group);
  136. };
  137. Scrollbar.prototype.applyOffset = function () {
  138. this.moveElementTo(this.get('group'), {
  139. x: this.get('x'),
  140. y: this.get('y'),
  141. });
  142. };
  143. Scrollbar.prototype.initEvent = function () {
  144. this.bindEvents();
  145. };
  146. // 创建滑道的 shape
  147. Scrollbar.prototype.renderTrackShape = function (group) {
  148. var _a = this.cfg, trackLen = _a.trackLen, _b = _a.theme, theme = _b === void 0 ? { default: {} } : _b;
  149. var _c = util_1.deepMix({}, exports.DEFAULT_THEME, theme).default, lineCap = _c.lineCap, trackColor = _c.trackColor, themeSize = _c.size;
  150. var size = util_1.get(this.cfg, 'size', themeSize);
  151. var attrs = this.get('isHorizontal')
  152. ? {
  153. x1: 0 + size / 2,
  154. y1: size / 2,
  155. x2: trackLen - size / 2,
  156. y2: size / 2,
  157. lineWidth: size,
  158. stroke: trackColor,
  159. lineCap: lineCap,
  160. }
  161. : {
  162. x1: size / 2,
  163. y1: 0 + size / 2,
  164. x2: size / 2,
  165. y2: trackLen - size / 2,
  166. lineWidth: size,
  167. stroke: trackColor,
  168. lineCap: lineCap,
  169. };
  170. return this.addShape(group, {
  171. id: this.getElementId('track'),
  172. name: 'track',
  173. type: 'line',
  174. attrs: attrs,
  175. });
  176. };
  177. // 创建滑块的 shape
  178. Scrollbar.prototype.renderThumbShape = function (group) {
  179. var _a = this.cfg, thumbOffset = _a.thumbOffset, thumbLen = _a.thumbLen, theme = _a.theme;
  180. var _b = util_1.deepMix({}, exports.DEFAULT_THEME, theme).default, themeSize = _b.size, lineCap = _b.lineCap, thumbColor = _b.thumbColor;
  181. var size = util_1.get(this.cfg, 'size', themeSize);
  182. var attrs = this.get('isHorizontal')
  183. ? {
  184. x1: thumbOffset + size / 2,
  185. y1: size / 2,
  186. x2: thumbOffset + thumbLen - size / 2,
  187. y2: size / 2,
  188. lineWidth: size,
  189. stroke: thumbColor,
  190. lineCap: lineCap,
  191. cursor: 'default',
  192. }
  193. : {
  194. x1: size / 2,
  195. y1: thumbOffset + size / 2,
  196. x2: size / 2,
  197. y2: thumbOffset + thumbLen - size / 2,
  198. lineWidth: size,
  199. stroke: thumbColor,
  200. lineCap: lineCap,
  201. cursor: 'default',
  202. };
  203. return this.addShape(group, {
  204. id: this.getElementId('thumb'),
  205. name: 'thumb',
  206. type: 'line',
  207. attrs: attrs,
  208. });
  209. };
  210. Scrollbar.prototype.bindEvents = function () {
  211. var group = this.get('group');
  212. group.on('mousedown', this.onStartEvent(false));
  213. group.on('mouseup', this.onMouseUp);
  214. group.on('touchstart', this.onStartEvent(true));
  215. group.on('touchend', this.onMouseUp);
  216. var trackShape = group.findById(this.getElementId('track'));
  217. trackShape.on('click', this.onTrackClick);
  218. var thumbShape = group.findById(this.getElementId('thumb'));
  219. thumbShape.on('mouseover', this.onThumbMouseOver);
  220. thumbShape.on('mouseout', this.onThumbMouseOut);
  221. };
  222. Scrollbar.prototype.getContainerDOM = function () {
  223. var container = this.get('container');
  224. var canvas = container && container.get('canvas');
  225. return canvas && canvas.get('container');
  226. };
  227. Scrollbar.prototype.validateRange = function (offset) {
  228. var _a = this.cfg, thumbLen = _a.thumbLen, trackLen = _a.trackLen;
  229. var newOffset = offset;
  230. if (offset + thumbLen > trackLen) {
  231. newOffset = trackLen - thumbLen;
  232. }
  233. else if (offset + thumbLen < thumbLen) {
  234. newOffset = 0;
  235. }
  236. return newOffset;
  237. };
  238. Scrollbar.prototype.draw = function () {
  239. var container = this.get('container');
  240. var canvas = container && container.get('canvas');
  241. if (canvas) {
  242. canvas.draw();
  243. }
  244. };
  245. Scrollbar.prototype.updateThumbOffset = function (offset) {
  246. var _a = this.cfg, thumbOffset = _a.thumbOffset, isHorizontal = _a.isHorizontal, thumbLen = _a.thumbLen, size = _a.size;
  247. var newOffset = this.validateRange(offset);
  248. if (newOffset === thumbOffset) {
  249. // 如果更新后的 offset 与原值相同,则不改变
  250. return;
  251. }
  252. var thumbShape = this.getElementByLocalId('thumb');
  253. if (isHorizontal) {
  254. thumbShape.attr({
  255. x1: newOffset + size / 2,
  256. x2: newOffset + thumbLen - size / 2,
  257. });
  258. }
  259. else {
  260. thumbShape.attr({
  261. y1: newOffset + size / 2,
  262. y2: newOffset + thumbLen - size / 2,
  263. });
  264. }
  265. this.emitOffsetChange(newOffset);
  266. };
  267. Scrollbar.prototype.emitOffsetChange = function (offset) {
  268. var _a = this.cfg, originalValue = _a.thumbOffset, trackLen = _a.trackLen, thumbLen = _a.thumbLen;
  269. this.cfg.thumbOffset = offset;
  270. // 发送事件
  271. this.emit('scrollchange', {
  272. thumbOffset: offset,
  273. ratio: util_1.clamp(offset / (trackLen - thumbLen), 0, 1),
  274. });
  275. this.delegateEmit('valuechange', {
  276. originalValue: originalValue,
  277. value: offset,
  278. });
  279. };
  280. return Scrollbar;
  281. }(group_component_1.default));
  282. exports.Scrollbar = Scrollbar;
  283. //# sourceMappingURL=scrollbar.js.map