mirror of
https://github.com/nasa/openmct.git
synced 2025-06-22 17:08:57 +00:00
[Mobile Gestures] Pan
Adds pan gesture to plots. Sets up the zoom gesture addition. Also the back button is visible on desktop versions.
This commit is contained in:
@ -153,18 +153,6 @@ define(
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function onPinchStart(event) {
|
||||
console.log("Pinch Start");
|
||||
}
|
||||
|
||||
function onPinchChange(event) {
|
||||
console.log("Pinch Change");
|
||||
}
|
||||
|
||||
function onPinchEnd(event) {
|
||||
console.log("Pinch End");
|
||||
}
|
||||
|
||||
function followDataIfLive() {
|
||||
if (isLive) {
|
||||
@ -175,10 +163,7 @@ define(
|
||||
$scope.$on('series:data:add', followDataIfLive);
|
||||
$scope.$on('user:viewport:change:end', onUserViewportChangeEnd);
|
||||
$scope.$on('user:viewport:change:start', onUserViewportChangeStart);
|
||||
$scope.$on('mct:pinch:start', onPinchStart);
|
||||
$scope.$on('mct:pinch:change', onPinchChange);
|
||||
$scope.$on('mct:pinch:end', onPinchEnd);
|
||||
|
||||
|
||||
$scope.$watch('domainObject', linkDomainObject);
|
||||
|
||||
return {
|
||||
|
@ -29,32 +29,43 @@ define(
|
||||
function MCTPinch($log, agentService) {
|
||||
|
||||
function link($scope, element, attrs) {
|
||||
var posPrev,
|
||||
evePrev;
|
||||
|
||||
// Returns position of touch event
|
||||
function trackPosition(event) {
|
||||
return [event.clientX, event.clientY];
|
||||
return {
|
||||
clientX: event.clientX,
|
||||
clientY: event.clientY
|
||||
};
|
||||
}
|
||||
|
||||
function calculateMidpoint(coordOne, coordTwo) {
|
||||
return {
|
||||
clientX: (coordOne.clientX + coordTwo.clientX) / 2,
|
||||
clientY: (coordOne.clientY + coordTwo.clientY) / 2
|
||||
};
|
||||
}
|
||||
|
||||
function calculateDistance(coordOne, coordTwo) {
|
||||
return Math.sqrt(Math.pow(coordOne.clientX - coordTwo.clientX, 2) +
|
||||
Math.pow(coordOne.clientY - coordTwo.clientY, 2));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// On touch start the 'touch' is tracked and
|
||||
// the event is emitted through scope
|
||||
function pinchStart(event) {
|
||||
if (event.changedTouches.length === 2 ||
|
||||
event.touches.length === 2) {
|
||||
var touchPosition = [trackPosition(event.touches[0]),
|
||||
trackPosition(event.touches[1])],
|
||||
touchPositionPrev = posPrev || touchPosition,
|
||||
eventPrev = evePrev || event;
|
||||
var touchPositions = [trackPosition(event.touches[0]),
|
||||
trackPosition(event.touches[1])];
|
||||
|
||||
$scope.$emit('mct:pinch:start');
|
||||
// Set current position to be previous position
|
||||
// for next touch action
|
||||
posPrev = touchPosition;
|
||||
|
||||
// Set current event to be previous event
|
||||
// for next touch action
|
||||
evePrev = event;
|
||||
$scope.$emit('mct:pinch:start', {
|
||||
touches: touchPositions,
|
||||
bounds: event.target.getBoundingClientRect(),
|
||||
midpoint: calculateMidpoint(touchPositions[0], touchPositions[1]),
|
||||
distance: calculateDistance(touchPositions[0], touchPositions[1])
|
||||
});
|
||||
|
||||
// Stops other gestures/button clicks from being active
|
||||
event.preventDefault();
|
||||
@ -66,18 +77,14 @@ define(
|
||||
function pinchChange(event) {
|
||||
if (event.changedTouches.length === 2) {
|
||||
var touchPosition = [trackPosition(event.changedTouches[0]),
|
||||
trackPosition(event.changedTouches[1])],
|
||||
touchPositionPrev = posPrev || touchPosition,
|
||||
eventPrev = evePrev || event;
|
||||
trackPosition(event.changedTouches[1])];
|
||||
|
||||
$scope.$emit('mct:pinch:change');
|
||||
// Set current position to be previous position
|
||||
// for next touch action
|
||||
posPrev = touchPosition;
|
||||
|
||||
// Set current event to be previous event
|
||||
// for next touch action
|
||||
evePrev = event;
|
||||
$scope.$emit('mct:pinch:change', {
|
||||
touches: touchPosition,
|
||||
bounds: event.target.getBoundingClientRect(),
|
||||
midpoint: calculateMidpoint(touchPosition[0], touchPosition[1]),
|
||||
distance: calculateDistance(touchPosition[0], touchPosition[1])
|
||||
});
|
||||
|
||||
// Stops other gestures/button clicks from being active
|
||||
event.preventDefault();
|
||||
@ -87,10 +94,10 @@ define(
|
||||
// On the 'touchend' or 'touchcancel' the event
|
||||
// is emitted through scope
|
||||
function pinchEnd(event) {
|
||||
$scope.$emit('mct:pinch:end');
|
||||
|
||||
// Stops other gestures/button clicks from being active
|
||||
event.preventDefault();
|
||||
$scope.$emit('mct:pinch:end');
|
||||
|
||||
// Stops other gestures/button clicks from being active
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
if (agentService.isMobile(navigator.userAgent)) {
|
||||
|
@ -39,16 +39,18 @@ define(
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
var dragStart,
|
||||
marqueeBox = {},
|
||||
marqueeRect, // Set when exists.
|
||||
chartElementBounds,
|
||||
firstTouches,
|
||||
firstTouchDistance,
|
||||
firstTouchPan,
|
||||
$canvas = $element.find('canvas');
|
||||
|
||||
function updateAxesForCurrentViewport() {
|
||||
// Update axes definitions for current viewport.
|
||||
['domain', 'range'].forEach(function(axisName) {
|
||||
['domain', 'range'].forEach(function (axisName) {
|
||||
var axis = $scope.axes[axisName],
|
||||
firstTick = $scope.viewport.topLeft[axisName],
|
||||
lastTick = $scope.viewport.bottomRight[axisName],
|
||||
@ -60,7 +62,7 @@ define(
|
||||
// Yes, ticksize is negative for domain and positive for range.
|
||||
// It's because ticks are generated/displayed top to bottom and left to right.
|
||||
axis.ticks = [];
|
||||
for (tickNumber = 0; tickNumber < axis.tickCount; tickNumber++) {
|
||||
for (tickNumber = 0; tickNumber < axis.tickCount; tickNumber = tickNumber + 1) {
|
||||
tickIncrement = (axisSize * (tickNumber / denominator));
|
||||
tickValue = firstTick - tickIncrement;
|
||||
axis.ticks.push(
|
||||
@ -147,6 +149,32 @@ define(
|
||||
dragStart = undefined;
|
||||
$scope.$emit('user:viewport:change:end', $scope.viewport);
|
||||
}
|
||||
|
||||
function trackTouchPosition(touchPosition, bounds) {
|
||||
var positionOverElement,
|
||||
positionAsPlotPoint,
|
||||
position;
|
||||
|
||||
chartElementBounds = bounds;
|
||||
|
||||
positionOverElement = {
|
||||
x: touchPosition.clientX - bounds.left,
|
||||
y: touchPosition.clientY - bounds.top
|
||||
};
|
||||
|
||||
positionAsPlotPoint = utils.elementPositionAsPlotPosition(
|
||||
positionOverElement,
|
||||
bounds,
|
||||
$scope.viewport
|
||||
);
|
||||
|
||||
position = {
|
||||
positionOverElement: positionOverElement,
|
||||
positionAsPlotPoint: positionAsPlotPoint
|
||||
};
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
function trackMousePosition($event) {
|
||||
// Calculate coordinates of mouse related to canvas and as
|
||||
@ -158,6 +186,7 @@ define(
|
||||
|
||||
chartElementBounds = bounds;
|
||||
|
||||
|
||||
positionOverElement = {
|
||||
x: $event.clientX - bounds.left,
|
||||
y: $event.clientY - bounds.top
|
||||
@ -202,13 +231,13 @@ define(
|
||||
}
|
||||
|
||||
function toggleInteractionMode(event) {
|
||||
if (event.keyCode === '18') { // control key.
|
||||
if (event.keyCode === 16) { // shift key.
|
||||
watchForDrag();
|
||||
}
|
||||
}
|
||||
|
||||
function resetInteractionMode(event) {
|
||||
if (event.keyCode === '18') {
|
||||
if (event.keyCode === 16) {
|
||||
watchForMarquee();
|
||||
}
|
||||
}
|
||||
@ -241,11 +270,61 @@ define(
|
||||
// TODO: Discuss whether marqueeBox start should be fixed to data or fixed to canvas element, especially when "isLive is true".
|
||||
updateAxesForCurrentViewport();
|
||||
}
|
||||
|
||||
function calculateDistanceChange(startDist, currDist) {
|
||||
return startDist / currDist;
|
||||
}
|
||||
|
||||
function updateZoom(midpoint, bounds, touches, distance) {
|
||||
// calculate offset between points. Apply that offset to viewport.
|
||||
var midpointPosition = trackTouchPosition(midpoint, bounds),
|
||||
newPosition = midpointPosition.positionAsPlotPoint,
|
||||
dDomain = firstTouchPan.domain - newPosition.domain,
|
||||
dRange = firstTouchPan.range - newPosition.range;
|
||||
|
||||
|
||||
$scope.viewport = {
|
||||
topLeft: {
|
||||
domain: $scope.viewport.topLeft.domain + dDomain,
|
||||
range: $scope.viewport.topLeft.range + dRange
|
||||
},
|
||||
bottomRight: {
|
||||
domain: $scope.viewport.bottomRight.domain + dDomain,
|
||||
range: $scope.viewport.bottomRight.range + dRange
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function startZoom(midpoint, bounds, touches, distance) {
|
||||
$scope.$emit('user:viewport:change:start');
|
||||
firstTouches = touches;
|
||||
firstTouchDistance = distance;
|
||||
firstTouchPan = trackTouchPosition(midpoint, bounds).positionAsPlotPoint;
|
||||
}
|
||||
|
||||
function endZoom() {
|
||||
$scope.$emit('user:viewport:change:end', $scope.viewport);
|
||||
}
|
||||
|
||||
function onPinchStart(event, touch) {
|
||||
startZoom(touch.midpoint, touch.bounds, touch.touches, touch.distance);
|
||||
}
|
||||
|
||||
function onPinchChange(event, touch) {
|
||||
updateZoom(touch.midpoint, touch.bounds, touch.touches, touch.distance);
|
||||
}
|
||||
|
||||
function onPinchEnd(event) {
|
||||
endZoom();
|
||||
}
|
||||
|
||||
$scope.$watchCollection('viewport', onViewportChange);
|
||||
|
||||
|
||||
$scope.$on('mct:pinch:start', onPinchStart);
|
||||
$scope.$on('mct:pinch:change', onPinchChange);
|
||||
$scope.$on('mct:pinch:end', onPinchEnd);
|
||||
|
||||
$scope.$on('$destroy', stopWatching);
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
|
Reference in New Issue
Block a user