Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Touch handling for sky browser #134

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 78 additions & 22 deletions src/components/BottomBar/SkyBrowser/WorldWideTelescope.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ function WorldWideTelescope({
const [isDragging, setIsDragging] = React.useState(false);
const [startDragPosition, setStartDragPosition] = React.useState([0, 0]);
const [wwtHasLoaded, setWwtHasLoaded] = React.useState(false);
const [isPinching, setIsPinching] = React.useState(false);
const [startPinchPositions, setStartPinchPositions] = React.useState([]);
const [setupWwtFunc, setSetupWwtFunc] = React.useState(null);
const TopBarHeight = 25;
// Refs
Expand Down Expand Up @@ -160,42 +162,93 @@ function WorldWideTelescope({
});
}

function handleDrag(mouse) {
if (isDragging) {
function getClientXY(interaction) {
let position = undefined;
if (interaction.type === "touchstart" || interaction.type === "touchmove") {
if (!interaction?.touches?.[0]?.clientX || !interaction?.touches?.[0]?.clientY) {
return;
}
if (interaction?.touches?.length > 1) {
const touches = interaction.touches;
position = [
[touches[0].clientX, touches[0].clientY],
[touches[1].clientX, touches[1].clientY]
];
}
else {
const touch = interaction.touches[0];
position = [touch.clientX, touch.clientY];
}
}
else { // mouse
position = [interaction.clientX, interaction.clientY];
}
if (!position) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if-statement seems unnecessary. If !position is true, it means that it's undefined, which means that we will return undefined even if we just return position as is

return undefined;
}
return position;
}

function scrollZoom(scroll) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "scroll" value here is a bit ambiguous. What doe sit mean? Does it deserve a more describing name?

if (inverseZoom) {
scroll *= -1;
}
skybrowserApi.scrollOverBrowser(browserId, scroll);
skybrowserApi.stopAnimations(browserId);
}

function handleDrag(interaction) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this is nitpicky, but as this is an event handler function, I would prefer to call the interaction variable event instead. To make it clear that it is actually an object of the javascript event type :) The same goes for all the interaction variables in this file

const end = getClientXY(interaction);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is a position, or rather, multiple positions, the name should reflect that. It's also the current position rather than the end position

Just positions?

if (isDragging && end) {
// Calculate pixel translation
const end = [mouse.clientX, mouse.clientY];
const width = size.width - BorderWidth;
const height = size.height - BorderWidth;
const translation = [end[0] - startDragPosition[0], end[1] - startDragPosition[1]];

const percentageX = translation[0] / width;
const percentageY = translation[1] / height;
// Calculate [ra, dec] translation without roll
const percentageTranslation = [translation[0] / width, translation[1] / height];
const percentageTranslation = [ percentageX, percentageY ];

// Call lua function
skybrowserApi.finetuneTargetPosition(
browserId,
percentageTranslation
);
}
else if (isPinching && end) {
const euclidianDistance = (coord => {
const a = coord[0][0] - coord[1][0];
const b = coord[0][1] - coord[1][1];
return Math.sqrt(a * a + b * b);
});
// See if distance is larger or smaller compared to first
// interaction
const startDistance = euclidianDistance(startPinchPositions);
const endDistance = euclidianDistance(end);

const scroll = startDistance < endDistance ? 1 : -1;
scrollZoom(scroll);
}
}

function mouseDown(mouse) {
function startInteraction(interaction) {
const position = getClientXY(interaction);
skybrowserApi.startFinetuningTarget(browserId);
const position = [mouse.clientX, mouse.clientY];
setIsDragging(true);
setStartDragPosition(position);
const hasMultipleCoords = Array.isArray(position[0]);
if (hasMultipleCoords) {
setIsPinching(true);
setStartPinchPositions(position);
} else {
setIsDragging(true);
setStartDragPosition(position);
}
skybrowserApi.stopAnimations(browserId);
}

function mouseUp(mouse) {
function endInteraction() {
setIsDragging(false);
}

function scroll(e) {
let scroll = e.deltaY;
if (inverseZoom) {
scroll *= -1;
}
skybrowserApi.scrollOverBrowser(browserId, scroll);
skybrowserApi.stopAnimations(browserId);
setIsPinching(false);
}

function changeSize(widthWwt, heightWwt) {
Expand All @@ -218,10 +271,13 @@ function WorldWideTelescope({
const interactionDiv = <div
className={styles.container}
onMouseMove={handleDrag}
onMouseDown={mouseDown}
onMouseUp={mouseUp}
onMouseLeave={mouseUp}
onWheel = {(e) => scroll(e)}
onMouseDown={startInteraction}
onMouseUp={endInteraction}
onMouseLeave={endInteraction}
onTouchStart={startInteraction}
onTouchMove={handleDrag}
onTouchEnd={endInteraction}
onWheel = {(e) => scrollZoom(e.deltaY)}
/>

return (
Expand Down