Updating OHIF draggable utility to use CSS3 translate
This commit is contained in:
1 parent
a7d6cb4fea
commit
edba1052da
8 files changed
+196
-137
No files matched your search
@@ -1,3 +1,5 @@
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
|
||||
// Allow attaching to jQuery selectors
|
||||
$.fn.draggable = function(options) {
|
||||
makeDraggable(this, options);
|
||||
@@ -12,19 +14,33 @@ $.fn.draggable = function(options) {
|
||||
* @param element
|
||||
*/
|
||||
function makeDraggable(element, options) {
|
||||
var container = $(window);
|
||||
var diffX,
|
||||
diffY,
|
||||
wasNotDragged = true;
|
||||
const $element = element;
|
||||
|
||||
// Force to hardware acceleration to move element if browser supports translate property
|
||||
const { styleProperty } = OHIF.ui;
|
||||
const useTransform = styleProperty.check('transform', 'translate(1px, 1px)');
|
||||
|
||||
const $container = $(window);
|
||||
let diffX;
|
||||
let diffY;
|
||||
let wasNotDragged = true;
|
||||
|
||||
let lastCursor, lastOffset;
|
||||
let lastTranslateX = 0;
|
||||
let lastTranslateY = 0;
|
||||
|
||||
options = options || {};
|
||||
options.defaultElementCursor = options.defaultElementCursor || 'default';
|
||||
|
||||
// initialize dragged flag
|
||||
element.data('wasDragged', false);
|
||||
$element.data('wasDragged', false);
|
||||
|
||||
function matrixToArray(str) {
|
||||
return str.match(/(-?[0-9\.]+)/g);
|
||||
}
|
||||
|
||||
function getCursorCoords(e) {
|
||||
var cursor = {
|
||||
const cursor = {
|
||||
x: e.clientX,
|
||||
y: e.clientY
|
||||
};
|
||||
@@ -33,12 +49,28 @@ function makeDraggable(element, options) {
|
||||
if (cursor.x === undefined) {
|
||||
cursor.x = e.originalEvent.touches[0].pageX;
|
||||
}
|
||||
|
||||
if (cursor.y === undefined) {
|
||||
cursor.y = e.originalEvent.touches[0].pageY;
|
||||
}
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
function reposition(elementLeft, elementTop) {
|
||||
if (useTransform) {
|
||||
const translation = `translate(${elementLeft}px, ${elementTop}px)`;
|
||||
styleProperty.set($element[0], 'transform', translation);
|
||||
} else {
|
||||
$element.css({
|
||||
left: elementLeft + 'px',
|
||||
top: elementTop + 'px',
|
||||
bottom: 'auto', // Setting these to empty doesn't seem to work in Firefox or Safari
|
||||
right: 'auto'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function startMoving(e) {
|
||||
// Prevent dragging dialog by clicking on slider
|
||||
// (could be extended for buttons, not sure it's necessary
|
||||
@@ -50,27 +82,31 @@ function makeDraggable(element, options) {
|
||||
if (e.button !== 0) return;
|
||||
|
||||
// Stop the dragging if the element is being resized
|
||||
if ($(element).hasClass('resizing')) {
|
||||
if ($element.hasClass('resizing')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var elementTop = parseFloat(element.offset().top),
|
||||
elementLeft = parseFloat(element.offset().left);
|
||||
let elementLeft = parseFloat($element.offset().left);
|
||||
let elementTop = parseFloat($element.offset().top);
|
||||
|
||||
var cursor = getCursorCoords(e);
|
||||
diffX = cursor.x - elementLeft;
|
||||
diffY = cursor.y - elementTop;
|
||||
const cursor = getCursorCoords(e);
|
||||
if (useTransform) {
|
||||
lastCursor = cursor;
|
||||
lastOffset = $element.offset();
|
||||
const transformMatrix = matrixToArray($element.css('transform')) || [];
|
||||
lastTranslateX = parseFloat(transformMatrix[4]) || lastTranslateX;
|
||||
lastTranslateY = parseFloat(transformMatrix[5]) || lastTranslateX;
|
||||
elementLeft = lastTranslateX;
|
||||
elementTop = lastTranslateY;
|
||||
} else {
|
||||
diffX = cursor.x - elementLeft;
|
||||
diffY = cursor.y - elementTop;
|
||||
}
|
||||
|
||||
container.css('cursor', 'move');
|
||||
element.css('cursor', 'move');
|
||||
$container.css('cursor', 'move');
|
||||
$element.css('cursor', 'move');
|
||||
|
||||
element.css({
|
||||
cursor: 'move',
|
||||
left: elementLeft + 'px',
|
||||
top: elementTop + 'px',
|
||||
bottom: 'auto', // Setting these to empty doesn't seem to work in Firefox or Safari
|
||||
right: 'auto'
|
||||
});
|
||||
reposition(elementLeft, elementTop);
|
||||
|
||||
$(document).on('mousemove', moveHandler);
|
||||
$(document).on('mouseup', stopMoving);
|
||||
@@ -80,15 +116,15 @@ function makeDraggable(element, options) {
|
||||
|
||||
// let outside world know that the element in question has been dragged
|
||||
if (wasNotDragged) {
|
||||
element.data('wasDragged', true);
|
||||
$element.data('wasDragged', true);
|
||||
wasNotDragged = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function stopMoving() {
|
||||
container.css('cursor', 'default');
|
||||
element.css('cursor', options.defaultElementCursor);
|
||||
$container.css('cursor', 'default');
|
||||
$element.css('cursor', options.defaultElementCursor);
|
||||
|
||||
$(document).off('mousemove', moveHandler);
|
||||
$(document).off('touchmove', moveHandler);
|
||||
@@ -98,35 +134,57 @@ function makeDraggable(element, options) {
|
||||
// Prevent dialog box dragging whole page in iOS
|
||||
e.preventDefault();
|
||||
|
||||
var elementWidth = parseFloat(element.outerWidth()),
|
||||
elementHeight = parseFloat(element.outerHeight()),
|
||||
containerWidth = parseFloat(container.width()),
|
||||
containerHeight = parseFloat(container.height());
|
||||
const elementWidth = parseFloat($element.outerWidth());
|
||||
const elementHeight = parseFloat($element.outerHeight());
|
||||
const containerWidth = parseFloat($container.width());
|
||||
const containerHeight = parseFloat($container.height());
|
||||
|
||||
var cursor = getCursorCoords(e);
|
||||
const cursor = getCursorCoords(e);
|
||||
|
||||
var elementLeft = cursor.x - diffX;
|
||||
var elementTop = cursor.y - diffY;
|
||||
let elementLeft, elementTop;
|
||||
if (useTransform) {
|
||||
elementLeft = lastTranslateX - (lastCursor.x - cursor.x);
|
||||
elementTop = lastTranslateY - (lastCursor.y - cursor.y);
|
||||
|
||||
elementLeft = Math.max(elementLeft, 0);
|
||||
elementTop = Math.max(elementTop, 0);
|
||||
const limitX = containerWidth - elementWidth;
|
||||
const limitY = containerHeight - elementHeight;
|
||||
const sumX = lastOffset.left + (elementLeft - lastTranslateX);
|
||||
const sumY = lastOffset.top + (elementTop - lastTranslateY);
|
||||
|
||||
if (elementLeft + elementWidth > containerWidth) {
|
||||
elementLeft = containerWidth - elementWidth;
|
||||
if (sumX > limitX) {
|
||||
elementLeft -= sumX - limitX;
|
||||
}
|
||||
|
||||
if (sumY > limitY) {
|
||||
elementTop -= sumY - limitY;
|
||||
}
|
||||
|
||||
if (sumX < 0) {
|
||||
elementLeft += 0 - sumX;
|
||||
}
|
||||
|
||||
if (sumY < 0) {
|
||||
elementTop += 0 - sumY;
|
||||
}
|
||||
} else {
|
||||
elementLeft = cursor.x - diffX;
|
||||
elementTop = cursor.y - diffY;
|
||||
|
||||
elementLeft = Math.max(elementLeft, 0);
|
||||
elementTop = Math.max(elementTop, 0);
|
||||
|
||||
if (elementLeft + elementWidth > containerWidth) {
|
||||
elementLeft = containerWidth - elementWidth;
|
||||
}
|
||||
|
||||
if (elementTop + elementHeight > containerHeight) {
|
||||
elementTop = containerHeight - elementHeight;
|
||||
}
|
||||
}
|
||||
|
||||
if (elementTop + elementHeight > containerHeight) {
|
||||
elementTop = containerHeight - elementHeight;
|
||||
}
|
||||
|
||||
element.css({
|
||||
left: elementLeft + 'px',
|
||||
top: elementTop + 'px',
|
||||
bottom: 'auto', // Setting these to empty doesn't seem to work in Firefox or Safari
|
||||
right: 'auto'
|
||||
});
|
||||
reposition(elementLeft, elementTop);
|
||||
}
|
||||
|
||||
element.on('mousedown', startMoving);
|
||||
element.on('touchstart', startMoving);
|
||||
};
|
||||
$element.on('mousedown', startMoving);
|
||||
$element.on('touchstart', startMoving);
|
||||
}
|
||||
Reference in new issue
Block a user