You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

drag.js 1.5KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. function reactToDrag(element, onDrag, beforeDrag) {
  2. let xStart, yStart
  3. let startDrag = event => {
  4. // Avoid the default events
  5. event.preventDefault()
  6. // Store the position where the drag started
  7. xStart = event.pageX
  8. yStart = event.pageY
  9. // Fire the start drag event
  10. if (beforeDrag) {
  11. var { x, y } = parent.point(event.pageX, event.pageY)
  12. beforeDrag(event, x, y)
  13. }
  14. // Register events to react to dragging and drag ends
  15. SVG.on(window, ['mousemove.drag', 'touchmove.drag'], reactDrag)
  16. SVG.on(window, ['mouseup.drag', 'touchend.drag'], stopDrag)
  17. }
  18. let reactDrag = event => {
  19. // Convert screen coordinates to svg coordinates and use them
  20. var { x, y } = parent.point(event.pageX, event.pageY)
  21. if (onDrag)
  22. onDrag(event, x, y)
  23. }
  24. let stopDrag = event => {
  25. SVG.off(window, ['mousemove.drag', 'touchmove.drag'])
  26. SVG.off(window, ['mouseup.drag', 'touchend.drag'])
  27. }
  28. // Bind the drag tracker to this element directly
  29. let parent = element.root()
  30. let point = new SVG.Point()
  31. element.mousedown(startDrag).touchstart(startDrag)
  32. }
  33. SVG.extend(SVG.Element, {
  34. draggable: function (after) {
  35. let sx, sy
  36. reactToDrag(this, (e, x, y) => {
  37. this.transform({
  38. origin: [sx, sy],
  39. position: [x, y],
  40. })
  41. if (after) {
  42. after(this, x, y)
  43. }
  44. }, (e, x, y) => {
  45. var toAbsolute = new SVG.Matrix(this).inverse()
  46. var p = new SVG.Point(x, y).transform(toAbsolute)
  47. sx = p.x
  48. sy = p.y
  49. })
  50. return this
  51. },
  52. })