Skip to content
Snippets Groups Projects
Commit ec02d12e authored by Klaas Kliffen's avatar Klaas Kliffen :satellite:
Browse files

Initial SkyView component

parent 6334bd00
Branches main
No related tags found
No related merge requests found
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
# Matches multiple files with brace expansion notation
# Set default charset
[*.{js,py}]
charset = utf-8
# 4 space indentation
[*.py]
indent_style = space
indent_size = 4
# Tab indentation (no size specified)
[Makefile]
indent_style = tab
# Indentation override for all JS under lib directory
[*.{js,ts,jsx,tsx}]
indent_style = space
indent_size = 2
# Matches the exact files either package.json or .travis.yml
[{package.json,.travis.yml}]
indent_style = space
indent_size = 2
{
"typescript.tsdk": "node_modules/typescript/lib"
}
This diff is collapsed.
......@@ -12,7 +12,7 @@
"@types/react-dom": "^18.0.6",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"react-scripts": "^5.0.1",
"typescript": "^4.7.4",
"web-vitals": "^2.1.4"
},
......
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<meta name="description" content="Web site created using create-react-app" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link rel='stylesheet' href='https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css' />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
......@@ -26,6 +26,7 @@
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
......@@ -39,5 +40,9 @@
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.1.min.js" charset="utf-8"></script>
<script type="text/javascript" src="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.js"
charset="utf-8"></script>
</body>
</html>
This diff is collapsed.
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
import React from 'react';
import logo from './logo.svg';
import './App.css';
import React, { useState } from 'react';
import SkyView from './SkyView';
// TODO: Load sources from somewhere else
const a = A.source(0, 0, { hello: "World", size: 42 });
const catalogA = A.catalog({ name: "A", sourceSize: 20, color: "#fff", onClick: "showPopup" });
catalogA.addSources([a]);
const b = A.source(0, 2, { hello: "universe", size: 42 });
const catalogB = A.catalog({ name: "B", sourceSize: 20, color: "#f00", onClick: "showPopup" });
catalogB.addSources([b]);
function App() {
const [catalogs, setCatalogs] = useState([catalogA]);
function handleClickA() {
console.log("A & B");
setCatalogs([catalogA, catalogB])
}
function handleClickB() {
console.log("A");
setCatalogs([catalogA]);
}
function handleClickC() {
catalogA.addSources(A.source(Math.random(), Math.random(), { hello: "World", size: 42 }));
setCatalogs([catalogA]);
}
function handleViewChanged(ra: number, dec: number, fov: number) {
console.log(ra, dec, fov)
}
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
<div>
<SkyView catalogs={catalogs} onViewChanged={handleViewChanged} />
<button onClick={handleClickA}>Add B</button>
<button onClick={handleClickB}>Remove B</button>
<button onClick={handleClickC}>Add new sources</button>
</div>
);
}
......
import React, { CSSProperties, useEffect, useRef, useState } from "react";
type Props = {
catalogs: AladinCatalog[],
onViewChanged: (ra: number, dec: number, fov: number) => void
};
const style: CSSProperties = { width: 800, height: 600, background: "#AAA" };
// TODO: Add event listeners for dragging -> updating the view
const SkyView = (props: Props) => {
const { catalogs, onViewChanged } = props;
const ref = useRef<HTMLDivElement>(null);
const [instance, setInstance] = useState<AladinInstance | null>(null);
useEffect(() => {
if (ref.current) {
const el = ref.current;
setInstance(A.aladin(`#${el.id}`));
console.error("sky view mounted");
return () => {
console.error("sky view unmounted");
// TODO: remove listeners?
// Check if everything is correctly cleared.
// Destroy aladin SkyView
el.innerHTML = "";
setInstance(null);
}
}
}, []);
/**
* Re add the catalog whenever the instance is changed
*/
useEffect(() => {
if (instance) {
console.log(catalogs);
for (let catalog of catalogs) {
instance.addCatalog(catalog);
}
instance.on("positionChanged", (_) => {
const [ra, dec] = instance?.getRaDec();
const fov = Math.max(...instance?.getFov());
onViewChanged(ra, dec, fov);
});
// TODO: add opZoomChanged
console.log("catalogs added");
return () => {
// This does not clear the layers in the `Manage Layers` toolbox
instance.removeLayers();
console.log("catalogs removed");
}
}
}, [catalogs, instance, onViewChanged]);
function handleDragEnd() {
console.log(instance?.getRaDec(), instance?.getFov());
}
return (
<div
onMouseUp={handleDragEnd}
onMouseLeave={handleDragEnd}
onWheel={handleDragEnd}
ref={ref} style={style} id="SkyView"/>
);
}
export default SkyView;
// Aladin SkyView Lite is declared as `A` in the global scope
type AladinColorMaps = "cubehelix" | "eosb" | "rainbow" | "grayscale" | "native";
interface AladinImageLayer {
// TODO: What are it's properties?
}
// TODO: Fix callback function declaration
interface AladinCallback {
success: (raDec: string) => void;
error: (err?: any) => void;
}
interface AladinHipsImageFormat {
imgFormat: "jpg" | "png";
}
interface AladinOptions {
target?: string;
cooFrame?: string;
survey?: string;
fov?: number;
showReticle?: boolean;
showZoomControl?: boolean;
showFullscreenControl?: boolean;
showLayersControl?: boolean;
showGotoControl?: boolean;
showShareControl?: boolean;
showSimbadPointerControl?: boolean;
showFrame?: boolean;
fullScreen?: boolean;
reticleColor?: string;
reicleSize?: number;
};
interface AladinSource {
}
interface AladinCatalog {
readonly addSources: (sources: AladinSource | AladinSource[]) => void;
readonly remove: (source: AladinSource) => void;
}
interface AladinInstance {
readonly getRaDec: () => [number, number];
readonly getSize: () => [number, number];
readonly getFov: () => [number, number];
readonly getFovCorners: (nbSteps?: number) => [number, number][];
readonly setFov: (degrees: number) => void;
readonly adjustFovForObject: (target: string) => void;
readonly setFovRange: (minFov: number, maxFov: number) => void;
readonly gotoRaDec: (ra: number, dec: number) => void;
readonly gotoObject: (target: string, callback?: AladinCallback) => void;
readonly setImageSurvey: (hhipsID: string, hipsName: string, hipsBaseUrl: string, hipsFrame: "equatorial" | "galactic", hipsMaxOrder: number, format: AladinHipsImageFormat) => void;
readonly getBaseImageLayer: () => AladinImageLayer;
readonly getColorMap: () => AladinColorMaps;
readonly displayFITS: (fitsUrl: string) => void;
readonly addCatalog: (catalog: AladinCatalog) => void;
readonly removeLayers: () => void;
// TODO: check if listener can be "cancelled"
readonly on: (type: "objectHovered" | "objectClicked" | "positionChanged", handler: (obj: any) => void) => void;
};
interface AladinCatalogOptions {
name?: string;
shape?: "circle" | "plus" | "rhomb" | "cross" | "triangle" | "square" | HTMLCanvasElement; // JPEG/PNG also supported, but how?
color?: string;
sourceSize?: number;
raField?: string;
decField?: string;
labelColumn?: string;
labelColor?: string;
labelFont?: string;
onClick?: "showTable" | "showPopup";
limit?: number;
}
type AladinCatalogCallback = (sources: AladinSource[]) => void;
interface Aladin {
readonly aladin: (id: string, options?: AladinOptions) => AladinInstance;
readonly catalog: (options?: AladinCatalogOptions) => AladinCatalog;
readonly source: (ra: number, dec: number, data: any) => AladinSource;
// TODO: add option info
readonly catalogFromUrl: (url: string, options?: AladinCatalogOptions, successCallback: AladinCatalogCallback, useProxy?: boolean) => AladinCatalog;
// TODO Add other catalog methods
// catalogFromSimbad(<target>, <radius-in-degrees>, <catalog-options>?, <successCallback>?)
// A.catalogFromVizieR(<vizier-cat-id>, <target>, <radius-in-deg>, <cat-options>?, <successCallback>?)
// A.catalogFromNED(<target>, <radius-in-degrees>, <catalog-options>?, <successCallback>?)
// Additional optional query options can be specified as a keyword/value dictionary, eg: {"-loc": 500, "-filter": 0}
// A.catalogFromSkyBot(<ra>, <dec>, <radius>, <epoch>, <query-options>?, <cat-options>?, <successCallback>?)
// Markers?
// A.marker(ra, dec, {popupTitle: <title of the popup>, popupDesc: <text (possibly HTML) for the popup>})
// TODO: Add the final functions
};
declare const A: Aladin;
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import './index.css';
import "./normalize.css";
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(
......
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>
\ No newline at end of file
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
/* Document
========================================================================== */
/**
* 1. Correct the line height in all browsers.
* 2. Prevent adjustments of font size after orientation changes in iOS.
*/
html {
line-height: 1.15; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
}
/* Sections
========================================================================== */
/**
* Remove the margin in all browsers.
*/
body {
margin: 0;
}
/**
* Render the `main` element consistently in IE.
*/
main {
display: block;
}
/**
* Correct the font size and margin on `h1` elements within `section` and
* `article` contexts in Chrome, Firefox, and Safari.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/* Grouping content
========================================================================== */
/**
* 1. Add the correct box sizing in Firefox.
* 2. Show the overflow in Edge and IE.
*/
hr {
box-sizing: content-box; /* 1 */
height: 0; /* 1 */
overflow: visible; /* 2 */
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
pre {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/* Text-level semantics
========================================================================== */
/**
* Remove the gray background on active links in IE 10.
*/
a {
background-color: transparent;
}
/**
* 1. Remove the bottom border in Chrome 57-
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
*/
abbr[title] {
border-bottom: none; /* 1 */
text-decoration: underline; /* 2 */
text-decoration: underline dotted; /* 2 */
}
/**
* Add the correct font weight in Chrome, Edge, and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
samp {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/**
* Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` elements from affecting the line height in
* all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/* Embedded content
========================================================================== */
/**
* Remove the border on images inside links in IE 10.
*/
img {
border-style: none;
}
/* Forms
========================================================================== */
/**
* 1. Change the font styles in all browsers.
* 2. Remove the margin in Firefox and Safari.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
line-height: 1.15; /* 1 */
margin: 0; /* 2 */
}
/**
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/
button,
input { /* 1 */
overflow: visible;
}
/**
* Remove the inheritance of text transform in Edge, Firefox, and IE.
* 1. Remove the inheritance of text transform in Firefox.
*/
button,
select { /* 1 */
text-transform: none;
}
/**
* Correct the inability to style clickable types in iOS and Safari.
*/
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
/**
* Remove the inner border and padding in Firefox.
*/
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* Restore the focus styles unset by the previous rule.
*/
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
/**
* Correct the padding in Firefox.
*/
fieldset {
padding: 0.35em 0.75em 0.625em;
}
/**
* 1. Correct the text wrapping in Edge and IE.
* 2. Correct the color inheritance from `fieldset` elements in IE.
* 3. Remove the padding so developers are not caught out when they zero out
* `fieldset` elements in all browsers.
*/
legend {
box-sizing: border-box; /* 1 */
color: inherit; /* 2 */
display: table; /* 1 */
max-width: 100%; /* 1 */
padding: 0; /* 3 */
white-space: normal; /* 1 */
}
/**
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/
progress {
vertical-align: baseline;
}
/**
* Remove the default vertical scrollbar in IE 10+.
*/
textarea {
overflow: auto;
}
/**
* 1. Add the correct box sizing in IE 10.
* 2. Remove the padding in IE 10.
*/
[type="checkbox"],
[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* Correct the cursor style of increment and decrement buttons in Chrome.
*/
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Correct the odd appearance in Chrome and Safari.
* 2. Correct the outline style in Safari.
*/
[type="search"] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/**
* Remove the inner padding in Chrome and Safari on macOS.
*/
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* 1. Correct the inability to style clickable types in iOS and Safari.
* 2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}
/* Interactive
========================================================================== */
/*
* Add the correct display in Edge, IE 10+, and Firefox.
*/
details {
display: block;
}
/*
* Add the correct display in all browsers.
*/
summary {
display: list-item;
}
/* Misc
========================================================================== */
/**
* Add the correct display in IE 10+.
*/
template {
display: none;
}
/**
* Add the correct display in IE 10.
*/
[hidden] {
display: none;
}
......@@ -18,7 +18,7 @@
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
"jsx": "react"
},
"include": [
"src"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment