mirror of
https://github.com/cds-astro/aladin-lite.git
synced 2026-04-28 11:53:18 -07:00
final commit
This commit is contained in:
committed by
Matthieu Baumann
parent
a10699c271
commit
634d652c54
@@ -28,7 +28,7 @@
|
||||
}
|
||||
);
|
||||
|
||||
hips = aladin.newImageSurvey("http://alasky.cds.unistra.fr/HIPS3D/MUSE-test", {
|
||||
hips = aladin.newImageSurvey("http://alasky.cds.unistra.fr/HIPS3D/GalfaHI", {
|
||||
successCallback: (hips) => {
|
||||
//hips.setFrequency({value: 6.374279333565797E-7, unit: "m"}) // GALFA
|
||||
}
|
||||
|
||||
@@ -179,6 +179,7 @@ impl HiPSProperties {
|
||||
#[wasm_bindgen]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum ImageExt {
|
||||
#[serde(alias = "fits", alias = "fits.fz")]
|
||||
Fits,
|
||||
Jpeg,
|
||||
Png,
|
||||
|
||||
@@ -675,11 +675,8 @@ impl App {
|
||||
|
||||
// TODO PNG/JPG case to handle here
|
||||
match img {
|
||||
ImageType::HTMLImageRgba8u {
|
||||
image: HTMLImage { image, .. },
|
||||
}
|
||||
| ImageType::HTMLImageRgb8u {
|
||||
image: HTMLImage { image, .. },
|
||||
ImageType::ImageRgba8u {
|
||||
image: Bitmap { image, .. },
|
||||
} => {
|
||||
let document = web_sys::window()
|
||||
.unwrap_abort()
|
||||
@@ -696,7 +693,7 @@ impl App {
|
||||
.dyn_into::<web_sys::CanvasRenderingContext2d>()?;
|
||||
// Get the data once for all for the whole image
|
||||
// This takes time so better do it once and not repeatly
|
||||
context.draw_image_with_html_image_element(
|
||||
context.draw_image_with_image_bitmap(
|
||||
image, 0.0, 0.0,
|
||||
)?;
|
||||
|
||||
@@ -710,11 +707,6 @@ impl App {
|
||||
.ceil()
|
||||
as u32;
|
||||
|
||||
debug_assert_eq!(
|
||||
num_rows * num_cols,
|
||||
tile_depth
|
||||
);
|
||||
|
||||
let tile_size = *tile_size;
|
||||
|
||||
let bytes = context
|
||||
@@ -729,11 +721,12 @@ impl App {
|
||||
|
||||
let mut decoded_bytes = vec![
|
||||
0_u8;
|
||||
(tile_size * tile_size * tile_depth)
|
||||
(tile_size * tile_size * tile_depth * 2)
|
||||
as usize
|
||||
];
|
||||
|
||||
let mut k = 0;
|
||||
let mut num_tiles_cropped = 0;
|
||||
for y in 0..num_rows {
|
||||
let sy = y * tile_size;
|
||||
|
||||
@@ -749,23 +742,31 @@ impl App {
|
||||
|
||||
decoded_bytes[k] =
|
||||
bytes[id_byte as usize];
|
||||
k += 1;
|
||||
decoded_bytes[k + 1] =
|
||||
bytes[id_byte as usize + 3];
|
||||
k += 2;
|
||||
}
|
||||
}
|
||||
|
||||
num_tiles_cropped += 1;
|
||||
|
||||
if num_tiles_cropped == tile_depth {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if num_tiles_cropped == tile_depth {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hips.push_tile_from_jpeg(
|
||||
hips.push_tile_from_png(
|
||||
cell,
|
||||
decoded_bytes.into_boxed_slice(),
|
||||
(tile_size, tile_size, tile_depth),
|
||||
tile.request.time_request,
|
||||
)?;
|
||||
}
|
||||
ImageType::ImageRgba8u {
|
||||
image: Bitmap { image, .. },
|
||||
}
|
||||
| ImageType::ImageRgb8u {
|
||||
ImageType::ImageRgb8u {
|
||||
image: Bitmap { image, .. },
|
||||
} => {
|
||||
let document = web_sys::window()
|
||||
|
||||
@@ -9,8 +9,11 @@ pub trait SpectralUnit: Into<Freq> + Clone + Copy {
|
||||
|
||||
use moclib::qty::{Frequency, MocQty};
|
||||
|
||||
pub const FREQ_MAX: Freq = Freq(5.846_006_549_323_611e48);
|
||||
pub const FREQ_MIN: Freq = Freq(5.048_709_793_414_476e-29);
|
||||
|
||||
/// Frequency in Hz unit
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
|
||||
pub struct Freq(pub f64);
|
||||
|
||||
impl Freq {
|
||||
|
||||
@@ -141,6 +141,24 @@ impl HiPS3DBuffer {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn push_tile_from_png(
|
||||
&mut self,
|
||||
cell: &HEALPixFreqCell,
|
||||
decoded_bytes: Box<[u8]>,
|
||||
size: (u32, u32, u32),
|
||||
time_request: Time,
|
||||
) -> Result<(), JsValue> {
|
||||
self.push_cell(cell, time_request)?;
|
||||
|
||||
let texture = self.textures.get_mut(cell).unwrap_abort();
|
||||
|
||||
// And copy the image in that cubic tile
|
||||
texture.set_data_from_png(decoded_bytes, size)?;
|
||||
self.available_tiles_during_frame = true;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Tell if a texture is available meaning all its sub tiles
|
||||
// must have been written for the GPU
|
||||
pub fn contains_slice(
|
||||
|
||||
@@ -6,6 +6,8 @@ use crate::healpix::moc::FreqSpaceMoc;
|
||||
use crate::math::angle::ToAngle;
|
||||
use crate::math::lonlat::LonLatT;
|
||||
use crate::math::spectra::SpectralUnit;
|
||||
use crate::math::spectra::FREQ_MAX;
|
||||
use crate::math::spectra::FREQ_MIN;
|
||||
|
||||
use crate::tile_fetcher::TileFetcherQueue;
|
||||
use al_api::hips::DataproductType;
|
||||
@@ -145,7 +147,7 @@ impl Cursor {
|
||||
let em_min = cfg.em_min.unwrap_abort();
|
||||
let em_max = cfg.em_max.unwrap_abort();
|
||||
|
||||
let freq = em_min;
|
||||
let freq = Freq((em_min.0 + em_max.0) * 0.5);
|
||||
let location = LonLatT::new(0.0.to_angle(), 0.0.to_angle());
|
||||
|
||||
let f_max_order = cfg.max_depth_freq.unwrap_or(Frequency::<u64>::MAX_DEPTH);
|
||||
@@ -276,12 +278,14 @@ impl Cursor {
|
||||
}
|
||||
|
||||
fn set_freq(&mut self, freq: Freq) {
|
||||
self.freq = freq;
|
||||
if freq < FREQ_MAX && freq > FREQ_MIN {
|
||||
self.freq = freq;
|
||||
|
||||
let s_order = self.cell.hpx.depth();
|
||||
let f_order = self.f_max_order - (self.s_max_order - s_order);
|
||||
let s_order = self.cell.hpx.depth();
|
||||
let f_order = self.f_max_order - (self.s_max_order - s_order);
|
||||
|
||||
self.cell = HEALPixFreqCell::from_lonlat(self.location, self.freq, s_order, f_order);
|
||||
self.cell = HEALPixFreqCell::from_lonlat(self.location, self.freq, s_order, f_order);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_surrounding_cells_along_spectra_axis(
|
||||
@@ -500,8 +504,6 @@ impl HiPS3D {
|
||||
None
|
||||
} else if let Some(moc) = self.moc.as_ref() {
|
||||
if moc.intersects_cell(&cell) {
|
||||
//al_core::log("not included in the moc");
|
||||
|
||||
Some(cell)
|
||||
} else {
|
||||
None
|
||||
@@ -647,8 +649,6 @@ impl HiPS3D {
|
||||
)
|
||||
.unwrap_abort();
|
||||
|
||||
//al_core::log(&format!("{:?}", freqs));
|
||||
|
||||
Reflect::set(
|
||||
&spectra_js_obj,
|
||||
&JsValue::from_str("freqs"),
|
||||
@@ -1157,6 +1157,24 @@ impl HiPS3D {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn push_tile_from_png(
|
||||
&mut self,
|
||||
cell: &HEALPixFreqCell,
|
||||
// the image slice
|
||||
data: Box<[u8]>,
|
||||
size: (u32, u32, u32),
|
||||
time_request: Time,
|
||||
) -> Result<(), JsValue> {
|
||||
self.buffer
|
||||
.push_tile_from_png(cell, data, size, time_request)
|
||||
.map(|()| {
|
||||
if self.cursor.is_contained_in_spectral_view(cell) {
|
||||
// compute the spectra in case the cell is contained into the current spectral view
|
||||
self.compute_spectra_on_cursor();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/* Accessors */
|
||||
#[inline]
|
||||
pub fn get_config(&self) -> &HiPSConfig {
|
||||
|
||||
@@ -6,6 +6,7 @@ use crate::WebGlContext;
|
||||
use al_core::image::fits::FitsImage;
|
||||
use al_core::image::raw::ImageBuffer;
|
||||
use al_core::image::Image;
|
||||
use al_core::texture::format::RGBA8U;
|
||||
use al_core::texture::format::{PixelType, R16I, R32F, R32I, R8U};
|
||||
use al_core::texture::Texture3D;
|
||||
use al_core::webgl_ctx::WebGlRenderingCtx;
|
||||
@@ -38,6 +39,10 @@ pub enum HpxFreqData {
|
||||
data: Box<[u8]>,
|
||||
size: (u32, u32, u32),
|
||||
},
|
||||
Png {
|
||||
data: Box<[u8]>,
|
||||
size: (u32, u32, u32),
|
||||
},
|
||||
}
|
||||
|
||||
pub enum Pixel {
|
||||
@@ -114,6 +119,12 @@ impl HpxFreqData {
|
||||
let p = data[pixel_bytes_off];
|
||||
Some(p as f32)
|
||||
}
|
||||
HpxFreqData::Png { data, size } => {
|
||||
let pixel_bytes_off = (x + y * size.0 + z * (size.0 * size.1)) as usize;
|
||||
|
||||
let p = data[2 * pixel_bytes_off];
|
||||
Some(p as f32)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -204,15 +215,28 @@ impl HpxFreqTex {
|
||||
let start_time = None;
|
||||
|
||||
let texture = match pixel_format {
|
||||
PixelType::RGBA8U | PixelType::RGB8U | PixelType::R8U => {
|
||||
Texture3D::create_empty::<R8U>(
|
||||
gl,
|
||||
tile_size as i32,
|
||||
tile_size as i32,
|
||||
num_slices as i32,
|
||||
TEX_PARAMS,
|
||||
)
|
||||
}
|
||||
// alpha transparency
|
||||
PixelType::RGBA8U => Texture3D::create_empty::<R16I>(
|
||||
gl,
|
||||
tile_size as i32,
|
||||
tile_size as i32,
|
||||
num_slices as i32,
|
||||
TEX_PARAMS,
|
||||
),
|
||||
PixelType::RGB8U => Texture3D::create_empty::<R8U>(
|
||||
gl,
|
||||
tile_size as i32,
|
||||
tile_size as i32,
|
||||
num_slices as i32,
|
||||
TEX_PARAMS,
|
||||
),
|
||||
PixelType::R8U => Texture3D::create_empty::<R8U>(
|
||||
gl,
|
||||
tile_size as i32,
|
||||
tile_size as i32,
|
||||
num_slices as i32,
|
||||
TEX_PARAMS,
|
||||
),
|
||||
PixelType::R32F => Texture3D::create_empty::<R32F>(
|
||||
gl,
|
||||
tile_size as i32,
|
||||
@@ -325,6 +349,7 @@ impl HpxFreqTex {
|
||||
size: (u32, u32, u32),
|
||||
) -> Result<(), JsValue> {
|
||||
let cubic_tile = ImageBuffer::<R8U>::new(decoded_bytes, size.0, size.1, size.2);
|
||||
|
||||
cubic_tile.insert_into_3d_texture(&self.texture, &Vector3::<i32>::new(0, 0, 0))?;
|
||||
|
||||
self.data = Some(HpxFreqData::Jpeg {
|
||||
@@ -337,6 +362,27 @@ impl HpxFreqTex {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_data_from_png(
|
||||
&mut self,
|
||||
// the tile image of the whole cubic tile
|
||||
decoded_bytes: Box<[u8]>,
|
||||
// size of the cube
|
||||
size: (u32, u32, u32),
|
||||
) -> Result<(), JsValue> {
|
||||
let cubic_tile = ImageBuffer::<R16I>::new(decoded_bytes, size.0, size.1, size.2);
|
||||
|
||||
cubic_tile.insert_into_3d_texture(&self.texture, &Vector3::<i32>::new(0, 0, 0))?;
|
||||
|
||||
self.data = Some(HpxFreqData::Png {
|
||||
data: cubic_tile.data,
|
||||
size,
|
||||
});
|
||||
self.num_stored_slices = self.num_slices;
|
||||
self.start_time = Some(Time::now());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Panic if cell is not contained in the texture
|
||||
// Do nothing if the texture is full
|
||||
// Return true if the tile is newly added
|
||||
|
||||
@@ -15,18 +15,19 @@ uniform float reversed;
|
||||
/////////////////////////////////////////////
|
||||
/// RED sampler
|
||||
vec4 uvw2c_r(vec3 uv) {
|
||||
float v = texture(tex, uv).r;
|
||||
vec2 va = texture(tex, uv).ra;
|
||||
|
||||
v = transfer_func(H, v, min_value, max_value);
|
||||
va.x = transfer_func(H, va.x, min_value, max_value);
|
||||
|
||||
// apply reversed
|
||||
v = mix(v, 1.0 - v, reversed);
|
||||
va.x = mix(va.x, 1.0 - va.x, reversed);
|
||||
|
||||
return apply_tonal(colormap_f(v));
|
||||
vec4 c = colormap_f(va.x);
|
||||
return apply_tonal(c);
|
||||
}
|
||||
|
||||
/// RGBA sampler
|
||||
vec4 uvw2c_rgba(vec3 uv) {
|
||||
vec4 uvw2c_rgba(vec3 uv) {
|
||||
vec4 c = texture(tex, uv).rgba;
|
||||
|
||||
c.r = transfer_func(H, c.r, min_value, max_value);
|
||||
@@ -39,6 +40,19 @@ vec4 uvw2c_rgba(vec3 uv) {
|
||||
return apply_tonal(c);
|
||||
}
|
||||
|
||||
vec4 uvw2c_ra(vec3 uv) {
|
||||
vec2 c = texture(tex, uv).rg;
|
||||
|
||||
c.r = transfer_func(H, c.r, min_value, max_value);
|
||||
|
||||
// apply reversed
|
||||
c.r = mix(c.r, 1.0 - c.r, reversed);
|
||||
|
||||
vec3 color = colormap_f(c.r).rgb;
|
||||
|
||||
return apply_tonal(vec4(color, c.g));
|
||||
}
|
||||
|
||||
vec4 uvw2cmap_rgba(vec3 uv) {
|
||||
float v = texture(tex, uv).r;
|
||||
// apply transfer f
|
||||
@@ -53,7 +67,6 @@ vec4 uvw2cmap_rgba(vec3 uv) {
|
||||
|
||||
/////////////////////////////////////////////
|
||||
/// FITS sampler
|
||||
|
||||
vec4 val2c_f32(float x) {
|
||||
float alpha = x * scale + offset;
|
||||
alpha = transfer_func(H, alpha, min_value, max_value);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#version 300 es
|
||||
precision lowp float;
|
||||
precision lowp sampler3D;
|
||||
precision lowp isampler3D;
|
||||
precision lowp usampler3D;
|
||||
|
||||
uniform sampler3D tex;
|
||||
|
||||
@@ -13,7 +15,7 @@ uniform float opacity;
|
||||
|
||||
void main() {
|
||||
vec3 uv = vec3(frag_uv.xyz);
|
||||
vec4 color = uvw2c_r(uv);
|
||||
vec4 color = uvw2c_ra(uv);
|
||||
|
||||
out_frag_color = color;
|
||||
out_frag_color.a = opacity * out_frag_color.a;
|
||||
|
||||
@@ -372,8 +372,6 @@ export let HiPS = (function () {
|
||||
|
||||
this.query = new Promise(async (resolve, reject) => {
|
||||
if (isIncompleteOptions) {
|
||||
|
||||
console.log(self.url)
|
||||
// ID typed url
|
||||
if (self.startUrl && isID) {
|
||||
// First download the properties from the start url
|
||||
@@ -581,6 +579,8 @@ export let HiPS = (function () {
|
||||
return "jpeg";
|
||||
} else if (acceptedFormats.indexOf("fits") >= 0) {
|
||||
return "fits";
|
||||
} else if (acceptedFormats.indexOf("fits.fz") >= 0) {
|
||||
return "fits";
|
||||
} else {
|
||||
throw (
|
||||
"Unsupported format(s) found in the properties: " +
|
||||
|
||||
@@ -235,7 +235,7 @@ export class SpectraDisplayer {
|
||||
divNode.appendChild(canvasLabels)
|
||||
divNode.appendChild(unitSelector.element())
|
||||
divNode.appendChild(autoCenterBtn.element())
|
||||
divNode.appendChild(extractionBtn.element())
|
||||
//divNode.appendChild(extractionBtn.element())
|
||||
|
||||
this.divNode = divNode;
|
||||
|
||||
@@ -393,11 +393,13 @@ export class SpectraDisplayer {
|
||||
df = self.data.freqs[self.data.freqs.length - 1] - self.data.freqs[self.data.freqs.length - 2];
|
||||
f = self.data.freqs[self.data.freqs.length - 1] - dx * df;
|
||||
}
|
||||
|
||||
self.hips.setFrequency({
|
||||
value: f,
|
||||
unit: 'Hz'
|
||||
})
|
||||
|
||||
|
||||
lastMouse = { x: mx, y: my };
|
||||
}
|
||||
});
|
||||
@@ -538,8 +540,6 @@ export class SpectraDisplayer {
|
||||
|
||||
this.resetScale();
|
||||
this.show()
|
||||
|
||||
//this.selector.update({value: hips.name, title: hips.name})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ import { Form } from "../Widgets/Form.js";
|
||||
import pixelHistIconUrl from '../../../../assets/icons/pixel_histogram.svg';
|
||||
import { RadioButton } from "../Widgets/Radio.js";
|
||||
import waveOnIconUrl from '../../../../assets/icons/wave-on.svg';
|
||||
|
||||
import { TogglerActionButton } from "../Button/Toggler.js";
|
||||
import { Layout } from "../Layout.js";
|
||||
|
||||
export class HiPSSettingsBox extends Box {
|
||||
@@ -44,61 +44,58 @@ import { Form } from "../Widgets/Form.js";
|
||||
constructor(aladin, options) {
|
||||
let self;
|
||||
|
||||
let radioOptions = () => {
|
||||
return {
|
||||
luminosity: {
|
||||
icon: {
|
||||
size: 'small',
|
||||
monochrome: true,
|
||||
url: luminosityIconUrl
|
||||
},
|
||||
tooltip: {content: 'Contrast', position: {direction: 'bottom'}},
|
||||
action: (e) => {
|
||||
const content = Layout.vertical({
|
||||
layout: [self.selector, self.luminositySettingsContent]
|
||||
});
|
||||
self.update({content})
|
||||
}
|
||||
let selector = new RadioButton({
|
||||
luminosity: {
|
||||
icon: {
|
||||
size: 'small',
|
||||
monochrome: true,
|
||||
url: luminosityIconUrl
|
||||
},
|
||||
opacity: {
|
||||
icon: {
|
||||
size: 'small',
|
||||
monochrome: true,
|
||||
url: opacityIconUrl
|
||||
},
|
||||
tooltip: {content: 'Opacity', position: {direction: 'bottom'}},
|
||||
action: (e) => {
|
||||
const content = Layout.vertical({layout: [self.selector, self.opacitySettingsContent]});
|
||||
self.update({content})
|
||||
}
|
||||
tooltip: {content: 'Contrast', position: {direction: 'bottom'}},
|
||||
action: (e) => {
|
||||
const content = Layout.vertical({
|
||||
layout: [Layout.horizontal([self.selector, self.spectraBtn]), self.luminositySettingsContent]
|
||||
});
|
||||
self.update({content})
|
||||
}
|
||||
},
|
||||
opacity: {
|
||||
icon: {
|
||||
size: 'small',
|
||||
monochrome: true,
|
||||
url: opacityIconUrl
|
||||
},
|
||||
colors: {
|
||||
icon: {
|
||||
size: 'small',
|
||||
url: colorIconUrl
|
||||
},
|
||||
tooltip: {content: 'Colormap', position: {direction: 'bottom'}},
|
||||
action: (e) => {
|
||||
const content = Layout.vertical({layout: [self.selector, self.colorSettingsContent]});
|
||||
self.update({content})
|
||||
}
|
||||
tooltip: {content: 'Opacity', position: {direction: 'bottom'}},
|
||||
action: (e) => {
|
||||
const content = Layout.vertical({layout: [Layout.horizontal([self.selector, self.spectraBtn]), self.opacitySettingsContent]});
|
||||
self.update({content})
|
||||
}
|
||||
},
|
||||
colors: {
|
||||
icon: {
|
||||
size: 'small',
|
||||
url: colorIconUrl
|
||||
},
|
||||
pixel: {
|
||||
icon: {
|
||||
size: 'small',
|
||||
monochrome: true,
|
||||
url: pixelHistIconUrl
|
||||
},
|
||||
tooltip: {content: 'Cutouts', position: {direction: 'bottom'}},
|
||||
action: (e) => {
|
||||
const content = Layout.vertical({layout: [self.selector, self.pixelSettingsContent]});
|
||||
self.update({content})
|
||||
}
|
||||
tooltip: {content: 'Colormap', position: {direction: 'bottom'}},
|
||||
action: (e) => {
|
||||
const content = Layout.vertical({layout: [Layout.horizontal([self.selector, self.spectraBtn]), self.colorSettingsContent]});
|
||||
self.update({content})
|
||||
}
|
||||
},
|
||||
pixel: {
|
||||
icon: {
|
||||
size: 'small',
|
||||
monochrome: true,
|
||||
url: pixelHistIconUrl
|
||||
},
|
||||
selected: 'opacity'
|
||||
}
|
||||
};
|
||||
let selector = new RadioButton(radioOptions(), aladin);
|
||||
tooltip: {content: 'Cutouts', position: {direction: 'bottom'}},
|
||||
action: (e) => {
|
||||
const content = Layout.vertical({layout: [Layout.horizontal([self.selector, self.spectraBtn]), self.pixelSettingsContent]});
|
||||
self.update({content})
|
||||
}
|
||||
},
|
||||
selected: 'opacity'
|
||||
}, aladin);
|
||||
|
||||
// Define the contents
|
||||
|
||||
@@ -288,8 +285,6 @@ import { Form } from "../Widgets/Form.js";
|
||||
aladin.aladinDiv)
|
||||
self = this;
|
||||
|
||||
this.radioOptions = radioOptions;
|
||||
|
||||
this.aladin = aladin;
|
||||
this._addListeners()
|
||||
|
||||
@@ -337,30 +332,27 @@ import { Form } from "../Widgets/Form.js";
|
||||
if (options.layer) {
|
||||
let self = this;
|
||||
if (options.layer.isSpectralCube()) {
|
||||
self.selector = new RadioButton({
|
||||
...this.radioOptions(),
|
||||
spectra: {
|
||||
icon: {
|
||||
size: 'small',
|
||||
monochrome: true,
|
||||
url: waveOnIconUrl
|
||||
},
|
||||
tooltip: {content: 'Spectra', position: {direction: 'bottom'}},
|
||||
action: (e) => {
|
||||
let spectraDisplayer = self.aladin.view.spectraDisplayer;
|
||||
if (spectraDisplayer.isHidden) {
|
||||
spectraDisplayer.attachHiPS3D(options.layer)
|
||||
spectraDisplayer.show()
|
||||
} else {
|
||||
spectraDisplayer.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
}, self.aladin);
|
||||
let spectraDisplayer = self.aladin.view.spectraDisplayer;
|
||||
|
||||
console.log(self)
|
||||
self.spectraBtn = new TogglerActionButton({
|
||||
content: 'Spectra',
|
||||
icon: {
|
||||
size: 'small',
|
||||
monochrome: true,
|
||||
url: waveOnIconUrl
|
||||
},
|
||||
tooltip: {content: 'Show/hide spectra', position: {direction: 'bottom'}},
|
||||
toggled: true,
|
||||
actionOn: () => {
|
||||
spectraDisplayer.attachHiPS3D(options.layer)
|
||||
spectraDisplayer.show()
|
||||
},
|
||||
actionOff: () => {
|
||||
spectraDisplayer.hide()
|
||||
}
|
||||
});
|
||||
|
||||
self.update({content: Layout.vertical([self.selector, self.opacitySettingsContent])})
|
||||
self.update({content: Layout.vertical([Layout.horizontal([self.selector, self.spectraBtn]), self.opacitySettingsContent])})
|
||||
}
|
||||
|
||||
this._update(options.layer)
|
||||
|
||||
Reference in New Issue
Block a user