mirror of
https://github.com/cds-astro/aladin-lite.git
synced 2025-12-25 12:25:52 -08:00
Compare commits
6 Commits
select-imp
...
small-devi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9202375d2e | ||
|
|
b77267709d | ||
|
|
4d8ca68f8c | ||
|
|
c63284fc12 | ||
|
|
630f4453cc | ||
|
|
c80cba8ec8 |
2
.github/workflows/api_doc.yml
vendored
2
.github/workflows/api_doc.yml
vendored
@@ -43,7 +43,7 @@ jobs:
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
# Upload entire repository
|
||||
path: './doc'
|
||||
path: './docs'
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
## 3.4.2-beta
|
||||
|
||||
* [impr] Improve smartphone support by setting media queries + a better logic for deploying the contextual menu sub options.
|
||||
* [impr] Improve `WCS` view export with 3rd euler rotation encoding: <https://github.com/cds-astro/aladin-lite/issues/170>. Still some cases are to be handled like: crval on the equator or cylindrical with a galactic frame rotation.
|
||||
* [fixed] Change `RADECSYS` to `RADESYS` for `Aladin#getViewWCS` to follow fits standard deprecation
|
||||
* [feat] Add new method `Aladin#getViewImageBuffer` to get the current view as a PNG buffer
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, height=device-height, maximum-scale=1.0, initial-scale=1.0, user-scalable=no">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
@@ -77,11 +77,7 @@
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
.aladin-stack-control {
|
||||
position: absolute;
|
||||
top: 10rem;
|
||||
left: 10rem;
|
||||
}
|
||||
|
||||
|
||||
.myBox {
|
||||
top: unset;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, height=device-height, maximum-scale=1.0, initial-scale=1.0, user-scalable=no">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
import A from '../src/js/A.js';
|
||||
let aladin;
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin('#aladin-lite-div', {target: '00 00 00 +07 00 00', fov: 130, survey: 'P/Mellinger/color', showContextMenu: true});
|
||||
aladin = A.aladin('#aladin-lite-div', {target: '00 00 00 +07 00 00', fov: 130, survey: 'P/Mellinger/color', showContextMenu: true, fullScreen: true});
|
||||
var moc11 = A.MOCFromURL('http://skies.esac.esa.int/HST/NICMOS/Moc.fits', {color: '#84f', lineWidth: 3}, (moc) => {
|
||||
// moc is ready
|
||||
console.log(moc.contains(205.9019247, +2.4492764));
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "aladin-lite"
|
||||
description = "Aladin Lite v3 introduces a new graphical engine written in Rust with the use of WebGL"
|
||||
license = "BSD-3-Clause"
|
||||
repository = "https://github.com/cds-astro/aladin-lite"
|
||||
version = "3.4.1-beta"
|
||||
version = "3.4.2-beta"
|
||||
authors = [ "baumannmatthieu0@gmail.com", "matthieu.baumann@astro.unistra.fr",]
|
||||
edition = "2018"
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
There can be a more supported alternative here: https://caniuse.com/?search=grid-template-columns */
|
||||
/*container-type: inline-size;*/
|
||||
|
||||
font-size: 1rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.aladin-imageCanvas {
|
||||
@@ -58,7 +58,6 @@
|
||||
|
||||
.aladin-measurement-div {
|
||||
font-family: monospace;
|
||||
font-size: 0.8rem;
|
||||
|
||||
display: block;
|
||||
|
||||
@@ -132,7 +131,7 @@
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
/*font-family: monospace;*/
|
||||
font-size: 11px;
|
||||
|
||||
color: #000;
|
||||
}
|
||||
.aladin-marker-measurement table {
|
||||
@@ -205,8 +204,8 @@
|
||||
border-radius: 2px;
|
||||
position: absolute;
|
||||
max-width: 15em;
|
||||
font-size: inherit;
|
||||
|
||||
font-size: 0.8rem;
|
||||
font-family: monospace;
|
||||
background: #fff;
|
||||
|
||||
@@ -234,7 +233,7 @@ canvas {
|
||||
}
|
||||
|
||||
.aladin-box-title {
|
||||
font-size: 16px;
|
||||
font-size: 1.0rem;
|
||||
/*font-family: Verdana, Geneva, Tahoma, sans-serif;*/
|
||||
line-height: 1.5em;
|
||||
font-weight: bold;
|
||||
@@ -256,7 +255,7 @@ canvas {
|
||||
border: 1px solid #AEAEAE!important;
|
||||
|
||||
border-radius: 3px;
|
||||
font-size: 13px!important;
|
||||
font-size: 1rem;
|
||||
background: #fff!important;
|
||||
margin-right: 0.2em!important;
|
||||
|
||||
@@ -277,7 +276,7 @@ canvas {
|
||||
border: 1px solid #AEAEAE;
|
||||
border-radius: 3px;
|
||||
background: #fff;
|
||||
font-size: 15px;
|
||||
font-size: 1.0rem;
|
||||
font-weight: bold;
|
||||
line-height: 0px;
|
||||
padding: 8px 2px;
|
||||
@@ -313,7 +312,8 @@ canvas {
|
||||
margin: 0;
|
||||
padding: 0.2rem;
|
||||
|
||||
font-size: 1rem;
|
||||
font-size: inherit;
|
||||
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
@@ -418,7 +418,6 @@ canvas {
|
||||
.aladin-input-text.search {
|
||||
background-image:none;
|
||||
text-indent: 0rem;
|
||||
font-size: 1rem;
|
||||
line-height: 1.2rem;
|
||||
}
|
||||
|
||||
@@ -541,7 +540,6 @@ canvas {
|
||||
|
||||
.aladin-window {
|
||||
/*font-family: Verdana, Geneva, Tahoma, sans-serif;*/
|
||||
font-size: 13px;
|
||||
background: white;
|
||||
border: 1px solid #bbb;
|
||||
border-radius: 2px;
|
||||
@@ -560,7 +558,6 @@ canvas {
|
||||
|
||||
.aladin-popup {
|
||||
/*font-family: Verdana, Geneva, Tahoma, sans-serif;*/
|
||||
font-size: 13px;
|
||||
background: white;
|
||||
border: 1px solid #bbb;
|
||||
border-radius: 2px;
|
||||
@@ -637,8 +634,6 @@ canvas {
|
||||
scrollbar-width: none;
|
||||
|
||||
max-width: 20rem;
|
||||
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.aladin-sp-title a {
|
||||
@@ -646,14 +641,9 @@ canvas {
|
||||
color: #317d8d;
|
||||
}
|
||||
|
||||
.aladin-sp-content {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.aladin-sp-content a {
|
||||
text-decoration: none;
|
||||
color: #478ade;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.aladin-cuts {
|
||||
@@ -704,8 +694,6 @@ canvas {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
box-shadow: 0 0 8px rgba(0,0,0,0.2);
|
||||
font-size: 0.9rem;
|
||||
/*font-family: Verdana, Geneva, Tahoma, sans-serif;*/
|
||||
|
||||
border-radius: 3px;
|
||||
@@ -754,12 +742,22 @@ canvas {
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.aladin-context-menu-item:hover > .aladin-context-sub-menu {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.aladin-context-menu-item:hover {
|
||||
/* This is for the tooltip to appear outside the item, i.e. over the sibling item */
|
||||
.aladin-context-menu-item:hover {
|
||||
color: greenyellow;
|
||||
}
|
||||
|
||||
.aladin-context-menu-item:not(hover) {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.aladin-context-menu-item .aladin-context-sub-menu {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.aladin-context-menu .aladin-context-menu-item span {
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
@@ -776,20 +774,31 @@ canvas {
|
||||
display: block;
|
||||
}
|
||||
*/
|
||||
.aladin-context-menu.left .aladin-context-sub-menu {
|
||||
.aladin-context-menu .aladin-context-sub-menu.left {
|
||||
left: 0;
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
.aladin-context-menu.top .aladin-context-sub-menu {
|
||||
.aladin-context-menu .aladin-context-sub-menu.right {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.aladin-context-menu .aladin-context-sub-menu.bottom {
|
||||
top: 100%;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.aladin-context-menu .aladin-context-sub-menu.top {
|
||||
top: 0;
|
||||
left: 0;
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
|
||||
.aladin-context-menu.left.top .aladin-context-sub-menu {
|
||||
.aladin-context-menu .aladin-context-sub-menu.left.top {
|
||||
transform: translate(-100%, -100%);
|
||||
}
|
||||
|
||||
|
||||
.aladin-reticle {
|
||||
position: absolute;
|
||||
|
||||
@@ -816,7 +825,6 @@ canvas {
|
||||
padding: 0.3rem;
|
||||
border-radius: 5px;
|
||||
font-family: monospace;
|
||||
font-size: 1rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@@ -835,14 +843,14 @@ canvas {
|
||||
/* Reset */
|
||||
border: 1px solid white;
|
||||
outline: 0;
|
||||
font: inherit;
|
||||
/*font: inherit;*/
|
||||
/* Personalize */
|
||||
padding: 2px;
|
||||
padding: 0.2em;
|
||||
font-size: inherit;
|
||||
border-radius: 0.25em;
|
||||
box-shadow: 0 0 1em 0 rgba(0, 0, 0, 0.2);
|
||||
cursor: pointer;
|
||||
font-family: monospace;
|
||||
font-size: 1rem;
|
||||
width: 100%;
|
||||
/* <option> colors */
|
||||
/* Remove focus outline */
|
||||
@@ -989,7 +997,6 @@ canvas {
|
||||
position: absolute;
|
||||
|
||||
/*font-family: Verdana, Geneva, Tahoma, sans-serif;*/
|
||||
font-size: 0.9rem;
|
||||
|
||||
transition-delay: 100ms;
|
||||
}
|
||||
@@ -1097,10 +1104,9 @@ canvas {
|
||||
|
||||
color: white;
|
||||
|
||||
font-size: 1rem;
|
||||
border-radius: 5px;
|
||||
height: 1.7rem;
|
||||
width: 5rem;
|
||||
width: 4.5rem;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1125,18 +1131,29 @@ canvas {
|
||||
.aladin-location {
|
||||
position: absolute;
|
||||
top: 0.2rem;
|
||||
left: 5.4rem;
|
||||
left: 5.0rem;
|
||||
font-family: monospace;
|
||||
|
||||
color: white;
|
||||
|
||||
font-size: 1rem;
|
||||
border-radius: 5px;
|
||||
height: 1.7rem;
|
||||
}
|
||||
|
||||
.aladin-input-text {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.aladin-location .aladin-input-text {
|
||||
width: 15rem;
|
||||
width: 13.5rem;
|
||||
height: 100%;
|
||||
border-radius: 0 0.4rem 0.4rem 0;
|
||||
}
|
||||
|
||||
.aladin-location .aladin-location-copy {
|
||||
margin-right: -0.2rem;
|
||||
border-radius: 0.4rem 0px 0px 0.4rem;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.aladin-fov {
|
||||
@@ -1148,7 +1165,6 @@ canvas {
|
||||
|
||||
font-family: monospace;
|
||||
|
||||
font-size: 1rem;
|
||||
border-radius: 5px;
|
||||
line-height: 1.7rem;
|
||||
}
|
||||
@@ -1224,6 +1240,35 @@ canvas {
|
||||
}
|
||||
|
||||
/* Media query */
|
||||
@media screen and (max-width:480px) {
|
||||
/* smartphones, Android phones, landscape iPhone */
|
||||
.aladin-location > .aladin-btn {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.aladin-location > .aladin-input-text {
|
||||
border-radius: 0.4rem;
|
||||
}
|
||||
|
||||
.aladin-projection-control {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.aladin-location .aladin-location-copy {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width:370px) {
|
||||
/* smartphones, Android phones, landscape iPhone */
|
||||
.aladin-location {
|
||||
left: 0.2rem;
|
||||
}
|
||||
.aladin-cooFrame {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/*@media screen and (max-width: 31rem) {
|
||||
.aladin-projection-control {
|
||||
display: none;
|
||||
|
||||
22
src/js/A.js
22
src/js/A.js
@@ -452,28 +452,6 @@ A.MOCFromPolygon= function (polygon, options, successCallback, errorCallback) {
|
||||
return moc;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents options for configuring a catalog.
|
||||
*
|
||||
* @typedef {Object} CatalogOptions
|
||||
* @property {string} url - The URL of the catalog.
|
||||
* @property {string} [name="catalog"] - The name of the catalog.
|
||||
* @property {string} [color] - The color associated with the catalog.
|
||||
* @property {number} [sourceSize=8] - The size of the sources in the catalog.
|
||||
* @property {number} [markerSize=12] - The size of the markers associated with sources.
|
||||
* @property {string} [shape="square"] - The shape of the sources (e.g., "square", "circle", "rhomb", "triangle", "cross").
|
||||
* @property {number} [limit] - The maximum number of sources to display.
|
||||
* @property {function} [onClick] - The callback function to execute on a source click.
|
||||
* @property {boolean} [readOnly=false] - Whether the catalog is read-only.
|
||||
* @property {string} [raField] - The ID or name of the field holding Right Ascension (RA).
|
||||
* @property {string} [decField] - The ID or name of the field holding Declination (dec).
|
||||
* @property {function} [filter] - The filtering function for sources. Returns a boolean
|
||||
* @property {boolean} [displayLabel=false] - Whether to display labels for sources.
|
||||
* @property {string} [labelColumn] - The name of the column to be used for the label.
|
||||
* @property {string} [labelColor] - The color of the source labels.
|
||||
* @property {string} [labelFont="10px sans-serif"] - The font for the source labels.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a catalog with configurable options for display and interaction.
|
||||
*
|
||||
|
||||
@@ -40,34 +40,35 @@ import { Circle } from "./shapes/Circle.js";
|
||||
import { Footprint } from "./Footprint.js";
|
||||
|
||||
/**
|
||||
* Represents options for configuring a catalog.
|
||||
*
|
||||
* @namespace
|
||||
* @typedef {Object} Catalog
|
||||
* @typedef {Object} CatalogOptions
|
||||
* @property {string} url - The URL of the catalog.
|
||||
* @property {string} [name="catalog"] - The name of the catalog.
|
||||
* @property {string} [color] - The color associated with the catalog.
|
||||
* @property {number} [sourceSize=8] - The size of the sources in the catalog.
|
||||
* @property {string|function|Image|HTMLCanvasElement} [shape="square"] - The shape of the sources (can be, "square", "circle", "plus", "cross", "rhomb", "triangle").
|
||||
* @property {number} [limit] - The maximum number of sources to display.
|
||||
* @property {string|Function} [onClick] - Whether the source data appears as a table row or a in popup. Can be 'showTable' string, 'showPopup' string or a custom user defined function that handles the click.
|
||||
* @property {boolean} [readOnly=false] - Whether the catalog is read-only.
|
||||
* @property {string} [raField] - The ID or name of the field holding Right Ascension (RA).
|
||||
* @property {string} [decField] - The ID or name of the field holding Declination (dec).
|
||||
* @property {function} [filter] - The filtering function for sources.
|
||||
* @property {string} [selectionColor="#00ff00"] - The color to apply to selected sources in the catalog.
|
||||
* @property {string} [hoverColor=color] - The color to apply to sources in the catalog when they are hovered.
|
||||
* @property {boolean} [displayLabel=false] - Whether to display labels for sources.
|
||||
* @property {string} [labelColumn] - The name of the column to be used for the label.
|
||||
* @property {string} [labelColor=color] - The color of the source labels.
|
||||
* @property {string} [labelFont="10px sans-serif"] - The font for the source labels.
|
||||
*/
|
||||
|
||||
export let Catalog = (function () {
|
||||
/**
|
||||
* Represents a catalog with configurable options for display and interaction.
|
||||
*
|
||||
* @class
|
||||
* @constructs Catalog
|
||||
* @param {Object} options - Configuration options for the catalog.
|
||||
* @param {string} options.url - The URL of the catalog.
|
||||
* @param {string} [options.name="catalog"] - The name of the catalog.
|
||||
* @param {string} [options.color] - The color associated with the catalog.
|
||||
* @param {number} [options.sourceSize=8] - The size of the sources in the catalog.
|
||||
* @param {string|function|Image|HTMLCanvasElement} [options.shape="square"] - The shape of the sources (can be, "square", "circle", "plus", "cross", "rhomb", "triangle").
|
||||
* @param {number} [options.limit] - The maximum number of sources to display.
|
||||
* @param {string|Function} [options.onClick] - Whether the source data appears as a table row or a in popup. Can be 'showTable' string, 'showPopup' string or a custom user defined function that handles the click.
|
||||
* @param {boolean} [options.readOnly=false] - Whether the catalog is read-only.
|
||||
* @param {string} [options.raField] - The ID or name of the field holding Right Ascension (RA).
|
||||
* @param {string} [options.decField] - The ID or name of the field holding Declination (dec).
|
||||
* @param {function} [options.filter] - The filtering function for sources.
|
||||
* @param {string} [options.selectionColor] - The color to apply to selected sources in the catalog.
|
||||
* @param {string} [options.hoverColor] - The color to apply to sources in the catalog when they are hovered.
|
||||
* @param {boolean} [options.displayLabel=false] - Whether to display labels for sources.
|
||||
* @param {string} [options.labelColumn] - The name of the column to be used for the label.
|
||||
* @param {string} [options.labelColor] - The color of the source labels.
|
||||
* @param {string} [options.labelFont="10px sans-serif"] - The font for the source labels.
|
||||
* @param {CatalogOptions} options - Configuration options for the catalog.
|
||||
*
|
||||
* @example
|
||||
* const catalogOptions = {
|
||||
|
||||
@@ -34,6 +34,7 @@ import { CatalogQueryBox } from "./gui/Box/CatalogQueryBox.js";
|
||||
import cameraIconUrl from '../../assets/icons/camera.svg'
|
||||
import targetIconUrl from '../../assets/icons/target.svg';
|
||||
import uploadIconUrl from '../../assets/icons/upload.svg';
|
||||
import selectIconUrl from '../../assets/icons/select.svg';
|
||||
|
||||
export let DefaultActionsForContextMenu = (function () {
|
||||
|
||||
@@ -164,7 +165,7 @@ export let DefaultActionsForContextMenu = (function () {
|
||||
|
||||
files.forEach(file => {
|
||||
const url = URL.createObjectURL(file);
|
||||
let moc = A.MOCFromURL(url, { name: file.name, edge: true });
|
||||
let moc = A.MOCFromURL(url, { name: file.name });
|
||||
a.addMOC(moc);
|
||||
});
|
||||
};
|
||||
@@ -190,6 +191,30 @@ export let DefaultActionsForContextMenu = (function () {
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: {
|
||||
icon: {
|
||||
monochrome: true,
|
||||
url: selectIconUrl,
|
||||
size: 'small',
|
||||
},
|
||||
content: "Select sources"
|
||||
},
|
||||
subMenu: [
|
||||
{
|
||||
label: 'Circular',
|
||||
action(o) {
|
||||
a.select('circle', selectObjects)
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Rectangular',
|
||||
action(o) {
|
||||
a.select('rect', selectObjects)
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: {
|
||||
icon: {
|
||||
@@ -219,23 +244,6 @@ export let DefaultActionsForContextMenu = (function () {
|
||||
window.open(hips2fitsUrl, '_blank');
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "Select sources",
|
||||
subMenu: [
|
||||
{
|
||||
label: 'Circular',
|
||||
action(o) {
|
||||
a.select('circle', selectObjects)
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Rectangular',
|
||||
action(o) {
|
||||
a.select('rect', selectObjects)
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -539,7 +539,17 @@ export class OverlayStackBox extends Box {
|
||||
self.hipsSelectorBox._show({
|
||||
position: self.position,
|
||||
});*/
|
||||
self.aladin.addNewImageLayer();
|
||||
self.aladin.addNewImageLayer(
|
||||
A.imageHiPS('CDS/P/DSS2/color', {
|
||||
errorCallback: (e) => {
|
||||
aladin.addStatusBarMessage({
|
||||
duration: 2000,
|
||||
type: 'info',
|
||||
message: 'DSS2 colored HiPS could not plot',
|
||||
})
|
||||
}
|
||||
})
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -107,9 +107,6 @@ export class Location extends DOMElement {
|
||||
}
|
||||
},
|
||||
value: parseCoo(),
|
||||
cssStyle: {
|
||||
borderRadius: "0px 5px 5px 0px",
|
||||
}
|
||||
});
|
||||
|
||||
let copyBtn = new ActionButton({
|
||||
@@ -122,15 +119,8 @@ export class Location extends DOMElement {
|
||||
action(e) {
|
||||
self.copyCoordinatesToClipboard()
|
||||
},
|
||||
cssStyle: {
|
||||
height: '1.4rem',
|
||||
width: '1.4rem',
|
||||
paddingRight: '0.2rem',
|
||||
borderRadius: "5px 0px 0px 5px",
|
||||
borderRight: 'none',
|
||||
}
|
||||
})
|
||||
copyBtn.element().style.marginRight = 0;
|
||||
copyBtn.el.classList.add("aladin-location-copy");
|
||||
|
||||
let el = Layout.horizontal({
|
||||
layout: [
|
||||
|
||||
@@ -91,7 +91,7 @@ export class ContextMenu extends DOMElement {
|
||||
ContextMenu._menus.push(this);
|
||||
}
|
||||
|
||||
static lastHoveredItem;
|
||||
//static lastHoveredItem;
|
||||
|
||||
_attachOption(target, opt, e, cssStyle) {
|
||||
let item = document.createElement('li');
|
||||
@@ -202,7 +202,8 @@ export class ContextMenu extends DOMElement {
|
||||
}
|
||||
|
||||
if (opt.subMenu && opt.subMenu.length > 0) {
|
||||
item.appendChild(new Icon({url: nextIconSvg, size: 'small', monochrome: true}).element());
|
||||
let iconElt = new Icon({url: nextIconSvg, size: 'small', monochrome: true}).element();
|
||||
item.appendChild(iconElt);
|
||||
item.style.display = 'flex';
|
||||
item.style.alignItems = 'center';
|
||||
item.style.justifyContent = 'space-between';
|
||||
@@ -218,19 +219,27 @@ export class ContextMenu extends DOMElement {
|
||||
}
|
||||
|
||||
if (opt.subMenu) {
|
||||
// User
|
||||
item.addEventListener('click', e => {
|
||||
e.stopPropagation();
|
||||
|
||||
if (item.parentNode) {
|
||||
let subMenus = item.parentNode.querySelectorAll(".aladin-context-sub-menu")
|
||||
for (let subMenuChild of subMenus) {
|
||||
subMenuChild.style.display = 'none';
|
||||
}
|
||||
/* Add the ability to deploy the menu/sub-menus for touch screen devices */
|
||||
if (Utils.hasTouchScreen()) {
|
||||
let subMenu = item.querySelector(".aladin-context-sub-menu")
|
||||
let subMenuIsShown = subMenu.style.display === "block";
|
||||
|
||||
if (item.parentNode) {
|
||||
let subMenus = item.parentNode.querySelectorAll(".aladin-context-sub-menu")
|
||||
for (let subMenuChild of subMenus) {
|
||||
subMenuChild.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
if (!subMenuIsShown) {
|
||||
subMenu.style.setProperty('display', 'block');
|
||||
}
|
||||
}
|
||||
|
||||
item.querySelector(".aladin-context-sub-menu")
|
||||
.style.display = 'block';
|
||||
|
||||
if (opt.action && (!opt.disabled || opt.disabled === false)) {
|
||||
opt.action(e, self);
|
||||
}
|
||||
@@ -278,7 +287,7 @@ export class ContextMenu extends DOMElement {
|
||||
opt.hover(e, item);
|
||||
}
|
||||
|
||||
if (ContextMenu.lastHoveredItem) {
|
||||
/*if (ContextMenu.lastHoveredItem) {
|
||||
let parent = ContextMenu.lastHoveredItem.parentNode;
|
||||
if (parent && (areSiblings(parent, item) || item.contains(parent) || item === parent)) {
|
||||
ContextMenu.lastHoveredItem.style.display = 'none';
|
||||
@@ -289,7 +298,7 @@ export class ContextMenu extends DOMElement {
|
||||
if (subMenu) {
|
||||
subMenu.style.display = 'block';
|
||||
ContextMenu.lastHoveredItem = subMenu;
|
||||
}
|
||||
}*/
|
||||
})
|
||||
|
||||
item.addEventListener('mouseout', e => {
|
||||
@@ -308,44 +317,43 @@ export class ContextMenu extends DOMElement {
|
||||
target.appendChild(item);
|
||||
}
|
||||
|
||||
_subMenuDisplay(parent) {
|
||||
const {offsetWidth, offsetHeight} = this.aladin.aladinDiv;
|
||||
const aladinRect = this.aladin.aladinDiv.getBoundingClientRect();
|
||||
_subMenuDisplay(parent, child) {
|
||||
parent.style.display = "block";
|
||||
child.style.display = "block";
|
||||
|
||||
if (child.classList.contains('aladin-context-sub-menu')) {
|
||||
const aladinRect = this.aladin.aladinDiv.getBoundingClientRect();
|
||||
|
||||
let leftDir = 0;
|
||||
let topDir = 0;
|
||||
let o = parent.getBoundingClientRect();
|
||||
let c = child.getBoundingClientRect();
|
||||
|
||||
for (let item of parent.children) {
|
||||
item.style.display = "block";
|
||||
child.classList.remove('left', 'right', 'top', 'bottom');
|
||||
|
||||
let r = item.getBoundingClientRect();
|
||||
|
||||
if (r.x - aladinRect.left <= aladinRect.right - (r.x + r.width)) {
|
||||
leftDir -= 1;
|
||||
// First check if there is place towards the right, which is the desired behaviour
|
||||
if (aladinRect.right - (o.x + o.width) >= c.width) {
|
||||
// do nothing as it is by default considering this case
|
||||
} else if (o.x - aladinRect.left >= c.width) {
|
||||
child.classList.add('left');
|
||||
} else if (aladinRect.bottom - (o.y + o.height) >= c.height) {
|
||||
child.classList.add('bottom');
|
||||
} else {
|
||||
leftDir += 1;
|
||||
child.classList.add('top');
|
||||
}
|
||||
|
||||
if (r.y - aladinRect.top <= offsetHeight / 2.0) {
|
||||
/*if (r.y - aladinRect.top <= offsetHeight / 2.0) {
|
||||
topDir -= 1;
|
||||
} else {
|
||||
topDir += 1;
|
||||
}
|
||||
|
||||
item.style.display = "";
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
if (leftDir > 0) {
|
||||
this.el.classList.add('left');
|
||||
} else {
|
||||
this.el.classList.add('right');
|
||||
for (let grandChild of child.children) {
|
||||
this._subMenuDisplay(child, grandChild);
|
||||
}
|
||||
|
||||
if (topDir > 0) {
|
||||
this.el.classList.add('top');
|
||||
} else {
|
||||
this.el.classList.add('bottom');
|
||||
}
|
||||
child.style.display = "";
|
||||
parent.style.display = "";
|
||||
}
|
||||
|
||||
show(options) {
|
||||
@@ -366,14 +374,14 @@ export class ContextMenu extends DOMElement {
|
||||
let mouseCoords = options && options.e && Utils.relMouseCoords(options.e)
|
||||
// Set position
|
||||
const position =
|
||||
options && options.position ||
|
||||
{left: mouseCoords.x, top: mouseCoords.y};
|
||||
options && options.position ||
|
||||
{left: mouseCoords.x, top: mouseCoords.y};
|
||||
|
||||
this.setPosition({...position, aladin: this.aladin})
|
||||
|
||||
this.el.classList.remove('left')
|
||||
this.el.classList.remove('top')
|
||||
|
||||
this._subMenuDisplay(this.el)
|
||||
for (let childEl of this.el.children) {
|
||||
this._subMenuDisplay(this.el, childEl);
|
||||
}
|
||||
|
||||
super._show()
|
||||
}
|
||||
|
||||
3
tutorials/Examples.md
Normal file
3
tutorials/Examples.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# JS API
|
||||
|
||||
A list of examples illustrating the API is available at this [link](https://aladin.cds.unistra.fr/AladinLite/doc/API/examples/)
|
||||
@@ -1,4 +1,4 @@
|
||||
# User guide
|
||||
# Customization
|
||||
|
||||
This is a guide for users wanting to customize the apparence of Aladin Lite user interface.
|
||||
|
||||
Reference in New Issue
Block a user