first commit

This commit is contained in:
Matthieu Baumann
2024-04-02 18:31:46 +02:00
committed by Matthieu Baumann
parent 8b8c1460eb
commit d56dbd1659
33 changed files with 556 additions and 256 deletions

View File

@@ -1,5 +1,9 @@
# Changelogs
## 3.3.3
* [feat] Hover color support by @pmatsson and @bmatthieu3 in <https://github.com/cds-astro/aladin-lite/pull/145>
## 3.3.2
* [fixed] do not allow to query the properties several times for an imageHiPS

View File

@@ -52,8 +52,8 @@
}
}
aladin.view.setGridConfig({opacity: 0, color: {r: 51/255, g: 209/255, b: 1}})
aladin.view.setGridConfig({enabled: true})
aladin.setCooGrid({opacity: 0, color: {r: 51/255, g: 209/255, b: 1}})
aladin.setCooGrid({enabled: true})
async function s_1() {
return new Promise((resolve, reject) => {
@@ -98,7 +98,7 @@
async function showGrid() {
for await(const it of interval(50, 40)) {
aladin.view.setGridConfig({opacity: it / 40})
aladin.setCooGrid({opacity: it / 40})
}
}
@@ -155,7 +155,7 @@
async function hideGrid() {
for await(const it of interval(50, 40)) {
aladin.view.setGridConfig({opacity: 1 - it / 40})
aladin.setCooGrid({opacity: 1 - it / 40})
}
}

View File

@@ -0,0 +1,45 @@
<!doctype html>
<html>
<head>
</head>
<body>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<script>let aladin;</script>
<script type="module">
import A from '../src/js/A.js';
A.init.then(() => {
// Start up Aladin Lite
aladin = A.aladin('#aladin-lite-div', {
target: "M31",
fov: 2,
showContextMenu: true,
fullScreen: true,
showSimbadPointerControl: true,
showShareControl: true,
showSettingsControl: true,
showStackLayerControl: true,
samp: true,
});
aladin.addCatalog(A.catalogFromVizieR("VII/237/pgc", "M31", 3, {
limit: 1000,
//orderBy: 'nb_ref',
onClick: 'showTable',
color: 'yellow',
hoverColor: 'blue',
shape: (s) => {
let coo = A.coo();
coo.parse(s.data['RAJ2000'] + ' ' + s.data['DEJ2000'])
let a = (0.1 * Math.pow(10, +s.data.logD25)) / 60;
let b = (1.0 / Math.pow(10, +s.data.logR25)) * a
return A.ellipse(coo.lon, coo.lat, a, b, +s.data.PA, {lineWidth: 3});
}
}));
});
</script>
</body>
</html>

View File

@@ -10,7 +10,7 @@
import A from '../src/js/A.js';
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {target: 'LMC', fov: 55, showContextMenu: true});
aladin = A.aladin('#aladin-lite-div', {target: '12 25 41.512 +12 48 47.2', fov: 1, showContextMenu: true});
// define custom draw function
var drawFunction = function(source, canvasCtx, viewParams) {
canvasCtx.beginPath();
@@ -31,7 +31,19 @@
canvasCtx.globalAlpha = 1;
};
var hips = A.catalogHiPS('https://axel.u-strasbg.fr/HiPSCatService/Simbad', {onClick: 'showTable', name: 'Simbad', shape: drawFunction});
var drawFunctionFootprint = function(s) {
let a = +s.data.size_maj;
let b = +s.data.size_min;
if (a < 0.1 || b < 0.1) {
return;
}
let angle = +s.data.size_angle || 0.0;
return A.ellipse(s.ra, s.dec, a / 60, b / 60, angle, {lineWidth: 3, hoverColor: 'yellow'});
};
var hips = A.catalogHiPS('https://axel.u-strasbg.fr/HiPSCatService/Simbad', {onClick: 'showTable', name: 'Simbad', color: 'cyan', hoverColor: 'red', shape: drawFunctionFootprint});
aladin.addCatalog(hips);
});
</script>

View File

@@ -23,7 +23,7 @@
});
aladin.addCatalog(A.catalogFromSimbad('M 82', 0.1, {onClick: 'showTable'}));
aladin.addCatalog(A.catalogFromNED('09 55 52.4 +69 40 47', 0.1, {onClick: 'showPopup', shape: 'plus'}));
aladin.addCatalog(A.catalogFromNED('09 55 52.4 +69 40 47', 0.1, {onClick: 'showPopup', shape: 'plus'}));
});
</script>

View File

@@ -34,7 +34,7 @@
console.log("Object hovered stopped: ", object, "mouse coords xy: ", xyMouseCoords.x, xyMouseCoords.y);
})
const cat = A.catalogFromVizieR('B/assocdata/obscore', 'M 1', 100, {onClick: 'showTable', limit: 1000});
const cat = A.catalogFromVizieR('B/assocdata/obscore', 'M 1', 100, {onClick: 'showTable', hoverColor: 'purple', limit: 1000});
aladin.addCatalog(cat);
});
</script>

View File

@@ -16,7 +16,7 @@
aladin.addCatalog(catalog)
});
aladin.addCatalog(A.catalogFromVizieR("B/assocdata/obscore", "0 +0", 20, {limit: 1000, hoverColor: 'cyan'}))
aladin.addCatalog(A.catalogFromVizieR("B/assocdata/obscore", "0 +0", 20, {limit: 1000}))
});
</script>
</body>

View File

@@ -8,15 +8,13 @@
<script type="module">
import A from '../src/js/A.js';
import {AladinUtils} from '../src/js/AladinUtils.js';
A.init.then(() => {
let vertices = AladinUtils.HEALPix.vertices(8, 0n)
let lonlat = AladinUtils.HEALPix.pix2ang(8, 0n)
let ipix = AladinUtils.HEALPix.ang2pix(8, 0.1, 0.4)
console.log(vertices, lonlat, ipix)
let vertices = A.Utils.HEALPix.vertices(Math.pow(2, 3), BigInt(276))
//let lonlat = A.Utils.HEALPix.pix2ang(8, 0n)
//let ipix = A.Utils.HEALPix.ang2pix(8, 0.1, 0.4)
//console.log("vertices", vertices, lonlat, ipix)
console.log(vertices)
})
</script>

View File

