mirror of
https://github.com/cds-astro/aladin-lite.git
synced 2025-12-25 20:34:50 -08:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f1f69983f |
25
AUTHORS
Normal file
25
AUTHORS
Normal file
@@ -0,0 +1,25 @@
|
||||
AUTHORS
|
||||
=======
|
||||
|
||||
This file lists the main developers and contributors to this project.
|
||||
For a full list of commit authors, see: https://github.com/cds-astro/aladin-lite/graphs/contributors
|
||||
|
||||
Institutional Affiliation
|
||||
--------------------------
|
||||
Centre de Données astronomiques de Strasbourg (CDS)
|
||||
https://cds.unistra.fr/
|
||||
|
||||
Main Developers
|
||||
---------------
|
||||
Thomas Boch (@tboch)
|
||||
Matthieu Baumann (@bmatthieu3)
|
||||
|
||||
|
||||
|
||||
Acknowledgments
|
||||
---------------
|
||||
We also acknowledge all contributors who have submitted bug reports, feature requests,
|
||||
documentation improvements, and patches through GitHub issues and pull requests.
|
||||
|
||||
This project is hosted on GitHub:
|
||||
https://github.com/cds-astro/aladin-lite
|
||||
@@ -8,8 +8,8 @@
|
||||
"dateModified": "2023-01-31",
|
||||
"issueTracker": "https://github.com/cds-astro/aladin-lite/issues",
|
||||
"name": "Aladin Lite",
|
||||
"version": "3.6.4",
|
||||
"softwareVersion": "3.6.4",
|
||||
"version": "3.6.1",
|
||||
"softwareVersion": "3.6.1",
|
||||
"description": "An astronomical HiPS visualizer in the browser.",
|
||||
"identifier": "10.5281/zenodo.7638833",
|
||||
"applicationCategory": "Astronomy, Visualization",
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
let aladin;
|
||||
A.init.then(() => {
|
||||
// Start up Aladin Lite
|
||||
aladin = A.aladin('#aladin-lite-div', {target: 'M 1', fov: 0.2, showContextMenu: true, fullScreen: true});
|
||||
aladin = A.aladin('#aladin-lite-div', {survey: "CDS/P/DSS2/color", target: 'M 1', fov: 0.2, showContextMenu: true, fullScreen: true});
|
||||
var overlay = A.graphicOverlay({color: '#ee2345', lineWidth: 3, lineDash: [2, 2]});
|
||||
aladin.addOverlay(overlay);
|
||||
/*aladin.addOverlay(overlay);
|
||||
overlay.addFootprints([
|
||||
A.polygon([[83.64287, 22.01713], [83.59872, 22.01692], [83.59852, 21.97629], [83.64295, 21.97629]], {hoverColor: 'green'}),
|
||||
A.polygon([[83.62807, 22.06330], [83.58397, 22.02280], [83.62792, 22.02258]]),
|
||||
@@ -21,7 +21,7 @@
|
||||
]);
|
||||
overlay.add(A.circle(83.66067, 22.03081, 0.04, {color: 'cyan'})); // radius in degrees
|
||||
overlay.add(A.vector(83.66067, 22.03081, 0.04, {color: 'cyan'})); // radius in degrees
|
||||
|
||||
*/
|
||||
aladin.on("footprintClicked", (footprint, xyMouseCoords) => {
|
||||
console.log("footprint clicked catched: ", footprint, "mouse coords xy: ", xyMouseCoords.x, xyMouseCoords.y);
|
||||
})
|
||||
@@ -35,8 +35,8 @@
|
||||
console.log("Object hovered stopped: ", object, "mouse coords xy: ", xyMouseCoords.x, xyMouseCoords.y);
|
||||
})
|
||||
|
||||
//const cat = A.catalogFromVizieR('B/assocdata/obscore', 'M 1', 10, {onClick: 'showTable', selectionColor: "orange", hoverColor: 'red', limit: 10000});
|
||||
//aladin.addCatalog(cat);
|
||||
const cat = A.catalogFromVizieR('B/assocdata/obscore', 'M 1', 10, {onClick: 'showTable', selectionColor: "orange", hoverColor: 'red', limit: 10000});
|
||||
aladin.addCatalog(cat);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<script type="module">
|
||||
import A from '../src/js/A.js';
|
||||
A.init.then(() => {
|
||||
let aladin = A.aladin('#aladin-lite-div', {fov: 30, target: "280 +0", projection: "AIT", showShareControl:true, showSettingsControl: true, showContextMenu:true});
|
||||
let aladin = A.aladin('#aladin-lite-div', {fov: 30, survey: "CDS/P/DSS2/color", target: "280 +0", projection: "AIT", showShareControl:true, showSettingsControl: true, showContextMenu:true});
|
||||
|
||||
aladin.setOverlayImageLayer(A.image(
|
||||
"https://www.virtualastronomy.org/images/sig05-013.jpg",
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
showCooGrid: true,
|
||||
fullScreen: true,
|
||||
samp: true,
|
||||
realFullscreen: true,
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"homepage": "https://aladin.u-strasbg.fr/",
|
||||
"name": "aladin-lite",
|
||||
"type": "module",
|
||||
"version": "3.6.5",
|
||||
"version": "3.6.1",
|
||||
"description": "An astronomical HiPS visualizer in the browser",
|
||||
"author": "Thomas Boch and Matthieu Baumann",
|
||||
"license": "GPL-3",
|
||||
|
||||
@@ -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.6.5"
|
||||
version = "3.6.1"
|
||||
authors = [ "baumannmatthieu0@gmail.com", "matthieu.baumann@astro.unistra.fr",]
|
||||
edition = "2018"
|
||||
|
||||
@@ -22,7 +22,7 @@ url-lite = "0.1.0"
|
||||
serde_json = "1.0.104"
|
||||
serde-wasm-bindgen = "0.5"
|
||||
enum_dispatch = "0.3.8"
|
||||
wasm-bindgen = "=0.2.92"
|
||||
wasm-bindgen = "0.2.100"
|
||||
wasm-streams = "0.3.0"
|
||||
async-channel = "1.8.0"
|
||||
mapproj = "0.3.0"
|
||||
@@ -64,7 +64,7 @@ path = "./al-core"
|
||||
path = "./al-api"
|
||||
|
||||
[dependencies.web-sys]
|
||||
version = "0.3.56"
|
||||
version = "*"
|
||||
features = [ "console", "CssStyleDeclaration", "Document", "Element", "HtmlCollection", "HtmlElement", "HtmlImageElement", "HtmlCanvasElement", "Blob", "ImageBitmap", "ImageData", "CanvasRenderingContext2d", "WebGlBuffer", "WebGlContextAttributes", "WebGlFramebuffer", "WebGlProgram", "WebGlShader", "WebGlUniformLocation", "WebGlTexture", "WebGlActiveInfo", "Headers", "Window", "Request", "RequestInit", "RequestMode", "Response", "XmlHttpRequest", "XmlHttpRequestResponseType", "PerformanceTiming", "Performance", "Url", "ReadableStream", "File", "FileList",]
|
||||
|
||||
[dev-dependencies.image-decoder]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "al-api"
|
||||
version = "3.6.5"
|
||||
version = "0.1.0"
|
||||
authors = ["baumannmatthieu0@gmail.com", "matthieu.baumann@astro.unistra.fr"]
|
||||
edition = "2018"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "al-core"
|
||||
version = "3.6.5"
|
||||
version = "0.1.0"
|
||||
authors = ["baumannmatthieu0@gmail.com", "matthieu.baumann@astro.unistra.fr"]
|
||||
edition = "2018"
|
||||
|
||||
@@ -17,7 +17,9 @@ serde-wasm-bindgen = "0.4"
|
||||
wasm-streams = "0.3.0"
|
||||
futures = "0.3.25"
|
||||
colorgrad = "0.6.2"
|
||||
wasm-bindgen = "0.2.92"
|
||||
|
||||
[dependencies.wasm-bindgen]
|
||||
version = "0.2.92"
|
||||
|
||||
[dev-dependencies]
|
||||
fontdue = "0.7.2"
|
||||
@@ -36,7 +38,7 @@ webgl2 = [
|
||||
]
|
||||
|
||||
[dependencies.web-sys]
|
||||
version = "0.3.56"
|
||||
version = "0.3.77"
|
||||
features = [
|
||||
'console',
|
||||
'CssStyleDeclaration',
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use crate::renderable::ImageLayer;
|
||||
use crate::tile_fetcher::HiPSLocalFiles;
|
||||
|
||||
use crate::math::angle::ToAngle;
|
||||
use crate::renderable::hips::HiPS;
|
||||
use crate::{
|
||||
//async_task::{BuildCatalogIndex, ParseTableTask, TaskExecutor, TaskResult, TaskType},
|
||||
@@ -22,6 +21,7 @@ use crate::{
|
||||
time::DeltaTime,
|
||||
};
|
||||
use al_api::moc::MOCOptions;
|
||||
use crate::math::angle::ToAngle;
|
||||
use wcs::WCS;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
@@ -188,7 +188,7 @@ impl App {
|
||||
let request_for_new_tiles = true;
|
||||
|
||||
let moc = MOCRenderer::new(&gl)?;
|
||||
gl.clear_color(0.1, 0.1, 0.1, 1.0);
|
||||
gl.clear_color(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
let (img_send, img_recv) = async_channel::unbounded::<ImageLayer>();
|
||||
let (ack_img_send, ack_img_recv) = async_channel::unbounded::<ImageParams>();
|
||||
@@ -714,8 +714,8 @@ impl App {
|
||||
)?,
|
||||
}
|
||||
self.time_start_blending = Time::now();
|
||||
}
|
||||
_ => (),
|
||||
},
|
||||
_ => ()
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1277,7 +1277,8 @@ impl App {
|
||||
// Set the new meta
|
||||
// keep the old meta data
|
||||
let new_img_ext = meta.img_format;
|
||||
self.layers.set_layer_cfg(layer.clone(), meta)?;
|
||||
self.layers
|
||||
.set_layer_cfg(layer.clone(), meta)?;
|
||||
|
||||
if old_meta.img_format != new_img_ext {
|
||||
// The image format has been changed
|
||||
|
||||
@@ -5,8 +5,8 @@ pub enum UserAction {
|
||||
Moving = 3,
|
||||
Starting = 4,
|
||||
}
|
||||
|
||||
use web_sys::WebGl2RenderingContext;
|
||||
|
||||
// Longitude reversed identity matrix
|
||||
const ID_R: &Matrix4<f64> = &Matrix4::new(
|
||||
-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
|
||||
@@ -488,11 +488,11 @@ impl CameraViewPort {
|
||||
pub fn set_center(&mut self, lonlat: &LonLatT<f64>, proj: &ProjectionType) {
|
||||
let icrs_pos: Vector4<_> = lonlat.vector();
|
||||
|
||||
let center = (CooSystem::ICRS.to(self.get_coo_system()) * icrs_pos).truncate();
|
||||
let rot_to_center = Rotation::from_sky_position(¢er);
|
||||
let view_pos = CooSystem::ICRS.to(self.get_coo_system()) * icrs_pos;
|
||||
let rot_to_center = Rotation::from_sky_position(&view_pos);
|
||||
|
||||
let phi = self.get_center_pos_angle();
|
||||
let third_euler_rot = Rotation::from_axis_angle(¢er, phi);
|
||||
let third_euler_rot = Rotation::from_axis_angle(&view_pos.truncate(), phi);
|
||||
|
||||
let rot = third_euler_rot * rot_to_center;
|
||||
|
||||
@@ -502,9 +502,8 @@ impl CameraViewPort {
|
||||
}
|
||||
|
||||
pub fn set_center_pos_angle(&mut self, phi: Angle<f64>, proj: &ProjectionType) {
|
||||
let c = self.center.truncate();
|
||||
let rot_to_center = Rotation::from_sky_position(&c);
|
||||
let third_euler_rot = Rotation::from_axis_angle(&c, phi);
|
||||
let rot_to_center = Rotation::from_sky_position(&self.center);
|
||||
let third_euler_rot = Rotation::from_axis_angle(&self.center.truncate(), phi);
|
||||
|
||||
let total_rot = third_euler_rot * rot_to_center;
|
||||
self.set_rotation(&total_rot, proj);
|
||||
@@ -524,7 +523,7 @@ impl CameraViewPort {
|
||||
// Compute the center position according to the new coordinate frame system
|
||||
let new_center = coosys::apply_coo_system(self.coo_sys, new_coo_sys, &self.center);
|
||||
// Create a rotation object from that position
|
||||
let new_rotation = Rotation::from_sky_position(&new_center.truncate());
|
||||
let new_rotation = Rotation::from_sky_position(&new_center);
|
||||
// Apply it to the center of the view
|
||||
self.set_rotation(&new_rotation, proj);
|
||||
|
||||
|
||||
@@ -130,9 +130,9 @@ impl From<query::Allsky> for AllskyRequest {
|
||||
Ok(allsky_tiles)
|
||||
}
|
||||
_ => {
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method("GET");
|
||||
opts.mode(RequestMode::Cors);
|
||||
let opts = RequestInit::new();
|
||||
opts.set_method("GET");
|
||||
opts.set_mode(RequestMode::Cors);
|
||||
let window = web_sys::window().unwrap_abort();
|
||||
|
||||
let request = web_sys::Request::new_with_str_and_init(&url_clone, &opts)?;
|
||||
@@ -185,24 +185,14 @@ impl From<query::Allsky> for AllskyRequest {
|
||||
.collect())
|
||||
}
|
||||
InMemData::F32(data) => {
|
||||
let data = unsafe {
|
||||
std::slice::from_raw_parts(
|
||||
data.as_ptr() as *const u8,
|
||||
data.len() * 4,
|
||||
)
|
||||
};
|
||||
let data = unsafe { std::slice::from_raw_parts(data.as_ptr() as *const u8, data.len() * 4) };
|
||||
Ok(handle_allsky_fits(&data, tile_size, texture_size)?
|
||||
.map(|image| ImageType::RawRgba8u { image })
|
||||
.collect())
|
||||
}
|
||||
InMemData::F64(data) => {
|
||||
let data = data.iter().map(|v| *v as f32).collect::<Vec<_>>();
|
||||
let data = unsafe {
|
||||
std::slice::from_raw_parts(
|
||||
data.as_ptr() as *const u8,
|
||||
data.len() * 4,
|
||||
)
|
||||
};
|
||||
let data = unsafe { std::slice::from_raw_parts(data.as_ptr() as *const u8, data.len() * 4) };
|
||||
|
||||
Ok(handle_allsky_fits(&data, tile_size, texture_size)?
|
||||
.map(|image| ImageType::RawRgba8u { image })
|
||||
@@ -238,77 +228,71 @@ fn handle_allsky_file<F: ImageFormat>(
|
||||
let num_allsky_tiles_per_tile = (tile_size / allsky_tile_size) * (tile_size / allsky_tile_size);
|
||||
|
||||
let mut src_idx = 0;
|
||||
let tiles = (0..num_tiles).map(move |_| {
|
||||
let mut base_tile =
|
||||
let tiles = (0..num_tiles)
|
||||
.map(move |_| {
|
||||
let mut base_tile =
|
||||
ImageBuffer::<F>::allocate(&<F as ImageFormat>::P::BLACK, tile_size, tile_size);
|
||||
for idx_tile in 0..num_allsky_tiles_per_tile {
|
||||
let (x, y) = crate::utils::unmortonize(idx_tile as u64);
|
||||
let dx = x * (allsky_tile_size as u32);
|
||||
let dy = y * (allsky_tile_size as u32);
|
||||
for idx_tile in 0..num_allsky_tiles_per_tile {
|
||||
let (x, y) = crate::utils::unmortonize(idx_tile as u64);
|
||||
let dx = x * (allsky_tile_size as u32);
|
||||
let dy = y * (allsky_tile_size as u32);
|
||||
|
||||
let sx = (src_idx % 27) * allsky_tile_size;
|
||||
let sy = (src_idx / 27) * allsky_tile_size;
|
||||
let s = ImageBufferView {
|
||||
x: sx as i32,
|
||||
y: sy as i32,
|
||||
w: allsky_tile_size as i32,
|
||||
h: allsky_tile_size as i32,
|
||||
};
|
||||
let d = ImageBufferView {
|
||||
x: dx as i32,
|
||||
y: dy as i32,
|
||||
w: allsky_tile_size as i32,
|
||||
h: allsky_tile_size as i32,
|
||||
};
|
||||
let sx = (src_idx % 27) * allsky_tile_size;
|
||||
let sy = (src_idx / 27) * allsky_tile_size;
|
||||
let s = ImageBufferView {
|
||||
x: sx as i32,
|
||||
y: sy as i32,
|
||||
w: allsky_tile_size as i32,
|
||||
h: allsky_tile_size as i32,
|
||||
};
|
||||
let d = ImageBufferView {
|
||||
x: dx as i32,
|
||||
y: dy as i32,
|
||||
w: allsky_tile_size as i32,
|
||||
h: allsky_tile_size as i32,
|
||||
};
|
||||
|
||||
base_tile.tex_sub(&allsky, &s, &d);
|
||||
base_tile.tex_sub(&allsky, &s, &d);
|
||||
|
||||
src_idx += 1;
|
||||
}
|
||||
src_idx += 1;
|
||||
}
|
||||
|
||||
base_tile
|
||||
});
|
||||
base_tile
|
||||
});
|
||||
|
||||
Ok(tiles)
|
||||
}
|
||||
|
||||
fn handle_allsky_fits<F: ImageFormat>(
|
||||
allsky_data: &[<<F as ImageFormat>::P as Pixel>::Item],
|
||||
|
||||
tile_size: i32,
|
||||
texture_size: i32,
|
||||
) -> Result<impl Iterator<Item = ImageBuffer<F>>, JsValue> {
|
||||
) -> Result<impl Iterator<Item=ImageBuffer<F>>, JsValue> {
|
||||
let allsky_tile_size = std::cmp::min(tile_size, 64);
|
||||
let width_allsky_px = 27 * allsky_tile_size;
|
||||
let height_allsky_px = 29 * allsky_tile_size;
|
||||
// The fits image layout stores rows in reverse
|
||||
let reversed_rows_data = allsky_data
|
||||
.chunks(width_allsky_px as usize * F::NUM_CHANNELS)
|
||||
.chunks(width_allsky_px as usize)
|
||||
.rev()
|
||||
.flatten()
|
||||
.copied()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let allsky = ImageBuffer::<F>::new(reversed_rows_data, width_allsky_px, height_allsky_px);
|
||||
|
||||
let allsky_tiles_iter =
|
||||
handle_allsky_file::<F>(allsky, allsky_tile_size, texture_size, tile_size)?.map(
|
||||
move |image| {
|
||||
// The GPU does a specific transformation on the UV for FITS tiles
|
||||
// We must revert this to be compatible with this GPU transformation
|
||||
let new_image_data = image
|
||||
.get_data()
|
||||
.chunks((tile_size * tile_size) as usize * F::NUM_CHANNELS)
|
||||
.flat_map(|c| {
|
||||
c.chunks(tile_size as usize * F::NUM_CHANNELS)
|
||||
.rev()
|
||||
.flatten()
|
||||
})
|
||||
.cloned()
|
||||
.collect();
|
||||
let allsky_tiles_iter = handle_allsky_file::<F>(allsky, allsky_tile_size, texture_size, tile_size)?
|
||||
.map(move |image| {
|
||||
// The GPU does a specific transformation on the UV
|
||||
// for FITS tiles
|
||||
// We must revert this to be compatible with this GPU transformation
|
||||
let mut new_image_data = Vec::with_capacity(tile_size as usize);
|
||||
for c in image.get_data().chunks((tile_size * tile_size) as usize) {
|
||||
new_image_data.extend(c.chunks(tile_size as usize).rev().flatten());
|
||||
}
|
||||
|
||||
ImageBuffer::<F>::new(new_image_data, tile_size, tile_size)
|
||||
},
|
||||
);
|
||||
ImageBuffer::<F>::new(new_image_data, tile_size, tile_size)
|
||||
});
|
||||
|
||||
Ok(allsky_tiles_iter)
|
||||
}
|
||||
|
||||
@@ -61,9 +61,9 @@ impl From<query::PixelMetadata> for PixelMetadataRequest {
|
||||
let request = match channel {
|
||||
ChannelType::R32F | ChannelType::R32I | ChannelType::R16I | ChannelType::R8UI => {
|
||||
Request::new(async move {
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method("GET");
|
||||
opts.mode(RequestMode::Cors);
|
||||
let opts = RequestInit::new();
|
||||
opts.set_method("GET");
|
||||
opts.set_mode(RequestMode::Cors);
|
||||
|
||||
let request =
|
||||
web_sys::Request::new_with_str_and_init(&url_clone, &opts).unwrap_abort();
|
||||
|
||||
@@ -61,9 +61,9 @@ impl From<query::Moc> for MOCRequest {
|
||||
|
||||
let window = web_sys::window().unwrap_abort();
|
||||
let request = Request::new(async move {
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method("GET");
|
||||
opts.mode(RequestMode::Cors);
|
||||
let opts = RequestInit::new();
|
||||
opts.set_method("GET");
|
||||
opts.set_mode(RequestMode::Cors);
|
||||
|
||||
let request = web_sys::Request::new_with_str_and_init(&url_clone, &opts).unwrap_abort();
|
||||
let resp_value = JsFuture::from(window.fetch_with_request(&request)).await?;
|
||||
|
||||
@@ -142,9 +142,9 @@ impl From<query::Tile> for TileRequest {
|
||||
| ChannelType::R32I
|
||||
| ChannelType::R16I
|
||||
| ChannelType::R8UI => Request::new(async move {
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method("GET");
|
||||
opts.mode(RequestMode::Cors);
|
||||
let opts = RequestInit::new();
|
||||
opts.set_method("GET");
|
||||
opts.set_mode(RequestMode::Cors);
|
||||
|
||||
let request =
|
||||
web_sys::Request::new_with_str_and_init(&url_clone, &opts).unwrap_abort();
|
||||
|
||||
@@ -523,7 +523,7 @@ impl WebClient {
|
||||
|
||||
/// Get if the longitude axis is reversed
|
||||
#[wasm_bindgen(js_name = getLongitudeReversed)]
|
||||
pub fn get_longitude_reversed(&self) -> bool {
|
||||
pub fn get_longitude_reversed(&mut self) -> bool {
|
||||
self.app.get_longitude_reversed()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use crate::math;
|
||||
use crate::math::angle::ToAngle;
|
||||
use cgmath::{BaseFloat, InnerSpace};
|
||||
use cgmath::{Euler, Quaternion};
|
||||
use cgmath::{Vector3, Vector4};
|
||||
use crate::math::angle::ToAngle;
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
// Internal structure of a rotation, a quaternion
|
||||
@@ -109,13 +109,13 @@ where
|
||||
// Define a rotation from an axis and a angle
|
||||
pub fn from_axis_angle(axis: &Vector3<S>, angle: Angle<S>) -> Rotation<S> {
|
||||
let angle: Rad<S> = angle.into();
|
||||
let mat4 = Matrix4::from_axis_angle(axis.normalize(), angle);
|
||||
let mat4 = Matrix4::from_axis_angle(*axis, angle);
|
||||
(&mat4).into()
|
||||
}
|
||||
|
||||
// Define a rotation from a normalized vector
|
||||
pub fn from_sky_position(pos: &Vector3<S>) -> Rotation<S> {
|
||||
let (lon, lat) = math::lonlat::xyz_to_radec(&pos);
|
||||
pub fn from_sky_position(pos: &Vector4<S>) -> Rotation<S> {
|
||||
let (lon, lat) = math::lonlat::xyzw_to_radec(&pos.normalize());
|
||||
|
||||
let rot_y = Matrix4::from_angle_y(lon);
|
||||
let rot_x = Matrix4::from_angle_x(-lat);
|
||||
|
||||
@@ -95,7 +95,7 @@ impl Renderer for TextRenderManager {
|
||||
// reset the font and color
|
||||
self.ctx
|
||||
.set_font(&format!("{}px verdana, sans-serif", self.font_size));
|
||||
self.ctx.set_fill_style(&JsValue::from_str(&self.color));
|
||||
self.ctx.set_fill_style_str(&self.color);
|
||||
}
|
||||
|
||||
fn end(&mut self) {}
|
||||
|
||||
@@ -2,10 +2,10 @@ use crate::downloader::{query, Downloader};
|
||||
use crate::time::{DeltaTime, Time};
|
||||
use crate::Abort;
|
||||
|
||||
use al_api::moc::MOCOptions;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use std::rc::Rc;
|
||||
use al_api::moc::MOCOptions;
|
||||
|
||||
const MAX_NUM_TILE_FETCHING: usize = 8;
|
||||
const MAX_QUERY_QUEUE_LENGTH: usize = 100;
|
||||
@@ -214,7 +214,7 @@ impl TileFetcherQueue {
|
||||
|
||||
let tile_size = cfg.get_tile_size();
|
||||
//Request the allsky for the small tile size or if base tiles are not available
|
||||
if tile_size <= 256 || cfg.get_min_depth_tile() > 0 {
|
||||
if tile_size <= 128 || cfg.get_min_depth_tile() > 0 {
|
||||
// Request the allsky
|
||||
downloader.borrow_mut().fetch(query::Allsky::new(
|
||||
cfg,
|
||||
|
||||
@@ -505,15 +505,12 @@
|
||||
|
||||
.aladin-form .aladin-form-input {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.aladin-form-group > * {
|
||||
margin-bottom: 0.4rem;
|
||||
}
|
||||
|
||||
.aladin-form-group > *:last-of-type {
|
||||
.aladin-form .aladin-form-input:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
@@ -530,6 +527,10 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.aladin-form .aladin-form-input > label {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.aladin-form .aladin-form-input .aladin-input {
|
||||
flex: 2;
|
||||
}
|
||||
@@ -839,18 +840,13 @@
|
||||
box-shadow: 0 0 1em 0 rgba(0, 0, 0, 0.2);
|
||||
cursor: pointer;
|
||||
font-family: monospace;
|
||||
width: 100%;
|
||||
box-sizing: content-box;
|
||||
/* <option> colors */
|
||||
/* Remove focus outline */
|
||||
/* Remove IE arrow */
|
||||
}
|
||||
|
||||
/* This is done so that the select shrink to the size of its parent (coupled with flex)
|
||||
otherwise it fits its content options. If those are too big the select can go out of its parent */
|
||||
.aladin-horizontal-list .aladin-input-select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.aladin-input-select option {
|
||||
color: inherit;
|
||||
background-color: #320a28;
|
||||
|
||||
@@ -1036,7 +1036,7 @@ A.init = (async () => {
|
||||
.createElement('canvas')
|
||||
.getContext('webgl2');
|
||||
|
||||
await init();
|
||||
await init({});
|
||||
// Check for webgl2 support
|
||||
if (isWebGL2Supported) {
|
||||
Aladin.wasmLibs.core = module;
|
||||
|
||||
@@ -426,8 +426,6 @@ export let Aladin = (function () {
|
||||
// Merge what is already in the cache for that HiPS with new properties
|
||||
// coming from the MOCServer
|
||||
this.hipsFavorites.push(hipsObj);
|
||||
// Favorites are also directly pushed to the cache
|
||||
this.hipsCache.append(hipsObj.id, hipsObj)
|
||||
}
|
||||
|
||||
this._setupUI(options);
|
||||
@@ -447,7 +445,11 @@ export let Aladin = (function () {
|
||||
});
|
||||
} else if (options.survey === HiPS.DEFAULT_SURVEY_ID) {
|
||||
// DSS is cached inside HiPS class, no need to provide any further information
|
||||
this.setBaseImageLayer(HiPS.DEFAULT_SURVEY_ID);
|
||||
const survey = this.createImageSurvey(
|
||||
HiPS.DEFAULT_SURVEY_ID
|
||||
);
|
||||
|
||||
this.setBaseImageLayer(survey);
|
||||
} else {
|
||||
this.setBaseImageLayer(options.survey);
|
||||
}
|
||||
@@ -483,24 +485,22 @@ export let Aladin = (function () {
|
||||
// maximize control
|
||||
if (options.showFullscreenControl) {
|
||||
// react to fullscreenchange event to restore initial width/height (if user pressed ESC to go back from full screen)
|
||||
// This event is only triggered with realFullscreen on
|
||||
Utils.on(
|
||||
document,
|
||||
"fullscreenchange webkitfullscreenchange mozfullscreenchange MSFullscreenChange",
|
||||
() => {
|
||||
function (e) {
|
||||
var fullscreenElt =
|
||||
document.fullscreenElement ||
|
||||
document.webkitFullscreenElement ||
|
||||
document.mozFullScreenElement ||
|
||||
document.msFullscreenElement;
|
||||
if (fullscreenElt === null || fullscreenElt === undefined) {
|
||||
// fix: Only toggle off the screen once because in case of closing the real fullscreen from the ui button, this could be called 2 times
|
||||
// * one toggleFullscreen from the button itself
|
||||
// * one toggleFullscreen from the fullscreenchange event
|
||||
// => resulting in closing and opening the fullscreen again.
|
||||
if (self.isInFullscreen) {
|
||||
self.toggleFullscreen(options.realFullscreen);
|
||||
}
|
||||
self.toggleFullscreen(options.realFullscreen);
|
||||
|
||||
var fullScreenToggledFn =
|
||||
self.callbacksByEventName["fullScreenToggled"];
|
||||
typeof fullScreenToggledFn === "function" &&
|
||||
fullScreenToggledFn(self.isInFullscreen);
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -716,6 +716,7 @@ export let Aladin = (function () {
|
||||
Aladin.prototype.toggleFullscreen = function (realFullscreen) {
|
||||
let self = this;
|
||||
|
||||
realFullscreen = Boolean(realFullscreen);
|
||||
self.isInFullscreen = !self.isInFullscreen;
|
||||
|
||||
ContextMenu.hideAll();
|
||||
@@ -726,7 +727,13 @@ export let Aladin = (function () {
|
||||
ui.toggle();
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
if (this.aladinDiv.classList.contains("aladin-fullscreen")) {
|
||||
this.aladinDiv.classList.remove("aladin-fullscreen");
|
||||
} else {
|
||||
this.aladinDiv.classList.add("aladin-fullscreen");
|
||||
}
|
||||
|
||||
if (realFullscreen) {
|
||||
// go to "real" full screen mode
|
||||
if (self.isInFullscreen) {
|
||||
@@ -757,8 +764,6 @@ export let Aladin = (function () {
|
||||
}
|
||||
}
|
||||
|
||||
this.aladinDiv.classList.toggle("aladin-fullscreen");
|
||||
|
||||
// Delay the fixLayoutDimensions layout for firefox
|
||||
/*setTimeout(function () {
|
||||
self.view.fixLayoutDimensions();
|
||||
@@ -1564,8 +1569,10 @@ export let Aladin = (function () {
|
||||
let hipsOptions = { id, name, maxOrder, url, cooFrame, ...options };
|
||||
let hips = new HiPS(id, url || id, hipsOptions)
|
||||
|
||||
// A HiPS can be refered by its unique ID thus we add it to the cache (cf excample/al-cfht.html that refers to HiPS object just by their unique ID)
|
||||
if (this instanceof Aladin) {
|
||||
// This allows to retrieve the survey's options when it will be
|
||||
// added later to the view.
|
||||
if (this instanceof Aladin && !this.hipsCache.contains(hips.id)) {
|
||||
// Add it to the cache as soon as possible if we have a reference to the aladin object
|
||||
this.hipsCache.append(hips.id, hipsOptions)
|
||||
}
|
||||
|
||||
@@ -1922,14 +1929,12 @@ export let Aladin = (function () {
|
||||
let imageLayer;
|
||||
|
||||
let hipsCache = this.hipsCache;
|
||||
|
||||
// 1. User gives an ID
|
||||
if (typeof urlOrHiPSOrFITS === "string") {
|
||||
const idOrUrl = urlOrHiPSOrFITS;
|
||||
// many cases here
|
||||
// 1/ It has been already added to the cache
|
||||
let cachedOptions = hipsCache.get(idOrUrl)
|
||||
|
||||
if (cachedOptions) {
|
||||
imageLayer = A.HiPS(idOrUrl, cachedOptions);
|
||||
} else {
|
||||
@@ -1949,7 +1954,7 @@ export let Aladin = (function () {
|
||||
if (!cachedLayerOptions) {
|
||||
hipsCache.append(imageLayer.id, imageLayer.options)
|
||||
} else {
|
||||
// Set the options from what is in the cache
|
||||
// set the options from what is in the cache
|
||||
imageLayer.setOptions(cachedLayerOptions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -613,6 +613,7 @@ export let Catalog = (function () {
|
||||
// Set the same color of the shape than the catalog.
|
||||
// FIXME: the color/shape could be a parameter at the source level, allowing the user single catalogs handling different shapes
|
||||
shape.setColor(this.color)
|
||||
|
||||
shape.setSelectionColor(this.selectionColor);
|
||||
shape.setHoverColor(this.hoverColor);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ 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';
|
||||
import { Utils } from "./Utils";
|
||||
|
||||
export let DefaultActionsForContextMenu = (function () {
|
||||
|
||||
@@ -56,7 +55,7 @@ export let DefaultActionsForContextMenu = (function () {
|
||||
return false;
|
||||
}
|
||||
|
||||
Utils.copy2Clipboard(text)
|
||||
navigator.clipboard.writeText(text)
|
||||
.then(() => {
|
||||
msg = 'successful'
|
||||
if (aladinInstance.statusBar) {
|
||||
|
||||
@@ -30,8 +30,6 @@ import { ColorCfg } from "./ColorCfg.js";
|
||||
import { HiPSProperties } from "./HiPSProperties.js";
|
||||
import { Aladin } from "./Aladin.js";
|
||||
import { CooFrameEnum } from "./CooFrameEnum.js";
|
||||
import { Utils } from "./Utils"
|
||||
|
||||
let PropertyParser = {};
|
||||
// Utilitary functions for parsing the properties and giving default values
|
||||
/// Mandatory tileSize property
|
||||
@@ -862,8 +860,9 @@ export let HiPS = (function () {
|
||||
|
||||
let isIncompleteOptions = true;
|
||||
|
||||
let isID = Utils.isUrl(this.url) === undefined;
|
||||
|
||||
// This is very dirty but it allows me to differentiate the location from whether it is an ID or a plain url
|
||||
let isID = this.url.includes("P/") || this.url.includes("C/")
|
||||
|
||||
if (this.imgFormat === "fits") {
|
||||
// a fits is given
|
||||
isIncompleteOptions = !(
|
||||
@@ -888,6 +887,7 @@ export let HiPS = (function () {
|
||||
if (isIncompleteOptions) {
|
||||
// ID typed url
|
||||
if (self.startUrl && isID) {
|
||||
|
||||
// First download the properties from the start url
|
||||
await HiPSProperties.fetchFromUrl(self.startUrl)
|
||||
.then((p) => {
|
||||
@@ -909,16 +909,9 @@ export let HiPS = (function () {
|
||||
|
||||
HiPSProperties.fetchFromID(id)
|
||||
.then((p) => {
|
||||
//self.url = self.startUrl;
|
||||
self._fetchFasterUrlFromProperties(p);
|
||||
})
|
||||
.catch(() => {
|
||||
// If no ID has been found then it may actually be a path
|
||||
// url pointing to a local HiPS
|
||||
return HiPSProperties.fetchFromUrl(id)
|
||||
.then((p) => {
|
||||
self._parseProperties(p);
|
||||
})
|
||||
})
|
||||
},
|
||||
1000
|
||||
);
|
||||
@@ -939,14 +932,6 @@ export let HiPS = (function () {
|
||||
self._parseProperties(p);
|
||||
self._fetchFasterUrlFromProperties(p);
|
||||
})
|
||||
.catch(() => {
|
||||
// If no ID has been found then it may actually be a path
|
||||
// url pointing to a local HiPS
|
||||
return HiPSProperties.fetchFromUrl(id)
|
||||
.then((p) => {
|
||||
self._parseProperties(p);
|
||||
})
|
||||
})
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ HiPSProperties.fetchFromID = async function(ID) {
|
||||
const params = {
|
||||
get: "record",
|
||||
fmt: "json",
|
||||
ID: "*" + decodeURI(ID) + "*",
|
||||
ID: "*" + ID + "*",
|
||||
};
|
||||
|
||||
let metadata = await Utils.loadFromUrls(MocServer.MIRRORS_HTTPS, {
|
||||
|
||||
@@ -246,6 +246,8 @@ export let View = (function () {
|
||||
// some variables for mouse handling
|
||||
this.dragging = false;
|
||||
this.dragCoo = null;
|
||||
this.rightclickx = null;
|
||||
this.rightclicky = null;
|
||||
this.selectedLayer = 'base';
|
||||
|
||||
this.needRedraw = true;
|
||||
@@ -616,7 +618,6 @@ export let View = (function () {
|
||||
};
|
||||
var longTouchTimer;
|
||||
var longTouchDuration = 800;
|
||||
var showContextMenu = true;
|
||||
var xystart;
|
||||
|
||||
var handleSelect = function(xy, tolerance) {
|
||||
@@ -630,7 +631,6 @@ export let View = (function () {
|
||||
var footprintClickedFunction = view.aladin.callbacksByEventName['footprintClicked'];
|
||||
|
||||
let objsByCats = {};
|
||||
let shapes = [];
|
||||
for (let o of objs) {
|
||||
// classify the different objects by catalog
|
||||
let cat = o.getCatalog && o.getCatalog();
|
||||
@@ -649,22 +649,11 @@ export let View = (function () {
|
||||
footprintClickedFunction(o, xy);
|
||||
}
|
||||
}
|
||||
|
||||
// If this shape has a catalog then it will be selected from its source
|
||||
// so we will not add it
|
||||
if (!cat) {
|
||||
shapes.push(o);
|
||||
}
|
||||
}
|
||||
|
||||
// Rewrite objs
|
||||
// rewrite objs
|
||||
objs = Array.from(Object.values(objsByCats));
|
||||
// Add the external shapes (i.e. which are not associated with catalog sources e.g. those from GraphicOverlay)
|
||||
if (shapes.length > 0) {
|
||||
objs.push(shapes)
|
||||
}
|
||||
view.selectObjects(objs);
|
||||
|
||||
view.lastClickedObject = objs;
|
||||
|
||||
} else {
|
||||
@@ -699,7 +688,9 @@ export let View = (function () {
|
||||
|
||||
if (e.which === 3 || e.button === 2) {
|
||||
view.rightClick = true;
|
||||
showContextMenu = true;
|
||||
view.rightClickTimeStart = Date.now();
|
||||
view.rightclickx = xymouse.x;
|
||||
view.rightclicky = xymouse.y;
|
||||
|
||||
if (view.selectedLayer) {
|
||||
const imageLayer = view.imageLayers.get(view.selectedLayer);
|
||||
@@ -785,11 +776,15 @@ export let View = (function () {
|
||||
});
|
||||
|
||||
if (view.rightClick) {
|
||||
if (showContextMenu) {
|
||||
const rightClickDurationMs = Date.now() - view.rightClickTimeStart;
|
||||
if (rightClickDurationMs < 100) {
|
||||
view.aladin.contextMenu && view.aladin.contextMenu.show({e});
|
||||
}
|
||||
|
||||
view.rightClick = false;
|
||||
view.rightclickx = null;
|
||||
view.rightclicky = null;
|
||||
view.rightClickTimeStart = undefined;
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -820,10 +815,11 @@ export let View = (function () {
|
||||
view.aladin.statusBar.removeMessage('opening-ctxmenu')
|
||||
}
|
||||
clearTimeout(longTouchTimer)
|
||||
longTouchTimer = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
xystart = undefined;
|
||||
|
||||
if ((e.type === 'touchend' || e.type === 'touchcancel') && view.pinchZoomParameters.isPinching) {
|
||||
view.pinchZoomParameters.isPinching = false;
|
||||
view.pinchZoomParameters.initialFov = view.pinchZoomParameters.initialDistance = undefined;
|
||||
@@ -925,6 +921,7 @@ export let View = (function () {
|
||||
var lastMouseMovePos = null;
|
||||
Utils.on(view.catalogCanvas, "mousemove touchmove", function (e) {
|
||||
e.preventDefault();
|
||||
//e.stopPropagation();
|
||||
|
||||
const xymouse = Utils.relMouseCoords(e);
|
||||
|
||||
@@ -938,18 +935,16 @@ export let View = (function () {
|
||||
xy: xymouse,
|
||||
});
|
||||
|
||||
let dist;
|
||||
if (xystart) {
|
||||
dist = (xymouse.x - xystart.x)*(xymouse.x - xystart.x) + (xymouse.y - xystart.y)*(xymouse.y - xystart.y);
|
||||
}
|
||||
|
||||
if (e.type === 'touchmove' && xystart) {
|
||||
let dist = (() => {
|
||||
return (xymouse.x - xystart.x)*(xymouse.x - xystart.x) + (xymouse.y - xystart.y)*(xymouse.y - xystart.y)
|
||||
})();
|
||||
if (longTouchTimer && dist > 100) {
|
||||
if (view.aladin.statusBar) {
|
||||
view.aladin.statusBar.removeMessage('opening-ctxmenu')
|
||||
}
|
||||
clearTimeout(longTouchTimer)
|
||||
longTouchTimer = undefined;
|
||||
xystart = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -962,12 +957,11 @@ export let View = (function () {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dist < 100) {
|
||||
const rightClickDurationMs = Date.now() - view.rightClickTimeStart;
|
||||
if (rightClickDurationMs < 100) {
|
||||
return;
|
||||
}
|
||||
|
||||
showContextMenu = false;
|
||||
|
||||
if(view.selectedLayer) {
|
||||
let selectedLayer = view.imageLayers.get(view.selectedLayer);
|
||||
|
||||
@@ -1261,9 +1255,17 @@ export let View = (function () {
|
||||
return;
|
||||
|
||||
switch (e.keyCode) {
|
||||
// shift
|
||||
case 16:
|
||||
view.aladin.select('rect', (selection) => {
|
||||
view.selectObjects(selection);
|
||||
})
|
||||
break;
|
||||
// escape
|
||||
case 27:
|
||||
// Called when realfullscreen is false. Escaping from real fullscreen does not seem to trigger the keydown event
|
||||
// if there is a selection occuring
|
||||
view.selector && view.selector.cancel()
|
||||
|
||||
if (view.aladin.isInFullscreen) {
|
||||
view.aladin.toggleFullscreen(view.aladin.options.realFullscreen);
|
||||
}
|
||||
@@ -2172,21 +2174,26 @@ export let View = (function () {
|
||||
}
|
||||
|
||||
let closests = [];
|
||||
|
||||
footprints.forEach((footprint) => {
|
||||
if (!footprint.source || !footprint.source.tooSmallFootprint) {
|
||||
const originLineWidth = footprint.getLineWidth();
|
||||
let spreadedLineWidth = (originLineWidth || 1) + 3;
|
||||
|
||||
footprint.setLineWidth(spreadedLineWidth);
|
||||
if (footprint.isShowing && footprint.isInStroke(ctx, this, x * window.devicePixelRatio, y * window.devicePixelRatio)) {
|
||||
closests.push(footprint);
|
||||
const fLineWidth = (footprints && footprints[0] && footprints[0].getLineWidth()) || 1;
|
||||
let lw = fLineWidth + 3;
|
||||
//for (var lw = startLw + 1; lw <= startLw + 3; lw++) {
|
||||
footprints.forEach((footprint) => {
|
||||
if (!footprint.source || !footprint.source.tooSmallFootprint) {
|
||||
// Hidden footprints are not considered
|
||||
//let originLineWidth = footprint.getLineWidth();
|
||||
|
||||
footprint.setLineWidth(lw);
|
||||
if (footprint.isShowing && footprint.isInStroke(ctx, this, x * window.devicePixelRatio, y * window.devicePixelRatio)) {
|
||||
closests.push(footprint);
|
||||
}
|
||||
footprint.setLineWidth(fLineWidth);
|
||||
}
|
||||
})
|
||||
|
||||
footprint.setLineWidth(originLineWidth);
|
||||
/* if (closests.length > 0) {
|
||||
break;
|
||||
}
|
||||
})
|
||||
|
||||
}*/
|
||||
|
||||
return closests;
|
||||
};
|
||||
@@ -2198,11 +2205,13 @@ export let View = (function () {
|
||||
var canvas = this.catalogCanvas;
|
||||
var ctx = canvas.getContext("2d");
|
||||
// this makes footprint selection easier as the catch-zone is larger
|
||||
//let pastLineWidth = ctx.lineWidth;
|
||||
|
||||
let closests = [];
|
||||
if (this.overlays) {
|
||||
for (var k = 0; k < this.overlays.length; k++) {
|
||||
overlay = this.overlays[k];
|
||||
|
||||
closests = closests.concat(this.closestFootprints(overlay.overlayItems, ctx, x, y));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,7 +279,7 @@ import { ActionButton } from "../Widgets/ActionButton.js";
|
||||
header: Layout.horizontal([selectorBtn, 'Cone search']),
|
||||
subInputs: [
|
||||
{
|
||||
label: "RA:",
|
||||
label: "ra:",
|
||||
name: "ra",
|
||||
type: "text",
|
||||
value: defaultRa,
|
||||
@@ -291,7 +291,7 @@ import { ActionButton } from "../Widgets/ActionButton.js";
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "Dec:",
|
||||
label: "dec:",
|
||||
name: "dec",
|
||||
type: "text",
|
||||
value: defaultDec,
|
||||
|
||||
@@ -528,7 +528,15 @@ export class OverlayStackBox extends Box {
|
||||
position: self.position,
|
||||
});*/
|
||||
self.aladin.addNewImageLayer(
|
||||
'P/DSS2/color'
|
||||
A.imageHiPS('P/DSS2/color', {
|
||||
errorCallback: (e) => {
|
||||
aladin.addStatusBarMessage({
|
||||
duration: 2000,
|
||||
type: 'info',
|
||||
message: 'DSS2 colored HiPS could not plot',
|
||||
})
|
||||
}
|
||||
})
|
||||
);
|
||||
},
|
||||
},
|
||||
@@ -932,7 +940,6 @@ export class OverlayStackBox extends Box {
|
||||
options.push(value)
|
||||
}
|
||||
|
||||
|
||||
let HiPSSelector = Input.select({
|
||||
value,
|
||||
options,
|
||||
|
||||
@@ -57,8 +57,8 @@ export class FullScreenActionButton extends ActionButton {
|
||||
if (aladin.statusBar) {
|
||||
aladin.statusBar.removeMessage('tooltip')
|
||||
}
|
||||
|
||||
aladin.toggleFullscreen(aladin.options.realFullscreen);
|
||||
|
||||
aladin.toggleFullscreen(aladin.options.realFullscreen);
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import shareIconUrl from '../../../../assets/icons/share.svg';
|
||||
import cameraIconUrl from '../../../../assets/icons/camera.svg';
|
||||
import linkIconUrl from '../../../../assets/icons/link.svg';
|
||||
import jupyterIconUrl from '../../../../assets/icons/jupyter.svg';
|
||||
import { Utils } from "../../Utils";
|
||||
|
||||
/******************************************************************************
|
||||
* Aladin Lite project
|
||||
*
|
||||
@@ -62,16 +62,15 @@ import { Utils } from "../../Utils";
|
||||
},
|
||||
action(o) {
|
||||
var url = aladin.getShareURL();
|
||||
Utils.copy2Clipboard(url)
|
||||
.then(() => {
|
||||
if (aladin.statusBar) {
|
||||
aladin.statusBar.appendMessage({
|
||||
message: 'View URL saved into your clipboard!',
|
||||
duration: 2000,
|
||||
type: 'info'
|
||||
})
|
||||
}
|
||||
navigator.clipboard.writeText(url);
|
||||
|
||||
if (aladin.statusBar) {
|
||||
aladin.statusBar.appendMessage({
|
||||
message: 'View URL saved into your clipboard!',
|
||||
duration: 2000,
|
||||
type: 'info'
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -48,7 +48,7 @@ export let Circle = (function() {
|
||||
|
||||
this.color = options['color'] || undefined;
|
||||
this.fillColor = options['fillColor'] || undefined;
|
||||
this.lineWidth = options["lineWidth"] || undefined;
|
||||
this.lineWidth = options["lineWidth"] || 2;
|
||||
this.selectionColor = options["selectionColor"] || '#00ff00';
|
||||
this.hoverColor = options["hoverColor"] || undefined;
|
||||
this.opacity = options['opacity'] || 1;
|
||||
@@ -297,10 +297,6 @@ export let Circle = (function() {
|
||||
ctx.strokeStyle = baseColor;
|
||||
}
|
||||
|
||||
if (!this.lineWidth) {
|
||||
this.lineWidth = (this.overlay && this.overlay.lineWidth) || 2;
|
||||
}
|
||||
|
||||
ctx.lineWidth = this.lineWidth;
|
||||
ctx.globalAlpha = this.opacity;
|
||||
ctx.beginPath();
|
||||
|
||||
@@ -51,7 +51,7 @@ export let Ellipse = (function() {
|
||||
|
||||
this.color = options['color'] || undefined;
|
||||
this.fillColor = options['fillColor'] || undefined;
|
||||
this.lineWidth = options["lineWidth"] || undefined;
|
||||
this.lineWidth = options["lineWidth"] || 2;
|
||||
this.selectionColor = options["selectionColor"] || '#00ff00';
|
||||
this.hoverColor = options["hoverColor"] || undefined;
|
||||
this.opacity = options['opacity'] || 1;
|
||||
@@ -283,10 +283,6 @@ export let Ellipse = (function() {
|
||||
ctx.strokeStyle = baseColor;
|
||||
}
|
||||
|
||||
if (!this.lineWidth) {
|
||||
this.lineWidth = (this.overlay && this.overlay.lineWidth) || 2;
|
||||
}
|
||||
|
||||
ctx.lineWidth = this.lineWidth;
|
||||
ctx.globalAlpha = this.opacity;
|
||||
ctx.beginPath();
|
||||
|
||||
Reference in New Issue
Block a user