Guest User

Untitled

a guest
May 20th, 2018
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.19 KB | None | 0 0
  1. function isSupportPassive() {
  2. let isSupport = false;
  3. try {
  4. const opts = Object.defineProperty({}, 'passive', {
  5. get() {
  6. isSupport = true;
  7. },
  8. });
  9. window.addEventListener('test', null, opts);
  10. } catch (e) {
  11. //
  12. }
  13. return isSupport;
  14. }
  15.  
  16. const passiveOptions = isSupportPassive() ? {
  17. passive: true,
  18. capture: false,
  19. } : false;
  20.  
  21. function setStyle($node, name, value) {
  22. $node.style[name] = typeof value === 'number' ? `${value}px` : value; // eslint-disable-line
  23. }
  24.  
  25. function $(selector) {
  26. return typeof selector === 'string' ? document.querySelector(selector) : selector;
  27. }
  28.  
  29. export default class Movable {
  30. /**
  31. * Constructor
  32. * params:
  33. * handlerSelector: handler document node selector.
  34. * containerSelector: container document node selector.
  35. * boundable: support have boundary, default false.
  36. */
  37. constructor(options = {}) {
  38. const {
  39. handlerSelector = '.handler',
  40. containerSelector = '.container',
  41. boundable = false,
  42. } = options;
  43.  
  44. this.$handler = $(handlerSelector);
  45. this.$container = $(containerSelector);
  46.  
  47. this.state = {
  48. boundable,
  49. movable: false,
  50. currentX: 0,
  51. currentY: 0,
  52. top: 0,
  53. left: 0,
  54. maxLeft: 0,
  55. maxTop: 0,
  56. };
  57.  
  58. this.listen();
  59. }
  60.  
  61. /**
  62. * style memebers: handler + container
  63. * 1 make container position absolute
  64. * 2 make handler cursor as move
  65. */
  66. styledMembers() {
  67. // @1 make container absolute
  68. setStyle(this.$container, 'position', 'absolute');
  69. // @2 make handler cusor move
  70. setStyle(this.$handler, 'cursor', 'move');
  71. }
  72.  
  73. listen() {
  74. this.styledMembers();
  75.  
  76. // @1 mouse down on handler
  77. this.$handler.addEventListener('mousedown', this.onMouseDown, passiveOptions);
  78.  
  79. // @2 mouse up on document
  80. document.addEventListener('mouseup', this.onMouseUp, passiveOptions);
  81.  
  82. // @3 mouse move on documnent
  83. document.addEventListener('mousemove', this.onMouseMove, passiveOptions);
  84. }
  85.  
  86. onMouseDown = (event) => {
  87. const {
  88. top,
  89. left,
  90. width,
  91. height,
  92. } = this.$container.getBoundingClientRect();
  93.  
  94. this.state.top = top;
  95. this.state.left = left;
  96. this.state.width = width;
  97. this.state.height = height;
  98. this.state.maxLeft = window.innerWidth - width;
  99. this.state.maxTop = window.innerHeight - height;
  100. this.state.currentX = event.clientX;
  101. this.state.currentY = event.clientY;
  102. this.state.movable = true;
  103. };
  104.  
  105. onMouseUp = () => {
  106. this.state.movable = false;
  107. };
  108.  
  109. onMouseMove = (event) => {
  110. if (!this.state.movable) return false;
  111.  
  112. const deltaX = event.clientX - this.state.currentX;
  113. const deltaY = event.clientY - this.state.currentY;
  114. let left = this.state.left + deltaX;
  115. let top = this.state.top + deltaY;
  116.  
  117. if (this.state.boundable) {
  118. if (left < 0) {
  119. left = 0;
  120. } else if (left > this.state.maxLeft) {
  121. left = this.state.maxLeft;
  122. }
  123.  
  124. if (top < 0) {
  125. top = 0;
  126. } else if (top > this.state.maxTop) {
  127. top = this.state.maxTop;
  128. }
  129. }
  130.  
  131. setStyle(this.$container, 'top', top);
  132. setStyle(this.$container, 'left', left);
  133. };
  134. }
  135.  
  136.  
  137. // test
  138. new Movable('.handler', '.container', true);
Add Comment
Please, Sign In to add comment