@@ -36,7 +36,7 @@
}
if (searchParams.has('showCooGrid')) {
const b = searchParams.get('showCooGrid') === 'true';
aladin.view.setGridConfig({
aladin.setCooGrid({
enabled: b
});
}

View File

@@ -37,7 +37,7 @@
}
if (searchParams.has('showCooGrid')) {
const b = searchParams.get('showCooGrid') === 'true';
aladin.view.setGridConfig({
aladin.setCooGrid({
enabled: b
});
}

View File

@@ -36,7 +36,7 @@
}
if (searchParams.has('showCooGrid')) {
const b = searchParams.get('showCooGrid') === 'true';
aladin.view.setGridConfig({
aladin.setCooGrid({
enabled: b
});
}

View File

@@ -2,7 +2,7 @@
"homepage": "https://aladin.u-strasbg.fr/",
"name": "aladin-lite",
"type": "module",
"version": "3.3.2",
"version": "3.3.3",
"description": "An astronomical HiPS visualizer in the browser",
"author": "Thomas Boch and Matthieu Baumann",
"license": "GPL-3",

View File

@@ -27,12 +27,12 @@ impl Texture2DArray {
tex_params: &'static [(u32, u32)],
) -> Result<Texture2DArray, JsValue> {
let textures: Result<Vec<_>, _> = (0..num_slices)
.map(|_| {
Texture2D::create_empty_with_format::<F>(gl, width, height, tex_params)
})
.map(|_| Texture2D::create_empty_with_format::<F>(gl, width, height, tex_params))
.collect();
Ok(Texture2DArray { textures: textures? })
Ok(Texture2DArray {
textures: textures?,
})
}
}

View File

@@ -126,9 +126,9 @@ impl ProjetedGrid {
if let Some(enabled) = enabled {
self.enabled = enabled;
if !self.enabled {
/*if !self.enabled {
self.text_renderer.clear_text_canvas();
}
}*/
}
Ok(())

View File

@@ -442,7 +442,7 @@ impl WebClient {
/// * `green` - Green amount (between 0.0 and 1.0)
/// * `blue` - Blue amount (between 0.0 and 1.0)
/// * `alpha` - Alpha amount (between 0.0 and 1.0)
#[wasm_bindgen(js_name = setGridConfig)]
#[wasm_bindgen(js_name = setGridOptions)]
pub fn set_grid_cfg(&mut self, cfg: JsValue) -> Result<(), JsValue> {
let cfg = serde_wasm_bindgen::from_value(cfg)?;

View File

@@ -1,4 +1,5 @@
use super::Renderer;
use al_core::log::console_log;
use web_sys::CanvasRenderingContext2d;
pub struct TextRenderManager {
@@ -25,7 +26,7 @@ impl TextRenderManager {
pub fn new(aladin_div: &HtmlElement) -> Result<Self, JsValue> {
let canvas = aladin_div
// Inside it, retrieve the canvas
.get_elements_by_class_name("aladin-gridCanvas")
.get_elements_by_class_name("aladin-catalogCanvas")
.get_with_index(0)
.unwrap_abort()
.dyn_into::<web_sys::HtmlCanvasElement>()?;
@@ -67,6 +68,7 @@ impl TextRenderManager {
angle: A,
) -> Result<(), JsValue> {
self.ctx.save();
self.ctx
.translate(screen_pos.x as f64, screen_pos.y as f64)?;
@@ -89,15 +91,6 @@ impl TextRenderManager {
) -> Result<(), JsValue> {
Ok(())
}
pub fn clear_text_canvas(&mut self) {
self.ctx.clear_rect(
0_f64,
0_f64,
self.canvas.width() as f64,
self.canvas.height() as f64,
);
}
}
impl Renderer for TextRenderManager {
@@ -110,7 +103,15 @@ impl Renderer for TextRenderManager {
.dyn_into::<web_sys::CanvasRenderingContext2d>()
.unwrap_abort();
self.clear_text_canvas();
//self.clear_text_canvas();
// Clear the Aladin Lite 2d canvas
// This canvas is where catalogs, grid labels, Hpx grid are drawn
/*self.ctx.clear_rect(
0_f64,
0_f64,
self.canvas.width() as f64,
self.canvas.height() as f64,
);*/
// reset the font and color
self.ctx

View File

@@ -17,11 +17,11 @@
top: 0;
}
.aladin-gridCanvas {
/*.aladin-gridCanvas {
position: absolute;
left: 0;
top: 0;
}
}*/
.aladin-catalogCanvas {
position: absolute;
@@ -752,6 +752,10 @@ canvas {
box-shadow:inset 1px 1px 0px 0px #fff;
background-color: rgba(0, 0, 0, 0.7);
margin: 0;
box-sizing: content-box;
line-height: normal;
}
.aladin-context-menu .aladin-context-menu-item:first-of-type {

View File

@@ -318,8 +318,8 @@ A.coo = function (longitude, latitude, prec) {
};
// API
A.footprint = function(shapes, source) {
return new Footprint(shapes, source);
A.footprint = function(shapes) {
return new Footprint(shapes);
};
// API
@@ -329,15 +329,52 @@ A.footprintsFromSTCS = function (stcs, options) {
return footprints;
}
// API
A.MOCFromURL = function (url, options, successCallback) {
/**
* Creates a new MOC (Multi-Order-Coverage) from an url
*
* @function
* @memberof A
* @name MOCFromURL
*
* @param {string} url - The url to the MOC (e.g. stored as FITS file)
* @param {MOCOptions} [options] - Display options for the MOC
* @param {function} [successCallback] - Callback function when the MOC loads
* @param {function} [errorCallback] - Callback function when the MOC fails loading
* @returns {MOC} Returns a new MOC object
*/
A.MOCFromURL = function (url, options, successCallback, errorCallback) {
var moc = new MOC(options);
moc.parse(url, successCallback);
moc.parse(url, successCallback, errorCallback);
return moc;
};
// API
/**
* Creates a new MOC (Multi-Order-Coverage) from a JSON-like dictionary (javascript Object)
*
* @function
* @memberof A
* @name MOCFromJSON
*
* @param {Object} jsonMOC - The MOC stores as a JSON-like dictionary
* @param {MOCOptions} [options] - Display options for the MOC
* @param {function} [successCallback] - Callback function when the MOC loads
* @param {function} [errorCallback] - Callback function when the MOC fails loading
* @returns {MOC} Returns a new MOC object
*
* @example
* var json = {"3":[517],
* "4":[2065,2066,2067,2112,2344,2346,2432],
* "5":[8221,8257,8258,8259,8293,8304,8305,8307,8308,8452,8456,9346,9352,9354,9736],
* "6":[32861,32862,32863,32881,32882,32883,32892,32893,33025,33026,33027,33157,33168,33169,33171,
* 33181,33224,33225,33227,33236,33240,33812,33816,33828,33832,37377,37378,37379,37382,37388,
* 37390,37412,37414,37420,37422,37562,38928,38930,38936,38948,38952],
* "7":[131423,131439,131443,131523,131556,131557,131580,131581,132099,132612,132613,132624,132625,132627,132637,
* 132680,132681,132683,132709,132720,132721,132904,132905,132948,132952,132964,132968,133008,133009,133012,135252,135256,135268,135316,135320,135332,135336,148143,148152,148154,149507,149520
* ,149522,149523,149652,149654,149660,149662,149684,149686,149692,149694,149695,150120,150122,150208,150210,150216,150218,150240,150242,150243,155748,155752,155796,155800,155812,155816]};
* var moc = A.MOCFromJSON(json, {opacity: 0.25, color: 'magenta', lineWidth: 3});
* aladin.addMOC(moc);
*/
A.MOCFromJSON = function (jsonMOC, options, successCallback, errorCallback) {
var moc = new MOC(options);
moc.parse(jsonMOC, successCallback, errorCallback);
@@ -345,14 +382,44 @@ A.MOCFromJSON = function (jsonMOC, options, successCallback, errorCallback) {
return moc;
};
// API
A.MOCFromCircle = function (circle, options, successCallback, errorCallback) {
/**
* Creates a new MOC (Multi-Order-Coverage) from an object describing a cone on the sky
*
* @function
* @memberof A
* @name MOCFromCone
*
* @param {Object} circle - A object describing a cone in the sky
* @param {number} circle.ra - Right-ascension of the circle's center (in deg)
* @param {number} circle.dec - Declination of the circle's center (in deg)
* @param {number} circle.radius - Radius of the circle (in deg)
* @param {MOCOptions} [options] - Display options for the MOC
* @param {function} [successCallback] - Callback function when the MOC loads
* @param {function} [errorCallback] - Callback function when the MOC fails loading
* @returns {MOC} Returns a new MOC object
*/
A.MOCFromCone = function (circle, options, successCallback, errorCallback) {
var moc = new MOC(options);
moc.parse(circle, successCallback, errorCallback);
return moc;
};
/**
* Creates a new MOC (Multi-Order-Coverage) from an object describing a polygon on the sky
*
* @function
* @memberof A
* @name MOCFromPolygon
*
* @param {Object} polygon - A object describing a polygon in the sky
* @param {number[]} polygon.ra - Right-ascensions of the polygon's vertices (in deg)
* @param {number[]} polygon.dec - Declination of the polygon's vertices (in deg)
* @param {MOCOptions} [options] - Display options for the MOC
* @param {function} [successCallback] - Callback function when the MOC loads
* @param {function} [errorCallback] - Callback function when the MOC fails loading
* @returns {MOC} Returns a new MOC object
*/
A.MOCFromPolygon= function (polygon, options, successCallback, errorCallback) {
var moc = new MOC(options);
moc.parse(polygon, successCallback, errorCallback);

View File

@@ -524,7 +524,7 @@ export let Aladin = (function () {
gridOptions: {
enabled: false,
showLabels: true,
thickness: 2,
thickness: 3,
labelSize: 15
},
projection: 'SIN',
@@ -1649,19 +1649,19 @@ export let Aladin = (function () {
options.color.b /= 255;
}
this.view.setGridConfig(options);
this.view.setGridOptions(options);
}
Aladin.prototype.getGridOptions = function() {
return this.view.getGridConfig();
return this.view.getGridOptions();
}
Aladin.prototype.showCooGrid = function () {
this.view.setGridConfig({enabled: true});
this.setCooGrid({enabled: true});
};
Aladin.prototype.hideCooGrid = function() {
this.view.setGridConfig({enabled: false});
this.setCooGrid({enabled: false});
}
Aladin.prototype.layerByName = function (name) {

View File

@@ -34,9 +34,13 @@ import { Color } from "./Color.js"
import { Utils } from "./Utils";
import { Coo } from "./libs/astro/coo.js";
import { VOTable } from "./vo/VOTable.js";
import { Footprint } from "./Footprint.js";
import { ObsCore } from "./vo/ObsCore.js";
import A from "./A.js";
import { Polyline } from "./Polyline.js";
import { Ellipse } from "./Ellipse.js";
import { Circle } from "./Circle.js";
import { Footprint } from "./Footprint.js";
/**
* Represents a catalog with configurable options for display and interaction.
@@ -55,7 +59,7 @@ export let Catalog = (function() {
* @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} [options.shape="square"] - The shape of the sources (can be, "square", "circle", "plus", "cross", "rhomb", "triangle").
* @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 {function} [options.onClick] - The callback function to execute on a source click.
* @param {boolean} [options.readOnly=false] - Whether the catalog is read-only.
@@ -431,10 +435,10 @@ export let Catalog = (function() {
if (successCallback) {
successCallback({
sources: sources,
footprints: footprints,
fields: fields,
type: type
sources,
footprints,
fields,
type
});
}
},
@@ -453,11 +457,16 @@ export let Catalog = (function() {
this.shape = options.shape || this.shape || "square";
this._shapeIsFunction = false; // if true, the shape is a function drawing on the canvas
this._shapeIsFootprintFunction = false;
if (typeof this.shape === 'function') {
this._shapeIsFunction = true;
}
// do not need to compute any canvas
if (this.shape instanceof Image || this.shape instanceof HTMLCanvasElement) {
// there is a possibility that the user gives a function returning shape objects such as
// circle, polyline, line or even footprints
// we must test that here and precompute all those objects and add them as footprints to draw
// at this point, we do not have to draw any sources
} else if (this.shape instanceof Image || this.shape instanceof HTMLCanvasElement) {
this.sourceSize = this.shape.width;
}
@@ -491,6 +500,10 @@ export let Catalog = (function() {
this.setFields(fields);
}
let footprints = this.parseFootprintsFromSources(sources);
sources = sources.filter((s) => s.hasFootprint !== true);
this.addFootprints(footprints);
this.sources = this.sources.concat(sources);
for (var k=0, len=sources.length; k<len; k++) {
sources[k].setCatalog(this);
@@ -506,15 +519,40 @@ export let Catalog = (function() {
Catalog.prototype.addFootprints = function(footprintsToAdd) {
footprintsToAdd = [].concat(footprintsToAdd); // make sure we have an array and not an individual footprints
this.footprints = this.footprints.concat(footprintsToAdd);
for (var k=0, len=footprintsToAdd.length; k<len; k++) {
footprintsToAdd[k].setCatalog(this);
footprintsToAdd[k].setColor(this.color);
footprintsToAdd[k].setSelectionColor(this.selectionColor);
footprintsToAdd[k].setHoverColor(this.hoverColor);
}
footprintsToAdd.forEach(f => {
f.setCatalog(this);
})
this.reportChange();
};
Catalog.prototype.parseFootprintsFromSources = function(sources) {
let footprints = [];
if (this._shapeIsFunction) {
for(const source of sources) {
try {
let shape = this.shape(source)
// convert simple shapes to footprints
if (shape instanceof Circle || shape instanceof Polyline || shape instanceof Ellipse) {
shape = new Footprint(shape, source);
}
if (shape instanceof Footprint) {
this._shapeIsFootprintFunction = true;
// store the footprints
footprints.push(shape);
}
} catch(e) {
// do not create the footprint
continue;
}
};
}
return footprints;
}
Catalog.prototype.setFields = function(fields) {
this.fields = fields;
};
@@ -668,19 +706,19 @@ export let Catalog = (function() {
this.footprints = [];
};
Catalog.prototype.draw = function(ctx, frame, width, height, largestDim) {
Catalog.prototype.draw = function(ctx, width, height) {
if (! this.isShowing) {
return;
}
// tracé simple
ctx.strokeStyle= this.color;
//ctx.lineWidth = 1;
//ctx.beginPath();
// Draw the footprints
this.drawFootprints(ctx);
if (this._shapeIsFunction) {
ctx.save();
}
const sourcesInView = this.drawSources(ctx, width, height);
if (this._shapeIsFunction) {
@@ -695,9 +733,6 @@ export let Catalog = (function() {
this.drawSourceLabel(s, ctx);
})
}
// Draw the footprints
this.drawFootprints(ctx);
};
Catalog.prototype.drawSources = function(ctx, width, height) {
@@ -729,19 +764,23 @@ export let Catalog = (function() {
return false;
}
if (s.hasFootprint) {
return false;
}
if (s.x <= width && s.x >= 0 && s.y <= height && s.y >= 0) {
if (this._shapeIsFunction) {
if (this._shapeIsFunction && !this._shapeIsFootprintFunction) {
this.shape(s, ctx, this.view.getViewParams());
}
else if (s.marker && s.useMarkerDefaultIcon) {
ctx.drawImage(this.cacheMarkerCanvas, s.x-this.sourceSize/2, s.y-this.sourceSize/2);
}
else if (s.isHovered) {
ctx.drawImage(this.cacheHoverCanvas, s.x-this.selectSize/2, s.y-this.selectSize/2);
}
else if (s.isSelected) {
ctx.drawImage(this.cacheSelectCanvas, s.x-this.selectSize/2, s.y-this.selectSize/2);
}
else if (s.isHovered) {
ctx.drawImage(this.cacheHoverCanvas, s.x-this.selectSize/2, s.y-this.selectSize/2);
}
else {
ctx.drawImage(this.cacheCanvas, s.x-this.cacheCanvas.width/2, s.y-this.cacheCanvas.height/2);
}
@@ -771,9 +810,9 @@ export let Catalog = (function() {
};
Catalog.prototype.drawFootprints = function(ctx) {
this.footprints.forEach((f) => {
f.draw(ctx, this.view)
});
for(let k = 0; k < this.footprints.length; k++) {
this.footprints[k].draw(ctx, this.view)
};
};

View File

@@ -57,7 +57,7 @@ export let Circle = (function() {
};
Circle.prototype.setColor = function(color) {
if (this.color == color) {
if (!color || this.color == color) {
return;
}
this.color = color;
@@ -67,7 +67,7 @@ export let Circle = (function() {
};
Circle.prototype.setSelectionColor = function(color) {
if (this.selectionColor == color) {
if (!color || this.selectionColor == color) {
return;
}
this.selectionColor = color;
@@ -77,7 +77,7 @@ export let Circle = (function() {
};
Circle.prototype.setHoverColor = function(color) {
if (this.hoverColor == color) {
if (!color || this.hoverColor == color) {
return;
}
this.hoverColor = color;
@@ -189,7 +189,7 @@ export let Circle = (function() {
}
noStroke = noStroke===true || false;
var centerXyview = AladinUtils.radecToViewXy(this.centerRaDec[0], this.centerRaDec[1], view.aladin);
var centerXyview = view.aladin.world2pix(this.centerRaDec[0], this.centerRaDec[1]);
if (!centerXyview) {
// the center goes out of the projection
// we do not draw it
@@ -203,39 +203,24 @@ export let Circle = (function() {
let hidden = true;
var ra, dec, vertOnCircle, dx, dy;
//if (this.radiusDegrees > 30) {
this.radius = Number.NEGATIVE_INFINITY;
// Project 4 points lying on the circle and take the minimal dist with the center as radius
[[-1, 0], [1, 0], [0, -1], [0, 1]].forEach(([cardDirRa, cardDirDec]) => {
ra = this.centerRaDec[0] + cardDirRa * this.radiusDegrees;
dec = this.centerRaDec[1] + cardDirDec * this.radiusDegrees;
this.radius = Number.NEGATIVE_INFINITY;
// Project 4 points lying on the circle and take the minimal dist with the center as radius
[[-1, 0], [1, 0], [0, -1], [0, 1]].forEach(([cardDirRa, cardDirDec]) => {
ra = this.centerRaDec[0] + cardDirRa * this.radiusDegrees;
dec = this.centerRaDec[1] + cardDirDec * this.radiusDegrees;
vertOnCircle = AladinUtils.radecToViewXy(ra, dec, view.aladin);
if (vertOnCircle) {
dx = vertOnCircle[0] - this.center.x;
dy = vertOnCircle[1] - this.center.y;
this.radius = Math.max(Math.sqrt(dx*dx + dy*dy), this.radius);
hidden = false;
}
});
/*} else {
ra = this.centerRaDec[0] + this.radiusDegrees;
dec = this.centerRaDec[1];
vertOnCircle = AladinUtils.radecToViewXy(ra, dec, view);
vertOnCircle = view.aladin.world2pix(ra, dec);
if (vertOnCircle) {
dx = vertOnCircle[0] - this.center.x;
dy = vertOnCircle[1] - this.center.y;
this.radius = Math.sqrt(dx*dx + dy*dy);
this.radius = Math.max(Math.sqrt(dx*dx + dy*dy), this.radius);
hidden = false;
}
}*/
}
});
if (hidden) {
return;

View File

@@ -49,7 +49,12 @@ export let DefaultActionsForContextMenu = (function () {
{
label: "Copy position", action(o) {
let msg;
navigator.clipboard.writeText(o.target.innerText)
let text = o.target.innerText;
if (!text) {
return false;
}
navigator.clipboard.writeText(text)
.then(() => {
msg = 'successful'
if (aladinInstance.statusBar) {

View File

@@ -29,7 +29,6 @@
*****************************************************************************/
import { Utils } from "./Utils";
import { AladinUtils } from "./AladinUtils.js";
import { Overlay } from "./Overlay.js";
// TODO : Ellipse, Circle and Footprint should inherit from the same root object
@@ -58,7 +57,7 @@ export let Ellipse = (function() {
};
Ellipse.prototype.setColor = function(color) {
if (this.color == color) {
if (!color || this.color == color) {
return;
}
this.color = color;
@@ -68,7 +67,7 @@ export let Ellipse = (function() {
};
Ellipse.prototype.setSelectionColor = function(color) {
if (this.selectionColor == color) {
if (!color || this.selectionColor == color) {
return;
}
this.selectionColor = color;
@@ -78,7 +77,7 @@ export let Ellipse = (function() {
};
Ellipse.prototype.setHoverColor = function(color) {
if (this.hoverColor == color) {
if (!color || this.hoverColor == color) {
return;
}
this.hoverColor = color;
@@ -187,8 +186,8 @@ export let Ellipse = (function() {
};
Ellipse.prototype.setRadiuses = function(radiusXDegrees, radiusYDegrees) {
this.radiusXDegrees = radiusXDegrees;
this.radiusYDegrees = radiusYDegrees;
this.a = radiusXDegrees;
this.b = radiusYDegrees;
if (this.overlay) {
this.overlay.reportChange();
@@ -205,15 +204,44 @@ export let Ellipse = (function() {
return;
}
var centerXyview = AladinUtils.radecToViewXy(this.centerRaDec[0], this.centerRaDec[1], view.aladin);
if (!centerXyview) {
var originScreen = view.aladin.world2pix(this.centerRaDec[0], this.centerRaDec[1]);
if (!originScreen) {
// the center goes out of the projection
// we do not draw it
return;
}
let circlePtXyViewRa = AladinUtils.radecToViewXy(this.centerRaDec[0] + this.radiusXDegrees, this.centerRaDec[1], view.aladin);
let circlePtXyViewDec = AladinUtils.radecToViewXy(this.centerRaDec[0], this.centerRaDec[1] + this.radiusYDegrees, view.aladin);
// 1. Find the spherical tangent vector going to the north
let toNorth = [this.centerRaDec[0], this.centerRaDec[1] + 1e-3];
// 2. Project it to the screen
let toNorthScreen = view.aladin.world2pix(toNorth[0], toNorth[1]);
if(!toNorthScreen) {
return;
}
// 3. normalize this vector
let toNorthVec = [toNorthScreen[0] - originScreen[0], toNorthScreen[1] - originScreen[1]];
let norm = Math.sqrt(toNorthVec[0]*toNorthVec[0] + toNorthVec[1]*toNorthVec[1]);
toNorthVec = [toNorthVec[0] / norm, toNorthVec[1] / norm];
let toWestVec = [1.0, 0.0];
let x1 = toWestVec[0];
let y1 = toWestVec[1];
let x2 = toNorthVec[0];
let y2 = toNorthVec[1];
// 4. Compute the west to north angle
let westToNorthAngle = Math.atan2(x1*y2-y1*x2, x1*x2+y1*y2);
// 5. Get the correct ellipse angle
let theta = -this.rotation + westToNorthAngle;
//let ct = Math.cos(theta);
//let st = Math.sin(theta);
/*let circlePtXyViewRa = view.aladin.world2pix(view.viewCenter.lon + 1.0, view.viewCenter.lat);
let circlePtXyViewDec = view.aladin.world2pix(view.viewCenter.lon, view.viewCenter.lat + 1.0);
if (!circlePtXyViewRa || !circlePtXyViewDec) {
// the circle border goes out of the projection
@@ -223,17 +251,20 @@ export let Ellipse = (function() {
var dxRa = circlePtXyViewRa[0] - centerXyview[0];
var dyRa = circlePtXyViewRa[1] - centerXyview[1];
var radiusInPixX = Math.sqrt(dxRa*dxRa + dyRa*dyRa);
var dRa = Math.sqrt(dxRa*dxRa + dyRa*dyRa);
var dxDec = circlePtXyViewDec[0] - centerXyview[0];
var dyDec = circlePtXyViewDec[1] - centerXyview[1];
var radiusInPixY = Math.sqrt(dxDec*dxDec + dyDec*dyDec);
var dDec = Math.sqrt(dxDec*dxDec + dyDec*dyDec);*/
//var radiusInPixX = Math.abs(this.a * ct * dRa) + Math.abs(this.a * st * dDec);
//var radiusInPixY = Math.abs(this.b * st * dRa) + Math.abs(this.b * ct * dDec);
// Ellipse crossing the projection
if ((dxRa*dyDec - dxDec*dyRa) <= 0.0) {
/*if ((dxRa*dyDec - dxDec*dyRa) <= 0.0) {
// We do not draw it
return;
}
}*/
noStroke = noStroke===true || false;
// TODO : check each 4 point until show
@@ -257,33 +288,10 @@ export let Ellipse = (function() {
ctx.strokeStyle = baseColor;
}
// 1. Find the spherical tangent vector going to the north
let origin = this.centerRaDec;
let toNorth = [this.centerRaDec[0], this.centerRaDec[1] + 1e-3];
// 2. Project it to the screen
let originScreen = this.overlay.view.wasm.worldToScreen(origin[0], origin[1]);
let toNorthScreen = this.overlay.view.wasm.worldToScreen(toNorth[0], toNorth[1]);
// 3. normalize this vector
let toNorthVec = [toNorthScreen[0] - originScreen[0], toNorthScreen[1] - originScreen[1]];
let norm = Math.sqrt(toNorthVec[0]*toNorthVec[0] + toNorthVec[1]*toNorthVec[1]);
toNorthVec = [toNorthVec[0] / norm, toNorthVec[1] / norm];
let toWestVec = [1.0, 0.0];
let x1 = toWestVec[0];
let y1 = toWestVec[1];
let x2 = toNorthVec[0];
let y2 = toNorthVec[1];
// 4. Compute the west to north angle
let westToNorthAngle = Math.atan2(x1*y2-y1*x2, x1*x2+y1*y2);
// 5. Get the correct ellipse angle
let theta = -this.rotation + westToNorthAngle;
ctx.lineWidth = this.lineWidth;
ctx.beginPath();
ctx.ellipse(centerXyview[0], centerXyview[1], radiusInPixX, radiusInPixY, theta, 0, 2*Math.PI, false);
let px_per_deg = view.width / view.fov;
ctx.ellipse(originScreen[0], originScreen[1], px_per_deg * this.a, px_per_deg * this.b, theta, 0, 2*Math.PI, false);
if (!noStroke) {
if (this.fillColor) {
ctx.fillStyle = this.fillColor;

View File

@@ -56,10 +56,11 @@ export class CircleSelect extends FSM {
let draw = () => {
let ctx = view.catalogCtx;
if (!view.catalogCanvasCleared) {
/*if (!view.catalogCanvasCleared) {
ctx.clearRect(0, 0, view.width, view.height);
view.catalogCanvasCleared = true;
}
}*/
// draw the selection
ctx.fillStyle = options.color + '7f';
ctx.strokeStyle = options.color;

View File

@@ -119,10 +119,11 @@ export class PolySelect extends FSM {
let draw = () => {
let ctx = view.catalogCtx;
if (!view.catalogCanvasCleared) {
/*if (!view.catalogCanvasCleared) {
ctx.clearRect(0, 0, view.width, view.height);
view.catalogCanvasCleared = true;
}
}*/
// draw the selection
ctx.save();
ctx.fillStyle = options.color + '7f';

View File

@@ -57,10 +57,11 @@ export class RectSelect extends FSM {
let draw = () => {
let ctx = view.catalogCtx;
if (!view.catalogCanvasCleared) {
/*if (!view.catalogCanvasCleared) {
ctx.clearRect(0, 0, view.width, view.height);
view.catalogCanvasCleared = true;
}
}*/
// draw the selection
ctx.fillStyle = options.color + '7f';
ctx.strokeStyle = options.color;

View File

@@ -33,7 +33,6 @@
*
*****************************************************************************/
import { AladinUtils } from './AladinUtils.js';
import { Utils } from './Utils';
export let Footprint= (function() {
@@ -43,7 +42,11 @@ export let Footprint= (function() {
this.id = 'footprint-' + Utils.uuidv4();
this.source = source;
this.shapes = shapes;
if (this.source) {
this.source.hasFootprint = true;
}
this.shapes = [].concat(shapes);
this.isShowing = true;
this.isHovered = false;
@@ -54,6 +57,11 @@ export let Footprint= (function() {
Footprint.prototype.setCatalog = function(catalog) {
if (this.source) {
this.source.setCatalog(catalog);
// Take the color properties of the catalog
this.setColor(catalog.color);
this.setSelectionColor(catalog.selectionColor);
this.setHoverColor(catalog.hoverColor);
}
};
@@ -93,8 +101,12 @@ export let Footprint= (function() {
if (this.overlay) {
this.overlay.reportChange();
} else if (this.source && this.source.catalog) {
this.source.catalog.view && this.source.catalog.view.requestRedraw();
return;
}
let catalog = this.getCatalog();
if (catalog) {
catalog.view && catalog.view.requestRedraw();
}
};
@@ -108,30 +120,43 @@ export let Footprint= (function() {
if (this.overlay) {
this.overlay.reportChange();
} else if (this.source && this.source.catalog) {
this.source.catalog.view && this.source.catalog.view.requestRedraw();
}
let catalog = this.getCatalog();
if (catalog) {
catalog.view && catalog.view.requestRedraw();
}
};
Footprint.prototype.getLineWidth = function() {
return this.shapes && this.shapes[0].getLineWidth();
};
Footprint.prototype.setLineWidth = function(lineWidth) {
this.shapes.forEach((shape) => shape.setLineWidth(lineWidth))
};
Footprint.prototype.getLineWidth = function() {
if (this.shapes && this.shapes.length > 0) {
return this.shapes[0].getLineWidth();
}
};
Footprint.prototype.setColor = function(color) {
if(!color) {
return;
}
this.shapes.forEach((shape) => shape.setColor(color))
};
Footprint.prototype.setSelectionColor = function(color) {
if (!color) {
return;
}
this.shapes.forEach((shape) => shape.setSelectionColor(color))
};
Footprint.prototype.setHoverColor = function(color) {
if (!color)
return;
this.shapes.forEach((shape) => shape.setHoverColor(color))
};
@@ -185,7 +210,7 @@ export let Footprint= (function() {
y: s.y,
};
} else {
var xy = AladinUtils.radecToViewXy(s.ra, s.dec, view.aladin);
var xy = view.aladin.world2pix(s.ra, s.dec);
if (!xy) {
return false;
}

View File

@@ -15,7 +15,35 @@ import { Color } from "./Color.js";
import { ALEvent } from "./events/ALEvent.js";
/**
* @typedef {Object} MOCOptions
* @description Options for configuring a MOC (Multi-Order-Coverage).
*
* @property {Object} options - Configuration options for the MOC.
* @property {string} [options.name="MOC"] - The name of the catalog.
* @property {string} [options.color] - The color of the MOC HEALPix cell edges.
* @property {string} [options.fillColor] - A filling color of the MOC HEALPix cells.
* @property {string} [options.fill=false] - Fill the MOC with `options.fillColor`
* @property {string} [options.edge=true] - Draw the edges of the HEALPix cells with `options.color`.
* @property {number} [options.lineWidth=3] - The line width in pixels
* @property {Boolean} [options.perimeter=false] - A filling color of the MOC HEALPix cells.
* @property {number} [options.opacity=1.0] - The opacity of the MOC
*/
/**
* Represents a Multi-Order-Coverage with configurable options for display and interaction.
*
* @namespace
* @typedef {Object} MOC
*/
export let MOC = (function() {
/**
* Constructor function for creating a new catalog instance.
*
* @constructor
* @memberof MOC
* @param {MOCOptions} options - Configuration options for the MOC.
*/
let MOC = function(options) {
//this.order = undefined;
@@ -61,7 +89,7 @@ export let MOC = (function() {
}
this.opacity = Math.max(0, Math.min(1, this.opacity)); // 0 <= this.opacity <= 1
this.lineWidth = options["lineWidth"] || 1;
this.lineWidth = options["lineWidth"] || 3;
//this.proxyCalled = false; // this is a flag to check whether we already tried to load the MOC through the proxy

View File

@@ -183,9 +183,10 @@ export let Polyline= (function() {
};
Polyline.prototype.setColor = function(color) {
if (this.color == color) {
if (!color || this.color == color) {
return;
}
this.color = color;
if (this.overlay) {
this.overlay.reportChange();
@@ -193,7 +194,7 @@ export let Polyline= (function() {
};
Polyline.prototype.setSelectionColor = function(color) {
if (this.selectionColor == color) {
if (!color || this.selectionColor == color) {
return;
}
this.selectionColor = color;
@@ -203,7 +204,7 @@ export let Polyline= (function() {
};
Polyline.prototype.setHoverColor = function(color) {
if (this.hoverColor == color) {
if (!color || this.hoverColor == color) {
return;
}
this.hoverColor = color;
@@ -263,7 +264,7 @@ export let Polyline= (function() {
let ymax = Number.NEGATIVE_INFINITY;
for (var k=0; k<len; k++) {
var xyview = AladinUtils.radecToViewXy(this.radecArray[k][0], this.radecArray[k][1], view.aladin);
var xyview = view.aladin.world2pix(this.radecArray[k][0], this.radecArray[k][1]);
if (!xyview) {
return;
}
@@ -306,7 +307,7 @@ export let Polyline= (function() {
return true;
};
}
} else if (view.projection === ProjectionEnum.HPX) {
/*} else if (view.projection === ProjectionEnum.HPX) {
drawLine = (v0, v1) => {
const line = new Line(v0.x, v0.y, v1.x, v1.y);
@@ -346,7 +347,7 @@ export let Polyline= (function() {
return false;
}
};
}
}*/
} else {
drawLine = (v0, v1) => {
const line = new Line(v0.x, v0.y, v1.x, v1.y);
@@ -429,7 +430,7 @@ export let Polyline= (function() {
let pointXY = [];
for (var j = 0; j < this.radecArray.length; j++) {
var xy = AladinUtils.radecToViewXy(this.radecArray[j][0], this.radecArray[j][1], view.aladin);
var xy = view.aladin.world2pix(this.radecArray[j][0], this.radecArray[j][1]);
if (!xy) {
return false;
}

View File

@@ -33,7 +33,11 @@ import { Color } from "./Color.js";
import { Coo } from "./libs/astro/coo.js";
import { Utils } from "./Utils";
import { CooFrameEnum } from "./CooFrameEnum.js";
import { Footprint } from "./Footprint.js";
import { Circle } from "./Circle.js";
import { Ellipse } from "./Ellipse.js";
import { Line } from "./Line.js";
import { Polyline } from "./Polyline.js";
// TODO: index sources according to their HEALPix ipix
// TODO : merge parsing with class Catalog
export let ProgressiveCat = (function() {
@@ -74,20 +78,11 @@ export let ProgressiveCat = (function() {
this.onClick = options.onClick || undefined; // TODO: inherit from catalog
// we cache the list of sources in each healpix tile. Key of the cache is norder+'-'+npix
this.sourcesCache = new Utils.LRUCache(256);
this.footprintsCache = new Utils.LRUCache(256);
//added to allow hips catalogue to also use shape functions
if (this.shape instanceof Image || this.shape instanceof HTMLCanvasElement) {
this.sourceSize = this.shape.width;
}
this._shapeIsFunction = false; // if true, the shape is a function drawing on the canvas
if (typeof this.shape === 'function') {
this._shapeIsFunction = true;
}
this.updateShape(options);
this.maxOrderAllsky = 2;
@@ -219,7 +214,14 @@ export let ProgressiveCat = (function() {
sources.push(newSource);
newSource.setCatalog(instance);
}
return sources;
let footprints = instance.parseFootprintsFromSources(sources);
footprints.forEach(f => {
f.setCatalog(instance);
})
sources = sources.filter((s) => s.hasFootprint !== true);
return [sources, footprints];
};
ProgressiveCat.prototype = {
@@ -272,7 +274,10 @@ export let ProgressiveCat = (function() {
url: self.rootUrl + '/' + 'Norder1/Allsky.tsv',
method: 'GET',
success: function(tsv) {
self.order1Sources = getSources(self, tsv, self.fields);
let [sources, footprints] = getSources(self, tsv, self.fields);
self.order1Footprints = footprints;
self.order1Sources = sources;
if (self.order2Sources) {
self.isReady = true;
@@ -289,7 +294,10 @@ export let ProgressiveCat = (function() {
url: self.rootUrl + '/' + 'Norder2/Allsky.tsv',
method: 'GET',
success: function(tsv) {
self.order2Sources = getSources(self, tsv, self.fields);
let [sources, footprints] = getSources(self, tsv, self.fields);
self.order2Footprints = footprints;
self.order2Sources = sources;
if (self.order1Sources) {
self.isReady = true;
@@ -319,7 +327,12 @@ export let ProgressiveCat = (function() {
let xml = ProgressiveCat.parser.parseFromString(text, "text/xml")
self.fields = getFields(self, xml);
self.order2Sources = getSources(self, xml.querySelectorAll('CSV').innerText, self.fields);
let [sources, footprints] = getSources(self, xml.querySelectorAll('CSV').innerText, self.fields);
self.order2Footprints = footprints
self.order2Sources = sources
if (self.order3Sources) {
self.isReady = true;
self._finishInitWhenReady();
@@ -339,7 +352,10 @@ export let ProgressiveCat = (function() {
method: 'GET',
success: function(text) {
let xml = ProgressiveCat.parser.parseFromString(text, "text/xml")
self.order3Sources = getSources(self, xml.querySelectorAll('CSV').innerText, self.fields);
let [sources, footprints] = getSources(self, xml.querySelectorAll('CSV').innerText, self.fields);
self.order3Footprints = footprints
self.order3Sources = sources
if (self.order2Sources) {
self.isReady = true;
self._finishInitWhenReady();
@@ -356,7 +372,7 @@ export let ProgressiveCat = (function() {
this.loadNeededTiles();
},
draw: function(ctx, frame, width, height, largestDim) {
draw: function(ctx, width, height) {
if (! this.isShowing || ! this.isReady) {
return;
}
@@ -366,38 +382,67 @@ export let ProgressiveCat = (function() {
}
// Order must be >= 0
this.drawSources(this.order1Sources, ctx, width, height);
if (this.order1Sources) {
this.drawSources(this.order1Sources, ctx, width, height);
}
if (this.order1Footprints) {
this.order1Footprints.forEach((f) => {
f.draw(ctx, this.view)
});
}
if (this.view.realNorder >= 1) {
this.drawSources(this.order2Sources, ctx, width, height);
if (this.order2Sources) {
this.drawSources(this.order2Sources, ctx, width, height);
}
if (this.order2Footprints) {
this.order2Footprints.forEach((f) => {
f.draw(ctx, this.view)
});
}
}
// For old allsky, tilesInView refers to tiles at orders 4..
// For new allsky, tilesInView will contains order3 sources
if (this.maxOrderAllsky === 3) {
if (this.view.realNorder >= 2) {
this.drawSources(this.order3Sources, ctx, width, height);
if (this.order3Sources) {
this.drawSources(this.order3Sources, ctx, width, height);
}
if (this.order3Footprints) {
this.order3Footprints.forEach((f) => {
f.draw(ctx, this.view)
});
}
}
}
let key, sources;
let key, sources, footprints;
this.tilesInView.forEach((tile) => {
key = tile[0] + '-' + tile[1];
sources = this.sourcesCache.get(key);
footprints = this.footprintsCache.get(key);
if (sources) {
this.drawSources(sources, ctx, width, height);
}
if (footprints) {
footprints.forEach((f) => {
f.draw(ctx, this.view)
});
}
});
if (this._shapeIsFunction) {
ctx.restore();
}
},
drawSources: function(sources, ctx, width, height) {
if (!sources) {
return;
}
let ra = [], dec = [];
let ra = []
let dec = [];
sources.forEach((s) => {
ra.push(s.ra);
dec.push(s.dec);
@@ -445,7 +490,32 @@ export let ProgressiveCat = (function() {
return ret;
},
getFootprints: function() {
var ret = [];
if (this.order1Footprints) {
ret = ret.concat(this.order1Footprints);
}
if (this.order2Footprints) {
ret = ret.concat(this.order2Footprints);
}
if (this.order3Footprints) {
ret = ret.concat(this.order3Footprints);
}
if (this.tilesInView) {
var footprints, key, t;
for (var k=0; k < this.tilesInView.length; k++) {
t = this.tilesInView[k];
key = t[0] + '-' + t[1];
footprints = this.footprintsCache.get(key);
if (footprints) {
ret = ret.concat(footprints);
}
}
}
return ret;
},
deselectAll: function() {
if (this.order1Sources) {
@@ -474,6 +544,11 @@ export let ProgressiveCat = (function() {
for (var k=0; k<sources.length; k++) {
sources[k].deselect();
}
var footprints = this.footprintsCache[key];
for (var k=0; k<footprints.length; k++) {
footprints[k].deselect();
}
}
},
@@ -501,11 +576,6 @@ export let ProgressiveCat = (function() {
return this.rootUrl + "/" + "Norder" + norder + "/Dir" + dirIdx + "/Npix" + npix + ".tsv";
},
// todo, allow HiPS cats to support footprints
getFootprints: function() {
return null;
},
loadNeededTiles: function() {
if ( ! this.isShowing) {
return;
@@ -559,18 +629,23 @@ export let ProgressiveCat = (function() {
url: Aladin.JSONP_PROXY,
data: {"url": self.getTileURL(norder, ipix)},
*/
// ATTENTIOn : je passe en JSON direct, car je n'arrive pas a choper les 404 en JSONP
// ATTENTION : je passe en JSON direct, car je n'arrive pas a choper les 404 en JSONP
url: self.getTileURL(norder, ipix),
desc: "Get tile .tsv " + norder + ' ' + ipix + ' of ' + self.name,
method: 'GET',
//dataType: 'jsonp',
success: function(tsv) {
self.sourcesCache.set(key, getSources(self, tsv, self.fields));
let [sources, footprints] = getSources(self, tsv, self.fields);
self.sourcesCache.set(key, sources);
self.footprintsCache.set(key, footprints);
self.view.requestRedraw();
},
error: function() {
// on suppose qu'il s'agit d'une erreur 404
self.sourcesCache.set(key, []);
self.footprintsCache.set(key, []);
}
});
})(this, t[0], t[1]);
@@ -578,6 +653,8 @@ export let ProgressiveCat = (function() {
}
},
parseFootprintsFromSources: Catalog.prototype.parseFootprintsFromSources,
reportChange: function() { // TODO: to be shared with Catalog
this.view && this.view.requestRedraw();
}

View File

@@ -316,10 +316,10 @@ export let View = (function () {
imageCanvas.remove();
}
let gridCanvas = this.aladinDiv.querySelector('.aladin-gridCanvas');
/*let gridCanvas = this.aladinDiv.querySelector('.aladin-gridCanvas');
if (gridCanvas) {
gridCanvas.remove();
}
}*/
let catalogCanvas = this.aladinDiv.querySelector('.aladin-catalogCanvas')
if (catalogCanvas) {
@@ -339,7 +339,7 @@ export let View = (function () {
};
this.catalogCanvas = createCanvas('aladin-catalogCanvas');
this.gridCanvas = createCanvas('aladin-gridCanvas');
//this.gridCanvas = createCanvas('aladin-gridCanvas');
this.imageCanvas = createCanvas('aladin-imageCanvas');
};
@@ -369,13 +369,16 @@ export let View = (function () {
// reinitialize 2D context
this.catalogCtx = this.catalogCanvas.getContext("2d");
this.catalogCtx.canvas.width = this.width;
this.catalogCtx.canvas.height = this.height;
this.catalogCtx.canvas.width = this.width * window.devicePixelRatio;
this.catalogCtx.canvas.height = this.height * window.devicePixelRatio;
this.catalogCtx.canvas.style.width = this.width + "px";
this.catalogCtx.canvas.style.height = this.height + "px";
this.catalogCtx.scale(window.devicePixelRatio, window.devicePixelRatio);
this.gridCtx = this.gridCanvas.getContext("2d");
/*this.gridCtx = this.gridCanvas.getContext("2d");
this.gridCtx.canvas.width = this.width;
this.gridCtx.canvas.height = this.height;
*/
this.imageCtx = this.imageCanvas.getContext("webgl2");
this.imageCtx.canvas.style.width = this.width + "px";
this.imageCtx.canvas.style.height = this.height + "px";
@@ -467,9 +470,8 @@ export let View = (function () {
const canvas = this.wasm.canvas();
var c = document.createElement('canvas');
let dpi = window.devicePixelRatio;
c.width = width || (this.width * dpi);
c.height = height || (this.height * dpi);
c.width = width || (this.width * window.devicePixelRatio);
c.height = height || (this.height * window.devicePixelRatio);
var ctx = c.getContext('2d');
@@ -506,9 +508,8 @@ export let View = (function () {
view.unselectObjects()
try {
const lonlat = view.wasm.screenToWorld(xymouse.x, xymouse.y);
var radec = view.wasm.viewToICRSCooSys(lonlat[0], lonlat[1]);
view.pointTo(radec[0], radec[1]);
const [lon, lat] = view.aladin.pix2world(xymouse.x, xymouse.y, 'icrs');
view.pointTo(lon, lat);
}
catch (err) {
return;
@@ -1207,12 +1208,11 @@ export let View = (function () {
// specified fpsInterval not being a multiple of RAF's interval (16.7ms)
// Drawing code
try {
this.moving = this.wasm.update(elapsedTime);
} catch (e) {
console.error(e)
}
//try {
this.moving = this.wasm.update(elapsedTime);
//} catch (e) {
// console.error(e)
//}
////// 2. Draw catalogues////////
const isViewRendering = this.wasm.isRendering();
@@ -1230,6 +1230,7 @@ export let View = (function () {
View.prototype.drawAllOverlays = function () {
var ctx = this.catalogCtx;
this.catalogCanvasCleared = false;
if (this.mustClearCatalog) {
ctx.clearRect(0, 0, this.width, this.height);
this.catalogCanvasCleared = true;
@@ -1246,7 +1247,7 @@ export let View = (function () {
for (var i = 0; i < this.catalogs.length; i++) {
var cat = this.catalogs[i];
cat.draw(ctx, this.cooFrame, this.width, this.height, this.largestDim);
cat.draw(ctx, this.width, this.height);
}
}
// draw popup catalog
@@ -1320,8 +1321,7 @@ export let View = (function () {
View.prototype.getVisiblePixList = function (norder) {
var pixList = [];
let centerWorldPosition = this.wasm.screenToWorld(this.cx, this.cy);
const [lon, lat] = this.wasm.viewToICRSCooSys(centerWorldPosition[0], centerWorldPosition[1]);
let [lon, lat] = this.aladin.pix2world(this.cx, this.cy, 'icrs');
var radius = this.fov * 0.5 * this.ratio;
this.wasm.queryDisc(norder, lon, lat, radius).forEach(x => pixList.push(Number(x)));
@@ -1476,26 +1476,20 @@ export let View = (function () {
this.wasm.setRotationAroundCenter(rotation);
}
View.prototype.setGridConfig = function (gridCfg) {
this.gridCfg = {...this.gridCfg, ...gridCfg};
this.wasm.setGridConfig(this.gridCfg);
View.prototype.setGridOptions = function (options) {
this.gridCfg = {...this.gridCfg, ...options};
this.wasm.setGridOptions(this.gridCfg);
// send events
/*if (this.gridCfg.hasOwnProperty('enabled')) {
if (this.gridCfg.enabled === true) {
ALEvent.COO_GRID_ENABLED.dispatchedTo(this.aladinDiv);
}
else {
ALEvent.COO_GRID_DISABLED.dispatchedTo(this.aladinDiv);
}
}*/
if (!this.gridCfg.enabled) {
this.mustClearCatalog = true;
}
ALEvent.COO_GRID_UPDATED.dispatchedTo(this.aladinDiv, this.gridCfg);
this.requestRedraw();
};
View.prototype.getGridConfig = function() {
View.prototype.getGridOptions = function() {
return this.gridCfg;
}
@@ -1782,10 +1776,10 @@ export let View = (function () {
// Set the grid label format
if (this.cooFrame.label == "J2000d") {
this.setGridConfig({fmt: "HMS"});
this.setGridOptions({fmt: "HMS"});
}
else {
this.setGridConfig({fmt: "DMS"});
this.setGridOptions({fmt: "DMS"});
}
// Get the new view center position (given in icrs)
@@ -1987,7 +1981,7 @@ export let View = (function () {
let lineWidth = footprint.getLineWidth();
footprint.setLineWidth(10.0);
if (footprint.isShowing && footprint.isInStroke(ctx, this, x, y)) {
if (footprint.isShowing && footprint.isInStroke(ctx, this, x * window.devicePixelRatio, y * window.devicePixelRatio)) {
closest = footprint;
}
footprint.setLineWidth(lineWidth);
@@ -2025,8 +2019,9 @@ export let View = (function () {
if (this.catalogs) {
for (var k = 0; k < this.catalogs.length; k++) {
let catalog = this.catalogs[k];
let footprints = catalog.getFootprints();
let closest = this.closestFootprints(catalog.footprints, ctx, x, y);
let closest = this.closestFootprints(footprints, ctx, x, y);
if (closest) {
//ctx.lineWidth = pastLineWidth;
return [closest];

View File

@@ -297,7 +297,7 @@ export class OverlayStack extends ContextMenu {
let radius = self.aladin.angularDist(c.x, c.y, c.x + c.r, c.y);
// the moc needs a
let moc = A.MOCFromCircle(
let moc = A.MOCFromCone(
{ra, dec, radius},
{name: 'cone', lineWidth: 3.0},
);

View File

@@ -121,11 +121,12 @@ export class ContextMenu extends DOMElement {
monochrome: true,
url: copyIconUrl,
size: 'small',
tooltip: {content: 'Copy the position!', position: {direction: 'bottom'}}
cssStyle: {
cursor: 'not-allowed',
}
}),
posStr
]).attachTo(item)
} catch (e) {
item.innerHTML = '<span>Out of projection</span>';
}
@@ -240,11 +241,13 @@ export class ContextMenu extends DOMElement {
if (!opt.disabled || opt.disabled === false) {
if (!opt.subMenu || opt.subMenu.length === 0) {
if ((opt.mustHide === undefined || opt.mustHide === true) && (!self.options || self.options.hideOnClick === undefined || self.options.hideOnClick === true)) {
let close = opt.action(e, self);
close = close !== undefined ? close : true;
if (close && ((opt.mustHide === undefined || opt.mustHide === true) && (!self.options || self.options.hideOnClick === undefined || self.options.hideOnClick === true))) {
self._hide();
}
opt.action(e, self);
}
}
});