Skip to content

Instantly share code, notes, and snippets.

@rootscity
Created February 7, 2016 05:24
Show Gist options
  • Save rootscity/fcf909f5820407a67c8e to your computer and use it in GitHub Desktop.
Save rootscity/fcf909f5820407a67c8e to your computer and use it in GitHub Desktop.
angular-material modal drag directive
// Usage
//
//<md-dialog rc-drag="md-toolbar" ng-cloak>
// <form>
// <md-toolbar>
// ...
// </md-toolbar>
// <md-dialog-content>
// ...
// </md-dialog-content>
// </form>
//</md-dialog>
function rcDragDirective($window, $document) {
'ngInject';
const moveThreshold = 100;
let documentListenersActive = false;
let rAFPending = false;
let mouseStart = null;
let mouseLast = null;
let mouseDelta = {x: 0, y: 0};
let offset = {x: 0, y: 0};
let target;
function setupDocumentListeners() {
if (!documentListenersActive) {
$document.on('mousemove', mousemove);
$document.on('mouseup', mouseup);
documentListenersActive = true;
}
}
function takedownDocumentListeners() {
if (documentListenersActive) {
$document.off('mousemove', mousemove);
$document.off('mouseup', mouseup);
documentListenersActive = false;
}
}
function updateViewport() {
target.css('transform', 'translate('+ (offset.x + mouseDelta.x) +'px,'+ (offset.y + mouseDelta.y) +'px)');
}
function requestUpdateViewport() {
if (!rAFPending) {
$window.requestAnimationFrame(function() {
updateViewport();
rAFPending = false;
});
rAFPending = true;
}
}
function mousedown(ev) {
mouseStart = {x: ev.pageX, y: ev.pageY};
mouseLast = mouseStart;
setupDocumentListeners();
}
function mousemove(ev) {
if (mouseLast === null || Math.abs(ev.pageX - mouseLast.x) > moveThreshold || Math.abs(ev.pageY - mouseLast.y) > moveThreshold) {
mouseStart = null;
mouseup();
}
else {
mouseLast = {x: ev.pageX, y: ev.pageY};
mouseDelta = {x: (ev.pageX - mouseStart.x), y: (ev.pageY - mouseStart.y)};
requestUpdateViewport();
}
}
function mouseup() {
if (mouseStart !== null) {
offset.x += mouseDelta.x;
offset.y += mouseDelta.y;
mouseDelta = {x: 0, y: 0};
}
mouseStart = null;
mouseLast = null;
takedownDocumentListeners();
}
function link(scope, elem, attrs) {
target = elem;
angular.element(elem[0].querySelector(attrs.rcDrag)).bind('mousedown', mousedown);
scope.$on('$destroy', function() {
takedownDocumentListeners();
});
}
return {
restrict: 'A',
link: link
};
}
export default rcDragDirective;
@AndreyBespamyatnov
Copy link

Thanks a lot!

@cmark11
Copy link

cmark11 commented Apr 7, 2018

Can this be updated or work with mat-dialog?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment