Compare commits

..

5 Commits

Author SHA1 Message Date
Thomas Boch
64fcc777de Update release notes 2020-08-24 11:58:58 +02:00
Thomas Boch
0f74b5e94f Merge pull request #22 from imbasimba/polyline
Polyline improvements
2020-08-24 11:55:41 +02:00
Thomas Boch
5799482dde Merge branch 'master' into polyline 2020-08-24 11:53:56 +02:00
Henrik Norman
416c20cecc Fixed Polyline flickering & added possibility to set line width and color 2019-12-06 13:54:02 +01:00
Henrik Norman
09ef8418bb Fixed error when mouse x position is 0 2019-12-05 09:51:58 +01:00
343 changed files with 5074 additions and 40386 deletions

1
.gitignore vendored
View File

@@ -1 +0,0 @@
node_modules

View File

@@ -1,5 +1,4 @@
# Aladin Lite v3
# Aladin Lite
**An astronomical HiPS visualizer in the browser** <img src="aladin-logo.png" alt="Aladin Lite logo" width="220">
Aladin Lite is a Web application which enables HiPS visualization from the browser. It is developed at [CDS, Strasbourg astronomical data center](http://cds.unistra.fr/).
@@ -10,48 +9,9 @@ Aladin Lite is built to be easily embeddable in any web page. It powers astronom
More details on [Aladin Lite documentation page](http://aladin.u-strasbg.fr/AladinLite/doc/).
This repo contains the Aladin Lite v3 source code and specifically the code of its new WebGL core written in Rust.
## How to test it ?
You can test it [here](https://bmatthieu3.github.io/hips_webgl_renderer/test_moc_moll.html)!
For Safari users only: make sure to enable WebGL2 experimental feature and refresh the page once it is done. You can find it in the Developer Menu > Experimental Features > WebGL2.
Safari will soon [enable WebGL2 by default](https://developer.apple.com/safari/technology-preview/release-notes/).
Do not hesitate to give a feedback either by sending a mail to:
- matthieu.baumann@astro.unistra.fr / baumannmatthieu0@gmail.com
- thomas.boch@astro.unistra.fr
or simply by posting an issue in this repo.
## Goals of v3
- Rust/WebGL new core integration
- Remove jQuery dep
- UI dev, using VueJS, better support for smartphones
- package the core and its API as a WASM npm package
- FITS images support
- easy sharing of current « view »
- support of all VOTable serializations (using votable.js?)
- support of FITS tables?
- creating HiPS instance from an URL
- multiple mirrors handling for HiPS tile retrival
## Source code
Source code is available in the ``src`` directory.
Precisely, the core is implemented in Rust and can be found in ``src/core``.
## Licence
@@ -59,6 +19,15 @@ Aladin Lite is currently licensed under GPL v3.0
If you think this license might prevent you from using Aladin Lite in your pages/application/portal, please open an issue or [contact us](mailto:cds-question@unistra.fr)
## Building the application
1. Clone the repository
2. Go to the ``scripts``directory
3. Open the `build.sh` file and adapt paths to ``uglifyjs`` and ``lessc``
4. Launch ``./build.sh``
5. Go to directory ``../distrib/latest/`` , type ``python3 -m http.server 42195`` and open your browser at [http://0.0.0.0:42195/](http://0.0.0.0:42195/) to launch the built application
## Contributing
There are several ways to contribute to Aladin Lite:
@@ -69,48 +38,3 @@ There are several ways to contribute to Aladin Lite:
- **develop new features/provide code fixing bugs**. As open development is a new thing for us, we will in a first time only take into consideration code contribution (_i.e._ Pull Requests) from our close partners.
In any case, please get in touch before starting a major update or rewrite.
### Building the application steps
First you need to install the dependencies from the package.json
Please run:
```bash
npm install
```
After that you are supposed to have the Rust toolchain installed
to compile the core project into WebAssembly.
Follow the steps from the Rust official website [here](https://www.rust-lang.org/learn/get-started)
Once it's installed you can only build the project:
```bash
npm run build
```
Or build it and launch a localhost server (usually starting on port 8080 but it can be another one if 8080 is occupied):
```bash
npm run serve
```
For just compiling the rust core from the root location (it is faster to do so)
```bash
cd src/core
cargo check --features webgl2
```
and run the tests
```bash
cd src/core
cargo test
```
To generate the Rust backend API documentation
```bash
cd src/core
cargo doc --no-deps --open
```

View File

@@ -1,9 +0,0 @@
USER_ALADIN="matthieu.baumann"
ssh $USER_ALADIN@aladin 'sg hips -c "mkdir -p $HOME/al-tmp && rm -rf $HOME/al-tmp/*"'
scp dist/* $USER_ALADIN@aladin:~/al-tmp
ssh $USER_ALADIN@aladin 'sg hips -c "rm -rf /home/thomas.boch/AladinLite/www/api/v3/2022-10-17 &&
mkdir -p /home/thomas.boch/AladinLite/www/api/v3/2022-10-17 &&
cp $HOME/al-tmp/* /home/thomas.boch/AladinLite/www/api/v3/2022-10-17/ &&
rm /home/thomas.boch/AladinLite/www/api/v3/latest &&
ln -s /home/thomas.boch/AladinLite/www/api/v3/2022-10-17/ /home/thomas.boch/AladinLite/www/api/v3/latest"'

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,38 +0,0 @@
<!doctype html>
<html>
<head>
<!-- <link rel="stylesheet" href="../distrib/latest/aladin.min.css" /> -->
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', { fov:0.15, target: 'Arp 240', showReticle: false, fullScreen: true });
aladin.setBaseImageLayer(aladin.createImageSurvey('SDSS-DR9 r', 'SDSS-DR9 r', 'https://alasky.u-strasbg.fr/SDSS/DR9/band-r', 'equatorial', 10));
aladin.getBaseImageLayer().setColormap('rainbow', {stretch: 'Linear'});
var simbad = A.catalog({name: 'Simbad', sourceSize: 16, color: '#4050F0'});
aladin.addCatalog(simbad);
simbad.addSources([A.marker(204.97010833333336, 0.8400166666666667, {popupTitle: 'NGC 5257', popupDesc: '<em>Object type:</em> HII galaxy<br/><em>Morphological type:</em> Sbc<br/><br/>More info <a href="https://simbad.u-strasbg.fr/simbad/sim-id?Ident=NGC+5257">in Simbad</a>'}), A.marker(204.9903125, 0.8309694444444445, {popupTitle: 'NGC 5258', popupDesc: '<em>Object type:</em> Galaxy in Pair of Galaxies <br/><em>Morphological type:</em> Sb<br/><br/>More info <a href="https://simbad.u-strasbg.fr/simbad/sim-id?Ident=NGC+5258">in Simbad</a>'})]);
var overlay = A.graphicOverlay({color: '#aa2222', lineWidth: 4});
aladin.addOverlay(overlay);
overlay.addFootprints(A.polygon([[204.970214, 0.81206], [204.97110047, 0.80993368], [204.978723, 0.79165], [204.999152, 0.800162], [204.99482125, 0.81055582], [205.002941, 0.813851], [204.99986816, 0.82141125], [205.010312, 0.825578], [205.002112, 0.846123], [204.981546, 0.837916], [204.98157771, 0.83783654], [204.962977, 0.830202], [204.9703941, 0.81213504]]));
aladin.displayJPG('http://images.ipac.caltech.edu/esahubble/heic0810at/esahubble_heic0810at_1600.jpg');
});
</script>
</body>
</html>

View File

@@ -1,25 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
<!--<link rel="stylesheet" href="./layers.css" />-->
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {target: 'M51', fov: 360, fullScreen: true, showAllskyRing: true, allskyRingColor: '#eee', allskyRingWidth: 2.0});
});
</script>
</body>
</html>

View File

@@ -1,31 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
<!--<link rel="stylesheet" href="./layers.css" />-->
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {survey: "P/SPITZER/color", cooFrame: 'galactic', fov: 5});
aladin.gotoRaDec(266.41683, -29.00781);
// Parameters are:
// <right ascension of final position>,
// <declination of final position>,
// <animation duration in seconds>
aladin.animateToRaDec(305.5, 38.5, 70);
});
</script>
</body>
</html>

View File

@@ -1,77 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
<!--<link rel="stylesheet" href="./layers.css" />-->
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
// Start up Aladin Lite
aladin = A.aladin('#aladin-lite-div', {target: '12 25 41.512 +12 48 47.2', fov: 0.8});
// define custom draw function
var drawFunction = function(source, canvasCtx, viewParams) {
canvasCtx.beginPath();
canvasCtx.arc(source.x, source.y, source.data['size'] * 2, 0, 2 * Math.PI, false);
canvasCtx.closePath();
canvasCtx.strokeStyle = '#c38';
canvasCtx.lineWidth = 3;
canvasCtx.globalAlpha = 0.7,
canvasCtx.stroke();
var fov = Math.max(viewParams['fov'][0], viewParams['fov'][1]);
// object name is displayed only if fov<10°
if (fov>10) {
return;
}
canvasCtx.globalAlpha = 0.9;
canvasCtx.globalAlpha = 1;
var xShift = 20;
canvasCtx.font = '15px Arial'
canvasCtx.fillStyle = '#eee';
canvasCtx.fillText(source.data['name'], source.x + xShift, source.y -4);
// object type is displayed only if fov<2°
if (fov>2) {
return;
}
canvasCtx.font = '12px Arial'
canvasCtx.fillStyle = '#abc';
canvasCtx.fillText(source.data['otype'], source.x + 2 + xShift, source.y + 10);
};
// create sources objects
var M87 = A.source(187.7059308, 12.3911233, {name: 'M 87', size: 4.5, otype: 'LINER AGN'});
var M49 = A.source(187.444992, 8.000411, {name: 'M 49', size: 6.28, otype: 'Seyfert 2'});
var M100 = A.source(185.728746, 15.822381, {name: 'M 100', size: 7.23, otype: 'AGN'});
var M84 = A.source(186.26559721, 12.88698314, {name: 'M 84', size: 3.91, otype: 'Seyfert 2'});
var M60 = A.source(190.916700, 11.552611, {name: 'M 60', size: 4.75, otype: 'Galaxy in pair of galaxies'});
var NGC4388 = A.source(186.445083, 12.662069 , {name: 'NGC 4388', size: 3.72, otype: 'Seyfert 2'});
var NGC4261 = A.source(184.84673421, 5.82491522 , {name: 'NGC 4261', size: 2.78, otype: 'LINER AGN'});
var M86 = A.source(186.549225, 12.945969, {name: 'M 86', size: 6.03, otype: 'Galaxy in group of galaxies'});
// create catalog layer with custom draw function
var cat = A.catalog({name: 'Virgo cluster', shape: drawFunction});
// add sources to the new layer
cat.addSources([M87, M49, M100, M84, M60, NGC4388, NGC4261, M86]);
aladin.addCatalog(cat);
});
</script>
</body>
</html>

View File

@@ -1,37 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
<!--<link rel="stylesheet" href="./layers.css" />-->
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {survey: 'P/DSS2/red', target: 'M50', fov: 0.3});
var customImg = new Image();
customImg.onload = function() {
var cat = A.catalog({shape: customImg});
aladin.addCatalog(cat);
cat.addSources(A.source(105.69239256, -8.45235969));
cat.addSources(A.source(105.70779763, -8.31350997));
cat.addSources(A.source(105.74242906, -8.34776709));
};
customImg.src = 'https://aladin.u-strasbg.fr/AladinLite/doc/API/examples/img/star.png';
});
</script>
</body>
</html>

View File

@@ -1,57 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
<!--<link rel="stylesheet" href="./layers.css" />-->
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
Show sources with proper motion greater than:
<input id='slider' style='vertical-align:middle;width:60vw;' step='1' min='0' max='500' type='range' value='0'>
<span id='pmVal' >0 mas/yr</span><br><br><div id='aladin-lite-div' style='width: 500px;height: 500px;'></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
var pmThreshold = 0;
var slider = document.getElementById('slider');
slider.oninput = function() {
pmThreshold = this.value;
$('#pmVal').html(pmThreshold + ' mas/yr');
hips.reportChange();
}
var myFilterFunction = function(source) {
var pmra = parseFloat(source.data['pmra']);
var pmdec = parseFloat(source.data['pmdec']);
if (isNaN(pmra) || isNaN(pmdec)) {
return false;
}
var totalPm = Math.sqrt(pmra*pmra+pmdec*pmdec);
return totalPm>pmThreshold;
}
aladin = A.aladin('#aladin-lite-div', {target: 'gal center',fov: 150});
var hips = A.catalogHiPS('http://axel.u-strasbg.fr/HiPSCatService/I/345/gaia2', {onClick: 'showTable', color: 'orange', name: 'Gaia', filter: myFilterFunction});
aladin.addCatalog(hips);
$('input[type=radio][name=otype]').change(function() {
requestedOtype = this.value;
hips.reportChange();
});
});
</script>
</body>
</html>

View File

@@ -1,29 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
<!--<link rel="stylesheet" href="./layers.css" />-->
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {target: 'LMC', fov: 55});
var hips = A.catalogHiPS('https://axel.u-strasbg.fr/HiPSCatService/Simbad', {onClick: 'showTable', name: 'Simbad'});
aladin.addCatalog(hips);
});
</script>
</body>
</html>

View File

@@ -1,26 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
// Start up Aladin Lite
aladin = A.aladin('#aladin-lite-div', {target: 'M81', fov: 360, showCooGrid: true});
aladin.setImageSurvey(aladin.createImageSurvey('Panstarrs', 'Panstarrs', 'http://hips.china-vo.org/change2-moon-7m-dom', 'equatorial', 9, {imgFormat: 'fits', colormap: "redtemperature"}));
});
</script>
</body>
</html>

View File

@@ -1,533 +0,0 @@
<!doctype html>
<html>
<head>
<meta name="apple-mobile-web-app-capable" content="yes">
<!--<link rel="manifest" href="manifest.json">-->
<link rel="apple-touch-icon" href="apple-touch-icon.png">
<script type="text/javascript" defer="" async="" src="https://cdsannotations.u-strasbg.fr/piwik/piwik.js"></script><script type="text/javascript" src="js/libs/jquery-3.5.1.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/purecss@2.0.3/build/pure-min.css" integrity="sha384-cg6SkqEOCV1NbJoCu11+bm0NvBRc8IYLRGXkmNrqUBfTjmMYwNKPWBTIKyw9mHNJ" crossorigin="anonymous">
<!--link rel="stylesheet" href="css/pure-min.css"-->
<link rel="stylesheet" href="https://unpkg.com/purecss@1.0.1/build/base-min.css">
<!--link rel="stylesheet" href="css/base-min.css"-->
<link rel="stylesheet" href="https://unpkg.com/purecss@2.0.3/build/grids-min.css">
<link rel="stylesheet" href="https://unpkg.com/purecss@2.0.3/build/grids-responsive-min.css">
<!--link rel="stylesheet" href="css/grids-responsive-min.css"-->
<link rel="stylesheet" href="https://unpkg.com/purecss@2.0.3/build/buttons.css">
<link rel="stylesheet" href="https://unpkg.com/purecss@2.0.3/build/buttons-core.css">
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css">
<!--meta name="viewport" content="initial-scale=1.0, user-scalable=no"-->
<meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width:100vw;height:100vh;">
<div id="calibCircle" style="display: none;"></div>
<div id="explain" class="aladin-box"></div>
<div id="overlayDiv" style="position: absolute; width: 100%; height: 100%; z-index:4; display: none;"><canvas id="drawOverlay"></canvas></div>
<div id="layersControlLeft" class="aladin-box" style="display: block;">
<!-- temporaire gestion cercle -->
<label for="circle-checkbox">Cercle</label> <input id="circle-checkbox" type="checkbox" unchecked=""><br><br>
<!-- fin temporaire gestion cercle -->
<b>Orientation</b><br>
<button id="hips-coronelli" class="pure-button" name="ref-hips" onclick="aladin.setImageSurvey('Coronelli')">Normal</button><br>
<button id="hips-illenoroc" class="pure-button" name="ref-hips" onclick="aladin.setImageSurvey('illenoroC')">Inversé</button>
<br><br>
<b>Constellations</b>
<br>
<a id="constellations-boundaries" class="pure-button catlayer" href="#">Frontières</a><br>
<a id="const-outlines" class="pure-button img-hips" href="#">Tracé</a><br>
<a id="const-jaxa" class="pure-button img-hips" href="#">JAXA</a>
<br>
<b>Ciel</b>
<br>
<a id="P/Mellinger/color" class="pure-button img-hips" href="#">Mellinger</a><br>
<a id="dss2" class="pure-button img-hips" href="#">DSS</a><br>
<a id="decaps" class="pure-button img-hips" href="#">DECaPS</a><br>
<a id="panstarrs" class="pure-button img-hips" href="#">PanSTARRS</a><br>
<a id="gaiamap" class="pure-button img-hips" href="#">Gaia</a>
<br><br><label for="overlay-checkbox">Dessin</label> <input id="overlay-checkbox" type="checkbox" unchecked="">
</div>
<div id="layersCL2" class="aladin-box" style="display: block;">
Opacité<br>
<input id="opacity-slider" type="range" min="0" max="1" step="0.01" value="0.0"><br>
</div>
<div id="layersControlRight" class="aladin-box" style="display: block;">
<b>Data</b><br>
<a id="simbad" class="pure-button catlayer" href="#">SIMBAD</a><br>
<a id="gaia" class="pure-button catlayer" href="#">Gaia DR2</a>
<br><br>
<div>Coronelli<br>
<!--a id="coronelli-stars" class="pure-button catcoro" href="#">Coronelli</a-->
<a href="#"><img id="coronelli-stars-white" class="catcoro coro-star" src="star_white.png"></a>
<a href="#"><img id="coronelli-stars-yellow" class="catcoro coro-star" src="star_yellow.png"></a><br>
<a href="#"><img id="coronelli-stars-red" class="catcoro coro-star" src="star_red.png"></a>
<a href="#"><img id="coronelli-stars-blue" class="catcoro coro-star" src="star_blue.png"></a>
</div>
<br><br>
<b>Navigation</b>&nbsp;&nbsp;<br><button id="stop">Stop</button>
<br>
<div id="coo_epoca">
<a class="pure-button nav-button nav-goto" href="#">De Epoca</a><br>
&nbsp;&nbsp;<a class="pure-button nav-button nav-flyto" href="#">Move</a>
</div>
<div id="coo_legende">
<a class="pure-button nav-button nav-goto" href="#">Légende</a><br>
&nbsp;&nbsp;<a class="pure-button nav-button nav-flyto" href="#">Move</a>
</div>
<div id="coo_orion">
<a class="pure-button nav-button nav-goto" href="#">Orion</a><br>
&nbsp;&nbsp;<a class="pure-button nav-button nav-flyto" href="#">Move</a>
</div>
<div id="coo_magellan">
<a class="pure-button nav-button nav-goto" href="#">Magellan</a><br>
&nbsp;&nbsp;<a class="pure-button nav-button nav-flyto" href="#">Move</a>
</div>
<div id="coo_halley">
<a class="pure-button nav-button nav-goto" href="#">Halley</a><br>
&nbsp;&nbsp;<a class="pure-button nav-button nav-flyto" href="#">Move</a>
</div>
</div>
<style type="text/css"> .aladin-reticleColor { color: rgb(178, 50, 178); font-weight:bold;} </style>
<style type="text/css">
html, body {
height: 100%;
}
body {
display: flex;
flex-direction: column;
}
.aladin-zoomControl {
top: 10% !important;
left: unset !important;
right: 4px !important;
}
.aladin-zoomControl a {
font-size: 24px !important;
padding: 22px !important;
}
#aladin{
flex: 1 1 0;
}
#explain {
padding: 4px;
top: 30%;
max-height: 50%;
font-size: 11pt;
overflow: scroll;
}
#explain tbody tr:nth-child(even) {
background-color: #ffffff;
}
#explain tbody tr:nth-child(odd) {
background-color: #ccdaeb;
}
#layersControlLeft {
padding: 10px;
right: unset;
left: 4px;
top: 20vh;
}
#layersCL2 {
padding: 10px;
right: unset;
left: 4px;
top: 90vh;
}
#layersControlRight {
padding: 4px;
left: unset;
right: 4px;
top: 25vh;
}
#layersControlLeft, #layersControlRight, #layersCL2 input {
margin-right: 5px;
}
.img-hips {
padding: 5px;
margin: 5px;
}
#opacity-slider {
-webkit-appearance: none !important; /* Override default CSS styles */
width: 220px;
height: 25px;
}
#opacity-slider::-webkit-slider-thumb {
-webkit-appearance: none !important; /* Override default look */
appearance: none;
width: 25px; /* Set a specific slider handle width */
height: 25px; /* Slider handle height */
background: #4CAF50; /* Green background */
cursor: pointer; /* Cursor on hover */
}
#opacity-slider::-moz-range-thumb {
width: 25px; /* Set a specific slider handle width */
height: 25px; /* Slider handle height */
background: #4CAF50; /* Green background */
cursor: pointer; /* Cursor on hover */
}
.aladin-box {
font-size: 12px !important;
}
#calibCircle {
position: fixed;
border: 8px solid red;
border-radius: min(50vw, 50vh);
height: min(100vw, 100vh);
width: min(100vw, 100vh);
top: -8px;
left: calc(max(50vw, 50vh) - min(50vw, 50vh) - 8px);
z-index: 1000;
pointer-events: none;
}
.pure-table {
font-size: small;
}
.catcoro {
display: inline;
vertical-align: middle;
}
.coro-star {
vertical-align: middle;
}
</style>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
var hipsDir="http://alasky.u-strasbg.fr/CDS_P_Coronelli";
aladin = A.aladin("#aladin-lite-div", {showSimbadPointerControl: true, realFullscreen: true, fov: 100, allowFullZoomout: true, showReticle: false });
aladin.createImageSurvey('illenoroC', 'illenoroC', hipsDir, 'equatorial', 4, {imgFormat: 'jpg', longitudeReversed: false, minOrder: 3});
aladin.createImageSurvey('Coronelli', 'Coronelli', hipsDir, 'equatorial', 4, {imgFormat: 'jpg', longitudeReversed: true, minOrder: 3});
aladin.setImageSurvey('Coronelli');
$('#layersControlLeft').show();
$('#layersCL2').show();
$('#layersControlRight').show();
var hipsCats = {
'constellations-boundaries': A.catalogFromVizieR('VI/49/bound_20', '0 +0', 180, {color: 'red'}),
'simbad': A.catalogHiPS('http://axel.u-strasbg.fr/HiPSCatService/Simbad', {name: 'Simbad', color: '#6dbdce'}),
'gaia': A.catalogHiPS('http://axel.u-strasbg.fr/HiPSCatService/I/345/gaia2', {name: 'Gaia DR2', color: '#6666cc', shape: 'circle', sourceSize: 6})
};
hipsCats['simbad'].hide();
hipsCats['constellations-boundaries'].hide();
hipsCats['gaia'].hide();
aladin.addCatalog(hipsCats['simbad']);
aladin.addCatalog(hipsCats['constellations-boundaries']);
aladin.addCatalog(hipsCats['gaia']);
var coronelliStars = {
'coronelli-stars-white': A.catalogFromURL("http://cdsweb.u-strasbg.fr/~derriere/coronelli/white.xml", {name: 'Coronelli white', color: '#ffffff', shape: 'rhomb', sourceSize: 10}),
'coronelli-stars-yellow': A.catalogFromURL("http://cdsweb.u-strasbg.fr/~derriere/coronelli/yellow.xml", {name: 'Coronelli yellow', color: '#f6f874', shape: 'rhomb', sourceSize: 10}),
'coronelli-stars-red': A.catalogFromURL("http://cdsweb.u-strasbg.fr/~derriere/coronelli/red.xml", {name: 'Coronelli red', color: '#ff5555', shape: 'rhomb', sourceSize: 10}),
'coronelli-stars-blue': A.catalogFromURL("http://cdsweb.u-strasbg.fr/~derriere/coronelli/blue.xml", {name: 'Coronelli blue', color: '#1ca5ec', shape: 'rhomb', sourceSize: 10})
};
coronelliStars['coronelli-stars-white'].hide();
coronelliStars['coronelli-stars-yellow'].hide();
coronelliStars['coronelli-stars-red'].hide();
coronelliStars['coronelli-stars-blue'].hide();
aladin.addCatalog(coronelliStars['coronelli-stars-white']);
aladin.addCatalog(coronelliStars['coronelli-stars-yellow']);
aladin.addCatalog(coronelliStars['coronelli-stars-red']);
aladin.addCatalog(coronelliStars['coronelli-stars-blue']);
// ajout de nouveaux relevés custom ?
// Mellinger : P/Mellinger/color
// PanSTARRS couleur : CDS/P/PanSTARRS/DR1/color-i-r-g
// gaia flux : CDS/P/DM/flux-color-Rp-G-Bp/I/345/gaia2
aladin.createImageSurvey("dss2", "DSS color", "http://alasky.u-strasbg.fr/DSS/DSSColor/", "equatorial", 9, {imgFormat: 'jpg'});
aladin.createImageSurvey("decaps", "DECaPS DR1", "http://alasky.u-strasbg.fr/DECaPS/DR1/color/", "equatorial", 11, {imgFormat: 'png'});
aladin.createImageSurvey("gaiamap", "Gaia Flux", "http://alasky.u-strasbg.fr/ancillary/GaiaDR2/color-Rp-G-Bp-flux-map/", "equatorial", 4, {imgFormat: 'jpg'});
aladin.createImageSurvey("panstarrs", "PanSTARRS", "http://alasky.u-strasbg.fr/Pan-STARRS/DR1/color-i-r-g/", "equatorial", 11, {imgFormat: 'jpg'});
aladin.createImageSurvey('const-outlines', 'Constellation outlines', 'http://alaskybis.u-strasbg.fr/JAXA/JAXA_P_CONSTELLATIONS5/', 'equatorial', 6, {imgFormat: 'png'});
aladin.createImageSurvey('const-jaxa', 'Constellation by JAXA', 'http://alaskybis.u-strasbg.fr/JAXA/JAXA_P_CONSTELLATIONS6/', 'equatorial', 6, {imgFormat: 'png'});
var curSelectedSource = null;
aladin.setOverlayImageLayer('P/Mellinger/color');
aladin.getOverlayImageLayer().setAlpha(0.0);
// listen changes on HiPS image background selection
$('.img-hips').click(function() {
if (!$(this).hasClass("selected")) {
$('.img-hips').removeClass("selected pure-button-active");
$(this).addClass("selected pure-button-active");
aladin.setOverlayImageLayer(this.id);
aladin.getOverlayImageLayer().setAlpha(0.75);
$('#opacity-slider').val(0.75);
}
else {
$(this).removeClass("selected pure-button-active");
// possibilité ? aladin.setOverlayImageLayer(null);
aladin.getOverlayImageLayer().setAlpha(0);
$('#opacity-slider').val(0);
}
});
$('#opacity-slider').on('input', function() {
aladin.getOverlayImageLayer().setAlpha($(this).val());
});
// listen changes on HiPS catalogues selection
$('.catlayer').click(function() {
var cat = hipsCats[$(this).attr('id')];
if (!$(this).hasClass("selected")) {
$(this).addClass("selected pure-button-active");
cat.show();
}
else {
$(this).removeClass("selected pure-button-active");
cat.hide();
}
});
// listen changes on Coronelli catalogues selection
$('.catcoro').click(function() {
var cat = coronelliStars[$(this).attr('id')];
if (!$(this).hasClass("selected")) {
$(this).addClass("selected");
cat.show();
}
else {
$(this).removeClass("selected");
cat.hide();
}
});
var cooNav = {
'coo_epoca': {ra: 4.0, dec: -30.0, time: 10},
'coo_legende': {ra: 33.0, dec: -32.0, time: 10},
'coo_orion': {ra: 85.2, dec: -2.5, time: 10},
'coo_magellan': {ra: 45.0, dec: -79.0, time: 10},
'coo_halley': {ra: 219.6, dec: 7.0, time: 10}
};
// listen click on navigation buttons
$('.nav-button').click(function() {
var cooTarget = $(this).parent().attr('id');
if ($(this).hasClass("nav-goto")) {
aladin.gotoRaDec(cooNav[cooTarget].ra, cooNav[cooTarget].dec);
}
else if ($(this).hasClass("nav-flyto")) {
aladin.animateToRaDec(cooNav[cooTarget].ra, cooNav[cooTarget].dec, cooNav[cooTarget].time);
}
});
// stop animations
$('#stop').click(function() {
aladin.stopAnimation();
});
// listen to click on objects
aladin.on('objectClicked', function(source) {
var html = '<table class="pure-table">';
if (curSelectedSource != null) {
curSelectedSource.deselect();
}
if (source==null) {
$('#explain').html('');
$('#explain').hide();
return;
}
source.select();
curSelectedSource = source;
html += '<tbody>';
if (source.catalog.name == 'Simbad') {
console.log(source.data);
html += '<h3>Simbad object <em>' + source.data.main_id + '</em></h3>';
html += '<tr class="pure-table-odd"><td><b>ra</b></td><td>' + source.data.ra + '</td><td><em>deg</em></td></tr>';
html += '<tr><td><b>dec</b></td><td>' + source.data.dec + '</td><td><em>deg</em></td></tr>';
html += '<tr><td><b>main_type</b></td><td>' + source.data.main_type + '</td><td><em>deg</em></td></tr>';
html += '<tr class="pure-table-odd"><td><b>pmra</b></td><td>' + source.data.pmra + '</td><td><em>mas/yr</em></td></tr>';
html += '<tr><td><b>pmdec</b></td><td>' + source.data.pmdec + '</td><td><em>mas/yr</em></td></tr>';
html += '<tr class="pure-table-odd"><td><b>parallax</b></td><td>' + source.data.plx + '</td><td><em>mas</em></td></tr>';
html += '<tr><td><b>B mag.</b></td><td>' + source.data.B + '</td><td><em>mag</em></td></tr>';
html += '<tr class="pure-table-odd"><td><b>V mag.</b></td><td>' + source.data.V + '</td><td><em>mag</em></td></tr>';
html += '</tbody>';
html += '</table>';
html += '<br/><a target="_blank" href="http://simbad.u-strasbg.fr/simbad/sim-id?Ident=' + encodeURIComponent(source.data.main_id) + '">More details</a>';
}
$('#explain').html(html);
$('#explain').show();
});
aladin.on('fullScreenToggled', function(fullScreenFlag) {
setTimeout(initOverlayCanvas, 500);
if (fullScreenFlag) {
$('#calibCircle').show();
//temporaire gestion cercle
document.getElementById("circle-checkbox").checked = true;
}
else {
$('#calibCircle').hide();
//temporaire gestion cercle
document.getElementById("circle-checkbox").checked = false;
}
});
//temporaire gestion cercle
document.getElementById("circle-checkbox").addEventListener('change', (event) => {
if (event.target.checked) {
$('#calibCircle').show();
} else {
$('#calibCircle').hide();
}
})
// enable/disable overlay layer
document.getElementById("overlay-checkbox").addEventListener('change', (event) => {
if (!drawOverlayCanvas) {
return;
}
if (event.target.checked) {
$('#overlayDiv').show();
initOverlayCanvas();
} else {
$('#overlayDiv').hide();
}
})
/*
document.addEventListener('touchmove', function (event) {
if (event.scale !== 1) { event.preventDefault(); }
}, false);
var lastTouchEnd = 0;
document.addEventListener('touchend', function (event) {
var now = (new Date()).getTime();
if (now - lastTouchEnd <= 300) {
event.preventDefault();
}
lastTouchEnd = now;
}, false);
*/
/*
document.addEventListener("touchstart", event => {
if(event.touches.length > 1) {
console.log("zoom plz stahp");
event.preventDefault();
//event.stopPropagation(); // maybe useless
}
}, {passive: false});
*/
// initialize drawOverlay
var drawOverlayCanvas = document.getElementById('drawOverlay');
var timeBeforeDeletion = 7 * 1000; // in ms
var drawOverlayCtx;
var deleteOverlayTimeout;
var points = [];
function initOverlayCanvas() {
drawOverlayCanvas.style.width='100%';
drawOverlayCanvas.style.height='100%';
drawOverlayCanvas.width = drawOverlayCanvas.offsetWidth;
drawOverlayCanvas.height = drawOverlayCanvas.offsetHeight;
drawOverlayCtx = drawOverlayCanvas.getContext('2d');
drawOverlayCtx.lineWidth = 10;
drawOverlayCtx.lineJoin = drawOverlayCtx.lineCap = 'round';
drawOverlayCtx.strokeStyle = 'rgba(240, 0, 0, 0.7)';
points = [];
}
function deleteOverlayCanvas() {
drawOverlayCtx.clearRect(0, 0, drawOverlayCtx.canvas.width, drawOverlayCtx.canvas.height);
points = [];
}
if (drawOverlayCanvas) {
var isDrawing = false;
$(drawOverlayCanvas).on('mousedown touchstart', function(e) {
if (deleteOverlayTimeout) {
clearTimeout(deleteOverlayTimeout);
deleteOverlayTimeout = undefined;
}
isDrawing = true;
points.push([drawOverlayCanvas.relMouseCoords(e)]);
});
$(drawOverlayCanvas).on('mousemove touchmove', function(e) {
if (!isDrawing) return;
e.preventDefault();
drawOverlayCtx.clearRect(0, 0, drawOverlayCtx.canvas.width, drawOverlayCtx.canvas.height);
points[points.length-1].push(drawOverlayCanvas.relMouseCoords(e));
drawOverlayCtx.beginPath();
for (var k=0; k<points.length; k++) {
drawOverlayCtx.moveTo(points[k][0].x, points[k][0].y);
for (var i = 1; i < points[k].length; i++) {
drawOverlayCtx.lineTo(points[k][i].x, points[k][i].y);
}
}
drawOverlayCtx.stroke();
});
drawOverlayCanvas.onmouseup = drawOverlayCanvas.ontouchend = function() {
isDrawing = false;
deleteOverlayTimeout = setTimeout(deleteOverlayCanvas, timeBeforeDeletion);
};
}
});
</script>
</body>
</html>

View File

@@ -1,63 +0,0 @@
<!doctype html>
<html>
<head>
<!-- <link rel="stylesheet" href="../distrib/latest/aladin.min.css" /> -->
<!--<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" /> -->
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
Image Opacity: <br/> <input id="slider" type="range" value=1 min=0 max=1 step=0.05 ; style="width:120px;height:5px;line-height:0%">
<br/>
<br/>
<div id="aladin-lite-div" style="width:440px;height:300px"></div>
<input id="DSS" type="radio" name="survey" value="P/DSS2/Color" checked><label for="DSS">Optical (DSS2) <label>
<input id="2MASS" type="radio" name="survey" value="P/2MASS/Color"><label for="2MASS">Infrared (2MASS)<label>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {target: "0 0", cooFrame: "gal"});
var callback = function(ra, dec, fov) {
aladin.addCatalog(A.catalogFromSimbad( {ra: ra, dec: dec} , 1 , {shape: 'circle', color: '#5d5', onClick: 'showTable'}));
// we must return true, so that the default action (set view to center of image) is performed
return true;
}
$("#slider").on('input', function() {
const opacity = $(this).val();
aladin.getOverlayImageLayer().setOpacity(opacity);
});
aladin.setBaseImageLayer('P/Mellinger/color');
//let fits = aladin.displayFITS('http://goldmine.mib.infn.it/data//B/fits/A04_VC1316_ooooog.fits', 'overlay');
let jpg = aladin.displayJPG(
// the JPG to transform to HiPS
'https://noirlab.edu/public/media/archives/images/large/noirlab1912a.jpg',
// no options
{},
// A callback fn once the overlay is set
callback
);
$('input[name=survey]').change(function() {
let surveyName = $(this).val();
if (surveyName === "P/2MASS/Color") {
aladin.setBaseImageLayer("CDS/P/2MASS/color");
} else if (surveyName === "P/DSS2/Color") {
aladin.setBaseImageLayer("CDS/P/DSS2/color");
}
});
});
</script>
</body>
</html>

View File

@@ -1,60 +0,0 @@
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, user-scalable=no">
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
/*aladin = A.aladin('#aladin-lite-div', {fov: 360, fullScreen: true, cooFrame: 'galactic'});
aladin.setProjection('MOL');
aladin.setBaseImageLayer("P/PanSTARRS/DR1/g", {
imgFormat: 'fits',
colormap: 'redtemperature',
stretch: 'Asinh'
});*/
/*aladin = A.aladin('#aladin-lite-div', {fov: 360, fullScreen: true, cooFrame: 'galactic'});
aladin.setProjection('AIT');
aladin.setBaseImageLayer("P/PanSTARRS/DR1/g", {imgFormat: "fits"});
aladin.getBaseImageLayer().setColormap('redtemperature', {stretch: "Asinh"});*/
aladin = A.aladin('#aladin-lite-div', {survey: 'CDS/P/SDSS9/color', fov: 60, target: '0 90', fullScreen: true, cooFrame: 'equatorial', showCooGridControl: true, showSimbadPointerControl: true, showCooGrid: true});
aladin.setProjection('SIN');
//let survey = aladin.createImageSurvey("P/PanSTARRS/DR1/g", null, null, null, null, );
/*aladin.setBaseImageLayer("P/PanSTARRS/DR1/g");
aladin.getBaseImageLayer().setColormap('viridis', {stretch: "Asinh"});*/
// manage URL parameters
const searchParams = new URL(document.location).searchParams;
if (searchParams.has('baseImageLayer')) {
aladin.setBaseImageLayer(searchParams.get('baseImageLayer'));
}
if (searchParams.has('overlayImageLayer')) {
aladin.setOverlayImageLayer(searchParams.get('overlayImageLayer'));
}
if (searchParams.has('cooFrame')) {
aladin.setFrame(searchParams.get('cooFrame'));
}
if (searchParams.has('fov')) {
aladin.setFoV(parseFloat(searchParams.get('fov')));
}
if (searchParams.has('ra') && searchParams.has('dec')) {
aladin.gotoRaDec(parseFloat(searchParams.get('ra')), parseFloat(searchParams.get('dec')));
}
});
</script>
</body>
</html>

View File

@@ -1,28 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
// Start up Aladin Lite
var aladin = A.aladin('#aladin-lite-div', {target: 'M 82', fov: 0.25});
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'}));
});
</script>
</body>
</html>

View File

@@ -1,25 +0,0 @@
<!doctype html>
<html>
<head>
<!-- <link rel="stylesheet" href="../distrib/latest/aladin.min.css" /> -->
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {target: 'M 45', fov: 5});
aladin.addCatalog(A.catalogFromVizieR('I/311/hip2', 'M 45', 5, {onClick: 'showTable'}));
});
</script>
</body>
</html>

View File

@@ -1,55 +0,0 @@
<!doctype html>
<html>
<head>
<!-- <link rel="stylesheet" href="../distrib/latest/aladin.min.css" /> -->
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id='infoDiv'>&nbsp; </div>
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
A.init.then(() => {
var aladin = A.aladin('#aladin-lite-div', {target: '05 37 58 +08 17 35', fov: 12});
var cat = A.catalog({sourceSize: 20});
aladin.addCatalog(cat);
cat.addSources([A.source(83.784490, 09.934156, {name: 'Meissa'}), A.source(88.792939, 7.407064, {name: 'Betelgeuse'}), A.source(81.282764, 6.349703, {name: 'Bellatrix'})]);
// define function triggered when a source is hovered
aladin.on('objectHovered', function(object) {
var msg;
if (object) {
msg = 'You hovered object ' + object.data.name + ' located at ' + object.ra + ', ' + object.dec;
}
else {
msg = 'No object hovered';
}
$('#infoDiv').html(msg);
});
// define function triggered when an object is clicked
var objClicked;
aladin.on('objectClicked', function(object) {
var msg;
if (object) {
objClicked = object;
object.select();
msg = 'You clicked object ' + object.data.name + ' located at ' + object.ra + ', ' + object.dec;
}
else {
objClicked.deselect();
msg = 'You clicked in void';
}
$('#infoDiv').html(msg);
});
});
</script>
</body>
</html>

View File

@@ -1,37 +0,0 @@
<!doctype html>
<html>
<head>
<!-- <link rel="stylesheet" href="../distrib/latest/aladin.min.css" /> -->
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
// Start up Aladin Lite
aladin = A.aladin('#aladin-lite-div', {survey: "CDS/P/DSS2/color", target: 'M 1', fov: 0.2});
var overlay = A.graphicOverlay({color: '#ee2345', lineWidth: 3});
aladin.addOverlay(overlay);
overlay.addFootprints([
A.polygon([[83.64287, 22.01713], [83.59872, 22.01692], [83.59852, 21.97629], [83.64295, 21.97629]]),
A.polygon([[83.62807, 22.06330], [83.58397, 22.02280], [83.62792, 22.02258]]),
A.polygon([[8.62807, 220.06330], [83.58397, 10.02280], [150.62792, 87.02258]])
]);
overlay.add(A.circle(83.66067, 22.03081, 0.04, {color: 'cyan'})); // radius in degrees
});
</script>
</body>
</html>

View File

@@ -1,146 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- Recommendation for users smartphone/tablets users -->
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, user-scalable=no">
<title>Explore Gaia DR3 in Aladin Lite</title>
</head>
<body>
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
<form class="pure-form pure-form-stacked">
<fieldset>
<label for="option-gdr3-flux-color-map" class="pure-radio">
<input id="option-gdr3-flux-color-map" type="radio" name="img-hips" value="CDS/P/DM/flux-color-Rp-G-Bp/I/350/gaiaedr3" checked>
Gaia DR3 flux map
</label>
<label for="option-gdr3-density-map" class="pure-radio">
<input id="option-gdr3-density-map" type="radio" name="img-hips" value="CDS/P/DM/I/350/gaiaedr3">
Gaia DR3 density map
</label>
<label for="option-DSS-map" class="pure-radio">
<input id="option-DSS-map" type="radio" name="img-hips" value="P/DSS2/color">
DSS Color
</label>
<label for="option-PS1-map" class="pure-radio">
<input id="option-PS1-map" type="radio" name="img-hips" value="P/PanSTARRS/DR1/color-z-zg-g">
Pan-STARRS
</label>
</fieldset>
</form>
</body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
$('#layersControl').show();
var curSelectedSource = null;
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', { fov: 100, cooFrame: 'galactic', fullscreen: true, showSimbadPointerControl: true });
aladin.gotoRaDec(297.87, 25.96);
aladin.setProjection('MOL');
const fluxMap = aladin.createImageSurvey('gdr3-color-flux-map', 'Gaia DR3 flux map', 'https://alasky.u-strasbg.fr/ancillary/GaiaEDR3/color-Rp-G-Bp-flux-map', 'equatorial', 7);
const densityMap = aladin.createImageSurvey('gdr3-density-map', 'Gaia DR3 density map', 'https://alasky.u-strasbg.fr/ancillary/GaiaEDR3/density-map', 'equatorial', 7, {imgFormat: 'fits'});
aladin.setImageSurvey(fluxMap);
var hipsCats = {
//'gdr3': A.catalogHiPS('https://axel.u-strasbg.fr/HiPSCatService/I/355/gaiadr3', { name: 'Gaia DR3 sources', shape: 'circle', sourceSize: 8, color: '#d66bae' }),
'simbad': A.catalogHiPS('https://axel.u-strasbg.fr/HiPSCatService/Simbad', { name: 'Simbad', color: '#6dbdce' })
};
hipsCats['simbad'].hide();
aladin.addCatalog(hipsCats['simbad']);
//aladin.addCatalog(hipsCats['gdr3']);
cmDensMapChanged = false;
// listen changes on HiPS image background selection
$('input[type=radio][name=img-hips]').change(function () {
if (this.value == 'CDS/P/DM/I/350/gaiaedr3') {
aladin.setBaseImageLayer(densityMap);
}
else if (this.value == "CDS/P/DM/flux-color-Rp-G-Bp/I/350/gaiaedr3") {
aladin.setBaseImageLayer(fluxMap);
} else {
aladin.setBaseImageLayer(this.value)
}
});
// listen changes on HiPS catalogues selection
$('#overlay-form :checkbox').change(function () {
var cat = hipsCats[this.value];
if (this.checked) {
cat.show();
}
else {
cat.hide();
}
});
// listen to click on objects
aladin.on('objectClicked', function (source) {
var html = '<table class="pure-table">';
if (curSelectedSource != null) {
curSelectedSource.deselect();
}
if (source == null) {
$('#explain').html('');
$('#explain').hide();
return;
}
source.select();
curSelectedSource = source;
html += '<tbody>';
if (source.catalog.name !== 'Simbad') {
html += '<h3>Gaia DR3 <em>' + source.data.Source + '</em></h3>';
html += '<tr class="pure-table-odd"><td><b>ra</b></td><td>' + source.data.RAdeg + '</td><td><em>deg</em></td></tr>';
html += '<tr><td><b>dec</b></td><td>' + source.data.dec + '</td><td><em>deg</em></td></tr>';
html += '<tr class="pure-table-odd"><td><b>parallax</b></td><td>' + source.data['parallax'] + '</td><td><em>mas</em></td></tr>';
html += '<tr class="pure-table-odd"><td><b>pmra</b></td><td>' + source.data['pmra'] + '</td><td><em>mas/yr</em></td></tr>';
html += '<tr class="pure-table-odd"><td><b>pmdec</b></td><td>' + source.data['pmdec'] + '</td><td><em>mas/yr</em></td></tr>';
html += '<tr class="pure-table-odd"><td><b>Gmag</b></td><td>' + source.data['phot_g_mean_mag'] + '</td><td><em>mag</em></td></tr>';
html += '<tr class="pure-table-odd"><td><b>Bpmag</b></td><td>' + source.data['phot_bp_mean_mag'] + '</td><td><em>mag</em></td></tr>';
html += '<tr class="pure-table-odd"><td><b>Rpmag</b></td><td>' + source.data['phot_rp_mean_mag'] + '</td><td><em>mag</em></td></tr>';
html += '</tbody>';
html += '</table>';
html += '<br/><a target="_blank" href="https://vizier.u-strasbg.fr/viz-bin/VizieR-5?-out.form=%2bH&-source=I/350/gaiaedr3&Source=' + source.data.source_id + '">More details</a>';
}
else {
console.log(source.data);
html += '<h3>Simbad object <em>' + source.data.main_id + '</em></h3>';
html += '<tr class="pure-table-odd"><td><b>ra</b></td><td>' + source.data.ra + '</td><td><em>deg</em></td></tr>';
html += '<tr><td><b>dec</b></td><td>' + source.data.dec + '</td><td><em>deg</em></td></tr>';
html += '<tr><td><b>main_type</b></td><td>' + source.data.main_type + '</td><td><em>deg</em></td></tr>';
html += '<tr class="pure-table-odd"><td><b>pmra</b></td><td>' + source.data.pmra + '</td><td><em>mas/yr</em></td></tr>';
html += '<tr><td><b>pmdec</b></td><td>' + source.data.pmdec + '</td><td><em>mas/yr</em></td></tr>';
html += '<tr class="pure-table-odd"><td><b>parallax</b></td><td>' + source.data.plx + '</td><td><em>mas</em></td></tr>';
html += '<tr><td><b>B mag.</b></td><td>' + source.data.B + '</td><td><em>mag</em></td></tr>';
html += '<tr class="pure-table-odd"><td><b>V mag.</b></td><td>' + source.data.V + '</td><td><em>mag</em></td></tr>';
html += '</tbody>';
html += '</table>';
html += '<br/><a target="_blank" href="https://simbad.u-strasbg.fr/simbad/sim-id?Ident=' + encodeURIComponent(source.data.main_id) + '">More details</a>';
}
$('#explain').html(html);
$('#explain').show();
});
});
</script>
</html>

View File

@@ -1,25 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
<!--<link rel="stylesheet" href="./layers.css" />-->
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {survey: 'http://alasky.cds.unistra.fr/ancillary/GaiaDR2/hips-density-map/', target: 'galactic center'});
});
</script>
</body>
</html>

View File

@@ -1,35 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
<!--<link rel="stylesheet" href="./layers.css" />-->
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {survey: 'http://alasky.cds.unistra.fr/ancillary/GaiaDR2/hips-density-map/', target: 'galactic center'});
const fluxMap = aladin.createImageSurvey('gdr3-color-flux-map', 'Gaia DR3 flux map', 'https://alasky.u-strasbg.fr/ancillary/GaiaEDR3/color-Rp-G-Bp-flux-map', 'equatorial', 7);
const densityMap = aladin.createImageSurvey('gdr3-density-map', 'Gaia DR3 density map', 'https://alasky.u-strasbg.fr/ancillary/GaiaEDR3/density-map', 'equatorial', 7, {imgFormat: 'fits'});
const decaps = aladin.createImageSurvey("decaps", "DECaPS DR1", "http://alasky.u-strasbg.fr/DECaPS/DR1/color/", "equatorial", 11, {imgFormat: 'png'});
const panstarrs = aladin.createImageSurvey("panstarrs", "PanSTARRS", "http://alasky.u-strasbg.fr/Pan-STARRS/DR1/color-i-r-g/", "equatorial", 11, {imgFormat: 'jpg'});
aladin.setOverlayImageLayer(fluxMap)
aladin.setOverlayImageLayer(densityMap, "density")
aladin.setOverlayImageLayer(decaps, "decaps")
aladin.setOverlayImageLayer(panstarrs, "panstarrs")
});
</script>
</body>
</html>

View File

@@ -1,26 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
<!--<link rel="stylesheet" href="./layers.css" />-->
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {target: 'galactic center'});
aladin.setImageSurvey('P/allWISE/color');
});
</script>
</body>
</html>

View File

@@ -1,38 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
<!--<link rel="stylesheet" href="./layers.css" />-->
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
var aladin = A.aladin(
'#aladin-lite-div',
{
survey: 'P/allWISE/color', // set initial image survey
projection: 'AIT', // set a projection
fov: 1.5, // initial field of view in degrees
target: 'NGC 2175', // initial target
cooFrame: 'galactic', // set galactic frame
reticleColor: '#ff89ff', // change reticle color
reticleSize: 64, // change reticle size
showCooGrid: true, // set the grid
fullScreen: true,
}
);
});
</script>
</body>
</html>

View File

@@ -1,37 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
<!--<link rel="stylesheet" href="./layers.css" />-->
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin(
'#aladin-lite-div',
{
projection: 'AIT', // set a projection
fov: 0.06, // initial field of view in degrees
target: '110.82730 -73.45471', // initial target
cooFrame: 'equatorial', // set galactic frame
showCooGrid: true, // set the grid
fullScreen: true,
}
);
aladin.setOverlayImageLayer("https://alasky.cds.unistra.fr/JWST/CDS_P_JWST_deep_field_smacs0723-5mb")
});
</script>
</body>
</html>

View File

@@ -1,24 +0,0 @@
<!doctype html>
<html>
<head>
<!-- <link rel="stylesheet" href="../distrib/latest/aladin.min.css" /> -->
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
A.init.then(() => {
var aladin = A.aladin('#aladin-lite-div', {survey: 'P/DSS2/red', target: 'LMC', fov: 5});
aladin.addCatalog(A.catalogFromURL('https://vizier.u-strasbg.fr/viz-bin/votable?-source=HIP2&-c=LMC&-out.add=_RAJ,_DEJ&-oc.form=dm&-out.meta=DhuL&-out.max=9999&-c.rm=180', {sourceSize:12, color: '#f08080'}));
});
</script>
</body>
</html>

View File

@@ -1,32 +0,0 @@
<!doctype html>
<html>
<head>
<!-- <link rel="stylesheet" href="../distrib/latest/aladin.min.css" /> -->
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
A.init.then(() => {
let a = A.aladin('#aladin-lite-div', {target: '03 47 00.00 +24 07 00.0', survey: 'P/DSS2/color', zoom: 2, showReticle: false});
var cat = A.catalog({name: 'Some markers', sourceSize: 18});
a.addCatalog(cat);
cat.addSources([A.marker(56.87115, 24.10514, {popupTitle: 'Alcyone', popupDesc: '<em>Bmag:</em> 2.806<br/><em>Spectral type:</em> B7III<br/>More info <a target="_blank" href="https://simbad.u-strasbg.fr/simbad/sim-id?Ident=NAME%20ALCYONE&submit=submit">in Simbad</a>'})]);
cat.addSources([A.marker(57.29673, 24.13671, {popupTitle: 'Pleione', popupDesc: '<em>Bmag:</em> 4.97<br/><em>Spectral type:</em> B8vne<br/>More info <a target="_blank" href="https://simbad.u-strasbg.fr/simbad/sim-id?Ident=NAME+PLEIONE&NbIdent=1">in Simbad</a>'})]);
cat.addSources([A.marker(56.58156, 23.94836, {popupTitle: 'Merope', popupDesc: '<em>Bmag:</em> 4.113<br/><em>Spectral type:</em> BVI4e<br/>More info <a target="_blank" href="https://simbad.u-strasbg.fr/simbad/sim-id?Ident=V*+V971+Tau&NbIdent=1">in Simbad</a>'})]);
cat.addSources([A.marker(56.45669, 24.36775, {popupTitle: 'Maia', popupDesc: '<em>Bmag:</em> 3.812<br/><em>Spectral type:</em> B8III<br/>More info <a target="_blank" href="https://simbad.u-strasbg.fr/simbad/sim-id?Ident=NAME+MAIA&NbIdent=1">in Simbad</a>'})]);
cat.addSources([A.marker(56.21890, 24.11334, {popupTitle: 'Electra', popupDesc: '<em>Bmag:</em> 3.612<br/><em>Spectral type:</em> B6IIIe<br/>More info <a target="_blank" href="https://simbad.u-strasbg.fr/simbad/sim-id?Ident=NAME+ELECTRA&NbIdent=1">in Simbad</a>'})]);
cat.addSources([A.marker(57.29059, 24.05342, {popupTitle: 'Atlas', popupDesc: '<em>Bmag:</em> 3.54<br/><em>Spectral type:</em> B8III<br/>More info <a target="_blank" href="https://simbad.u-strasbg.fr/simbad/sim-id?Ident=NAME+ATLAS&NbIdent=1">in Simbad</a>'})]);
cat.addSources([A.marker(56.30207, 24.46728, {popupTitle: 'Taygeta', popupDesc: '<em>Bmag:</em> 4.199<br/><em>Spectral type:</em> B6IV<br/>More info <a target="_blank" href="https://simbad.u-strasbg.fr/simbad/sim-id?Ident=NAME+TAYGETA&NbIdent=1">in Simbad</a>'})]);
});
</script>
</body>
</html>

View File

@@ -1,57 +0,0 @@
<!doctype html>
<html>
<head>
<!-- <link rel="stylesheet" href="../distrib/latest/aladin.min.css" /> -->
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {target: '240 +10.65', cooFrame: 'j2000d', fov: 90, showFrame: false, showCooGrid: true, showLayersControl: false, showGotoControl: false, fullScreen: true});
var mars = aladin.createImageSurvey('Mars', 'Mars', 'http://hips-calculator1.astro.unistra.fr/boch/MARS-CTX/hips', 'j2000', 11);
aladin.setImageSurvey(mars);
var c = document.createElement('canvas'); c.width = c.height = 11; var ctx = c.getContext('2d'); ctx.beginPath(); ctx.arc(5, 5, 4, 0, 2 * Math.PI, false); ctx.closePath(); ctx.strokeStyle = '#ccc'; ctx.lineWidth = 2; ctx.stroke();
var geoFeatures = A.catalog({shape: c, labelColumn: 'name', displayLabel: true, labelColor: '#fff', labelFont: '14px sans-serif'});
aladin.addCatalog(geoFeatures);
geoFeatures.addSources(A.source(226.2, 18.65, {name: 'Olympus Mons'}));
geoFeatures.addSources(A.source(70.5, -42.4, {name: 'Hellas Planitia'}));
geoFeatures.addSources(A.source(250.4, 40.5, {name: 'Alba Mons'}));
geoFeatures.addSources(A.source(-59.2, -13.9, {name: 'Valles Marineris'}));
geoFeatures.addSources(A.source(147.21, 25.02, {name: 'Elysium Mons'}));
geoFeatures.addSources(A.source(316.0, -49.7, {name: 'Argyre Basin'}));
geoFeatures.addSources(A.source(32.53, 70, {name: 'Vastitas Borealis'}));
geoFeatures.addSources(A.source(-112.58, 1.57, {name: 'Tharsis Montes'}));
geoFeatures.addSources(A.source(298, 25, {name: 'Outflow channels'}));
geoFeatures.addSources(A.source(30, 19.79, {name: 'Arabia Terra'}));
geoFeatures.addSources(A.source(70.5, -42.4, {name: 'Hellas Basin'}));
geoFeatures.addSources(A.source(280, 45, {name: 'Tempe Terra'}));
geoFeatures.addSources(A.source(87, 12.9, {name: 'Isidis Basin'}));
geoFeatures.addSources(A.source(117.5, 46.7, {name: 'Utopia Basin'}));
geoFeatures.addSources(A.source(350, -45, {name: 'Noachis Terra'}));
var landingSites = A.catalog({sourceSize: 16}); aladin.addCatalog(landingSites);
landingSites.addSources([A.marker(-47.95, 22.27, {popupTitle: 'Viking 1', popupDesc: 'Landing date: July 20, 1976 11:53:06'})]);
landingSites.addSources([A.marker(-125.7, 68.22, {popupTitle: 'Phoenix', popupDesc: 'Landing date: May 25, 2008 23:53:44 UTC'})]);
landingSites.addSources([A.marker(-33.22, 19.13, {popupTitle: 'Pathfinder', popupDesc: 'Landing date: July 4, 1997 16:56:55 UTC'})]);
landingSites.addSources([A.marker(354.4734, -1.9462, {popupTitle: 'Opportunity', popupDesc: 'Landing date: January 25, 2004, 05:05 UTC'})]);
landingSites.addSources([A.marker(-225.71, 47.64, {popupTitle: 'Viking 2', popupDesc: 'Landing date: September 3, 1976 22:37:50'})]);
landingSites.addSources([A.marker(175.472636, -14.5684, {popupTitle: 'Spirit', popupDesc: 'Landing date: January 4, 2004, 04:35 UTC '})]);
landingSites.addSources([A.marker(137.4417, -4.5895, {popupTitle: 'Curiosity', popupDesc: 'Landing date: August 6, 2012, 05:17 UTC '})])
});
</script>
</body>
</html>

View File

@@ -1,66 +0,0 @@
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, user-scalable=no">
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {fov: 180, fullScreen: true, cooFrame: 'equatorial', showCooGridControl: true, showSimbadPointerControl: true, showCooGrid: false, survey: 'CDS/P/Mars/THEMIS-Day-100m-v12'});
aladin.setProjection('SIN');
const drawFunction = function(source, canvasCtx, viewParams) {
canvasCtx.beginPath();
canvasCtx.arc(source.x, source.y, 4, 0, 2 * Math.PI, false);
canvasCtx.closePath();
canvasCtx.strokeStyle = '#38c';
canvasCtx.lineWidth = 3;
canvasCtx.globalAlpha = 0.7,
canvasCtx.stroke();
const fov = Math.max(viewParams['fov'][0], viewParams['fov'][1]);
// object name is displayed only if fov<15°
if (fov>15) {
return;
}
canvasCtx.globalAlpha = 1;
const xShift = 10;
canvasCtx.font = '15px Arial'
canvasCtx.fillStyle = '#eee';
canvasCtx.strokeStyle = '#222';
canvasCtx.lineWidth = 1;
canvasCtx.fillText(source.data['Feature Name'], source.x + xShift, source.y -4);
//canvasCtx.strokeText(source.data['Feature Name'], source.x + xShift, source.y -4);
// object type is displayed only if fov<5°
if (fov>5) {
return;
}
canvasCtx.font = '12px Arial'
canvasCtx.fillStyle = '#abc';
canvasCtx.strokeStyle = '#222';
canvasCtx.lineWidth = 1;
canvasCtx.fillText(source.data['Feature Type'], source.x + 2 + xShift, source.y + 10);
//canvasCtx.strokeText(source.data['Feature Type'], source.x + 2 + xShift, source.y + 10);
};
aladin.addCatalog(A.catalogFromURL('https://aladin.cds.unistra.fr/AladinLite/doc/API/examples/data/mars-features.xml', {raField: 'Longitude', decField: 'Latitude', shape: drawFunction, onClick: 'showTable'}));
aladin.getBaseImageLayer().setColormap('yiorbr')
aladin.gotoRaDec(226.1433542, 18.6308694);
});
</script>
</body>
</html>

View File

@@ -1,57 +0,0 @@
<!doctype html>
<html>
<head>
<!-- <link rel="stylesheet" href="../distrib/latest/aladin.min.css" /> -->
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {target: '240 +10.65', cooFrame: 'j2000d', fov: 90, showFrame: false, showCooGrid: true, showLayersControl: false, showGotoControl: false, fullScreen: true});
var mars = aladin.createImageSurvey('Mars', 'Mars', 'https://alasky.u-strasbg.fr/Planets/Mars_Viking_MDIM21/', 'j2000', 5);
aladin.setImageSurvey(mars);
var c = document.createElement('canvas'); c.width = c.height = 11; var ctx = c.getContext('2d'); ctx.beginPath(); ctx.arc(5, 5, 4, 0, 2 * Math.PI, false); ctx.closePath(); ctx.strokeStyle = '#ccc'; ctx.lineWidth = 2; ctx.stroke();
var geoFeatures = A.catalog({shape: c, labelColumn: 'name', displayLabel: true, labelColor: '#fff', labelFont: '14px sans-serif'});
aladin.addCatalog(geoFeatures);
geoFeatures.addSources(A.source(226.2, 18.65, {name: 'Olympus Mons'}));
geoFeatures.addSources(A.source(70.5, -42.4, {name: 'Hellas Planitia'}));
geoFeatures.addSources(A.source(250.4, 40.5, {name: 'Alba Mons'}));
geoFeatures.addSources(A.source(-59.2, -13.9, {name: 'Valles Marineris'}));
geoFeatures.addSources(A.source(147.21, 25.02, {name: 'Elysium Mons'}));
geoFeatures.addSources(A.source(316.0, -49.7, {name: 'Argyre Basin'}));
geoFeatures.addSources(A.source(32.53, 70, {name: 'Vastitas Borealis'}));
geoFeatures.addSources(A.source(-112.58, 1.57, {name: 'Tharsis Montes'}));
geoFeatures.addSources(A.source(298, 25, {name: 'Outflow channels'}));
geoFeatures.addSources(A.source(30, 19.79, {name: 'Arabia Terra'}));
geoFeatures.addSources(A.source(70.5, -42.4, {name: 'Hellas Basin'}));
geoFeatures.addSources(A.source(280, 45, {name: 'Tempe Terra'}));
geoFeatures.addSources(A.source(87, 12.9, {name: 'Isidis Basin'}));
geoFeatures.addSources(A.source(117.5, 46.7, {name: 'Utopia Basin'}));
geoFeatures.addSources(A.source(350, -45, {name: 'Noachis Terra'}));
var landingSites = A.catalog({sourceSize: 16}); aladin.addCatalog(landingSites);
landingSites.addSources([A.marker(-47.95, 22.27, {popupTitle: 'Viking 1', popupDesc: 'Landing date: July 20, 1976 11:53:06'})]);
landingSites.addSources([A.marker(-125.7, 68.22, {popupTitle: 'Phoenix', popupDesc: 'Landing date: May 25, 2008 23:53:44 UTC'})]);
landingSites.addSources([A.marker(-33.22, 19.13, {popupTitle: 'Pathfinder', popupDesc: 'Landing date: July 4, 1997 16:56:55 UTC'})]);
landingSites.addSources([A.marker(354.4734, -1.9462, {popupTitle: 'Opportunity', popupDesc: 'Landing date: January 25, 2004, 05:05 UTC'})]);
landingSites.addSources([A.marker(-225.71, 47.64, {popupTitle: 'Viking 2', popupDesc: 'Landing date: September 3, 1976 22:37:50'})]);
landingSites.addSources([A.marker(175.472636, -14.5684, {popupTitle: 'Spirit', popupDesc: 'Landing date: January 4, 2004, 04:35 UTC '})]);
landingSites.addSources([A.marker(137.4417, -4.5895, {popupTitle: 'Curiosity', popupDesc: 'Landing date: August 6, 2012, 05:17 UTC '})])
});
</script>
</body>
</html>

View File

@@ -1,37 +0,0 @@
<!doctype html>
<html>
<head>
<!-- <link rel="stylesheet" href="../distrib/latest/aladin.min.css" /> -->
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px">
<div id="ui" class="ui">
</div>
</div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {target: '00 00 00 +07 00 00', fov: 130, survey: 'P/ISOPHOT/170'});
var moc = A.MOCFromURL('https://cds.unistra.fr/~boch/MOC-ISOPHOT.fits', {color: '#84f', lineWidth: 1, opacity: 1.0}, (moc) => {
// moc is ready
console.log(moc.contains(205.9019247, +2.4492764));
console.log(moc.contains(-205.9019247, +2.4492764));
});
aladin.addMOC(moc);
});
</script>
</body>
</html>

View File

@@ -1,41 +0,0 @@
<!doctype html>
<html>
<head>
<!-- <link rel="stylesheet" href="../distrib/latest/aladin.min.css" /> -->
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px">
<div id="ui" class="ui">
</div>
</div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {target: 'LMC', fov: 55});
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: 1, adaptativeDisplay: false});
aladin.addMOC(moc);
});
</script>
</body>
</html>

View File

@@ -1,42 +0,0 @@
<!doctype html>
<html>
<head>
<!-- <link rel="stylesheet" href="../distrib/latest/aladin.min.css" /> -->
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px">
<div id="ui" class="ui">
</div>
</div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {target: '00 00 00 +07 00 00', fov: 130, survey: 'P/Mellinger/color'});
var moc11 = A.MOCFromURL('http://skies.esac.esa.int/HST/NICMOS/Moc.fits', {color: '#84f', lineWidth: 1, opacity: 1.0}, (moc) => {
// moc is ready
console.log(moc.contains(205.9019247, +2.4492764));
console.log(moc.contains(-205.9019247, +2.4492764));
});
var moc10 = A.MOCFromURL('https://alasky.unistra.fr/MocServer/query?ivorn=ivo%3A%2F%2FCDS%2FV%2F139%2Fsdss9&get=moc&order=11&fmt=fits', {color: '#aabbcc', opacity: 0.1, lineWidth: 1});
var moc9 = A.MOCFromURL('https://alasky.unistra.fr/MocServer/query?ivorn=ivo%3A%2F%2FCDS%2FV%2F139%2Fsdss9&get=moc&order=4&fmt=fits', {color: '#00ff00', opacity: 0.5, lineWidth: 1});
aladin.addMOC(moc11);
aladin.addMOC(moc10);
aladin.addMOC(moc9);
});
</script>
</body>
</html>

View File

@@ -1,36 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
<!--<link rel="stylesheet" href="./layers.css" />-->
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin(
'#aladin-lite-div',
{
survey: 'https://alasky.cds.unistra.fr/hips-cube-services/moment/hips:httpsalasky.cds.unistra.fr;MaNGA_DR13_Ncube%7Cmoment_order:0',
projection: 'AIT', // set a projection
fov: 0.1, // initial field of view in degrees
target: '135.0668750000, 40.2981666667', // initial target
cooFrame: 'equatorial', // set galactic frame
showCooGrid: true, // set the grid
fullScreen: true,
}
);
});
</script>
</body>
</html>

View File

@@ -1,30 +0,0 @@
<!doctype html>
<html>
<head>
<!-- <link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" /> -->
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="al1" style="width: 500px; height: 500px">
</div>
<div id="al2" style="width: 500px; height: 500px">
</div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let al1;
let al2;
A.init.then(() => {
// Start up Aladin Lite
al1 = A.aladin('#al1', {target: 'M51', fov: 0.3, survey: 'P/DSS2/color', fullScreen: false});
al2 = A.aladin('#al2', {target: 'M51', fov: 180, survey: 'P/PanSTARRS/DR1/z', fullScreen: false});
});
</script>
</body>
</html>

View File

@@ -1,25 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
<!--<link rel="stylesheet" href="./layers.css" />-->
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {fullScreen: true, survey: ['P/DM/vizMine', 'P/HST/GOODS/color', 'P/MATLAS/g'], target: '0 0', showCooGrid: true, fov: 180});
});
</script>
</body>
</html>

View File

@@ -1,26 +0,0 @@
<!doctype html>
<html>
<head>
<!-- <link rel="stylesheet" href="../distrib/latest/aladin.min.css" /> -->
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {survey: 'P/DSS2/red', target: 'M1', fov: 0.3});
var cat = A.catalogFromURL('http://cdsxmatch.u-strasbg.fr/QueryCat/QueryCat?catName=SIMBAD&mode=cone&pos=M1&r=50arcmin&format=votable&limit=3000', {sourceSize:12, color: '#cc99bb', displayLabel: true, labelColumn: 'main_id', labelColor: '#ae4', labelFont: '9px sans-serif'});
aladin.addCatalog(cat);
});
</script>
</body>
</html>

View File

@@ -1,27 +0,0 @@
<!doctype html>
<html>
<head>
<!-- <link rel="stylesheet" href="../distrib/latest/aladin.min.css" /> -->
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {cooFrame: 'galactic', fov: 110, target: 'galactic center'});
aladin.setBaseImageLayer('P/Mellinger/color');
aladin.setOverlayImageLayer(aladin.createImageSurvey('VTSS', 'VTSS', 'https://alasky.u-strasbg.fr/VTSS/Ha', 'galactic', 3, {imgFormat: 'png'}));
aladin.getOverlayImageLayer().setOpacity(0.5);
});
</script>
</body>
</html>

View File

@@ -1,31 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
</head>
<body>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<div id='aladin-statsDiv'></div>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
// Start up Aladin Lite
aladin = A.aladin('#aladin-lite-div', {
fov: 360,
target: '0 0',
fullScreen: true,
survey: "CDS/P/Mars/Pan-Perseverance-PIA24422",
showCooGrid: true,
});
aladin.setProjection('MER');
});
</script>
</body>
</html>

View File

@@ -1,32 +0,0 @@
<!doctype html>
<html>
<head>
<!-- <link rel="stylesheet" href="../distrib/latest/aladin.min.css" /> -->
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {target: 'Gamma Cas', fov: 10});
var overlay = A.graphicOverlay({color: '#ee2345', lineWidth: 2});
aladin.addOverlay(overlay);
overlay.add(A.polyline([ [2.29452158, 59.14978110], [10.12683778, 56.53733116], [14.1772154, 60.7167403], [21.45396446, 60.23528403], [28.59885697, 63.67010079] ]));
});
</script>
</body>
</html>

View File

@@ -1,54 +0,0 @@
<!doctype html>
<html>
<head>
<!-- <link rel="stylesheet" href="../distrib/latest/aladin.min.css" /> -->
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<div id='buttons'></div>
<script type="text/javascript">
A.init.then(() => {
var a = A.aladin('#aladin-lite-div', {target: '03 47 00.00 +24 07 00.0', survey: 'P/DSS2/color', zoom: 2, showReticle: false});
var cat = A.catalog({color: 'red', onClick: 'showTable'});
var originalSources = [
A.source(56.87115, 24.10514, {name: 'Alcyone'}),
A.source(57.29673, 24.13671, {name: 'Pleione'}),
A.source(56.58156, 23.94836, {name: 'Merope'}),
A.source(56.45669, 24.36775, {name: 'Maia'}),
A.source(56.21890, 24.11334, {name: 'Electra'}),
A.source(57.29059, 24.05342, {name: 'Atlas'}),
A.source(56.30207, 24.46728, {name: 'Taygeta'})
];
cat.addSources(originalSources);
a.addCatalog(cat);
// add button to remove sources
var buttonsDiv = document.getElementById('buttons');
for (var k=0; k<originalSources.length; k++) {
var s = originalSources[k];
var btn = document.createElement('button');
btn.innerHTML = 'Delete ' + s.data.name;
btn.value = k; // we store the index in the originalSources array
buttonsDiv.appendChild(btn);
}
document.querySelectorAll('button').forEach(function(item) {
item.addEventListener('click', function() {
cat.remove(originalSources[parseInt(this.value)]);
});
});
});
</script>
</body>
</html>

View File

@@ -1,25 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
<!--<link rel="stylesheet" href="./layers.css" />-->
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {target: 'M81', fov: 1});
});
</script>
</body>
</html>

View File

@@ -1,59 +0,0 @@
<!doctype html>
<html>
<head>
<!-- <link rel="stylesheet" href="../distrib/latest/aladin.min.css" /> -->
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
// Start up Aladin Lite
aladin = A.aladin('#aladin-lite-div', { target: '0 0', cooFrame: 'j2000d', showCooGrid: true, fov: 90, fullScreen: true});
var mars = aladin.createImageSurvey('Mars', 'Mars', 'https://alasky.u-strasbg.fr/Planets/Mars_Viking_MDIM21/', 'j2000', 5);
aladin.setImageSurvey(mars);
var c = document.createElement('canvas'); c.width = c.height = 11; var ctx = c.getContext('2d'); ctx.beginPath(); ctx.arc(5, 5, 4, 0, 2 * Math.PI, false); ctx.closePath(); ctx.strokeStyle = '#ccc'; ctx.lineWidth = 2; ctx.stroke();
var geoFeatures = A.catalog({shape: c, labelColumn: 'name', displayLabel: true, labelColor: '#fff', labelFont: '14px sans-serif'});
aladin.addCatalog(geoFeatures);
geoFeatures.addSources(A.source(226.2, 18.65, {name: 'Olympus Mons'}));
geoFeatures.addSources(A.source(70.5, -42.4, {name: 'Hellas Planitia'}));
geoFeatures.addSources(A.source(250.4, 40.5, {name: 'Alba Mons'}));
geoFeatures.addSources(A.source(-59.2, -13.9, {name: 'Valles Marineris'}));
geoFeatures.addSources(A.source(147.21, 25.02, {name: 'Elysium Mons'}));
geoFeatures.addSources(A.source(316.0, -49.7, {name: 'Argyre Basin'}));
geoFeatures.addSources(A.source(32.53, 70, {name: 'Vastitas Borealis'}));
geoFeatures.addSources(A.source(-112.58, 1.57, {name: 'Tharsis Montes'}));
geoFeatures.addSources(A.source(298, 25, {name: 'Outflow channels'}));
geoFeatures.addSources(A.source(30, 19.79, {name: 'Arabia Terra'}));
geoFeatures.addSources(A.source(70.5, -42.4, {name: 'Hellas Basin'}));
geoFeatures.addSources(A.source(280, 45, {name: 'Tempe Terra'}));
geoFeatures.addSources(A.source(87, 12.9, {name: 'Isidis Basin'}));
geoFeatures.addSources(A.source(117.5, 46.7, {name: 'Utopia Basin'}));
geoFeatures.addSources(A.source(350, -45, {name: 'Noachis Terra'}));
var landingSites = A.catalog({sourceSize: 16}); aladin.addCatalog(landingSites);
landingSites.addSources([A.marker(-47.95, 22.27, {popupTitle: 'Viking 1', popupDesc: 'Landing date: July 20, 1976 11:53:06'})]);
landingSites.addSources([A.marker(-125.7, 68.22, {popupTitle: 'Phoenix', popupDesc: 'Landing date: May 25, 2008 23:53:44 UTC'})]);
landingSites.addSources([A.marker(-33.22, 19.13, {popupTitle: 'Pathfinder', popupDesc: 'Landing date: July 4, 1997 16:56:55 UTC'})]);
landingSites.addSources([A.marker(354.4734, -1.9462, {popupTitle: 'Opportunity', popupDesc: 'Landing date: January 25, 2004, 05:05 UTC'})]);
landingSites.addSources([A.marker(-225.71, 47.64, {popupTitle: 'Viking 2', popupDesc: 'Landing date: September 3, 1976 22:37:50'})]);
landingSites.addSources([A.marker(175.472636, -14.5684, {popupTitle: 'Spirit', popupDesc: 'Landing date: January 4, 2004, 04:35 UTC '})]);
landingSites.addSources([A.marker(137.4417, -4.5895, {popupTitle: 'Curiosity', popupDesc: 'Landing date: August 6, 2012, 05:17 UTC '})])
//aladin.setOverlayImageLayer(aladin.createImageSurvey('VTSS', 'VTSS', '', 'galactic', 3, {imgFormat: 'png'}));
});
</script>
</body>
</html>

View File

@@ -1,26 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
<!--<link rel="stylesheet" href="./layers.css" />-->
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {target: 'M81', fov: 1});
aladin.setImageSurvey(aladin.createImageSurvey('Panstarrs', 'Panstarrs', 'http://alasky.cds.unistra.fr/Pan-STARRS/DR1/g/', 'equatorial', 11, {imgFormat: 'fits', colormap: "redtemperature"}));
});
</script>
</body>
</html>

View File

@@ -1,29 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
<!--<link rel="stylesheet" href="./layers.css" />-->
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {cooFrame: 'galactic', target: 'galactic center', survey: 'P/Finkbeiner'});
// possible values are 'blues', 'cividis', 'cubehelix', 'eosb', 'grayscale', 'inferno', 'magma', 'native', 'parula', 'plasma', 'rainbow',
// 'rdbu', 'rdyibu', 'redtemperature', 'spectral', 'summer', 'viridis', 'yignbu' and 'yiorbr'
aladin.getBaseImageLayer().setColormap("cubehelix");
//aladin.getBaseImageLayer().setColor([1.0, 0.0, 1.0, 1.0], { tf: 'Linear'} );
});
</script>
</body>
</html>

View File

@@ -1,28 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
<!--<link rel="stylesheet" href="./layers.css" />-->
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
// Start up Aladin Lite
aladin = A.aladin('#aladin-lite-div', {fov: 180.0, fullScreen: true, survey: "CDS/P/DM/simbad-biblio/allObjects", target: '12 25 41.512 +12 48 47.2', showCooGrid: true});
aladin.setProjection("TAN");
aladin.getBaseImageLayer().setColormap("redtemperature")
});
</script>
</body>
</html>

View File

@@ -1,28 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
<!--<link rel="stylesheet" href="./layers.css" />-->
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
// Start up Aladin Lite
aladin = A.aladin('#aladin-lite-div', {target: '12 25 41.512 +12 48 47.2', fov: 0.8, showSimbadPointerControl: true});
});
</script>
</body>
</html>

View File

@@ -1,36 +0,0 @@
<!doctype html>
<html>
<head>
<!-- <link rel="stylesheet" href="../distrib/latest/aladin.min.css" /> -->
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
// Start up Aladin Lite
aladin = A.aladin('#aladin-lite-div', {survey: "CDS/P/DSS2/color", target: 'Sgr a*', fov: 0.5});
const overlay = A.graphicOverlay({color: '#2345ee', lineWidth: 2});
aladin.addOverlay(overlay);
aladin.addCatalog(A.catalogFromURL('https://aladin.cds.unistra.fr/AladinLite/doc/API/examples/data/alma-footprints.xml', {}, function(sources) {
sources.forEach(source => overlay.addFootprints(A.footprintsFromSTCS(source.data['s_region'])));
console.log(aladin.createFootprintsFromSTCS(source.data['s_region']));
}));
});
</script>
</body>
</html>

View File

@@ -1,37 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
<!--<link rel="stylesheet" href="./layers.css" />-->
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin(
'#aladin-lite-div',
{
projection: 'AIT', // set a projection
fov: 0.02, // initial field of view in degrees
target: '338.98958 33.96', // initial target
cooFrame: 'equatorial', // set galactic frame
showCooGrid: true, // set the grid
fullScreen: true,
}
);
aladin.setOverlayImageLayer("https://alasky.cds.unistra.fr/JWST/CDS_P_JWST_Stephans-Quintet_NIRCam+MIRI")
});
</script>
</body>
</html>

View File

@@ -1,48 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
<!--<link rel="stylesheet" href="./layers.css" />-->
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {survey: ["P/Mellinger"], cooFrame: 'galactic', fov: 1000, fullScreen: true, showCooGrid: true});
const meerkat = aladin.createImageSurvey('P/MeerKAT/Galactic-Centre-1284MHz-StokesI', "Galactic-Centre-1284MHz-StokesI", null, null, null, {imgFormat: 'fits'});
meerkat.setColormap('magma', {stretch: "Asinh"})
aladin.setOverlayImageLayer(meerkat)
aladin.setProjection("MOL")
let fov = 360;
setTimeout(function zoom() {
fov *= 0.995;
aladin.setFov(fov);
if (fov > 1) {
setTimeout(zoom, 10)
}
}, 10);
setInterval(function () {
const t = Date.now() / 1000;
let lambda = Math.sin(t) * 0.5 + 0.5;
let cut0 = -0.0004 * lambda + (1 - lambda) * -0.00132;
let cut1 = 0.005 * lambda + (1 - lambda) * 0.05759;
meerkat.setCuts([cut0, cut1]);
})
});
</script>
</body>
</html>

View File

@@ -1,28 +0,0 @@
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, user-scalable=no">
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {fov: 360, fullScreen: true, cooFrame: 'galactic', showCooGridControl: true, showSimbadPointerControl: true, showCooGrid: true});
aladin.setProjection('AIT');
aladin.on("zoomChanged", () => {
console.log("zoomChanged")
})
aladin.on("positionChanged", () => {
console.log("positionChanged")
})
});
</script>
</body>
</html>

View File

@@ -1,41 +0,0 @@
<!doctype html>
<html>
<head>
<!-- <link rel="stylesheet" href="../distrib/latest/aladin.min.css" /> -->
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
// Start up Aladin Lite
aladin = A.aladin('#aladin-lite-div', {survey: "CDS/P/DSS2/color", target: 'M 31', fov: 0.2});
var overlay = A.graphicOverlay({color: '#ee2345', lineWidth: 3});
aladin.addOverlay(overlay);
overlay.addFootprints([
A.polygon([[83.64287, 22.01713], [83.59872, 22.01692], [83.59852, 21.97629], [83.64295, 21.97629]]),
A.polygon([[83.62807, 22.06330], [83.58397, 22.02280], [83.62792, 22.02258]]),
A.ellipse(10.6833, 41.2669, 3.33333/2, 1.1798333/2, 35, {color: 'cyan'}),
// NGC 3048
A.ellipse(180.470842, -18.867589, 5.2/120, 3.1/120, 80, {color: 'cyan'}),
// NGC 3049
A.ellipse(180.4742, -18.8850, 3.1/120, 1.6/120, 50, {color: 'cyan'}),
]);
//overlay.add(); // radius in degrees
});
</script>
</body>
</html>

View File

@@ -1,795 +0,0 @@
<!doctype html>
<html>
<head>
<!-- <link rel="stylesheet" href="../distrib/latest/aladin.min.css" /> -->
<link rel="stylesheet" href="css/auto-complete.css">
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
<style>
.slider_tf {
width: 4em;
}
.box {
display: inline-block;
margin-left: 5px;
border: 1px solid;
padding: 2px;
}
.header {
margin-top: 0;
margin-bottom: 0;
}
</style>
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<div id="controls" style="display: flex;">
<!-- HiPSes control box -->
<div class="box">
<h3 class="header">Image Surveys</h3>
<table>
<tr>
<td><input type="color" id="color_c1" value="#ff0000"></td><td><input type="color" id="color_c2" value="#00ff00"></td><td><input type="color" id="color_c3" value="#0000ff"></td><td><input type="color" id="color_c4" value="#ffffff"></td>
</tr>
<tr>
<td><input id="c1_hips" style="width: 95%;"></td>
<td><input id="c2_hips" style="width: 95%;"></td>
<td><input id="c3_hips" style="width: 95%;"></td>
<td><input id="c4_hips" style="width: 95%;"></td>
</tr>
<tr>
<td>
<label for="colormap_c1">Colormap</label>
<select id="colormap_c1">
<option value="blackwhite">blackwhite</option>
<option value="blues">blues</option>
<option value="parula">parula</option>
<option value="rainbow">rainbow</option>
<option value="redtemperature">redtemperature</option>
<option value="RdBu">RdBu</option>
<option value="RdYiBu">RdYiBu</option>
<option value="spectral">spectral</option>
<option value="summer">summer</option>
<option value="YIGnBu">YIGnBu</option>
<option value="YIOrBr">YIOrBr</option>
<option value="Nothing" selected>Nothing</option>
</select>
<br>
<label for="k_c1">k</label>
<input id="k_c1" style="vertical-align: middle; width:10vw;" step="0.1" min="0" max="3" type="range" value="1" />
<br>
<label for="stretch_c1">Stretch</label>
<select id="stretch_c1">
<option value="power">Pow</option>
<option value="linear">Linear</option>
<option value="sqrt">Square root</option>
<option value="log">Log</option>
<option value="asinh" selected>Asinh</option>
</select>
<br>
<label for="min_cut_c1">Min cut</label>
<input id="min_cut_c1" style="vertical-align: middle; width:10vw;" step="0.1" min="-1" max="10" type="range" value="0" />
<br>
<input id="min_cut_c1_tf" type="text" class="slider_tf">
<br>
<label for="max_cut_c1">Max cut</label>
<input id="max_cut_c1" style="vertical-align: middle; width:10vw;" step="0.1" min="-1" max="10" type="range" value="2" />
<br>
<input id="max_cut_c1_tf" type="text" class="slider_tf">
</td>
<td>
<label for="k_c2">k</label>
<input id="k_c2" style="vertical-align: middle; width:10vw;" step="0.1" min="0" max="3" type="range" value="1" />
<br>
<label for="stretch_c2">Stretch</label>
<select id="stretch_c2">
<option value="power">Pow</option>
<option value="linear">Linear</option>
<option value="sqrt">Square root</option>
<option value="log">Log</option>
<option value="asinh" selected>Asinh</option>
</select>
<br/>
<label for="min_cut_c2">Min cut</label>
<input id="min_cut_c2" style="vertical-align: middle; width:10vw;" step="0.1" min="-1" max="10" type="range" value="0" />
<br>
<input id="min_cut_c2_tf" type="text" class="slider_tf">
<br>
<label for="max_cut_c2">Max cut</label>
<input id="max_cut_c2" style="vertical-align: middle; width:10vw;" step="0.1" min="-1" max="10" type="range" value="2" />
<br>
<input id="max_cut_c2_tf" type="text" class="slider_tf">
</td>
<td>
<label for="k_c3">k</label>
<input id="k_c3" style="vertical-align: middle; width:10vw;" step="0.1" min="0" max="3" type="range" value="1" />
<br>
<label for="stretch_c3">Stretch</label>
<select id="stretch_c3">
<option value="power">Pow</option>
<option value="linear">Linear</option>
<option value="sqrt">Square root</option>
<option value="log">Log</option>
<option value="asinh" selected>Asinh</option>
</select>
<br/>
<label for="min_cut_c3">Min cut</label>
<input id="min_cut_c3" style="vertical-align: middle; width:10vw;" step="0.1" min="-1" max="10" type="range" value="0" />
<br>
<input id="min_cut_c3_tf" type="text" class="slider_tf">
<br>
<label for="max_cut_c3">Max cut</label>
<input id="max_cut_c3" style="vertical-align: middle; width:10vw;" step="0.1" min="-1" max="10" type="range" value="3" />
<br>
<input id="max_cut_c3_tf" type="text" class="slider_tf">
</td>
<td>
<label for="k_c4">k</label>
<input id="k_c4" style="vertical-align: middle; width:10vw;" step="0.1" min="0" max="3" type="range" value="1" />
<br>
<label for="stretch_c4">Stretch</label>
<select id="stretch_c4">
<option value="power">Pow</option>
<option value="linear">Linear</option>
<option value="sqrt">Square root</option>
<option value="log">Log</option>
<option value="asinh" selected>Asinh</option>
</select>
<br/>
<label for="min_cut_c4">Min cut</label>
<input id="min_cut_c4" style="vertical-align: middle; width:10vw;" step="0.1" min="-1" max="10" type="range" value="0" />
<br>
<input id="min_cut_c4_tf" type="text" class="slider_tf">
<br>
<label for="max_cut_c4">Max cut</label>
<input id="max_cut_c4" style="vertical-align: middle; width:10vw;" step="0.1" min="-1" max="10" type="range" value="3" />
<br>
<input id="max_cut_c4_tf" type="text" class="slider_tf">
</td>
</tr>
</table>
</div>
<div class="box" style="border: 1px solid;">
<h3 class="header">Catalog</h3>
<!-- Catalog control box -->
<!-- <label for="c5_cat">Search</label>
<input id="c5_cat">-->
<select id="cat_selector">
<option value="CDS/IX/45/csc11">IX/45/csc11</option>
<option value="CDS/J/A+A/503/1023/meridian">J/A+A/503/1023/meridian</option>
<option value="CDS/J/A+A/604/A108/apogee12">J/A+A/604/A108/apogee12</option>
<option value="CDS/J/MNRAS/476/2117/apogeenn">J/MNRAS/476/2117/apogeenn</option>
<option value="CDS/II/122B/merged">II/122B/merged</option>
<option value="CDS/J/A+A/615/A49/members">J/A+A/615/A49/members</option>
<option value="CDS/I/313/lqrf">I/313/lqrf</option>
<option value="" selected></option>
</select>
<br />
<label for="opacity_cat">Opacity</label>
<input id="opacity_cat" style="vertical-align: middle; width:10vw;" step="0.02" min="0" max="1.0" type="range" value="1.0" />
<br />
<label for="strength_cat">Kernel Strength</label>
<input id="strength_cat" style="vertical-align: middle; width:10vw;" step="0.02" min="0" max="10.0" type="range" value="1.0" />
<br />
<label for="colormap_cat">Colormap</label>
<select id="colormap_cat">
<option value="blackwhite">blackwhite</option>
<option value="blues">blues</option>
<option value="parula">parula</option>
<option value="rainbow">rainbow</option>
<option value="RdBu">RdBu</option>
<option value="RdYiBu">RdYiBu</option>
<option value="redtemperature">redtemperature</option>
<option value="spectral">spectral</option>
<option value="summer">summer</option>
<option value="YIGnBu">YIGnBu</option>
<option value="YIOrBr">YIOrBr</option>
</select>
<p id="loading"></p>
</div>
<div class="box">
<h3 class="header">Grid</h3>
<!-- Grid control box -->
<label for="color_grid">Color</label>
<input type="color" id="color_grid" value="#00ff00">
<br />
<label for="opacity_grid">Opacity</label>
<input id="opacity_grid" style="vertical-align: middle; width:10vw;" step="0.02" min="0" max="1.0" type="range" value="0.2" />
<br />
<input id="showGrid" type="checkbox">
<label for="showGrid">Show grid</label>
<br />
<input id="hideLabels" type="checkbox">
<label for="hideLabels">Hide labels</label>
<br />
</div>
</div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script src="js/auto-complete.js"></script>
<script type="text/javascript">
let catalogArray = [];
let catalogMap = new Map();
let hipsesDict = {};
let hipsesArray = [];
let aladin;
$( document ).ready(function() {
$.ajax({
url: 'https://alasky.u-strasbg.fr/MocServer/query?dataproduct_type=image&get=record&fmt=json',
}).done(function(data) {
for (var k=0; k<data.length; k++) {
var hips = data[k];
var id = hips.ID;
// ignore color HiPS
if (hips.hasOwnProperty('dataproduct_subtype') && hips.dataproduct_subtype=='color') {
continue;
}
if (hips.hips_service_url) {
hips.hips_service_url = hips.hips_service_url.replace('http:', 'https:');
hips.hips_service_url = hips.hips_service_url.replace('alasky.', 'alaskybis.');
}
if (hips['hips_pixel_cut'] === undefined) {
//console.log('no pixel cut for: ', hips.ID);
continue;
}
var pixel_cuts = hips['hips_pixel_cut'].split(' ')
hips.min_cut = parseFloat(pixel_cuts[0]);
hips.max_cut = parseFloat(pixel_cuts[1]);
hipsesDict[id] = hips;
hipsesArray.push(hips);
}
//console.log(hipsesDict);
init();
});
/*$.ajax({
url: 'https://alasky.u-strasbg.fr/MocServer/query?expr=dataproduct_type%3Dcatalog%26%26nb_rows%3C%3D5000000%26%26nb_rows%3E%3D50000&get=record&fmt=json',
}).done(function(catalogs) {
for (var k = 0; k < catalogs.length; k++) {
var cat_id = catalogs[k].ID;
catalogMap[cat_id] = {
'obs_id': catalogs[k].obs_id,
};
catalogArray.push(cat_id);
}
console.log("CATALOGS", catalogs);
init_catalog();
});*/
});
/*
var init_catalog = function() {
new autoComplete({
selector: '#c5_cat',
minChars: 2,
source: function(term, suggest) {
term = term.toLowerCase();
var choices = catalogArray;
var matches = [];
for (let i=0; i<choices.length; i++) {
if (choices[i].toLowerCase().indexOf(term)>=0) {
matches.push(choices[i]);
}
}
console.log("MATCHES", matches)
suggest(matches);
},
renderItem: function (item, search) {
search = search.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
var re = new RegExp("(" + search.split(' ').join('|') + ")", "gi");
return '<div class="autocomplete-suggestion" data-val="' + item + '">' + item.replace(re, "<b>$1</b>") + '</div>';
},
onSelect: async function(e, term, item) {
let cat_id = term;
await loadCatalog(cat_id);
}
});
};
*/
function addLoadingInfo(catalogName) {
document.getElementById("loading").innerHTML = catalogName + " is loading...";
}
async function loadCatalog(cat_id) {
let colormap = $('#colormap_cat').val()
addLoadingInfo(cat_id);
/*let parallax_column_name = await getTableColumnName(catalog_id, "pos.parallax");
console.log('parallax column name: ', parallax_column_name);
let phot_mag_column_name = await getTableColumnName(catalog_id, "phot.mag");
console.log('phot mag column name: ', phot_mag_column_name);*/
let pos_ra_column_name = await getTableColumnName(cat_id, "pos.eq.ra");
let pos_dec_column_name = await getTableColumnName(cat_id, "pos.eq.dec");
let table_obs_id = cat_id.substring(4);
retrieveCatalog(table_obs_id, [pos_ra_column_name, pos_dec_column_name/*, phot_mag_column_name, parallax_column_name*/])
.then(sources => {
aladin.webglAPI.addCatalog("cat1", sources, colormap);
});
}
function getTableColumnName(table_name, ucd) {
let table_obs_id = table_name.substring(4);
let url = encodeURI('https://alasky.u-strasbg.fr/cgi/JSONProxy?url=') + encodeURIComponent('http://tapvizier.u-strasbg.fr/TAPVizieR/tap/sync?phase=RUN&lang=adql&format=json&request=doQuery&query=SELECT%20TOP%201%20table_name%2C%20column_name%2C%20ucd%20FROM%20TAP_SCHEMA.columns%20WHERE%20table_name%3D%27' + encodeURIComponent(table_obs_id) + '%27%20AND%20ucd%20LIKE%20%27' + encodeURIComponent(ucd) + '%25%27');
var request = {
method: 'GET',
headers: new Headers(),
mode: 'cors',
cache: 'default'
};
return fetch(url, request)
.then(response => response.json())
.then(table => {
// Return the column name of the first row corresponding to ucd
//console.log(table_name, ucd, ": here are the data", table.data);
return table.data[0][1];
});
}
function retrieveCatalog(table_obs_id, colnames, max_rows="*") {
let cols = [];
colnames.forEach(col => {
//console.log(col);
cols.push('"' + table_obs_id + '"."' + encodeURIComponent(col) + '"');
});
let cols_query = cols.join(", ");
let sql_query = 'SELECT ' + cols_query + ' FROM "' + table_obs_id + '"';
//console.log(sql_query);
let url = encodeURI('https://alasky.u-strasbg.fr/cgi/JSONProxy?url=') + encodeURIComponent('http://tapvizier.u-strasbg.fr/TAPVizieR/tap/sync?phase=RUN&lang=adql&format=json&request=doQuery&query=' + encodeURIComponent(sql_query)) ;
var request = {
method: 'GET',
headers: new Headers(),
mode: 'cors',
cache: 'default'
};
return fetch(url, request)
.then(response => response.json())
.then((votable) => {
let sources = votable.data;
return sources;
});
}
var init = function() {
new autoComplete({
selector: '#c1_hips',
minChars: 2,
source: function(term, suggest) {
term = term.toLowerCase();
var choices = hipsesArray;
var matches = [];
for (i=0; i<choices.length; i++)
if (choices[i].ID.toLowerCase().indexOf(term)>=0) {
matches.push(choices[i].ID);
}
suggest(matches);
},
renderItem: function (item, search){
search = search.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
var re = new RegExp("(" + search.split(' ').join('|') + ")", "gi");
return '<div class="autocomplete-suggestion" data-val="' + item + '">' + item.replace(re, "<b>$1</b>") + '</div>';
},
onSelect: function(e, term, item){
var hips = hipsesDict[term];
$('#min_cut_c1').attr('min', hips.min_cut - 0.4*(hips.max_cut - hips.min_cut));
$('#min_cut_c1').attr('max', hips.min_cut + 0.4*(hips.max_cut - hips.min_cut));
$('#min_cut_c1').attr('step', (hips.max_cut-hips.min_cut)/100.0);
$('#min_cut_c1').val(hips.min_cut);
$('#min_cut_c1_tf').val(hips.min_cut);
$('#max_cut_c1').attr('min', hips.max_cut - 0.4*(hips.max_cut - hips.min_cut));
$('#max_cut_c1').attr('max', hips.max_cut + 0.4*(hips.max_cut - hips.min_cut));
$('#max_cut_c1').attr('step', (hips.max_cut-hips.min_cut)/100.0);
$('#max_cut_c1').val(hips.max_cut);
$('#max_cut_c1_tf').val(hips.max_cut);
update();
}
});
new autoComplete({
selector: '#c2_hips',
minChars: 2,
source: function(term, suggest) {
term = term.toLowerCase();
var choices = hipsesArray;
var matches = [];
for (i=0; i<choices.length; i++)
if (choices[i].ID.toLowerCase().indexOf(term)>=0) {
matches.push(choices[i].ID);
}
suggest(matches);
},
renderItem: function (item, search){
search = search.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
var re = new RegExp("(" + search.split(' ').join('|') + ")", "gi");
return '<div class="autocomplete-suggestion" data-val="' + item + '">' + item.replace(re, "<b>$1</b>") + '</div>';
},
onSelect: function(e, term, item){
var hips = hipsesDict[term];
$('#min_cut_c2').attr('min', hips.min_cut - 0.4*(hips.max_cut - hips.min_cut));
$('#min_cut_c2').attr('max', hips.min_cut + 0.4*(hips.max_cut - hips.min_cut));
$('#min_cut_c2').attr('step', (hips.max_cut-hips.min_cut)/100.0);
$('#min_cut_c2').val(hips.min_cut);
$('#min_cut_c2_tf').val(hips.min_cut);
$('#max_cut_c2').attr('min', hips.max_cut - 0.4*(hips.max_cut - hips.min_cut));
$('#max_cut_c2').attr('max', hips.max_cut + 0.4*(hips.max_cut - hips.min_cut));
$('#max_cut_c2').attr('step', (hips.max_cut-hips.min_cut)/100.0);
$('#max_cut_c2').val(hips.max_cut);
$('#max_cut_c2_tf').val(hips.max_cut);
update();
}
});
new autoComplete({
selector: '#c3_hips',
minChars: 2,
source: function(term, suggest) {
term = term.toLowerCase();
var choices = hipsesArray;
var matches = [];
for (i=0; i<choices.length; i++)
if (choices[i].ID.toLowerCase().indexOf(term)>=0) {
matches.push(choices[i].ID);
}
suggest(matches);
},
renderItem: function (item, search){
search = search.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
var re = new RegExp("(" + search.split(' ').join('|') + ")", "gi");
return '<div class="autocomplete-suggestion" data-val="' + item + '">' + item.replace(re, "<b>$1</b>") + '</div>';
},
onSelect: function(e, term, item){
var hips = hipsesDict[term];
$('#min_cut_c3').attr('min', hips.min_cut - 0.4*(hips.max_cut - hips.min_cut));
$('#min_cut_c3').attr('max', hips.min_cut + 0.4*(hips.max_cut - hips.min_cut));
$('#min_cut_c3').attr('step', (hips.max_cut-hips.min_cut)/100.0);
$('#min_cut_c3').val(hips.min_cut);
$('#min_cut_c3_tf').val(hips.min_cut);
$('#max_cut_c3').attr('min', hips.max_cut - 0.4*(hips.max_cut - hips.min_cut));
$('#max_cut_c3').attr('max', hips.max_cut + 0.4*(hips.max_cut - hips.min_cut));
$('#max_cut_c3').attr('step', (hips.max_cut-hips.min_cut)/100.0);
$('#max_cut_c3').val(hips.max_cut);
$('#max_cut_c3_tf').val(hips.max_cut);
update();
}
});
new autoComplete({
selector: '#c4_hips',
minChars: 2,
source: function(term, suggest) {
term = term.toLowerCase();
var choices = hipsesArray;
var matches = [];
for (i=0; i<choices.length; i++)
if (choices[i].ID.toLowerCase().indexOf(term)>=0) {
matches.push(choices[i].ID);
}
suggest(matches);
},
renderItem: function (item, search){
search = search.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
var re = new RegExp("(" + search.split(' ').join('|') + ")", "gi");
return '<div class="autocomplete-suggestion" data-val="' + item + '">' + item.replace(re, "<b>$1</b>") + '</div>';
},
onSelect: function(e, term, item){
var hips = hipsesDict[term];
$('#min_cut_c4').attr('min', hips.min_cut - 0.4*(hips.max_cut - hips.min_cut));
$('#min_cut_c4').attr('max', hips.min_cut + 0.4*(hips.max_cut - hips.min_cut));
$('#min_cut_c4').attr('step', (hips.max_cut-hips.min_cut)/100.0);
$('#min_cut_c4').val(hips.min_cut);
$('#min_cut_c4_tf').val(hips.min_cut);
$('#max_cut_c4').attr('min', hips.max_cut - 0.4*(hips.max_cut - hips.min_cut));
$('#max_cut_c4').attr('max', hips.max_cut + 0.4*(hips.max_cut - hips.min_cut));
$('#max_cut_c4').attr('step', (hips.max_cut-hips.min_cut)/100.0);
$('#max_cut_c4').val(hips.max_cut);
$('#max_cut_c4_tf').val(hips.max_cut);
update();
}
});
};
function parseColor(colorHexaStr) {
var s = colorHexaStr.substring(1);
return [parseInt(s.substring(0, 2), 16)/255, parseInt(s.substring(2, 4), 16)/255, parseInt(s.substring(4, 6), 16)/255];
}
function update() {
var hipsComponents = [];
var c1Color = $('#color_c1').val();
var c2Color = $('#color_c2').val();
var c3Color = $('#color_c3').val();
var c4Color = $('#color_c4').val();
var stretch_c1 = $('#stretch_c1').val();
var colormap_c1 = $('#colormap_c1').val();
var min_cut_c1 = parseFloat($('#min_cut_c1_tf').val());
var max_cut_c1 = parseFloat($('#max_cut_c1_tf').val());
var stretch_c2 = $('#stretch_c2').val();
var min_cut_c2 = parseFloat($('#min_cut_c2_tf').val());
var max_cut_c2 = parseFloat($('#max_cut_c2_tf').val());
var stretch_c3 = $('#stretch_c3').val();
var min_cut_c3 = parseFloat($('#min_cut_c3_tf').val());
var max_cut_c3 = parseFloat($('#max_cut_c3_tf').val());
var stretch_c4 = $('#stretch_c4').val();
var min_cut_c4 = parseFloat($('#min_cut_c4_tf').val());
var max_cut_c4 = parseFloat($('#max_cut_c4_tf').val());
var c1HiPS = $('#c1_hips').val();
var c2HiPS = $('#c2_hips').val();
var c3HiPS = $('#c3_hips').val();
var c4HiPS = $('#c4_hips').val();
var useC1, useC2, useC3, useC4;
useC1 = useC2 = useC3 = useC4 = false;
if (c1HiPS.length>0) {
c1HiPS = hipsesDict[c1HiPS];
let color = {
Grayscale2Color: {
color: parseColor(c1Color),
k: parseFloat($('#k_c1').val()),
transfer: stretch_c1
}
};
if (colormap_c1 != "Nothing") {
color = {
Grayscale2Colormap: {
colormap: colormap_c1,
transfer: stretch_c1,
reversed: false,
}
};
}
let hipsComponent = {
properties: {
url: c1HiPS.hips_service_url,
maxOrder: parseInt(c1HiPS.hips_order),
// TODO
frame: { label: "J2000", system: "J2000" },
tileSize: parseInt(c1HiPS.hips_tile_width),
format: {
FITSImage: {
bitpix: parseInt(c1HiPS.hips_pixel_bitpix)
}
},
minCutout: parseFloat(min_cut_c1),
maxCutout: parseFloat(max_cut_c1),
},
color: color
};
hipsComponents.push(hipsComponent);
useC1 = true;
}
if (c2HiPS.length>0) {
c2HiPS = hipsesDict[c2HiPS];
hipsComponents.push({
properties: {
url: c2HiPS.hips_service_url,
maxOrder: parseInt(c2HiPS.hips_order),
// TODO
frame: { label: "J2000", system: "J2000" },
tileSize: parseInt(c2HiPS.hips_tile_width),
format: {
FITSImage: {
bitpix: parseInt(c2HiPS.hips_pixel_bitpix)
}
},
minCutout: parseFloat(min_cut_c2),
maxCutout: parseFloat(max_cut_c2),
},
color: {
Grayscale2Color: {
color: parseColor(c2Color),
k: parseFloat($('#k_c2').val()),
transfer: stretch_c2
}
}
});
useC2 = true;
}
if (c3HiPS.length>0) {
c3HiPS = hipsesDict[c3HiPS];
hipsComponents.push({
properties: {
url: c3HiPS.hips_service_url,
maxOrder: parseInt(c3HiPS.hips_order),
// TODO
frame: { label: "J2000", system: "J2000" },
tileSize: parseInt(c3HiPS.hips_tile_width),
format: {
FITSImage: {
bitpix: parseInt(c3HiPS.hips_pixel_bitpix)
}
},
minCutout: parseFloat(min_cut_c3),
maxCutout: parseFloat(max_cut_c3),
},
color: {
Grayscale2Color: {
color: parseColor(c3Color),
k: parseFloat($('#k_c3').val()),
transfer: stretch_c3
}
}
});
useC3 = true;
}
if (c4HiPS.length>0) {
c4HiPS = hipsesDict[c4HiPS];
hipsComponents.push({
properties: {
url: c4HiPS.hips_service_url,
maxOrder: parseInt(c4HiPS.hips_order),
// TODO
frame: { label: "J2000", system: "J2000" },
tileSize: parseInt(c4HiPS.hips_tile_width),
format: {
FITSImage: {
bitpix: parseInt(c4HiPS.hips_pixel_bitpix)
}
},
minCutout: parseFloat(min_cut_c4),
maxCutout: parseFloat(max_cut_c4),
},
color: {
Grayscale2Color: {
color: parseColor(c4Color),
k: parseFloat($('#k_c4').val()),
transfer: stretch_c4
}
}
});
useC4 = true;
}
if (!useC1 && !useC2 && !useC3 && !useC4) {
return;
}
console.log(hipsComponents)
try {
aladin.setImageSurveysLayer(hipsComponents);
} catch {
console.log("start")
}
}
$('#k_c1, #k_c2, #k_c3, #k_c4, #color_c1, #stretch_c1, #min_cut_c1, #max_cut_c1, #color_c2, #stretch_c2, #min_cut_c2, #max_cut_c2, #color_c3, #stretch_c3, #min_cut_c3, #max_cut_c3, #color_c4, #stretch_c4, #min_cut_c4, #max_cut_c4, #colormap_c1').on('change input', function() {
update();
});
$('#min_cut_c1, #max_cut_c1, #min_cut_c2, #max_cut_c2, #min_cut_c3, #max_cut_c3, #min_cut_c4, #max_cut_c4').on('change input', function() {
$(this).nextAll('.slider_tf').first().val($(this).val());
});
$('.slider_tf').on('keyup', function(event) {
// if key press on enter
if(event.keyCode == 13) {
update();
}
});
$('#c1_hips, #c2_hips, #c3_hips, #c4_hips').on('keyup', function(event) {
// if key enter pressed and text looks like a URL
if (event.keyCode == 13 && $(this).val().startsWith('http')) {
console.log($(this).val());
}
});
// show grid
document.querySelector('#showGrid').addEventListener('change', function(e) {
if (this.checked) {
aladin.webglAPI.enableGrid();
}
else {
aladin.webglAPI.disableGrid();
}
});
document.querySelector('#hideLabels').addEventListener('change', function(e) {
if (this.checked) {
aladin.webglAPI.hideGridLabels();
}
else {
aladin.webglAPI.showGridLabels();
}
});
document.querySelector('#cat_selector').addEventListener('change', async function(e) {
let cat_id = document.getElementById("cat_selector").value;
await loadCatalog(cat_id);
});
document.querySelector('#colormap_cat').addEventListener('change', function(e) {
let value = document.getElementById("colormap_cat").value;
aladin.webglAPI.setCatalogColormap("cat1", value);
});
document.querySelector('#opacity_cat').addEventListener('input', function(e) {
let value = document.getElementById("opacity_cat").value;
aladin.webglAPI.setCatalogOpacity("cat1", value);
});
document.querySelector('#strength_cat').addEventListener('input', function(e) {
let value = document.getElementById("strength_cat").value;
aladin.webglAPI.setCatalogKernelStrength("cat1", value);
});
document.querySelector('#color_grid').addEventListener('input', function(e) {
let color = parseColor(document.getElementById("color_grid").value);
aladin.webglAPI.setGridColor(color[0], color[1], color[2], 1.0);
});
document.querySelector('#opacity_grid').addEventListener('input', function(e) {
let alpha = document.getElementById("opacity_grid").value;
let color = parseColor(document.getElementById("color_grid").value);
aladin.webglAPI.setGridColor(color[0], color[1], color[2], alpha);
});
// catalog colormap
// show grid
A.init.then(() => {
// Start up Aladin Lite
aladin = A.aladin('#aladin-lite-div', {survey: 'CDS/P/DSS2/color', cooFrame: "gal"});
aladin.setProjection('aitoff');
//aladin.gotoRaDec(0, 0);
aladin.setFoV(360);
aladin.on('catalogReady', () => {
document.getElementById("loading").innerHTML = "Catalog loaded!";
})
});
</script>
</body>
</html>

View File

@@ -1,74 +0,0 @@
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, user-scalable=no">
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 500px; height: 400px"></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
/*aladin = A.aladin('#aladin-lite-div', {fov: 360, fullScreen: true, cooFrame: 'galactic'});
aladin.setProjection('MOL');
aladin.setBaseImageLayer("P/PanSTARRS/DR1/g", {
imgFormat: 'fits',
colormap: 'redtemperature',
stretch: 'Asinh'
});*/
/*aladin = A.aladin('#aladin-lite-div', {fov: 360, fullScreen: true, cooFrame: 'galactic'});
aladin.setProjection('AIT');
aladin.setBaseImageLayer("P/PanSTARRS/DR1/g", {imgFormat: "fits"});
aladin.getBaseImageLayer().setColormap('redtemperature', {stretch: "Asinh"});*/
aladin = A.aladin('#aladin-lite-div', {fov: 360, fullScreen: true, expandLayersControl: true, cooFrame: 'equatorial', showCooGridControl: true, showSimbadPointerControl: true, showCooGrid: true});
//aladin.setProjection('AIT');
//let survey = aladin.createImageSurvey("P/PanSTARRS/DR1/g", null, null, null, null, );
/*aladin.setBaseImageLayer("P/PanSTARRS/DR1/g");
aladin.getBaseImageLayer().setColormap('viridis', {stretch: "Asinh"});*/
// manage URL parameters
const searchParams = new URL(document.location).searchParams;
if (searchParams.has('baseImageLayer')) {
aladin.setBaseImageLayer(searchParams.get('baseImageLayer'));
}
if (searchParams.has('overlayImageLayer')) {
aladin.setOverlayImageLayer(searchParams.get('overlayImageLayer'));
}
if (searchParams.has('cooFrame')) {
aladin.setFrame(searchParams.get('cooFrame'));
}
if (searchParams.has('fov')) {
aladin.setFoV(parseFloat(searchParams.get('fov')));
}
if (searchParams.has('ra') && searchParams.has('dec')) {
aladin.gotoRaDec(parseFloat(searchParams.get('ra')), parseFloat(searchParams.get('dec')));
}
if (searchParams.has('showReticle')) {
aladin.showReticle(searchParams.get('showReticle')==='true');
}
if (searchParams.has('projection')) {
aladin.setProjection(searchParams.get('projection'));
}
if (searchParams.has('showCooGrid')) {
const b = searchParams.get('showCooGrid') === 'true';
aladin.view.setGridConfig({
enabled: b
});
aladin.view.showCooGrid = b;
}
});
</script>
</body>
</html>

View File

@@ -1,90 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
</head>
<body>
<script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
<div id="aladin-lite-div" style="width: 1024px; height: 768px"></div>
<div id='aladin-statsDiv'></div>
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<script type="text/javascript">
let aladin;
A.init.then(() => {
aladin = A.aladin('#aladin-lite-div', {survey: "CDS/P/DSS2/color", target: 'M51', fov: 180, fullScreen: true});
var json = {
"3": [13, 24],
"4": [36, 37, 48, 49, 51, 87, 91, 93, 94, 100, 101, 112, 430, 1553, 1555,
1556, 1558, 1564, 2576, 2577, 2579, 2585, 2587, 2618, 2704, 2706, 2712,
2714, 2736, 2738, 2745, 2747, 2848],
"5": [156, 157, 200, 201, 203, 241, 244, 319, 341, 343, 359, 361, 362, 363,
369, 370, 371, 380, 381, 382, 408, 409, 412, 413, 452, 453, 454, 456, 457,
458, 464, 465, 468, 1710, 1711, 1724, 1725, 1726, 4463, 4474, 4475, 6209,
6245, 10261, 10263, 10312, 10313, 10315, 10337, 10339, 10345, 10347,
10433, 10435, 10436, 10437, 10438, 10441, 10443, 10444, 10446, 10465,
10466, 10467, 10468, 10470, 10476, 10478, 10820, 10822, 10828, 10830,
10852, 10854, 10860, 10862, 10948, 10950, 10956, 10958, 10959, 10977,
10979, 10985, 10987, 10994, 11000, 11002, 11003, 11305, 11306, 11307,
11400, 11401, 11402],
"6": [238, 239, 250, 251, 254, 255, 506, 535, 541, 612, 613, 615, 633, 636,
637, 808, 809, 811, 916, 917, 960, 961, 963, 980, 981, 982, 1199, 1211,
1213, 1214, 1215, 1256, 1258, 1259, 1262, 1263, 1274, 1275, 1363, 1369,
1371, 1389, 1390, 1391, 1423, 1431, 1433, 1434, 1435, 1441, 1442, 1443,
1473, 1474, 1475, 1532, 1533, 1534, 1640, 1641, 1642, 1656, 1657, 1660,
1661, 1663, 1664, 1665, 1668, 1669, 1680, 1820, 1821, 1822, 1836, 1837,
1838, 1840, 1842, 1876, 1880, 6826, 6827, 6829, 6830, 6831, 6838, 6839,
6862, 6874, 6875, 6878, 6908, 6909, 6910, 7072, 17829, 17831, 17840,
17842, 17843, 17846, 17847, 17848, 17849, 17890, 17914, 17915, 18241,
18244, 18245, 18256, 18257, 18260, 24844, 24845, 24847, 24869, 24871,
24877, 24912, 24944, 24946, 24954, 24976, 24977, 24988, 24989, 24991,
25056, 25057, 25059, 25060, 41041, 41043, 41049, 41051, 41076, 41077,
41257, 41280, 41281, 41282, 41288, 41314, 41315, 41320, 41321, 41322,
41345, 41347, 41353, 41355, 41377, 41379, 41385, 41387, 41408, 41410,
41416, 41418, 41448, 41450, 41727, 41729, 41731, 41737, 41756, 41757,
41758, 41761, 41763, 41769, 41771, 41780, 41788, 41790, 41792, 41856,
41857, 41859, 41886, 41908, 41910, 41916, 41918, 43101, 43103, 43125,
43127, 43133, 43135, 43221, 43223, 43229, 43231, 43253, 43255, 43261,
43262, 43263, 43284, 43286, 43292, 43294, 43316, 43318, 43324, 43326,
43422, 43444, 43446, 43452, 43454, 43605, 43607, 43612, 43613, 43615,
43637, 43639, 43645, 43796, 43798, 43804, 43806, 43828, 43829, 43830,
43904, 43905, 43907, 43912, 43913, 43915, 43937, 43939, 43947, 43968,
43970, 43971, 44004, 44006, 45217, 45219, 45242, 45584, 45586, 45592,
45612, 45613, 45696],
"7": [1706, 1707, 1786, 1787, 1790, 1791, 1962, 1963, 1966, 1967, 1978, 1979,
1982, 1983, 3240, 3241, 3243, 3652, 3653, 3655, 3848, 3849, 3932, 3933,
3934, 4841, 4842, 4843, 5085, 5086, 5087, 5481, 5482, 5483, 5533, 5534,
5535, 5689, 5690, 5691, 6140, 6141, 6142, 6576, 6577, 6578, 6648, 6649,
6651, 6664, 6665, 6724, 6725, 7364, 7365, 7366, 7456, 7457, 7458, 7476,
7477, 7479, 7680, 7681, 27314, 27315, 27341, 27342, 27343, 27350, 27351,
27453, 27454, 27455, 27516, 27518, 27519, 27644, 27645, 27646, 98302,
98303, 99384, 99385, 99387, 99656, 99658, 99680, 99682, 99688, 99690,
99691, 99808, 99809, 99810, 99916, 99917, 99919, 165036, 165037, 165039,
165248, 165250, 165251, 165292, 165293, 165294, 165768, 165770, 165771,
166920, 166956, 166957, 166959, 167433, 167434, 167435, 167504, 167506,
167512, 167514, 167536, 167538, 167539, 172373, 172375, 172381, 172383,
173648, 173650, 173656, 173658, 173680, 173682, 173683, 174417, 174419,
174425, 174427, 175324, 175326, 175327, 175624, 175625, 175627, 175780,
175781, 175783, 175928, 175930, 175931, 176028, 176030, 176031, 180873,
180874, 180875, 180960, 180962, 180963, 182376, 182377, 182378, 182456,
182457, 182458, 182788, 182789, 182790, 182792, 182793, 182794],
"8": [667684, 667685, 667686],
"9": [2670748, 2670749],
"10": [10683000, 10683001]
};
var moc = A.MOCFromJSON(json, {opacity: 0.25, color: 'magenta', lineWidth: 1});
aladin.addMOC(moc);
const skyFraction = moc.skyFraction();
console.assert(0.027083873748779297==skyFraction, "Sky fraction ", skyFraction, "not equal to", 0.02708387374877929);
});
</script>
</body>
</html>

View File

@@ -1,5 +0,0 @@
#!/bin/bash
for filename in *.html; do
google-chrome http://localhost:8080/${filename}
done

View File

@@ -1,86 +0,0 @@
<h1>MOLLWEIDE Projection and GW MOC</h1>
<!-- Aladin Lite CSS style file -->
<link rel="stylesheet" href="https://aladin.u-strasbg.fr/AladinLite/api/v2/latest/aladin.min.css" />
<!-- Aladin Lite has a dependency on the jQuery library -->
<script type="text/javascript" src="https://code.jquery.com/jquery-1.9.1.min.js" charset="utf-8"></script>
<style>
#aladin-lite-div {
width: 1024px;
height: 768px;
}
</style>
<div id="aladin-lite-div"></div>
<input id="DSS" type="radio" name="survey" value='P/DSS2/Color' checked><label for="DSS">DSS color<label>
<input id="DSS-blue" type="radio" name="survey" value="P/DSS2/blue"><label for="DSS-blue">DSS blue<label>
<input id="2MASS" type="radio" name="survey" value="P/2MASS/color"><label for="2MASS">2MASS<label>
<input id="allwise" type="radio" name="survey" value="P/allWISE/color"><label for="allwise">AllWISE<label>
<!--<input id="glimpse" type="radio" name="survey" value="P/GLIMPSE360"><label for="glimpse">GLIMPSE 360<label>-->
<script type="text/javascript" src="./../aladin.js" charset="utf-8"></script>
<!-- Creation of Aladin Lite instance with initial parameters -->
<script type="text/javascript">
let surveys = {
"P/DSS2/color": {"properties":{"url":"https://alasky.u-strasbg.fr/DSS/DSSColor","maxOrder":9,"frame":{"label":"J2000","system":"J2000"},"tileSize":512,"format":{"Image":{"format":"jpeg"}},"minCutout":null,"maxCutout":null},"color":"Color"},
"P/DSS2/blue": {"properties":{"url":"https://alasky.u-strasbg.fr/DSS/DSS2-blue-XJ-S","maxOrder":9,"frame":{"label":"J2000","system":"J2000"},"tileSize":512,"format":{"FITSImage":{"bitpix":16}},"minCutout":4286,"maxCutout":19959},"color":{"Grayscale2Color":{"color":[1,1,1],"k":1,"transfer":"asinh"}}},
"P/2MASS/color": {"properties":{"url":"https://alasky.u-strasbg.fr/2MASS/Color","maxOrder":9,"frame":{"label":"J2000","system":"J2000"},"tileSize":512,"format":{"Image":{"format":"jpeg"}},"minCutout":null,"maxCutout":null},"color":"Color"},
"P/allWISE/color": {"properties":{"url":"https://alasky.u-strasbg.fr/AllWISE/RGB-W4-W2-W1","maxOrder":8,"frame":{"label":"J2000","system":"J2000"},"tileSize":512,"format":{"Image":{"format":"jpeg"}},"minCutout":0,"maxCutout":3},"color":"Color"},
};
var json = {
"2":[5,6,164,165,166,172],
"3":[15,19,28,29,31,36,37,54,106,221,380,382,383,448,450,
451,480,647,652,653,668,670,671,677,679,685,692,693,738],
"4":[53,54,55,59,69,70,71,73,74,75,120,123,152,153,187,
190,191,192,193,194,196,209,211,212,213,214,220,227,229,230,
231,232,233,236,240,241,242,388,390,394,397,416,418,419,428,
430,431,432,435,441,442,443,444,446,447,490,859,862,880,881,
883,892,893,1345,1348,1498,1499,1501,1503,1511,1517,1519,1525,1526,1527,
1798,1799,1816,1818,1819,1834,2493,2536,2538,2539,2582,2583,2585,2586,2587,
2599,2605,2606,2607,2616,2621,2622,2623,2676,2691,2692,2694,2697,2698,2699,
2705,2707,2713,2714,2715,2720,2736,2737,2739,2745,2748,2749,2776,2777,2778,
2780,2781,2784,2785,2786,2946,2958,2976,2977,2978,2980,2981],
"5":[127,207,211,229,230,231,233,235,269,271,273,274,275,289,291,
485,487,488,489,490,541,543,565,620,624,625,626,628,746,747,
754,755,757,758,759,780,781,782,788,789,790,792,793,794,829,
830,831,832,833,835,841,842,843,860,861,862,884,886,888,890,
903,907,913,914,915,936,937,938,940,948,949,972,974,992,993,
1210,1558,1564,1566,1567,1570,1585,1587,1596,1597,1599,1632,1634,1640,1642,
1643,1668,1670,1671,1685,1687,1688,1690,1718,1732,1734,1735,1736,1737,1739,
1752,1754,1755,1761,1762,1763,1780,1782,1783,3435,3452,3454,3455,3529,3556,
3557,3559,3565,3576,3577,3580,3581,3583,5376,5377,5396,5398,5399,5943,5948,
5949,5951,5976,5978,5979,5982,5987,5990,6001,6003,6009,6011,6035,6037,6038,
6039,6041,6043,6065,6067,6073,6075,6097,6098,6099,7184,7186,7187,7190,7242,
7270,7330,7342,7704,7706,7707,7712,7713,7714,7716,7717,7728,9536,9537,9540,
9947,9950,9951,9969,9980,9981,9983,10148,10150,10151,10168,10170,10171,10174,10301,
10303,10317,10319,10323,10326,10327,10337,10338,10339,10388,10389,10391,10393,10395,10413,
10415,10417,10418,10419,10468,10470,10472,10473,10474,10477,10478,10479,10481,10482,10483,
10708,10712,10714,10715,10757,10758,10759,10761,10763,10772,10773,10774,10785,10787,10800,
10802,10827,10849,10850,10851,10884,10888,10889,10890,10953,10954,10955,10977,11000,11116,
11117,11128,11129,11132,11133,11148,11152,11153,11154,11156,11157,11168,11200,11776,11778,
11788,11790,11791,11824,11826,11827,11836,11838,11839,11916,11917,11918,11928,11936,11946,
11947,11950,11968],
"6":[1945,1947,3025,3026,3027,3452,3453,3454,3556,3557,3558,3625,3626,3627,3756,
3757,3758,3764,3765,3766,3800,3801,3802,6392,6393,6395,6564,6566,6567,6584,
6586,6587,6876,6878,6879,6932,6934,6935,6984,6986,6987,7012,7014,7015,7032,
7034,7035,7124,7126,7127,7816,7818,7819,14328,14329,14331,23800,23801,23803,24145,
24146,24147,41273,41274,41275,41301,41302,41303,41561,41562,41563,41665,41666,41667,41876,
41877,41878,43145,43146,43147,47776,47778,47779],
"8":[390205,390206,390207]
};
var aladin;
A.init.then(() => {
// Start up Aladin Lite
aladin = A.aladin('#aladin-lite-div', {fov: 360, survey: "P/DSS2/color", showCooGrid: false});
aladin.setProjection('MOL');
var moc = A.MOCFromJSON(json, {color: 'magenta', lineWidth: 1, opacity: 0.6});
aladin.addMOC(moc);
});
</script>

View File

@@ -1,31 +0,0 @@
{
"homepage": "https://bmatthieu3.github.io/hips_webgl_renderer/",
"name": "hips_webgl_renderer",
"scripts": {
"predeploy": "npm run build",
"deploy": "./deploy.sh",
"build": "webpack && sed \"s/\\\\.\\\\/\\\\.\\\\.\\\\/aladin\\\\.js/https:\\\\/\\\\/aladin.cds.unistra.fr\\\\/AladinLite\\\\/api\\\\/v3\\\\/latest\\\\/aladin.js/g\" examples/index.html > dist/index.html",
"serve": "webpack-dev-server"
},
"devDependencies": {
"@babel/core": "^7.18.5",
"@babel/preset-env": "^7.18.2",
"@wasm-tool/wasm-pack-plugin": "^1.6.0",
"babel-loader": "^8.2.5",
"npm": "^8.19.2",
"terser-webpack-plugin": "^5.3.3",
"webpack": "^5.74.0",
"webpack-cli": "^4.9.0",
"webpack-dev-server": "^4.7.4",
"webpack-glsl-loader": "^1.0.1",
"webpack-glsl-minify": "^1.5.0"
},
"dependencies": {
"autocompleter": "^6.1.3",
"babel-preset-es2015": "^6.24.1",
"css-loader": "^5.0.1",
"file-loader": "^6.1.0",
"style-loader": "^3.3.1",
"wasm-pack": "^0.10.3"
}
}

View File

@@ -1,3 +1,6 @@
2020-08
- polyline improvements (by @imbasimba)
2020-07
- new method stopAnimation

View File

@@ -1,127 +0,0 @@
[package]
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 = "0.1.0"
authors = ["baumannmatthieu0@gmail.com", "matthieu.baumann@astro.unistra.fr"]
edition = "2018"
[workspace]
members = [
"al-core",
"al-api",
"al-task-exec",
#"al-ui"
]
[lib]
crate-type = ["cdylib"]
[dependencies]
#paste = "1.0.9"
#console_error_panic_hook = "0.1.6"
#wee_alloc = "0.4.5"
futures = "0.3.12"
js-sys = "0.3.47"
wasm-bindgen-futures = "0.4.20"
cgmath = "*"
cdshealpix = { package = "cdshealpix", git = 'https://github.com/cds-astro/cds-healpix-rust', branch = 'master' }
moclib = { package = "moc", git = 'https://github.com/cds-astro/cds-moc-rust', branch = 'main' }
serde = { version = "^1.0.59", features = ["derive"] }
serde_json = "1.0"
serde-wasm-bindgen = "0.4"
#num = "*"
#egui = "*"
#epi = "*"
enum_dispatch = "0.3.8"
wasm-bindgen = "0.2.79"
al-core = { path = "./al-core" }
#al-ui = { path = "./al-ui" }
al-task-exec = { path = "./al-task-exec" }
al-api = { path = "./al-api" }
[features]
webgl1 = [
"al-core/webgl1",
#"al-ui/webgl1",
"al-api/webgl1",
"web-sys/WebGlRenderingContext",
"web-sys/AngleInstancedArrays", # Enabling instancing features
"web-sys/ExtSRgb", # Enabling SRGB8_ALPHA8 internal format
"web-sys/OesTextureFloat"
]
webgl2 = [
"al-core/webgl2",
#"al-ui/webgl2",
"al-api/webgl2",
"web-sys/WebGl2RenderingContext",
"web-sys/WebGlVertexArrayObject",
"web-sys/ExtColorBufferFloat",
]
[dependencies.web-sys]
version = "0.3.56"
features = [
'console',
'CssStyleDeclaration',
'Document',
'Element',
'HtmlCollection',
'HtmlElement',
'HtmlImageElement',
'HtmlCanvasElement',
'Blob',
'ImageBitmap',
'ImageData',
'CanvasRenderingContext2d',
'WebGlBuffer',
'WebGlContextAttributes',
'WebGlFramebuffer',
'WebGlProgram',
'WebGlShader',
'WebGlUniformLocation',
'WebGlTexture',
'WebGlActiveInfo',
'Window',
'Request',
'RequestInit',
'RequestMode',
'Response',
'XmlHttpRequest',
'XmlHttpRequestResponseType',
'PerformanceTiming',
'Performance',
'Url',
]
[dev-dependencies]
image-decoder = { package = "image", version = "0.24.2", default-features = false, features = ["jpeg", "png"] }
[profile.dev]
opt-level = 's'
debug = true
debug-assertions = true
overflow-checks = true
lto = true
panic = 'unwind'
incremental = true
codegen-units = 256
rpath = false
[profile.release]
opt-level = 'z'
debug = false
debug-assertions = false
overflow-checks = false
lto = true
panic = 'unwind'
incremental = false
codegen-units = 16
rpath = false
[package.metadata.wasm-pack.profile.release]
wasm-opt = true

View File

@@ -1,88 +0,0 @@
[package]
name = "al-api"
version = "0.1.0"
authors = ["baumannmatthieu0@gmail.com", "matthieu.baumann@astro.unistra.fr"]
edition = "2018"
[dependencies]
js-sys = "0.3.47"
cgmath = "*"
serde = { version = "^1.0.59", features = ["derive"] }
serde-wasm-bindgen = "0.4"
wasm-bindgen = "0.2.79"
[features]
webgl1 = [
"web-sys/WebGlRenderingContext",
"web-sys/AngleInstancedArrays", # Enabling instancing features
"web-sys/ExtSRgb", # Enabling SRGB8_ALPHA8 internal format
"web-sys/OesTextureFloat"
]
webgl2 = [
"web-sys/WebGl2RenderingContext",
"web-sys/WebGlVertexArrayObject",
"web-sys/ExtColorBufferFloat",
]
[dependencies.web-sys]
version = "0.3.56"
features = [
'console',
'CssStyleDeclaration',
'Document',
'Element',
'HtmlCollection',
'HtmlElement',
'HtmlImageElement',
'HtmlCanvasElement',
'Blob',
'ImageBitmap',
'ImageData',
'CanvasRenderingContext2d',
'WebGlBuffer',
'WebGlContextAttributes',
'WebGlFramebuffer',
'WebGlProgram',
'WebGlShader',
'WebGlUniformLocation',
'WebGlTexture',
'WebGlActiveInfo',
'Window',
'Request',
'RequestInit',
'RequestMode',
'Response',
'XmlHttpRequest',
'XmlHttpRequestResponseType',
'PerformanceTiming',
'Performance',
'Url',
]
[profile.dev]
opt-level = 's'
debug = true
debug-assertions = true
overflow-checks = true
lto = false
panic = 'unwind'
incremental = true
codegen-units = 256
rpath = false
[profile.release]
opt-level = 's'
debug = false
debug-assertions = false
overflow-checks = false
lto = true
panic = 'unwind'
incremental = false
codegen-units = 16
rpath = false
[package.metadata.wasm-pack.profile.release]
wasm-opt = true

View File

@@ -1,118 +0,0 @@
use serde::Deserialize;
use wasm_bindgen::prelude::wasm_bindgen;
#[cfg(feature = "webgl2")]
pub type WebGlRenderingCtx = web_sys::WebGl2RenderingContext;
#[cfg(feature = "webgl1")]
pub type WebGlRenderingCtx = web_sys::WebGlRenderingContext;
#[derive(Deserialize, Debug, Clone, Copy)]
#[serde(rename_all = "camelCase")]
#[wasm_bindgen]
pub struct BlendCfg {
pub src_color_factor: BlendFactor,
pub dst_color_factor: BlendFactor,
pub func: BlendFunc,
}
impl Default for BlendCfg {
fn default() -> Self {
Self {
src_color_factor: BlendFactor::SrcAlpha,
dst_color_factor: BlendFactor::OneMinusConstantAlpha,
func: BlendFunc::FuncAdd,
}
}
}
#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
#[wasm_bindgen]
pub enum BlendFactor {
Zero,
One,
SrcColor,
OneMinusSrcColor,
DstColor,
OneMinusDstColor,
SrcAlpha,
OneMinusSrcAlpha,
DstAlpha,
OneMinusDstAlpha,
ConstantColor,
OneMinusConstantColor,
ConstantAlpha,
OneMinusConstantAlpha,
}
#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
#[wasm_bindgen]
pub enum BlendFunc {
FuncAdd,
FuncSubstract,
FuncReverseSubstract,
}
/*impl BlendFunc {
fn gl(&self) -> u32 {
match self {
BlendFunc::FuncAdd => WebGlRenderingCtx::FUNC_ADD,
BlendFunc::FuncSubstract => WebGlRenderingCtx::FUNC_SUBTRACT,
BlendFunc::FuncReverseSubstract => WebGlRenderingCtx::FUNC_REVERSE_SUBTRACT,
//BlendFunc::Min => WebGlRenderingCtx::MIN,
//BlendFunc::Max => WebGlRenderingCtx::MAX,
}
}
}*/
use std::fmt;
impl fmt::Display for BlendFactor {
// This trait requires `fmt` with this exact signature.
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// Write strictly the first element into the supplied output
// stream: `f`. Returns `fmt::Result` which indicates whether the
// operation succeeded or failed. Note that `write!` uses syntax which
// is very similar to `println!`.
let str = match self {
BlendFactor::ConstantAlpha => "ConstantAlpha",
BlendFactor::ConstantColor => "ConstantColor",
BlendFactor::Zero => "Zero",
BlendFactor::One => "One",
BlendFactor::DstAlpha => "DstAlpha",
BlendFactor::DstColor => "DstColor",
BlendFactor::OneMinusConstantAlpha => "OneMinusConstantAlpha",
BlendFactor::OneMinusDstColor => "OneMinusDstColor",
BlendFactor::OneMinusDstAlpha => "OneMinusDstAlpha",
BlendFactor::SrcAlpha => "SrcAlpha",
BlendFactor::SrcColor => "SrcColor",
BlendFactor::OneMinusSrcColor => "OneMinusSrcColor",
BlendFactor::OneMinusSrcAlpha => "OneMinusSrcAlpha",
BlendFactor::OneMinusConstantColor => "OneMinusConstantColor",
};
write!(f, "{}", str)
}
}
impl fmt::Display for BlendFunc {
// This trait requires `fmt` with this exact signature.
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// Write strictly the first element into the supplied output
// stream: `f`. Returns `fmt::Result` which indicates whether the
// operation succeeded or failed. Note that `write!` uses syntax which
// is very similar to `println!`.
let str = match self {
BlendFunc::FuncAdd => "Add",
BlendFunc::FuncSubstract => "Subtract",
BlendFunc::FuncReverseSubstract => "Reverse Subtract",
/*#[cfg(feature = "webgl2")]
BlendFunc::Min => "Min",
#[cfg(feature = "webgl2")]
BlendFunc::Max => "Max",*/
};
write!(f, "{}", str)
}
}

View File

@@ -1,9 +0,0 @@
use serde::{Serialize, Deserialize};
#[derive(Clone)]
#[derive(Deserialize, Serialize)]
pub struct HEALPixCellProjeted {
pub ipix: u64,
pub vx: [f64; 4],
pub vy: [f64; 4],
}

View File

@@ -1,83 +0,0 @@
use wasm_bindgen::prelude::*;
#[wasm_bindgen(raw_module = "../src/js/Color")]
extern "C" {
pub type Color;
#[wasm_bindgen(static_method_of = Color)]
pub fn hexToRgb(hex: String) -> JsValue;
}
#[derive(Debug, Clone, Copy)]
#[derive(Deserialize, Serialize)]
#[wasm_bindgen]
pub struct ColorRGB {
pub r: f32,
pub g: f32,
pub b: f32,
}
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy)]
#[derive(Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
#[wasm_bindgen]
pub struct ColorRGBA {
pub r: f32,
pub g: f32,
pub b: f32,
pub a: f32,
}
use std::ops::Mul;
impl<'a> Mul<f32> for &'a ColorRGB {
// The multiplication of rational numbers is a closed operation.
type Output = ColorRGB;
fn mul(self, rhs: f32) -> Self::Output {
ColorRGB {
r: self.r * rhs,
g: self.g * rhs,
b: self.b * rhs,
}
}
}
/*
#[wasm_bindgen]
impl Color {
#[wasm_bindgen(constructor)]
pub fn new(red: f32, green: f32, blue: f32, alpha: f32) -> Color {
Color {
red,
green,
blue,
}
}
}
impl Default for Color {
fn default() -> Self {
Color {
r: 1.0,
g: 1.0,
b: 1.0,
}
}
}
*/
use std::convert::TryFrom;
impl TryFrom<JsValue> for ColorRGB {
type Error = JsValue;
fn try_from(rgb: JsValue) -> Result<Self, JsValue> {
let mut c: ColorRGB = serde_wasm_bindgen::from_value(rgb)?;
c.r /= 255.0;
c.g /= 255.0;
c.b /= 255.0;
Ok(c)
}
}

View File

@@ -1,26 +0,0 @@
use wasm_bindgen::prelude::*;
use serde::{Deserialize, Serialize};
#[wasm_bindgen]
#[derive(Clone, Debug, Copy, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum Colormap {
Blues = 0,
Cividis = 1,
Cubehelix = 2,
Eosb = 3,
Grayscale = 4,
Inferno = 5,
Magma = 6,
Parula = 7,
Plasma = 8,
Rainbow = 9,
Rdbu = 10,
Rdyibu = 11,
Redtemperature = 12,
Spectral = 13,
Summer = 14,
Viridis = 15,
Yignbu = 16,
Yiorbr = 17,
}

View File

@@ -1,119 +0,0 @@
use cgmath::Matrix4;
pub trait CooBaseFloat: Sized + 'static {
const GALACTIC_TO_J2000: &'static Matrix4<Self>;
const J2000_TO_GALACTIC: &'static Matrix4<Self>;
const ID: &'static Matrix4<Self>;
}
impl CooBaseFloat for f32 {
const GALACTIC_TO_J2000: &'static Matrix4<Self> = &Matrix4::new(
-0.444_829_64,
0.746_982_2,
0.494_109_42,
0.0,
-0.198_076_37,
0.455_983_8,
-0.867_666_1,
0.0,
-0.873_437_1,
-0.483_835,
-0.054_875_56,
0.0,
0.0,
0.0,
0.0,
1.0,
);
const J2000_TO_GALACTIC: &'static Matrix4<Self> = &Matrix4::new(
-0.444_829_64,
-0.198_076_37,
-0.873_437_1,
0.0,
0.746_982_2,
0.455_983_8,
-0.483_835,
0.0,
0.494_109_42,
-0.867_666_1,
-0.054_875_56,
0.0,
0.0,
0.0,
0.0,
1.0,
);
const ID: &'static Matrix4<Self> = &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,
);
}
impl CooBaseFloat for f64 {
const GALACTIC_TO_J2000: &'static Matrix4<Self> = &Matrix4::new(
-0.4448296299195045,
0.7469822444763707,
0.4941094279435681,
0.0,
-0.1980763734646737,
0.4559837762325372,
-0.867_666_148_981_161,
0.0,
-0.873437090247923,
-0.4838350155267381,
-0.0548755604024359,
0.0,
0.0,
0.0,
0.0,
1.0,
);
const J2000_TO_GALACTIC: &'static Matrix4<Self> = &Matrix4::new(
-0.4448296299195045,
-0.1980763734646737,
-0.873437090247923,
0.0,
0.7469822444763707,
0.4559837762325372,
-0.4838350155267381,
0.0,
0.4941094279435681,
-0.867_666_148_981_161,
-0.0548755604024359,
0.0,
0.0,
0.0,
0.0,
1.0,
);
const ID: &'static Matrix4<Self> = &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,
);
}
use cgmath::BaseFloat;
use serde::Deserialize;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
#[derive(Clone, Copy, PartialEq, Eq, Debug, Deserialize, Hash)]
pub enum CooSystem {
ICRSJ2000 = 0,
GAL = 1,
}
pub const NUM_COOSYSTEM: usize = 2;
impl CooSystem {
#[inline]
pub fn to<S>(&self, coo_system: &Self) -> &Matrix4<S>
where
S: BaseFloat + CooBaseFloat,
{
match (self, coo_system) {
(CooSystem::GAL, CooSystem::ICRSJ2000) => S::GALACTIC_TO_J2000,
(CooSystem::ICRSJ2000, CooSystem::GAL) => S::J2000_TO_GALACTIC,
(_, _) => S::ID,
}
}
}

View File

@@ -1,35 +0,0 @@
use wasm_bindgen::prelude::*;
use serde::{Deserialize, Serialize};
use super::color::ColorRGB;
#[wasm_bindgen]
#[derive(Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GridCfg {
#[serde(default = "default_color")]
pub color: Option<ColorRGB>,
pub opacity: Option<f32>,
#[serde(default = "default_labels")]
pub show_labels: Option<bool>,
#[serde(default = "default_label_size")]
pub label_size: Option<f32>,
#[serde(default = "default_enabled")]
pub enabled: Option<bool>,
}
fn default_labels() -> Option<bool> {
None
}
fn default_enabled() -> Option<bool> {
None
}
fn default_color() -> Option<ColorRGB> {
None
}
fn default_label_size() -> Option<f32> {
None
}

View File

@@ -1,383 +0,0 @@
use wasm_bindgen::JsValue;
use super::blend::BlendCfg;
use serde::Deserialize;
#[derive(Deserialize, Debug)]
pub struct CompositeHiPS {
hipses: Vec<SimpleHiPS>,
}
use std::iter::IntoIterator;
impl IntoIterator for CompositeHiPS {
type Item = SimpleHiPS;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.hipses.into_iter()
}
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct SimpleHiPS {
/// Layer name
pub layer: String,
/// The HiPS metadata
pub properties: HiPSProperties,
pub meta: ImageSurveyMeta,
pub img_format: HiPSTileFormat,
}
/*#[wasm_bindgen]
impl SimpleHiPS {
#[wasm_bindgen(constructor)]
pub fn new(layer: String, properties: HiPSProperties, meta: ImageSurveyMeta) -> Self {
Self {
layer,
properties,
meta,
backend: None
}
}
}*/
impl SimpleHiPS {
pub fn get_layer(&self) -> String {
self.layer.clone()
}
pub fn get_properties(&self) -> &HiPSProperties {
&self.properties
}
}
use crate::coo_system::CooSystem;
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct HiPSProperties {
// Associated with the HiPS
url: String,
max_order: u8,
frame: CooSystem,
tile_size: i32,
bitpix: Option<i32>,
formats: Vec<HiPSTileFormat>,
sky_fraction: f32,
min_order: u8,
hips_initial_fov: Option<f64>,
hips_initial_ra: Option<f64>,
hips_initial_dec: Option<f64>,
// Parametrable by the user
pub min_cutout: Option<f32>,
pub max_cutout: Option<f32>,
}
impl HiPSProperties {
/*pub fn new(
url: String,
max_order: u8,
frame: CooSystem,
tile_size: i32,
min_cutout: Option<f32>,
max_cutout: Option<f32>,
bitpix: Option<i32>,
formats: Vec<HiPSTileFormat>,
sky_fraction: f32,
min_order: u8,
hips_initial_fov: Option<f64>,
hips_initial_ra: Option<f64>,
hips_initial_dec: Option<f64>,
) -> Self {
Self {
url,
max_order,
min_order,
frame,
tile_size,
formats,
bitpix,
min_cutout,
max_cutout,
sky_fraction,
hips_initial_fov,
hips_initial_dec,
hips_initial_ra,
}
}*/
#[inline]
pub fn get_url(&self) -> String {
self.url.clone()
}
#[inline]
pub fn get_max_order(&self) -> u8 {
self.max_order
}
#[inline]
pub fn get_min_order(&self) -> u8 {
self.min_order
}
#[inline]
pub fn get_bitpix(&self) -> Option<i32> {
self.bitpix
}
#[inline]
pub fn get_formats(&self) -> &[HiPSTileFormat] {
&self.formats[..]
}
#[inline]
pub fn get_tile_size(&self) -> i32 {
self.tile_size
}
#[inline]
pub fn get_frame(&self) -> CooSystem {
self.frame
}
#[inline]
pub fn get_sky_fraction(&self) -> f32 {
self.sky_fraction
}
#[inline]
pub fn get_initial_fov(&self) -> Option<f64> {
self.hips_initial_fov
}
#[inline]
pub fn get_initial_ra(&self) -> Option<f64> {
self.hips_initial_ra
}
#[inline]
pub fn get_initial_dec(&self) -> Option<f64> {
self.hips_initial_dec
}
}
#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
#[wasm_bindgen]
pub enum HiPSTileFormat {
FITS,
JPEG,
PNG,
}
use serde::Serialize;
/*#[wasm_bindgen]
#[derive(Deserialize, Serialize, Debug)]
#[derive(Clone, Copy)]
#[serde(rename_all = "camelCase")]
pub struct GrayscaleParameter {
pub h: TransferFunction,
pub min_value: f32,
pub max_value: f32,
}
impl Default for GrayscaleParameter {
fn default() -> Self {
Self {
h: TransferFunction::Asinh,
min_value: 0.0,
max_value: 1.0
}
}
}*/
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
#[derive(Clone, Copy, PartialEq, Debug, Deserialize, Serialize)]
pub enum TransferFunction {
Linear,
Sqrt,
Log,
Asinh,
Pow2,
}
impl TransferFunction {
pub fn new(id: &str) -> Self {
if id.contains("linear") {
TransferFunction::Linear
} else if id.contains("pow2") {
TransferFunction::Pow2
} else if id.contains("log") {
TransferFunction::Log
} else if id.contains("sqrt") {
TransferFunction::Sqrt
} else {
TransferFunction::Asinh
}
}
}
impl From<String> for TransferFunction {
fn from(id: String) -> Self {
TransferFunction::new(&id)
}
}
use crate::colormap::Colormap;
#[derive(Deserialize, Debug, Clone, Copy)]
#[serde(rename_all = "camelCase")]
pub enum HiPSColor {
// FITS tile
Grayscale {
#[serde(rename = "stretch")]
tf: TransferFunction,
#[serde(rename = "minCut")]
min_cut: Option<f32>,
#[serde(rename = "maxCut")]
max_cut: Option<f32>,
color: GrayscaleColor,
},
// JPG/PNG tile
Color,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
#[derive(Clone, Copy)]
pub enum GrayscaleColor {
Colormap { reversed: bool, name: Colormap },
Color([f32; 4]),
}
/*
impl Default for HiPSColor {
fn default() -> Self {
HiPSColor::Grayscale2Color {
color: [1.0, 0.0, 0.0],
param: GrayscaleParameter {
h: TransferFunction::Asinh,
min_value: 0.0,
max_value: 1.0,
},
k: 1.0
}
}
}*/
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
#[derive(Clone)]
#[wasm_bindgen]
pub struct ImageSurveyMeta {
/// Color config
#[wasm_bindgen(skip)]
pub color: HiPSColor,
// Blending config
#[serde(default)]
pub blend_cfg: BlendCfg,
#[serde(default = "default_opacity")]
pub opacity: f32,
pub longitude_reversed: bool,
}
fn default_opacity() -> f32 {
1.0
}
use crate::Abort;
#[wasm_bindgen]
impl ImageSurveyMeta {
#[wasm_bindgen(setter = color)]
pub fn set_color(&mut self, color: JsValue) -> std::result::Result<(), JsValue> {
self.color = serde_wasm_bindgen::from_value(color)?;
Ok(())
}
#[wasm_bindgen(getter = color)]
pub fn color(&self) -> JsValue {
let js_color_obj = js_sys::Object::new();
let color = match &self.color {
HiPSColor::Color => JsValue::from_str("Colored"),
HiPSColor::Grayscale {
tf,
min_cut,
max_cut,
color,
} => {
let js_grayscale = js_sys::Object::new();
js_sys::Reflect::set(
&js_grayscale,
&"stretch".into(),
&serde_wasm_bindgen::to_value(&tf).unwrap_abort(),
)
.unwrap_abort();
js_sys::Reflect::set(
&js_grayscale,
&"minCut".into(),
&serde_wasm_bindgen::to_value(&min_cut).unwrap_abort(),
)
.unwrap_abort();
js_sys::Reflect::set(
&js_grayscale,
&"maxCut".into(),
&serde_wasm_bindgen::to_value(&max_cut).unwrap_abort(),
)
.unwrap_abort();
let js_color = match color {
GrayscaleColor::Color(color) => {
let js_color = js_sys::Object::new();
js_sys::Reflect::set(
&js_color,
&"color".into(),
&serde_wasm_bindgen::to_value(&color).unwrap_abort(),
)
.unwrap_abort();
js_color
}
GrayscaleColor::Colormap { reversed, name } => {
let js_colormap = js_sys::Object::new();
js_sys::Reflect::set(
&js_colormap,
&"reversed".into(),
&JsValue::from_bool(*reversed),
)
.unwrap_abort();
js_sys::Reflect::set(
&js_colormap,
&"colormap".into(),
&serde_wasm_bindgen::to_value(&name).unwrap_abort(),
)
.unwrap_abort();
js_colormap
}
};
js_sys::Reflect::set(&js_grayscale, &"color".into(), &js_color).unwrap_abort();
js_grayscale.into()
}
};
js_sys::Reflect::set(&js_color_obj, &"color".into(), &color).unwrap_abort();
js_color_obj.into()
}
}
impl ImageSurveyMeta {
pub fn visible(&self) -> bool {
self.opacity > 0.0
}
}

View File

@@ -1,43 +0,0 @@
/* This crate defines the API types that the core can manage
It is used by al-ui and any javascript application calling
the WASM core of aladin lite v3
*/
pub mod blend;
pub mod color;
pub mod colormap;
pub mod coo_system;
pub mod grid;
pub mod hips;
pub mod moc;
pub mod resources;
pub mod cell;
pub trait Abort {
type Item;
fn unwrap_abort(self) -> Self::Item where Self: Sized;
}
impl<T> Abort for Option<T> {
type Item = T;
#[inline]
fn unwrap_abort(self) -> Self::Item {
use std::process;
match self {
Some(t) => t,
None => process::abort(),
}
}
}
impl<T, E> Abort for Result<T, E> {
type Item = T;
#[inline]
fn unwrap_abort(self) -> Self::Item {
use std::process;
match self {
Ok(t) => t,
Err(_) => process::abort(),
}
}
}

View File

@@ -1,76 +0,0 @@
use wasm_bindgen::prelude::wasm_bindgen;
use super::color::{Color, ColorRGB};
#[derive(Clone, Debug)]
#[wasm_bindgen]
pub struct MOC {
uuid: String,
opacity: f32,
line_width: f32,
is_showing: bool,
color: ColorRGB,
adaptative_display: bool,
}
use std::convert::TryInto;
use crate::Abort;
#[wasm_bindgen]
impl MOC {
#[wasm_bindgen(constructor)]
pub fn new(uuid: String, opacity: f32, line_width: f32, is_showing: bool, hex_color: String, adaptative_display: bool) -> Self {
let color = Color::hexToRgb(hex_color);
let color = color.try_into().unwrap_abort();
Self {
uuid,
opacity,
line_width,
color,
is_showing,
adaptative_display
}
}
#[wasm_bindgen(setter)]
pub fn set_is_showing(&mut self, is_showing: bool) {
self.is_showing = is_showing;
}
}
impl MOC {
pub fn get_uuid(&self) -> &String {
&self.uuid
}
pub fn get_color(&self) -> &ColorRGB {
&self.color
}
pub fn get_opacity(&self) -> f32 {
self.opacity
}
pub fn get_line_width(&self) -> f32 {
self.line_width
}
pub fn is_showing(&self) -> bool {
self.is_showing
}
pub fn is_adaptative_display(&self) -> bool {
self.adaptative_display
}
}
impl Default for MOC {
fn default() -> Self {
Self {
uuid: String::from("moc"),
opacity: 1.0,
line_width: 1.0,
is_showing: true,
color: ColorRGB {r: 1.0, g: 0.0, b: 0.0},
adaptative_display: true,
}
}
}

View File

@@ -1,11 +0,0 @@
use std::collections::HashMap;
use serde::Deserialize;
#[derive(Debug, Deserialize)]
pub struct Resources(HashMap<String, String>);
impl Resources {
pub fn get_filename<'a>(&'a self, name: &str) -> Option<&String> {
self.0.get(name)
}
}

View File

@@ -1,98 +0,0 @@
[package]
name = "al-core"
version = "0.1.0"
authors = ["baumannmatthieu0@gmail.com", "matthieu.baumann@astro.unistra.fr"]
edition = "2018"
[dependencies]
js-sys = "0.3.47"
cgmath = "*"
jpeg-decoder = "0.2"
png = "0.17.6"
fitsrs = { package = "fitsrs", git = 'https://github.com/cds-astro/fitsrs', branch = 'master' }
al-api = { path = "../al-api" }
serde = { version = "^1.0.59", features = ["derive"] }
serde_json = "1.0"
serde-wasm-bindgen = "0.4"
[dependencies.wasm-bindgen]
version = "0.2.79"
[dev-dependencies]
fontdue = "0.7.2"
[features]
webgl1 = [
"web-sys/WebGlRenderingContext",
"web-sys/AngleInstancedArrays", # Enabling instancing features
"web-sys/ExtSRgb", # Enabling SRGB8_ALPHA8 internal format
"web-sys/OesTextureFloat"
]
webgl2 = [
"web-sys/WebGl2RenderingContext",
"web-sys/WebGlVertexArrayObject",
"web-sys/ExtColorBufferFloat",
]
[dependencies.web-sys]
version = "0.3.56"
features = [
'console',
'CssStyleDeclaration',
'Document',
'Element',
'HtmlCollection',
'HtmlElement',
'HtmlImageElement',
'HtmlCanvasElement',
'Blob',
'ImageBitmap',
'ImageData',
'CanvasRenderingContext2d',
'WebGlBuffer',
'WebGlContextAttributes',
'WebGlFramebuffer',
'WebGlProgram',
'WebGlShader',
'WebGlUniformLocation',
'WebGlTexture',
'WebGlActiveInfo',
'Window',
'Request',
'RequestInit',
'RequestMode',
'Response',
'XmlHttpRequest',
'XmlHttpRequestResponseType',
'PerformanceTiming',
'Performance',
'Url',
]
[profile.dev]
opt-level = 's'
debug = true
debug-assertions = true
overflow-checks = true
lto = false
panic = 'unwind'
incremental = true
codegen-units = 256
rpath = false
[profile.release]
opt-level = 'z'
debug = false
debug-assertions = false
overflow-checks = false
lto = true
panic = 'unwind'
incremental = false
codegen-units = 16
rpath = false
[package.metadata.wasm-pack.profile.release]
wasm-opt = true

Binary file not shown.

View File

@@ -1,33 +0,0 @@
use cgmath::Vector3;
#[derive(Debug, Clone)]
pub struct Bitmap<F> {
pub image: web_sys::ImageBitmap,
format: std::marker::PhantomData<F>,
}
use crate::image::format::ImageFormat;
use crate::image::Image;
impl<F> Bitmap<F>
where
F: ImageFormat + Clone,
{
pub fn new(image: web_sys::ImageBitmap) -> Self {
Self {
image,
format: std::marker::PhantomData,
}
}
}
use crate::texture::Texture2DArray;
impl<F> Image for Bitmap<F>
where
F: ImageFormat + Clone,
{
fn tex_sub_image_3d(&self, textures: &Texture2DArray, offset: &Vector3<i32>) {
textures[offset.z as usize]
.bind()
.tex_sub_image_2d_with_u32_and_u32_and_image_bitmap(offset.x, offset.y, &self.image);
}
}

View File

@@ -1,293 +0,0 @@
use cgmath::{Vector2, Vector3};
use fitsrs::FitsMemAligned;
#[derive(Debug)]
pub struct Fits<F>
where
F: FitsImageFormat,
{
// Fits header properties
pub blank: f32,
pub bzero: f32,
pub bscale: f32,
// Tile size
size: Vector2<i32>,
// Aligned allocation layout
layout: std::alloc::Layout,
// Raw pointer to the fits in memory
aligned_raw_bytes_ptr: *mut u8,
// Raw pointer to the data part of the fits
pub aligned_data_raw_bytes_ptr: *const F::Type,
}
use std::alloc::{alloc, Layout};
impl<F> Fits<F>
where
F: FitsImageFormat,
{
/*pub async fn new_async(fits_raw_bytes: &[u8]) -> Result<Self, JsValue>
where
<F as FitsImageFormat>::Type: std::fmt::Debug
{
let fitsrs::Fits { data, header } = Fits::<F::Type>::from_byte_slice_async(fits_raw_bytes)
.map_err(|_| js_sys::Error::new("parsing FITS error"))?;
let bscale = if let Some(FITSHeaderKeyword::Other { value: FITSKeywordValue::FloatingPoint(bscale), .. }) = header.get("BSCALE") {
*bscale as f32
} else {
1.0
};
let bzero = if let Some(FITSHeaderKeyword::Other { value: FITSKeywordValue::FloatingPoint(bzero), .. }) = header.get("BZERO") {
*bzero as f32
} else {
0.0
};
let blank = if let Some(FITSHeaderKeyword::Blank(blank)) = header.get("BLANK") {
*blank as f32
} else {
std::f32::NAN
};
let width = header
.get("NAXIS1")
.and_then(|k| match k {
FITSHeaderKeyword::NaxisSize { size, .. } => Some(*size as i32),
_ => None,
})
.ok_or_else(|| JsValue::from_str("NAXIS1 not found in the fits"))?;
let height = header
.get("NAXIS2")
.and_then(|k| match k {
FITSHeaderKeyword::NaxisSize { size, .. } => Some(*size as i32),
_ => None,
})
.ok_or_else(|| JsValue::from_str("NAXIS2 not found in the fits"))?;
Ok(Self {
// Metadata fits header properties
blank,
bzero,
bscale,
// Tile size
size: Vector2::new(width, height),
// Allocation info of the layout
layout,
aligned_raw_bytes_ptr,
aligned_data_raw_bytes_ptr: data.as_ptr(),
})
}*/
pub fn new(fits_raw_bytes: &js_sys::Uint8Array) -> Result<Self, JsValue>
where
<F as FitsImageFormat>::Type: std::fmt::Debug
{
// Create a correctly aligned buffer to the type F
let align = std::mem::size_of::<F::Type>();
let layout = Layout::from_size_align(fits_raw_bytes.length() as usize, align)
.expect("Cannot create sized aligned memory layout");
// 1. Alloc the aligned memory buffer
let aligned_raw_bytes_ptr = unsafe { alloc(layout) };
let FitsMemAligned { data, header } = unsafe {
// 2. Copy the raw fits bytes into that aligned memory space
fits_raw_bytes.raw_copy_to_ptr(aligned_raw_bytes_ptr);
// 3. Convert to a slice of bytes
let aligned_raw_bytes =
std::slice::from_raw_parts(aligned_raw_bytes_ptr, fits_raw_bytes.length() as usize);
// 4. Parse the fits file to extract its data (big endianness is handled inside fitsrs and is O(n))
FitsMemAligned::<F::Type>::from_byte_slice(aligned_raw_bytes)
.map_err(|err| {
JsValue::from_str(&format!("Parsing fits error: {}", err))
})?
};
let bscale = if let Some(FITSHeaderKeyword::Other { value: FITSKeywordValue::FloatingPoint(bscale), .. }) = header.get("BSCALE") {
*bscale as f32
} else {
1.0
};
let bzero = if let Some(FITSHeaderKeyword::Other { value: FITSKeywordValue::FloatingPoint(bzero), .. }) = header.get("BZERO") {
*bzero as f32
} else {
0.0
};
let blank = if let Some(FITSHeaderKeyword::Blank(blank)) = header.get("BLANK") {
*blank as f32
} else {
std::f32::NAN
};
let width = header
.get("NAXIS1")
.and_then(|k| match k {
FITSHeaderKeyword::NaxisSize { size, .. } => Some(*size as i32),
_ => None,
})
.ok_or_else(|| JsValue::from_str("NAXIS1 not found in the fits"))?;
let height = header
.get("NAXIS2")
.and_then(|k| match k {
FITSHeaderKeyword::NaxisSize { size, .. } => Some(*size as i32),
_ => None,
})
.ok_or_else(|| JsValue::from_str("NAXIS2 not found in the fits"))?;
Ok(Self {
// Metadata fits header properties
blank,
bzero,
bscale,
// Tile size
size: Vector2::new(width, height),
// Allocation info of the layout
layout,
aligned_raw_bytes_ptr,
aligned_data_raw_bytes_ptr: data.as_ptr(),
})
}
pub fn get_size(&self) -> &Vector2<i32> {
&self.size
}
}
use crate::image::Image;
use crate::texture::Texture2DArray;
impl<F> Image for Fits<F>
where
F: FitsImageFormat,
{
fn tex_sub_image_3d(
&self,
// The texture array
textures: &Texture2DArray,
// An offset to write the image in the texture array
offset: &Vector3<i32>,
) {
let num_pixels = self.size.x * self.size.y;
let slice_raw_bytes = unsafe {
std::slice::from_raw_parts(
self.aligned_data_raw_bytes_ptr as *const _,
num_pixels as usize,
)
};
let array = unsafe { F::view(slice_raw_bytes) };
textures[offset.z as usize]
.bind()
.tex_sub_image_2d_with_i32_and_i32_and_u32_and_type_and_opt_array_buffer_view(
offset.x,
offset.y,
self.size.x,
self.size.y,
Some(array.as_ref()),
);
}
// The size of the image
/*fn get_size(&self) -> &Vector2<i32> {
&self.size
}*/
}
impl<F> Drop for Fits<F>
where
F: FitsImageFormat,
{
fn drop(&mut self) {
//al_core::log("dealloc fits tile");
unsafe {
std::alloc::dealloc(self.aligned_raw_bytes_ptr, self.layout);
}
}
}
use fitsrs::{FITSHeaderKeyword, FITSKeywordValue};
use wasm_bindgen::JsValue;
use crate::image::format::ImageFormat;
use fitsrs::ToBigEndian;
pub trait FitsImageFormat: ImageFormat {
type Type: ToBigEndian + Clone;
type ArrayBufferView: AsRef<js_sys::Object>;
/// Creates a JS typed array which is a view into wasm's linear memory at the slice specified.
/// This function returns a new typed array which is a view into wasm's memory. This view does not copy the underlying data.
///
/// # Safety
///
/// Views into WebAssembly memory are only valid so long as the backing buffer isn't resized in JS. Once this function is called any future calls to Box::new (or malloc of any form) may cause the returned value here to be invalidated. Use with caution!
///
/// Additionally the returned object can be safely mutated but the input slice isn't guaranteed to be mutable.
///
/// Finally, the returned object is disconnected from the input slice's lifetime, so there's no guarantee that the data is read at the right time.
unsafe fn view(s: &[Self::Type]) -> Self::ArrayBufferView;
}
use crate::image::R32F;
impl FitsImageFormat for R32F {
type Type = f32;
type ArrayBufferView = js_sys::Float32Array;
unsafe fn view(s: &[Self::Type]) -> Self::ArrayBufferView {
Self::ArrayBufferView::view(s)
}
}
#[cfg(feature = "webgl2")]
use crate::image::{R16I, R32I, R8UI, R64F};
#[cfg(feature = "webgl2")]
impl FitsImageFormat for R64F {
type Type = f64;
type ArrayBufferView = js_sys::Float64Array;
unsafe fn view(s: &[Self::Type]) -> Self::ArrayBufferView {
Self::ArrayBufferView::view(s)
}
}
#[cfg(feature = "webgl2")]
impl FitsImageFormat for R32I {
type Type = i32;
type ArrayBufferView = js_sys::Int32Array;
unsafe fn view(s: &[Self::Type]) -> Self::ArrayBufferView {
Self::ArrayBufferView::view(s)
}
}
#[cfg(feature = "webgl2")]
impl FitsImageFormat for R16I {
type Type = i16;
type ArrayBufferView = js_sys::Int16Array;
unsafe fn view(s: &[Self::Type]) -> Self::ArrayBufferView {
Self::ArrayBufferView::view(s)
}
}
#[cfg(feature = "webgl2")]
impl FitsImageFormat for R8UI {
type Type = u8;
type ArrayBufferView = js_sys::Uint8Array;
unsafe fn view(s: &[Self::Type]) -> Self::ArrayBufferView {
Self::ArrayBufferView::view(s)
}
}

View File

@@ -1,267 +0,0 @@
use crate::texture::pixel::Pixel;
pub enum Bytes<'a> {
Borrowed(&'a [u8]),
Owned(Vec<u8>),
}
pub trait ImageFormat {
type P: Pixel;
const NUM_CHANNELS: usize;
const EXT: &'static str;
const FORMAT: u32;
const INTERNAL_FORMAT: i32;
const TYPE: u32;
fn decode(raw_bytes: &[u8]) -> Result<Bytes<'_>, &'static str>;
}
use crate::webgl_ctx::WebGlRenderingCtx;
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
pub struct RGB8U;
impl ImageFormat for RGB8U {
type P = [u8; 3];
const NUM_CHANNELS: usize = 3;
const EXT: &'static str = "jpg";
const FORMAT: u32 = WebGlRenderingCtx::RGB as u32;
const INTERNAL_FORMAT: i32 = WebGlRenderingCtx::RGB as i32;
const TYPE: u32 = WebGlRenderingCtx::UNSIGNED_BYTE;
fn decode(raw_bytes: &[u8]) -> Result<Bytes<'_>, &'static str> {
let mut decoder = jpeg::Decoder::new(raw_bytes);
let bytes = decoder.decode().map_err(|_| "Cannot decoder jpeg. This image may not be compressed.")?;
Ok(Bytes::Owned(bytes))
}
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
pub struct RGBA8U;
#[cfg(feature = "webgl2")]
impl ImageFormat for RGBA8U {
type P = [u8; 4];
const NUM_CHANNELS: usize = 4;
const EXT: &'static str = "png";
const FORMAT: u32 = WebGlRenderingCtx::RGBA as u32;
const INTERNAL_FORMAT: i32 = WebGlRenderingCtx::RGBA as i32;
const TYPE: u32 = WebGlRenderingCtx::UNSIGNED_BYTE;
fn decode(raw_bytes: &[u8]) -> Result<Bytes<'_>, &'static str> {
let mut decoder = jpeg::Decoder::new(raw_bytes);
let bytes = decoder.decode().map_err(|_| "Cannot decoder png. This image may not be compressed.")?;
Ok(Bytes::Owned(bytes))
}
}
#[cfg(feature = "webgl1")]
impl ImageFormat for RGBA8U {
type P = [u8; 4];
const NUM_CHANNELS: usize = 4;
const EXT: &'static str = "png";
const FORMAT: u32 = WebGlRenderingCtx::RGBA as u32;
const INTERNAL_FORMAT: i32 = WebGlRenderingCtx::RGBA as i32;
const TYPE: u32 = WebGlRenderingCtx::UNSIGNED_BYTE;
fn decode(raw_bytes: &[u8]) -> Result<Bytes<'_>, &'static str> {
let mut decoder = jpeg::Decoder::new(raw_bytes);
let bytes = decoder.decode().map_err(|_| "Cannot decoder png. This image may not be compressed.")?;
Ok(Bytes::Owned(bytes))
}
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
pub struct RGBA32F;
impl ImageFormat for RGBA32F {
type P = [f32; 4];
const NUM_CHANNELS: usize = 4;
const EXT: &'static str = "png";
const FORMAT: u32 = WebGlRenderingCtx::RGBA as u32;
#[cfg(feature = "webgl2")]
const INTERNAL_FORMAT: i32 = WebGlRenderingCtx::RGBA32F as i32;
#[cfg(feature = "webgl1")]
const INTERNAL_FORMAT: i32 = WebGlRenderingCtx::RGBA as i32;
const TYPE: u32 = WebGlRenderingCtx::FLOAT;
fn decode(raw_bytes: &[u8]) -> Result<Bytes<'_>, &'static str> {
Ok(Bytes::Borrowed(raw_bytes))
}
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
pub struct RGB32F;
impl ImageFormat for RGB32F {
type P = [f32; 3];
const NUM_CHANNELS: usize = 3;
const EXT: &'static str = "jpg";
const FORMAT: u32 = WebGlRenderingCtx::RGB as u32;
#[cfg(feature = "webgl2")]
const INTERNAL_FORMAT: i32 = WebGlRenderingCtx::RGB32F as i32;
#[cfg(feature = "webgl1")]
const INTERNAL_FORMAT: i32 = WebGlRenderingCtx::RGB as i32;
const TYPE: u32 = WebGlRenderingCtx::FLOAT;
fn decode(raw_bytes: &[u8]) -> Result<Bytes<'_>, &'static str> {
Ok(Bytes::Borrowed(raw_bytes))
}
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
pub struct R32F;
impl ImageFormat for R32F {
type P = [f32; 1];
const NUM_CHANNELS: usize = 1;
const EXT: &'static str = "fits";
#[cfg(feature = "webgl2")]
const FORMAT: u32 = WebGlRenderingCtx::RED as u32;
#[cfg(feature = "webgl1")]
const FORMAT: u32 = WebGlRenderingCtx::LUMINANCE as u32;
#[cfg(feature = "webgl2")]
const INTERNAL_FORMAT: i32 = WebGlRenderingCtx::R32F as i32;
#[cfg(feature = "webgl1")]
const INTERNAL_FORMAT: i32 = WebGlRenderingCtx::LUMINANCE as i32;
const TYPE: u32 = WebGlRenderingCtx::FLOAT;
fn decode(raw_bytes: &[u8]) -> Result<Bytes<'_>, &'static str> {
Ok(Bytes::Borrowed(raw_bytes))
}
}
#[cfg(feature = "webgl2")]
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
pub struct R64F;
#[cfg(feature = "webgl2")]
impl ImageFormat for R64F {
type P = [f32; 1];
const NUM_CHANNELS: usize = 1;
const EXT: &'static str = "fits";
#[cfg(feature = "webgl2")]
const FORMAT: u32 = WebGlRenderingCtx::RED as u32;
#[cfg(feature = "webgl1")]
const FORMAT: u32 = WebGlRenderingCtx::LUMINANCE as u32;
#[cfg(feature = "webgl2")]
const INTERNAL_FORMAT: i32 = WebGlRenderingCtx::R32F as i32;
#[cfg(feature = "webgl1")]
const INTERNAL_FORMAT: i32 = WebGlRenderingCtx::LUMINANCE as i32;
const TYPE: u32 = WebGlRenderingCtx::FLOAT;
fn decode(raw_bytes: &[u8]) -> Result<Bytes<'_>, &'static str> {
Ok(Bytes::Borrowed(raw_bytes))
}
}
#[cfg(feature = "webgl2")]
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
pub struct R8UI;
#[cfg(feature = "webgl2")]
impl ImageFormat for R8UI {
type P = [u8; 1];
const NUM_CHANNELS: usize = 1;
const EXT: &'static str = "fits";
const FORMAT: u32 = WebGlRenderingCtx::RED_INTEGER as u32;
const INTERNAL_FORMAT: i32 = WebGlRenderingCtx::R8UI as i32;
const TYPE: u32 = WebGlRenderingCtx::UNSIGNED_BYTE;
fn decode(raw_bytes: &[u8]) -> Result<Bytes<'_>, &'static str> {
Ok(Bytes::Borrowed(raw_bytes))
}
}
#[cfg(feature = "webgl2")]
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
pub struct R16I;
#[cfg(feature = "webgl2")]
impl ImageFormat for R16I {
type P = [i16; 1];
const NUM_CHANNELS: usize = 1;
const EXT: &'static str = "fits";
const FORMAT: u32 = WebGlRenderingCtx::RED_INTEGER as u32;
const INTERNAL_FORMAT: i32 = WebGlRenderingCtx::R16I as i32;
const TYPE: u32 = WebGlRenderingCtx::SHORT;
fn decode(raw_bytes: &[u8]) -> Result<Bytes<'_>, &'static str> {
Ok(Bytes::Borrowed(raw_bytes))
}
}
#[cfg(feature = "webgl2")]
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
pub struct R32I;
#[cfg(feature = "webgl2")]
impl ImageFormat for R32I {
type P = [i32; 1];
const NUM_CHANNELS: usize = 1;
const EXT: &'static str = "fits";
const FORMAT: u32 = WebGlRenderingCtx::RED_INTEGER as u32;
const INTERNAL_FORMAT: i32 = WebGlRenderingCtx::R32I as i32;
const TYPE: u32 = WebGlRenderingCtx::INT;
fn decode(raw_bytes: &[u8]) -> Result<Bytes<'_>, &'static str> {
Ok(Bytes::Borrowed(raw_bytes))
}
}
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
pub enum ImageFormatType {
RGBA32F,
RGB32F,
RGBA8U,
RGB8U,
R32F,
#[cfg(feature = "webgl2")]
R64F,
#[cfg(feature = "webgl2")]
R8UI,
#[cfg(feature = "webgl2")]
R16I,
#[cfg(feature = "webgl2")]
R32I,
}
impl ImageFormatType {
pub fn get_ext_file(&self) -> &'static str {
match self {
ImageFormatType::RGBA32F => unimplemented!(),
ImageFormatType::RGB32F => unimplemented!(),
ImageFormatType::RGBA8U => RGBA8U::EXT,
ImageFormatType::RGB8U => RGB8U::EXT,
ImageFormatType::R32F => R32F::EXT,
ImageFormatType::R64F => R64F::EXT,
#[cfg(feature = "webgl2")]
ImageFormatType::R8UI => R8UI::EXT,
#[cfg(feature = "webgl2")]
ImageFormatType::R16I => R16I::EXT,
#[cfg(feature = "webgl2")]
ImageFormatType::R32I => R32I::EXT,
}
}
}

View File

@@ -1,44 +0,0 @@
/* ------------------------------------------------------ */
#[derive(Debug)]
pub struct HTMLImage<F> {
image: web_sys::HtmlImageElement,
format: std::marker::PhantomData<F>,
}
impl<F> HTMLImage<F>
where
F: ImageFormat + Clone,
{
pub fn new(image: web_sys::HtmlImageElement) -> Self {
Self {
image,
format: std::marker::PhantomData,
}
}
}
use cgmath::Vector3;
use crate::image::format::ImageFormat;
use crate::image::Image;
use crate::texture::Texture2DArray;
impl<F> Image for HTMLImage<F>
where
F: ImageFormat,
{
fn tex_sub_image_3d(
&self,
// The texture array
textures: &Texture2DArray,
// An offset to write the image in the texture array
offset: &Vector3<i32>,
) {
textures[offset.z as usize]
.bind()
.tex_sub_image_2d_with_u32_and_u32_and_html_image_element(
offset.x,
offset.y,
&self.image,
);
}
}

View File

@@ -1,331 +0,0 @@
pub mod bitmap;
pub mod fits;
pub mod format;
pub mod html;
pub mod raw;
pub trait ArrayBuffer: AsRef<js_sys::Object> + std::fmt::Debug {
type Item: std::cmp::PartialOrd + Clone + Copy + std::fmt::Debug + cgmath::Zero;
fn new(buf: &[Self::Item]) -> Self;
fn empty(size: u32, blank_value: Self::Item) -> Self;
fn to_vec(&self) -> Vec<Self::Item>;
fn set_index(&self, idx: u32, value: Self::Item);
fn get(&self, idx: u32) -> Self::Item;
}
#[derive(Debug)]
pub struct ArrayU8(js_sys::Uint8Array);
impl AsRef<js_sys::Object> for ArrayU8 {
fn as_ref(&self) -> &js_sys::Object {
self.0.as_ref()
}
}
impl ArrayBuffer for ArrayU8 {
type Item = u8;
fn new(buf: &[Self::Item]) -> Self {
ArrayU8(buf.into())
}
fn empty(size: u32, blank_value: Self::Item) -> Self {
let uint8_arr = js_sys::Uint8Array::new_with_length(size).fill(blank_value, 0, size);
let array = ArrayU8(uint8_arr);
array
}
fn to_vec(&self) -> Vec<Self::Item> {
self.0.to_vec()
}
fn set_index(&self, idx: u32, value: Self::Item) {
self.0.set_index(idx, value);
}
fn get(&self, idx: u32) -> Self::Item {
self.0.get_index(idx)
}
}
#[derive(Debug)]
pub struct ArrayI16(js_sys::Int16Array);
impl AsRef<js_sys::Object> for ArrayI16 {
fn as_ref(&self) -> &js_sys::Object {
self.0.as_ref()
}
}
impl ArrayBuffer for ArrayI16 {
type Item = i16;
fn new(buf: &[Self::Item]) -> Self {
ArrayI16(buf.into())
}
fn empty(size: u32, blank_value: Self::Item) -> Self {
let int16_arr = js_sys::Int16Array::new_with_length(size).fill(blank_value, 0, size);
let array = ArrayI16(int16_arr);
array
}
fn to_vec(&self) -> Vec<Self::Item> {
self.0.to_vec()
}
fn set_index(&self, idx: u32, value: Self::Item) {
self.0.set_index(idx, value);
}
fn get(&self, idx: u32) -> Self::Item {
self.0.get_index(idx)
}
}
#[derive(Debug)]
pub struct ArrayI32(js_sys::Int32Array);
impl AsRef<js_sys::Object> for ArrayI32 {
fn as_ref(&self) -> &js_sys::Object {
self.0.as_ref()
}
}
impl ArrayBuffer for ArrayI32 {
type Item = i32;
fn new(buf: &[Self::Item]) -> Self {
ArrayI32(buf.into())
}
fn empty(size: u32, blank_value: Self::Item) -> Self {
let int32_arr = js_sys::Int32Array::new_with_length(size).fill(blank_value, 0, size);
let array = ArrayI32(int32_arr);
array
}
fn to_vec(&self) -> Vec<Self::Item> {
self.0.to_vec()
}
fn set_index(&self, idx: u32, value: Self::Item) {
self.0.set_index(idx, value);
}
fn get(&self, idx: u32) -> Self::Item {
self.0.get_index(idx)
}
}
#[derive(Debug)]
pub struct ArrayF32(js_sys::Float32Array);
impl AsRef<js_sys::Object> for ArrayF32 {
fn as_ref(&self) -> &js_sys::Object {
self.0.as_ref()
}
}
impl ArrayBuffer for ArrayF32 {
type Item = f32;
fn new(buf: &[Self::Item]) -> Self {
ArrayF32(buf.into())
}
fn empty(size: u32, blank_value: Self::Item) -> Self {
let f32_arr = js_sys::Float32Array::new_with_length(size).fill(blank_value, 0, size);
let array = ArrayF32(f32_arr);
array
}
fn to_vec(&self) -> Vec<Self::Item> {
self.0.to_vec()
}
fn set_index(&self, idx: u32, value: Self::Item) {
self.0.set_index(idx, value);
}
fn get(&self, idx: u32) -> Self::Item {
self.0.get_index(idx)
}
}
#[derive(Debug)]
pub struct ArrayF64(js_sys::Float64Array);
impl AsRef<js_sys::Object> for ArrayF64 {
fn as_ref(&self) -> &js_sys::Object {
self.0.as_ref()
}
}
impl ArrayBuffer for ArrayF64 {
type Item = f64;
fn new(buf: &[Self::Item]) -> Self {
ArrayF64(buf.into())
}
fn empty(size: u32, blank_value: Self::Item) -> Self {
let f64_arr = js_sys::Float64Array::new_with_length(size).fill(blank_value, 0, size);
let array = ArrayF64(f64_arr);
array
}
fn to_vec(&self) -> Vec<Self::Item> {
self.0.to_vec()
}
fn set_index(&self, idx: u32, value: Self::Item) {
self.0.set_index(idx, value);
}
fn get(&self, idx: u32) -> Self::Item {
self.0.get_index(idx)
}
}
use self::html::HTMLImage;
use super::Texture2DArray;
pub trait Image {
fn tex_sub_image_3d(
&self,
// The texture array
textures: &Texture2DArray,
// An offset to write the image in the texture array
offset: &Vector3<i32>,
);
// The size of the image
//fn get_size(&self) -> &Vector2<i32>;
}
impl<'a, I> Image for &'a I
where
I: Image,
{
fn tex_sub_image_3d(
&self,
// The texture array
textures: &Texture2DArray,
// An offset to write the image in the texture array
offset: &Vector3<i32>,
) {
let image = &**self;
image.tex_sub_image_3d(textures, offset);
}
/*fn get_size(&self) -> &Vector2<i32> {
let image = &**self;
image.get_size()
}*/
}
use std::rc::Rc;
impl<I> Image for Rc<I>
where
I: Image,
{
fn tex_sub_image_3d(
&self,
// The texture array
textures: &Texture2DArray,
// An offset to write the image in the texture array
offset: &Vector3<i32>,
) {
let image = &**self;
image.tex_sub_image_3d(textures, offset);
}
/*fn get_size(&self) -> &Vector2<i32> {
let image = &**self;
image.get_size()
}*/
}
use crate::Abort;
use std::sync::{Arc, Mutex};
impl<I> Image for Arc<Mutex<Option<I>>>
where
I: Image,
{
fn tex_sub_image_3d(
&self,
// The texture array
textures: &Texture2DArray,
// An offset to write the image in the texture array
offset: &Vector3<i32>,
) {
if let Some(image) = &*self.lock().unwrap_abort() {
image.tex_sub_image_3d(textures, offset);
}
}
}
#[cfg(feature = "webgl2")]
use crate::image::format::{R16I, R32I, R8UI, R64F};
use crate::image::format::{R32F, RGB8U, RGBA8U};
use bitmap::Bitmap;
use fits::Fits;
use raw::ImageBuffer;
#[derive(Debug)]
#[cfg(feature = "webgl2")]
pub enum ImageType {
FitsImageR64f { image: Fits<R64F> },
FitsImageR32f { image: Fits<R32F> },
FitsImageR32i { image: Fits<R32I> },
FitsImageR16i { image: Fits<R16I> },
FitsImageR8ui { image: Fits<R8UI> },
PngImageRgba8u { image: Bitmap<RGBA8U> },
JpgImageRgb8u { image: Bitmap<RGB8U> },
PngHTMLImageRgba8u { image: HTMLImage<RGBA8U> },
JpgHTMLImageRgb8u { image: HTMLImage<RGB8U> },
RawRgb8u { image: ImageBuffer<RGB8U> },
RawRgba8u { image: ImageBuffer<RGBA8U> },
RawR32f { image: ImageBuffer<R32F> },
RawR32i { image: ImageBuffer<R32I> },
RawR16i { image: ImageBuffer<R16I> },
RawR8ui { image: ImageBuffer<R8UI> },
}
#[cfg(feature = "webgl1")]
pub enum ImageType {
FitsImageR32f { image: Fits<R32F> },
PngHTMLImageRgba8u { image: HTMLImage<RGBA8U> },
JpgHTMLImageRgb8u { image: HTMLImage<RGB8U> },
PngImageRgba8u { image: Bitmap<RGBA8U> },
JpgImageRgb8u { image: Bitmap<RGB8U> },
RawRgb8u { image: ImageBuffer<RGB8U> },
RawRgba8u { image: ImageBuffer<RGBA8U> },
RawR32f { image: ImageBuffer<R32F> },
}
use cgmath::Vector3;
impl Image for ImageType {
fn tex_sub_image_3d(
&self,
// The texture array
textures: &Texture2DArray,
// An offset to write the image in the texture array
offset: &Vector3<i32>,
) {
match self {
ImageType::FitsImageR64f { image } => {
let size = image.get_size();
let slice = unsafe { std::slice::from_raw_parts(image.aligned_data_raw_bytes_ptr as *const f64, (size.x as usize) * (size.y as usize) ) };
let data = slice.iter().map(|&v| v as f32).collect();
let image = ImageBuffer::<R32F>::new(data, size.x, size.y);
image.tex_sub_image_3d(textures, offset)
},
ImageType::FitsImageR32f { image } => image.tex_sub_image_3d(textures, offset),
ImageType::FitsImageR32i { image } => image.tex_sub_image_3d(textures, offset),
ImageType::FitsImageR16i { image } => image.tex_sub_image_3d(textures, offset),
ImageType::FitsImageR8ui { image } => image.tex_sub_image_3d(textures, offset),
ImageType::PngImageRgba8u { image } => image.tex_sub_image_3d(textures, offset),
ImageType::JpgImageRgb8u { image } => image.tex_sub_image_3d(textures, offset),
ImageType::PngHTMLImageRgba8u { image } => image.tex_sub_image_3d(textures, offset),
ImageType::JpgHTMLImageRgb8u { image } => image.tex_sub_image_3d(textures, offset),
ImageType::RawRgb8u { image } => image.tex_sub_image_3d(textures, offset),
ImageType::RawRgba8u { image } => image.tex_sub_image_3d(textures, offset),
ImageType::RawR32f { image } => image.tex_sub_image_3d(textures, offset),
ImageType::RawR32i { image } => image.tex_sub_image_3d(textures, offset),
ImageType::RawR16i { image } => image.tex_sub_image_3d(textures, offset),
ImageType::RawR8ui { image } => image.tex_sub_image_3d(textures, offset),
}
}
}

View File

@@ -1,175 +0,0 @@
use crate::image::format::ImageFormat;
use crate::texture::pixel::Pixel;
#[derive(Debug)]
#[allow(dead_code)]
pub struct ImageBuffer<T>
where
T: ImageFormat,
{
pub data: Vec<<<T as ImageFormat>::P as Pixel>::Item>,
pub size: Vector2<i32>,
}
use crate::image::format::Bytes;
pub struct ImageBufferView {
pub x: i32,
pub y: i32,
pub w: i32,
pub h: i32,
}
use crate::log;
use crate::inforec;
use wasm_bindgen::JsValue;
impl<T> ImageBuffer<T>
where
T: ImageFormat,
{
pub fn new(data: Vec<<<T as ImageFormat>::P as Pixel>::Item>, width: i32, height: i32) -> Self {
let size_buf = width * height * (T::NUM_CHANNELS as i32);
debug_assert!(size_buf == data.len() as i32);
//let buf = <<T as ImageFormat>::P as Pixel>::Container::new(buf);
let size = Vector2::new(width, height);
Self { data, size }
}
pub fn from_encoded_raw_bytes(raw_bytes: &[u8], width: i32, height: i32) -> Result<Self, JsValue> {
let mut decoded_bytes = match T::decode(raw_bytes).map_err(|e| JsValue::from_str(e))? {
Bytes::Borrowed(bytes) => bytes.to_vec(),
Bytes::Owned(bytes) => bytes
};
let decoded_pixels = unsafe {
decoded_bytes.set_len(
decoded_bytes.len() / std::mem::size_of::<<<T as ImageFormat>::P as Pixel>::Item>(),
);
std::mem::transmute(decoded_bytes)
};
Ok(Self::new(decoded_pixels, width, height))
}
pub fn from_raw_bytes(mut raw_bytes: Vec<u8>, width: i32, height: i32) -> Self {
let size_buf = width * height * (std::mem::size_of::<T::P>() as i32);
let len = raw_bytes.len();
crate::info!(len);
debug_assert!(size_buf == raw_bytes.len() as i32);
let decoded_pixels = unsafe {
raw_bytes.set_len(
raw_bytes.len() / std::mem::size_of::<<<T as ImageFormat>::P as Pixel>::Item>(),
);
std::mem::transmute(raw_bytes)
};
Self::new(decoded_pixels, width, height)
}
pub fn empty() -> Self {
let size = Vector2::new(0, 0);
Self { data: vec![], size }
}
pub fn allocate(pixel_fill: &<T as ImageFormat>::P, width: i32, height: i32) -> ImageBuffer<T> {
let size_buf = ((width * height) as usize) * (T::NUM_CHANNELS);
let data = pixel_fill
.as_ref()
.iter()
.cloned()
.cycle()
.take(size_buf)
.collect::<Vec<_>>();
ImageBuffer::<T>::new(data, width, height)
}
pub fn tex_sub(
&mut self,
src: &Self,
s: &ImageBufferView,
d: &ImageBufferView,
) {
let mut di = d.x;
let mut dj = d.y;
for ix in s.x..(s.x + s.w) {
for iy in s.y..(s.y + s.h) {
let s_idx = (iy * src.width() + ix) as usize;
let d_idx = (di * self.width() + dj) as usize;
for i in 0..T::NUM_CHANNELS {
let si = s_idx * T::NUM_CHANNELS + i;
let di = d_idx * T::NUM_CHANNELS + i;
let value = src.data[si];
self.data[di] = value;
}
di += 1;
if di >= d.x + d.w {
di = d.x;
dj += 1;
}
}
}
}
pub fn iter(&self) -> impl Iterator<Item = &<<T as ImageFormat>::P as Pixel>::Item> {
self.data.iter()
}
pub fn get_data(&self) -> &[<<T as ImageFormat>::P as Pixel>::Item] {
&self.data
}
pub fn width(&self) -> i32 {
self.size.x
}
pub fn height(&self) -> i32 {
self.size.y
}
}
use crate::image::format::{R16I, R32F, R32I, R8UI, RGB8U, RGBA8U};
pub enum ImageBufferType {
JPG(ImageBuffer<RGB8U>),
PNG(ImageBuffer<RGBA8U>),
R32F(ImageBuffer<R32F>),
R8UI(ImageBuffer<R8UI>),
R16I(ImageBuffer<R16I>),
R32I(ImageBuffer<R32I>),
}
use crate::image::{ArrayBuffer, Image};
use crate::Texture2DArray;
use cgmath::{Vector2, Vector3};
impl<I> Image for ImageBuffer<I>
where
I: ImageFormat,
{
fn tex_sub_image_3d(
&self,
// The texture array
textures: &Texture2DArray,
// An offset to write the image in the texture array
offset: &Vector3<i32>,
) {
let js_array =
<<<I as ImageFormat>::P as Pixel>::Container as ArrayBuffer>::new(&self.data);
textures[offset.z as usize]
.bind()
.tex_sub_image_2d_with_i32_and_i32_and_u32_and_type_and_opt_array_buffer_view(
offset.x,
offset.y,
self.size.x,
self.size.y,
Some(js_array.as_ref()),
);
}
// The size of the image
/*fn get_size(&self) -> &Vector2<i32> {
&self.size
}*/
}

View File

@@ -1,62 +0,0 @@
extern crate jpeg_decoder as jpeg;
extern crate png;
extern crate serde_json;
pub mod text;
pub mod image;
mod object;
pub mod shader;
pub mod texture;
pub mod webgl_ctx;
#[macro_use]
pub mod log;
pub use log::log;
pub use texture::pixel;
pub use texture::{Texture2D, Texture2DBound};
pub use texture::Texture2DArray;
pub use webgl_ctx::WebGlContext;
pub use object::array_buffer::ArrayBuffer;
pub use object::array_buffer_instanced::ArrayBufferInstanced;
pub use object::buffer_data::{BufferDataStorage, SliceData, VecData};
pub use object::element_array_buffer::ElementArrayBuffer;
pub use object::framebuffer::FrameBufferObject;
use object::array_buffer::VertexAttribPointerType;
pub use object::vertex_array_object::vao::{
ShaderVertexArrayObjectBound, ShaderVertexArrayObjectBoundRef, VertexArrayObject,
VertexArrayObjectBound,
};
pub trait Abort {
type Item;
fn unwrap_abort(self) -> Self::Item where Self: Sized;
}
impl<T> Abort for Option<T> {
type Item = T;
#[inline]
fn unwrap_abort(self) -> Self::Item {
use std::process;
match self {
Some(t) => t,
None => process::abort(),
}
}
}
impl<T, E> Abort for Result<T, E> {
type Item = T;
#[inline]
fn unwrap_abort(self) -> Self::Item {
use std::process;
match self {
Ok(t) => t,
Err(_) => process::abort(),
}
}
}

View File

@@ -1,52 +0,0 @@
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
pub fn log(s: &str);
}
// ----------------------------------------------------------------------------
// Helpers to hide some of the verbosity of web_sys
/// Log some text to the developer console (`console.log(…)` in JS)
pub fn console_log(s: impl Into<JsValue>) {
web_sys::console::log_1(&s.into());
}
/// Log a warning to the developer console (`console.warn(…)` in JS)
pub fn console_warn(s: impl Into<JsValue>) {
web_sys::console::warn_1(&s.into());
}
/// Log an error to the developer console (`console.error(…)` in JS)
pub fn console_error(s: impl Into<JsValue>) {
web_sys::console::error_1(&s.into());
}
#[macro_export]
macro_rules! log {
// The pattern for a single `eval`
($($arg:tt)*) => {
$( self::log(&format!("{:?}", $arg)); )*
};
}
#[macro_export]
macro_rules! inforec {
// The pattern for a single `eval`
// Base case:
($x:tt) => (format!("{:?}", $x));
// `$x` followed by at least one `$y,`
($x:tt, $($y:tt),+) => {
// Call `find_min!` on the tail `$y`
( format!( "{} {}", inforec!($x), inforec!($($y),+) ) );
}
}
#[macro_export]
macro_rules! info {
($($arg:tt),*) => {
self::log( &inforec!( $( $arg ),* ) );
};
}

View File

@@ -1,486 +0,0 @@
use crate::webgl_ctx::WebGlContext;
use web_sys::WebGlBuffer;
use super::buffer_data::BufferDataStorage;
pub trait VertexBufferObject {
fn bind(&self);
fn unbind(&self);
}
pub trait VertexAttribPointerType: std::marker::Sized {
type ArrayBufferView;
fn array_buffer_view<'a, B: BufferDataStorage<'a, Self>>(data: B) -> Self::ArrayBufferView;
/// Link the vertex attrib to the shader
fn vertex_attrib_pointer_with_i32(
gl: &WebGlContext,
idx: u32,
size: i32,
stride: i32,
offset: i32,
);
/// Pass the vertices data to the buffer
fn buffer_data_with_array_buffer_view<'a, B: BufferDataStorage<'a, Self>>(
gl: &WebGlContext,
data: B,
target: u32,
usage: u32,
);
fn buffer_sub_data_with_i32_and_array_buffer_view<'a, B: BufferDataStorage<'a, Self>>(
gl: &WebGlContext,
data: B,
target: u32,
);
// Initialize the VBO
fn initialize_buffer<'a, B: BufferDataStorage<'a, Self>>(
gl: &WebGlContext,
offset_idx: u32,
stride: usize,
sizes: &[usize],
offsets: &[usize],
usage: u32,
data: B,
) -> WebGlBuffer {
let buffer = gl.create_buffer().ok_or("failed to create buffer").unwrap_abort();
// Bind the buffer
gl.bind_buffer(WebGlRenderingCtx::ARRAY_BUFFER, Some(buffer.as_ref()));
Self::buffer_data_with_array_buffer_view(gl, data, WebGlRenderingCtx::ARRAY_BUFFER, usage);
// Attrib pointer to the shader
for (idx, (size, offset)) in sizes.iter().zip(offsets.iter()).enumerate() {
let idx = (idx as u32) + offset_idx;
Self::vertex_attrib_pointer_with_i32(
gl,
idx,
*size as i32,
stride as i32,
*offset as i32,
);
}
buffer
}
fn set_vertex_attrib_pointers(
gl: &WebGlContext,
offset_idx: u32,
stride: usize,
sizes: &[usize],
offsets: &[usize],
) {
// Attrib pointer to the shader
for (idx, (size, offset)) in sizes.iter().zip(offsets.iter()).enumerate() {
let idx = (idx as u32) + offset_idx;
Self::vertex_attrib_pointer_with_i32(
gl,
idx,
*size as i32,
stride as i32,
*offset as i32,
);
}
}
}
use crate::webgl_ctx::WebGlRenderingCtx;
use js_sys::WebAssembly;
use wasm_bindgen::JsCast;
impl VertexAttribPointerType for u8 {
type ArrayBufferView = js_sys::Uint8Array;
fn array_buffer_view<'a, B: BufferDataStorage<'a, Self>>(data: B) -> Self::ArrayBufferView {
let data = data.get_slice();
unsafe { Self::ArrayBufferView::view(data) }
}
fn buffer_sub_data_with_i32_and_array_buffer_view<'a, B: BufferDataStorage<'a, Self>>(
gl: &WebGlContext,
data: B,
target: u32,
) {
let data = Self::array_buffer_view(data);
gl.buffer_sub_data_with_i32_and_array_buffer_view(target, 0_i32, &data);
}
fn buffer_data_with_array_buffer_view<'a, B: BufferDataStorage<'a, Self>>(
gl: &WebGlContext,
data: B,
target: u32,
usage: u32,
) {
let data = Self::array_buffer_view(data);
gl.buffer_data_with_array_buffer_view(target, &data, usage);
}
fn vertex_attrib_pointer_with_i32(
gl: &WebGlContext,
idx: u32,
size: i32,
stride: i32,
offset: i32,
) {
#[cfg(feature = "webgl2")]
gl.vertex_attrib_i_pointer_with_i32(
idx,
size,
WebGlRenderingCtx::UNSIGNED_BYTE,
stride,
offset,
);
#[cfg(feature = "webgl1")]
gl.vertex_attrib_pointer_with_i32(
idx,
size,
WebGlRenderingCtx::UNSIGNED_BYTE,
false,
stride,
offset,
);
gl.enable_vertex_attrib_array(idx);
}
}
impl VertexAttribPointerType for u16 {
type ArrayBufferView = js_sys::Uint16Array;
fn array_buffer_view<'a, B: BufferDataStorage<'a, Self>>(data: B) -> Self::ArrayBufferView {
let data = data.get_slice();
unsafe { Self::ArrayBufferView::view(data) }
}
fn buffer_sub_data_with_i32_and_array_buffer_view<'a, B: BufferDataStorage<'a, Self>>(
gl: &WebGlContext,
data: B,
target: u32,
) {
let data = Self::array_buffer_view(data);
gl.buffer_sub_data_with_i32_and_array_buffer_view(target, 0_i32, &data);
}
fn buffer_data_with_array_buffer_view<'a, B: BufferDataStorage<'a, Self>>(
gl: &WebGlContext,
data: B,
target: u32,
usage: u32,
) {
let data = Self::array_buffer_view(data);
gl.buffer_data_with_array_buffer_view(target, &data, usage);
}
fn vertex_attrib_pointer_with_i32(
gl: &WebGlContext,
idx: u32,
size: i32,
stride: i32,
offset: i32,
) {
#[cfg(feature = "webgl2")]
gl.vertex_attrib_i_pointer_with_i32(
idx,
size,
WebGlRenderingCtx::UNSIGNED_SHORT,
stride,
offset,
);
#[cfg(feature = "webgl1")]
gl.vertex_attrib_pointer_with_i32(
idx,
size,
WebGlRenderingCtx::UNSIGNED_SHORT,
false,
stride,
offset,
);
gl.enable_vertex_attrib_array(idx);
}
}
impl VertexAttribPointerType for u32 {
type ArrayBufferView = js_sys::Uint32Array;
fn array_buffer_view<'a, B: BufferDataStorage<'a, Self>>(data: B) -> Self::ArrayBufferView {
let data = data.get_slice();
unsafe { Self::ArrayBufferView::view(data) }
}
fn buffer_sub_data_with_i32_and_array_buffer_view<'a, B: BufferDataStorage<'a, Self>>(
gl: &WebGlContext,
data: B,
target: u32,
) {
let data = Self::array_buffer_view(data);
gl.buffer_sub_data_with_i32_and_array_buffer_view(target, 0_i32, &data);
}
fn buffer_data_with_array_buffer_view<'a, B: BufferDataStorage<'a, Self>>(
gl: &WebGlContext,
data: B,
target: u32,
usage: u32,
) {
let data = Self::array_buffer_view(data);
gl.buffer_data_with_array_buffer_view(target, &data, usage);
}
fn vertex_attrib_pointer_with_i32(
gl: &WebGlContext,
idx: u32,
size: i32,
stride: i32,
offset: i32,
) {
#[cfg(feature = "webgl2")]
gl.vertex_attrib_i_pointer_with_i32(
idx,
size,
WebGlRenderingCtx::UNSIGNED_INT,
stride,
offset,
);
#[cfg(feature = "webgl1")]
gl.vertex_attrib_pointer_with_i32(
idx,
size,
WebGlRenderingCtx::UNSIGNED_INT,
false,
stride,
offset,
);
gl.enable_vertex_attrib_array(idx);
}
}
impl VertexAttribPointerType for i32 {
type ArrayBufferView = js_sys::Int32Array;
fn array_buffer_view<'a, B: BufferDataStorage<'a, Self>>(data: B) -> Self::ArrayBufferView {
let data = data.get_slice();
unsafe { Self::ArrayBufferView::view(data) }
}
fn buffer_sub_data_with_i32_and_array_buffer_view<'a, B: BufferDataStorage<'a, Self>>(
gl: &WebGlContext,
data: B,
target: u32,
) {
let data = Self::array_buffer_view(data);
gl.buffer_sub_data_with_i32_and_array_buffer_view(target, 0_i32, &data);
}
fn buffer_data_with_array_buffer_view<'a, B: BufferDataStorage<'a, Self>>(
gl: &WebGlContext,
data: B,
target: u32,
usage: u32,
) {
let data = Self::array_buffer_view(data);
gl.buffer_data_with_array_buffer_view(target, &data, usage);
}
fn vertex_attrib_pointer_with_i32(
gl: &WebGlContext,
idx: u32,
size: i32,
stride: i32,
offset: i32,
) {
#[cfg(feature = "webgl2")]
gl.vertex_attrib_i_pointer_with_i32(idx, size, WebGlRenderingCtx::INT, stride, offset);
#[cfg(feature = "webgl1")]
gl.vertex_attrib_pointer_with_i32(idx, size, WebGlRenderingCtx::INT, false, stride, offset);
gl.enable_vertex_attrib_array(idx);
}
}
use js_sys::Float32Array;
impl VertexAttribPointerType for f32 {
type ArrayBufferView = Float32Array;
fn array_buffer_view<'a, B: BufferDataStorage<'a, Self>>(data: B) -> Self::ArrayBufferView {
let data = data.get_slice();
//unsafe { Self::ArrayBufferView::view(&data) }
let memory_buffer = wasm_bindgen::memory()
.unchecked_ref::<WebAssembly::Memory>()
.buffer();
let len = data.len();
let ptr = data.as_ptr() as u32 / 4;
Float32Array::new(&memory_buffer)
.subarray(ptr, ptr + len as u32)
}
fn buffer_sub_data_with_i32_and_array_buffer_view<'a, B: BufferDataStorage<'a, Self>>(
gl: &WebGlContext,
data: B,
target: u32,
) {
/*let data = Self::array_buffer_view(data);
gl.buffer_sub_data_with_i32_and_array_buffer_view(
target,
0,
&data,
);*/
let data = Self::array_buffer_view(data);
gl.buffer_sub_data_with_i32_and_array_buffer_view(target, 0_i32, &data);
}
fn buffer_data_with_array_buffer_view<'a, B: BufferDataStorage<'a, Self>>(
gl: &WebGlContext,
data: B,
target: u32,
usage: u32,
) {
let data = Self::array_buffer_view(data);
gl.buffer_data_with_array_buffer_view(target, &data, usage);
}
fn vertex_attrib_pointer_with_i32(
gl: &WebGlContext,
idx: u32,
size: i32,
stride: i32,
offset: i32,
) {
gl.vertex_attrib_pointer_with_i32(
idx,
size,
WebGlRenderingCtx::FLOAT,
false,
stride,
offset,
);
gl.enable_vertex_attrib_array(idx);
}
}
pub struct ArrayBuffer {
buffer: WebGlBuffer,
// The size of the buffer in number of elements
len: usize,
num_packed_data: usize,
offset_idx: u32,
sizes: Box<[usize]>,
gl: WebGlContext,
}
use crate::shader::ShaderBound;
use crate::Abort;
impl ArrayBuffer {
pub fn new<'a, T: VertexAttribPointerType, B: BufferDataStorage<'a, T>>(
gl: &WebGlContext,
offset_idx: u32,
stride: usize,
sizes: &[usize],
offsets: &[usize],
usage: u32,
data: B,
) -> ArrayBuffer {
let len = data.len();
let buffer = T::initialize_buffer(gl, offset_idx, stride, sizes, offsets, usage, data);
let num_packed_data = sizes.len();
let gl = gl.clone();
// Returns an instance that keeps only the buffer
ArrayBuffer {
buffer,
len,
num_packed_data,
offset_idx,
sizes: sizes.into(),
gl,
}
}
pub fn set_vertex_attrib_pointer_by_name<'a, T: VertexAttribPointerType>(
&self,
shader: &ShaderBound<'a>,
location: &str,
) {
let loc = shader.get_attrib_location(&self.gl, location);
assert_eq!(self.sizes.len(), 1);
T::vertex_attrib_pointer_with_i32(
&self.gl,
loc as u32,
*self.sizes.first().unwrap_abort() as i32,
0,
0,
);
#[cfg(feature = "webgl2")]
self.gl.vertex_attrib_divisor(loc as u32, 0);
#[cfg(feature = "webgl1")]
self.gl
.ext
.angles
.vertex_attrib_divisor_angle(loc as u32, 0);
}
pub fn disable_vertex_attrib_pointer_by_name<'a>(
&self,
shader: &ShaderBound<'a>,
location: &str,
) {
let loc = shader.get_attrib_location(&self.gl, location);
self.gl.disable_vertex_attrib_array(loc as u32);
}
pub fn update<'a, T: VertexAttribPointerType, B: BufferDataStorage<'a, T>>(
&mut self,
usage: u32,
data: B,
) {
self.bind();
if self.len >= data.len() {
T::buffer_sub_data_with_i32_and_array_buffer_view(
&self.gl,
data,
WebGlRenderingCtx::ARRAY_BUFFER,
);
} else {
self.len = data.len();
T::buffer_data_with_array_buffer_view(
&self.gl,
data,
WebGlRenderingCtx::ARRAY_BUFFER,
usage,
);
}
}
}
impl VertexBufferObject for ArrayBuffer {
fn bind(&self) {
self.gl
.bind_buffer(WebGlRenderingCtx::ARRAY_BUFFER, Some(self.buffer.as_ref()));
}
fn unbind(&self) {
self.gl.bind_buffer(WebGlRenderingCtx::ARRAY_BUFFER, None);
}
}
impl Drop for ArrayBuffer {
fn drop(&mut self) {
for idx in 0..self.num_packed_data {
let idx = (idx as u32) + self.offset_idx;
self.gl.disable_vertex_attrib_array(idx);
}
self.gl.delete_buffer(Some(self.buffer.as_ref()));
}
}

View File

@@ -1,215 +0,0 @@
use crate::webgl_ctx::WebGlRenderingCtx;
use web_sys::WebGlBuffer;
use crate::webgl_ctx::WebGlContext;
pub struct ArrayBufferInstanced {
buffer: WebGlBuffer,
num_packed_data: usize,
offset_idx: u32,
num_instances: i32,
sizes: Vec<usize>,
stride: usize,
gl: WebGlContext,
}
use super::array_buffer::VertexBufferObject;
impl VertexBufferObject for ArrayBufferInstanced {
fn bind(&self) {
self.gl
.bind_buffer(WebGlRenderingCtx::ARRAY_BUFFER, Some(self.buffer.as_ref()));
}
fn unbind(&self) {
self.gl.bind_buffer(WebGlRenderingCtx::ARRAY_BUFFER, None);
}
}
use super::array_buffer::VertexAttribPointerType;
use super::buffer_data::BufferDataStorage;
use crate::shader::ShaderBound;
use crate::Abort;
impl ArrayBufferInstanced {
pub fn new<'a, B: BufferDataStorage<'a, f32>>(
gl: &WebGlContext,
offset_idx: u32,
stride: usize,
sizes: &[usize],
_offsets: &[usize],
usage: u32,
data: B,
) -> ArrayBufferInstanced {
// Instance length
let num_f32_per_instance = sizes.iter().sum::<usize>() as i32;
// Total length
let num_f32_in_buf = data.len() as i32;
let num_instances = num_f32_in_buf / (num_f32_per_instance as i32);
let buffer = gl.create_buffer().ok_or("failed to create buffer").unwrap_abort();
// Bind the buffer
gl.bind_buffer(WebGlRenderingCtx::ARRAY_BUFFER, Some(buffer.as_ref()));
// Pass the vertices data to the buffer
f32::buffer_data_with_array_buffer_view(gl, data, WebGlRenderingCtx::ARRAY_BUFFER, usage);
// Link to the shader
let idx = offset_idx;
f32::vertex_attrib_pointer_with_i32(gl, idx, *sizes.first().unwrap_abort() as i32, 0, 0);
gl.enable_vertex_attrib_array(idx);
#[cfg(feature = "webgl2")]
gl.vertex_attrib_divisor(idx, 1);
#[cfg(feature = "webgl1")]
gl.ext.angles.vertex_attrib_divisor_angle(idx, 1);
let num_packed_data = sizes.len();
let gl = gl.clone();
// Returns an instance that keeps only the buffer
ArrayBufferInstanced {
buffer,
num_packed_data,
offset_idx,
sizes: sizes.to_vec(),
stride,
num_instances,
gl,
}
}
pub fn set_vertex_attrib_pointer_by_name<'a, T: VertexAttribPointerType>(
&self,
shader: &ShaderBound<'a>,
location: &str,
) {
let loc = shader.get_attrib_location(&self.gl, location);
assert_eq!(self.sizes.len(), 1);
self.gl.vertex_attrib_pointer_with_i32(
loc as u32,
*self.sizes.first().unwrap_abort() as i32,
WebGlRenderingCtx::FLOAT,
false,
self.stride as i32,
0,
);
self.gl.enable_vertex_attrib_array(loc as u32);
#[cfg(feature = "webgl2")]
self.gl.vertex_attrib_divisor(loc as u32, 1);
#[cfg(feature = "webgl1")]
self.gl
.ext
.angles
.vertex_attrib_divisor_angle(loc as u32, 1);
}
pub fn disable_vertex_attrib_pointer_by_name<'a>(
&self,
shader: &ShaderBound<'a>,
location: &str,
) {
let loc = shader.get_attrib_location(&self.gl, location);
self.gl.disable_vertex_attrib_array(loc as u32);
}
pub fn update<'a, B: BufferDataStorage<'a, f32>>(&self, buffer: B) {
self.bind();
f32::buffer_sub_data_with_i32_and_array_buffer_view(
&self.gl,
buffer,
WebGlRenderingCtx::ARRAY_BUFFER,
);
/*self.gl.buffer_sub_data_with_i32_and_array_buffer_view(
WebGlRenderingCtx::ARRAY_BUFFER,
0,
&data,
);*/
}
// Add some data at the end of the buffer
/*pub fn append<'a, B: BufferDataStorage<'a, f32>>(&mut self, buffer: B) {
// Create the bigger buffer that will contain the new data appended to the old
// Get the size of the new data to add
let num_f32_in_appended_buf = buffer.len() as i32;
let num_bytes_in_appended_buf =
num_f32_in_appended_buf * (std::mem::size_of::<f32>() as i32);
let dest_buf = self
.gl
.create_buffer()
.ok_or("failed to create buffer")
.unwrap_abort();
// Set its size
self.gl.bind_buffer(
WebGlRenderingCtx::ARRAY_BUFFER,
Some(dest_buf.as_ref()),
);
let num_bytes_in_dest_buf = num_bytes_in_appended_buf + self.num_bytes_in_buf;
self.gl.buffer_data_with_i32(
WebGlRenderingCtx::ARRAY_BUFFER,
num_bytes_in_dest_buf,
self.usage,
);
#[cfg(feature = "webgl2")]
{
// Bind the current buffer to another target.
self.gl.bind_buffer(
WebGlRenderingCtx::COPY_READ_BUFFER,
Some(self.buffer.as_ref()),
);
// Link to the shader
self.set_vertex_attrib_pointers();
// Copy the current buffer to the new one
self.gl.copy_buffer_sub_data_with_i32_and_i32_and_i32(
WebGlRenderingCtx::COPY_READ_BUFFER, // src target
WebGlRenderingCtx::ARRAY_BUFFER, // dest target
0, // read offset
0, // write offset
self.num_bytes_in_buf, // number of bytes to copy
);
// Copy the new data at the end of the buffer
let buffer = f32::array_buffer_view(buffer);
self.gl.buffer_sub_data_with_i32_and_array_buffer_view(
WebGlRenderingCtx::ARRAY_BUFFER,
self.num_bytes_in_buf, // offset in bytes
&buffer,
);
// unbind the buffer of origin
self.gl
.bind_buffer(WebGlRenderingCtx::COPY_READ_BUFFER, None);
}
#[cfg(feature = "webgl1")]
self.buffer = dest_buf;
self.num_bytes_in_buf = num_bytes_in_dest_buf;
self.num_instances = num_bytes_in_dest_buf / self.num_bytes_per_instance;
}*/
// Returns the number of vertices stored in the array buffer
pub fn num_instances(&self) -> i32 {
self.num_instances
}
}
impl Drop for ArrayBufferInstanced {
fn drop(&mut self) {
for idx in 0..self.num_packed_data {
let idx = (idx as u32) + self.offset_idx;
self.gl.disable_vertex_attrib_array(idx);
}
self.gl.delete_buffer(Some(self.buffer.as_ref()));
}
}

View File

@@ -1,43 +0,0 @@
use super::array_buffer::VertexAttribPointerType;
pub trait BufferDataStorage<'a, T: VertexAttribPointerType> {
fn get_slice(&self) -> &[T];
fn is_empty(&self) -> bool {
self.len() == 0
}
fn len(&self) -> usize;
fn ptr(&self) -> *const T;
}
pub struct VecData<'a, T: VertexAttribPointerType>(pub &'a Vec<T>);
impl<'a, T> BufferDataStorage<'a, T> for VecData<'a, T>
where
T: VertexAttribPointerType,
{
fn get_slice(&self) -> &[T] {
self.0
}
fn len(&self) -> usize {
self.0.len()
}
fn ptr(&self) -> *const T {
self.0.as_ptr()
}
}
pub struct SliceData<'a, T: VertexAttribPointerType>(pub &'a [T]);
impl<'a, T> BufferDataStorage<'a, T> for SliceData<'a, T>
where
T: VertexAttribPointerType,
{
fn get_slice(&self) -> &[T] {
self.0
}
fn len(&self) -> usize {
self.0.len()
}
fn ptr(&self) -> *const T {
self.0.as_ptr()
}
}

View File

@@ -1,94 +0,0 @@
use crate::webgl_ctx::WebGlRenderingCtx;
use web_sys::WebGlBuffer;
use super::array_buffer::VertexBufferObject;
use crate::webgl_ctx::WebGlContext;
#[derive(Clone)]
pub struct ElementArrayBuffer {
buffer: WebGlBuffer,
// Size of the buffer in number of elements
len: usize,
gl: WebGlContext,
}
impl VertexBufferObject for ElementArrayBuffer {
fn bind(&self) {
self.gl.bind_buffer(
WebGlRenderingCtx::ELEMENT_ARRAY_BUFFER,
Some(self.buffer.as_ref()),
);
}
fn unbind(&self) {
self.gl
.bind_buffer(WebGlRenderingCtx::ELEMENT_ARRAY_BUFFER, None);
}
}
use super::array_buffer::VertexAttribPointerType;
use super::buffer_data::BufferDataStorage;
use crate::Abort;
impl ElementArrayBuffer {
pub fn new<'a, T: VertexAttribPointerType, B: BufferDataStorage<'a, T>>(
gl: &WebGlContext,
usage: u32,
data: B,
) -> ElementArrayBuffer {
let buffer = gl.create_buffer().ok_or("failed to create buffer").unwrap_abort();
// Bind the buffer
gl.bind_buffer(
WebGlRenderingCtx::ELEMENT_ARRAY_BUFFER,
Some(buffer.as_ref()),
);
// Total length
let len = data.len();
// Pass the vertices data to the buffer
T::buffer_data_with_array_buffer_view(
gl,
data,
WebGlRenderingCtx::ELEMENT_ARRAY_BUFFER,
usage,
);
// Returns an instance that keeps only the buffer
let gl = gl.clone();
ElementArrayBuffer { buffer, len, gl }
}
// Returns the number of vertices stored in the array buffer
pub fn num_elements(&self) -> usize {
self.len
}
pub fn update<'a, T: VertexAttribPointerType, B: BufferDataStorage<'a, T>>(
&mut self,
usage: u32,
data: B,
) {
self.bind();
if self.len >= data.len() {
T::buffer_sub_data_with_i32_and_array_buffer_view(
&self.gl,
data,
WebGlRenderingCtx::ELEMENT_ARRAY_BUFFER,
);
} else {
// Reallocation if the new data size exceeds the size of the buffer
self.len = data.len();
T::buffer_data_with_array_buffer_view(
&self.gl,
data,
WebGlRenderingCtx::ELEMENT_ARRAY_BUFFER,
usage,
);
}
}
}
impl Drop for ElementArrayBuffer {
fn drop(&mut self) {
self.gl.delete_buffer(Some(self.buffer.as_ref()));
}
}

View File

@@ -1,131 +0,0 @@
use {wasm_bindgen::prelude::*, web_sys::WebGlFramebuffer};
use crate::webgl_ctx::WebGlRenderingCtx;
pub struct FrameBufferObject {
gl: WebGlContext,
fbo: WebGlFramebuffer,
pub texture: Texture2D,
}
use crate::webgl_ctx::WebGlContext;
use crate::texture::Texture2D;
impl FrameBufferObject {
pub fn new(gl: &WebGlContext, width: usize, height: usize) -> Result<Self, JsValue> {
let fbo = gl
.create_framebuffer()
.ok_or("failed to create framebuffer")?;
gl.bind_framebuffer(WebGlRenderingCtx::FRAMEBUFFER, Some(&fbo));
let texture = Texture2D::create_empty_with_format::<crate::image::format::RGBA8U>(
gl,
width as i32,
height as i32,
&[
(
WebGlRenderingCtx::TEXTURE_MIN_FILTER,
WebGlRenderingCtx::LINEAR,
),
(
WebGlRenderingCtx::TEXTURE_MAG_FILTER,
WebGlRenderingCtx::LINEAR,
),
// Prevents s-coordinate wrapping (repeating)
(
WebGlRenderingCtx::TEXTURE_WRAP_S,
WebGlRenderingCtx::CLAMP_TO_EDGE,
),
// Prevents t-coordinate wrapping (repeating)
(
WebGlRenderingCtx::TEXTURE_WRAP_T,
WebGlRenderingCtx::CLAMP_TO_EDGE,
),
],
)?;
texture.attach_to_framebuffer();
gl.bind_framebuffer(WebGlRenderingCtx::FRAMEBUFFER, None);
Ok(Self {
gl: gl.clone(),
texture,
fbo,
})
}
pub fn resize(&mut self, width: usize, height: usize) {
if (width, height)
!= (
self.texture.width() as usize,
self.texture.height() as usize,
)
{
//let pixels = [0, 0, 0, 0].iter().cloned().cycle().take(4*height*width).collect::<Vec<_>>();
#[cfg(feature = "webgl2")]
self.texture
.bind_mut()
.tex_image_2d_with_i32_and_i32_and_i32_and_format_and_type_and_opt_u8_array(
width as i32,
height as i32,
WebGlRenderingCtx::SRGB8_ALPHA8 as i32,
WebGlRenderingCtx::RGBA,
WebGlRenderingCtx::UNSIGNED_BYTE,
None,
);
#[cfg(feature = "webgl1")]
self.texture
.bind_mut()
.tex_image_2d_with_i32_and_i32_and_i32_and_format_and_type_and_opt_u8_array(
width as i32,
height as i32,
WebGlRenderingCtx::RGBA as i32,
WebGlRenderingCtx::RGBA,
WebGlRenderingCtx::UNSIGNED_BYTE,
None,
);
}
}
pub fn bind(&self) {
// bind the fbo
self.gl
.bind_framebuffer(WebGlRenderingCtx::FRAMEBUFFER, Some(&self.fbo));
let w = self.texture.width() as i32;
let h = self.texture.height() as i32;
self.gl.viewport(0, 0, w, h);
self.gl.scissor(0, 0, w, h);
}
pub fn draw_onto(
&self,
f: impl FnOnce() -> Result<(), JsValue>,
cur_fbo: Option<&Self>,
) -> Result<(), JsValue> {
// bind the fbo
self.bind();
// clear the fbo
self.gl.clear_color(0.0, 0.0, 0.0, 0.0);
self.gl.clear(WebGlRenderingCtx::COLOR_BUFFER_BIT);
// render all the things onto the fbo
f()?;
// restore the fbo to its previous state
if let Some(prev_fbo) = cur_fbo {
prev_fbo.bind();
} else {
self.gl
.bind_framebuffer(WebGlRenderingCtx::FRAMEBUFFER, None);
}
Ok(())
}
}
impl Drop for FrameBufferObject {
fn drop(&mut self) {
self.gl.delete_framebuffer(Some(&self.fbo));
}
}

View File

@@ -1,14 +0,0 @@
pub mod array_buffer;
pub mod array_buffer_instanced;
pub mod framebuffer;
pub mod buffer_data;
pub mod element_array_buffer;
pub mod vertex_array_object;
pub use array_buffer::ArrayBuffer;
pub use array_buffer::VertexAttribPointerType;
pub use framebuffer::FrameBufferObject;
pub use vertex_array_object::vao::{
ShaderVertexArrayObjectBound, ShaderVertexArrayObjectBoundRef, VertexArrayObject,
};

View File

@@ -1,727 +0,0 @@
#[cfg(feature = "webgl2")]
pub mod vao {
use crate::VertexAttribPointerType;
use web_sys::WebGlVertexArrayObject;
use crate::object::array_buffer::ArrayBuffer;
use crate::object::array_buffer_instanced::ArrayBufferInstanced;
use crate::object::buffer_data::BufferDataStorage;
use crate::object::element_array_buffer::ElementArrayBuffer;
use crate::webgl_ctx::WebGlContext;
use std::collections::HashMap;
use crate::Abort;
pub struct VertexArrayObject {
array_buffer: HashMap<&'static str, ArrayBuffer>,
array_buffer_instanced: HashMap<&'static str, ArrayBufferInstanced>,
element_array_buffer: Option<ElementArrayBuffer>,
idx: u32, // Number of vertex attributes
vao: WebGlVertexArrayObject,
gl: WebGlContext,
}
impl VertexArrayObject {
pub fn new(gl: &WebGlContext) -> VertexArrayObject {
let vao = gl
.create_vertex_array()
.ok_or("failed to create the vertex array buffer")
.unwrap_abort();
let array_buffer = HashMap::new();
let array_buffer_instanced = HashMap::new();
let element_array_buffer = None;
let idx = 0;
let gl = gl.clone();
VertexArrayObject {
array_buffer,
array_buffer_instanced,
element_array_buffer,
idx,
vao,
gl,
}
}
// Shader has to be already bound before calling this
// This returns a ShaderVertexArrayObjectBound for which it is possible
// to add some buffers and or draw the buffers
pub fn bind<'a, 'b>(
&'a mut self,
_shader: &'b ShaderBound<'b>,
) -> ShaderVertexArrayObjectBound<'a, 'b> {
self.gl.bind_vertex_array(Some(self.vao.as_ref()));
ShaderVertexArrayObjectBound { vao: self, _shader }
}
// Shader has to be already bound before calling this
// This returns a ShaderVertexArrayObjectBound for which it is possible
// to add some buffers and or draw the buffers
pub fn bind_ref<'a, 'b>(
&'a self,
_shader: &'b ShaderBound<'b>,
) -> ShaderVertexArrayObjectBoundRef<'a, 'b> {
self.gl.bind_vertex_array(Some(self.vao.as_ref()));
ShaderVertexArrayObjectBoundRef { vao: self, _shader }
}
// No need to bind a shader here
// This returns a VertexArrayObjectBound for which it is only possible to
// update the buffers
pub fn bind_for_update(&mut self) -> VertexArrayObjectBound<'_> {
self.gl.bind_vertex_array(Some(self.vao.as_ref()));
VertexArrayObjectBound { vao: self }
}
/*pub fn bind_ref(&self) {
self.gl.bind_vertex_array(Some(self.vao.as_ref()));
}*/
pub fn num_elements(&self) -> usize {
self.element_array_buffer.as_ref().unwrap_abort().num_elements()
}
pub fn num_instances(&self) -> i32 {
self.array_buffer_instanced
.values()
.next()
.unwrap_abort()
.num_instances()
}
}
impl Drop for VertexArrayObject {
fn drop(&mut self) {
//self.unbind();
self.gl.delete_vertex_array(Some(self.vao.as_ref()));
}
}
use crate::shader::ShaderBound;
pub struct ShaderVertexArrayObjectBound<'a, 'b> {
vao: &'a mut VertexArrayObject,
_shader: &'b ShaderBound<'b>,
}
use web_sys::WebGl2RenderingContext;
impl<'a, 'b> ShaderVertexArrayObjectBound<'a, 'b> {
pub fn update_array<T: VertexAttribPointerType, B: BufferDataStorage<'a, T>>(
&mut self,
attr: &'static str,
usage: u32,
array_data: B,
) -> &mut Self {
self.vao
.array_buffer
.get_mut(attr)
.unwrap_abort()
.update(usage, array_data);
self
}
pub fn update_element_array<T: VertexAttribPointerType, B: BufferDataStorage<'a, T>>(
&mut self,
usage: u32,
element_data: B,
) -> &mut Self {
if let Some(ref mut element_array_buffer) = self.vao.element_array_buffer {
element_array_buffer.update(usage, element_data);
}
self
}
pub fn update_instanced_array<B: BufferDataStorage<'a, f32>>(
&mut self,
attr: &'static str,
array_data: B,
) -> &mut Self {
self.vao
.array_buffer_instanced
.get_mut(attr)
.unwrap_abort()
.update(array_data);
self
}
pub fn unbind(&self) {
self.vao.gl.bind_vertex_array(None);
}
}
impl<'a, 'b> Drop for ShaderVertexArrayObjectBound<'a, 'b> {
fn drop(&mut self) {
self.unbind();
}
}
pub struct ShaderVertexArrayObjectBoundRef<'a, 'b> {
vao: &'a VertexArrayObject,
_shader: &'b ShaderBound<'b>,
}
impl<'a, 'b> ShaderVertexArrayObjectBoundRef<'a, 'b> {
pub fn draw_arrays(&self, mode: u32, byte_offset: i32, size: i32) {
self.vao.gl.draw_arrays(mode, byte_offset, size);
}
pub fn draw_elements_with_i32(
&self,
mode: u32,
num_elements: Option<i32>,
type_: u32,
byte_offset: i32,
) {
let num_elements = num_elements.unwrap_or(self.vao.num_elements() as i32);
self.vao
.gl
.draw_elements_with_i32(mode, num_elements, type_, byte_offset);
}
pub fn draw_elements_instanced_with_i32(
&self,
mode: u32,
offset_element_idx: i32,
num_instances: i32,
) {
self.vao.gl.draw_elements_instanced_with_i32(
mode,
self.vao.num_elements() as i32,
WebGl2RenderingContext::UNSIGNED_SHORT,
offset_element_idx,
num_instances,
);
}
pub fn unbind(&self) {
self.vao.gl.bind_vertex_array(None);
}
}
impl<'a, 'b> Drop for ShaderVertexArrayObjectBoundRef<'a, 'b> {
fn drop(&mut self) {
self.unbind();
}
}
// Struct defined when only the Vertex Array Object is
// defined
pub struct VertexArrayObjectBound<'a> {
vao: &'a mut VertexArrayObject,
}
impl<'a> VertexArrayObjectBound<'a> {
/// Precondition: self must be bound
pub fn add_array_buffer<T: VertexAttribPointerType, B: BufferDataStorage<'a, T>>(
&mut self,
attr: &'static str,
stride: usize,
sizes: &[usize],
offsets: &[usize],
usage: u32,
data: B,
) -> &mut Self {
let array_buffer = ArrayBuffer::new(
&self.vao.gl,
self.vao.idx,
stride,
sizes,
offsets,
usage,
data,
);
// Update the number of vertex attrib
self.vao.idx += sizes.len() as u32;
self.vao.array_buffer.insert(attr, array_buffer);
self
}
pub fn add_array_buffer_single<T: VertexAttribPointerType, B: BufferDataStorage<'a, T>>(
&mut self,
size: usize,
attr: &'static str,
usage: u32,
data: B,
) -> &mut Self {
let array_buffer =
ArrayBuffer::new(&self.vao.gl, self.vao.idx, 0, &[size], &[0], usage, data);
// Update the number of vertex attrib
self.vao.idx += 1;
self.vao.array_buffer.insert(attr, array_buffer);
self
}
/// Precondition: self must be bound
pub fn add_instanced_array_buffer<B: BufferDataStorage<'a, f32>>(
&mut self,
attr: &'static str,
stride: usize,
sizes: &[usize],
offsets: &[usize],
usage: u32,
data: B,
) -> &mut Self {
let array_buffer = ArrayBufferInstanced::new(
&self.vao.gl,
self.vao.idx,
stride,
sizes,
offsets,
usage,
data,
);
// Update the number of vertex attrib
self.vao.idx += sizes.len() as u32;
self.vao.array_buffer_instanced.insert(attr, array_buffer);
self
}
/// Precondition: self must be bound
pub fn add_element_buffer<T: VertexAttribPointerType, B: BufferDataStorage<'a, T>>(
&mut self,
usage: u32,
data: B,
) -> &mut Self {
let element_buffer = ElementArrayBuffer::new(&self.vao.gl, usage, data);
self.vao.element_array_buffer = Some(element_buffer);
self
}
pub fn update_array<T: VertexAttribPointerType, B: BufferDataStorage<'a, T>>(
&mut self,
attr: &'static str,
usage: u32,
array_data: B,
) -> &mut Self {
self.vao
.array_buffer
.get_mut(attr)
.unwrap_abort()
.update(usage, array_data);
self
}
pub fn update_element_array<T: VertexAttribPointerType, B: BufferDataStorage<'a, T>>(
&mut self,
usage: u32,
element_data: B,
) -> &mut Self {
if let Some(ref mut element_array_buffer) = self.vao.element_array_buffer {
element_array_buffer.update(usage, element_data);
}
self
}
pub fn update_instanced_array<B: BufferDataStorage<'a, f32>>(
&mut self,
attr: &'static str,
array_data: B,
) -> &mut Self {
self.vao
.array_buffer_instanced
.get_mut(attr)
.unwrap_abort()
.update(array_data);
self
}
/*pub fn append_to_instanced_array<B: BufferDataStorage<'a, f32>>(
&mut self,
idx: usize,
buffer: B,
) -> &mut Self {
self.vao.array_buffer_instanced[idx].append(buffer);
self
}*/
pub fn unbind(&self) {
self.vao.gl.bind_vertex_array(None);
}
}
impl<'a> Drop for VertexArrayObjectBound<'a> {
fn drop(&mut self) {
self.unbind();
}
}
}
#[cfg(feature = "webgl1")]
pub mod vao {
use crate::object::array_buffer::ArrayBuffer;
use crate::object::array_buffer_instanced::ArrayBufferInstanced;
use crate::object::buffer_data::BufferDataStorage;
use crate::object::element_array_buffer::ElementArrayBuffer;
use crate::webgl_ctx::WebGlContext;
use crate::Abort;
use std::collections::HashMap;
pub struct VertexArrayObject {
array_buffer: HashMap<&'static str, ArrayBuffer>,
array_buffer_instanced: HashMap<&'static str, ArrayBufferInstanced>,
element_array_buffer: Option<ElementArrayBuffer>,
idx: u32, // Number of vertex attributes
gl: WebGlContext,
}
impl VertexArrayObject {
pub fn new(gl: &WebGlContext) -> VertexArrayObject {
let array_buffer = HashMap::new();
let array_buffer_instanced = HashMap::new();
let element_array_buffer = None;
let idx = 0;
let gl = gl.clone();
VertexArrayObject {
array_buffer,
array_buffer_instanced,
element_array_buffer,
idx,
gl,
}
}
// Shader has to be already bound before calling this
// This returns a ShaderVertexArrayObjectBound for which it is possible
// to add some buffers and or draw the buffers
pub fn bind<'a, 'b>(
&'a mut self,
_shader: &'b ShaderBound<'b>,
) -> ShaderVertexArrayObjectBound<'a, 'b> {
//self.gl.bind_vertex_array(Some(self.vao.as_ref()));
ShaderVertexArrayObjectBound { vao: self, _shader }
}
// Shader has to be already bound before calling this
// This returns a ShaderVertexArrayObjectBound for which it is possible
// to add some buffers and or draw the buffers
pub fn bind_ref<'a, 'b>(
&'a self,
shader: &'b ShaderBound<'b>,
) -> ShaderVertexArrayObjectBoundRef<'a, 'b> {
//self.gl.bind_vertex_array(Some(self.vao.as_ref()));
ShaderVertexArrayObjectBoundRef { vao: self, shader }
}
// No need to bind a shader here
// This returns a VertexArrayObjectBound for which it is only possible to
// update the buffers
pub fn bind_for_update<'a>(&'a mut self) -> VertexArrayObjectBound<'a> {
//self.gl.bind_vertex_array(Some(self.vao.as_ref()));
VertexArrayObjectBound { vao: self }
}
/*pub fn bind_ref(&self) {
self.gl.bind_vertex_array(Some(self.vao.as_ref()));
}*/
pub fn num_elements(&self) -> usize {
self.element_array_buffer.as_ref().unwrap_abort().num_elements()
}
pub fn num_instances(&self) -> i32 {
self.array_buffer_instanced
.values()
.next()
.unwrap_abort()
.num_instances()
}
}
impl Drop for VertexArrayObject {
fn drop(&mut self) {
//self.unbind();
//self.gl.delete_vertex_array(Some(self.vao.as_ref()));
}
}
use crate::shader::ShaderBound;
pub struct ShaderVertexArrayObjectBound<'a, 'b> {
vao: &'a mut VertexArrayObject,
_shader: &'b ShaderBound<'b>,
}
use crate::VertexAttribPointerType;
impl<'a, 'b> ShaderVertexArrayObjectBound<'a, 'b> {
pub fn update_array<T: VertexAttribPointerType, B: BufferDataStorage<'a, T>>(
&mut self,
attr: &'static str,
usage: u32,
array_data: B,
) -> &mut Self {
self.vao
.array_buffer
.get_mut(attr)
.unwrap_abort()
.update(usage, array_data);
self
}
pub fn update_element_array<T: VertexAttribPointerType, B: BufferDataStorage<'a, T>>(
&mut self,
usage: u32,
element_data: B,
) -> &mut Self {
if let Some(ref mut element_array_buffer) = self.vao.element_array_buffer {
element_array_buffer.update(usage, element_data);
}
self
}
pub fn update_instanced_array<B: BufferDataStorage<'a, f32>>(
&mut self,
attr: &'static str,
array_data: B,
) -> &mut Self {
self.vao
.array_buffer_instanced
.get_mut(attr)
.unwrap_abort()
.update(array_data);
self
}
pub fn unbind(&self) {
//self.vao.gl.bind_vertex_array(None);
}
}
impl<'a, 'b> Drop for ShaderVertexArrayObjectBound<'a, 'b> {
fn drop(&mut self) {
self.unbind();
}
}
use crate::webgl_ctx::WebGlRenderingCtx;
pub struct ShaderVertexArrayObjectBoundRef<'a, 'b> {
vao: &'a VertexArrayObject,
shader: &'b ShaderBound<'b>,
}
use crate::object::array_buffer::VertexBufferObject;
impl<'a, 'b> ShaderVertexArrayObjectBoundRef<'a, 'b> {
pub fn draw_arrays(&self, mode: u32, byte_offset: i32, size: i32) {
for (attr, buf) in self.vao.array_buffer.iter() {
buf.bind();
buf.set_vertex_attrib_pointer_by_name::<f32>(self.shader, attr);
}
self.vao.gl.draw_arrays(mode, byte_offset, size);
}
pub fn draw_elements_with_i32(
&self,
mode: u32,
num_elements: Option<i32>,
type_: u32,
byte_offset: i32,
) {
for (attr, buf) in self.vao.array_buffer.iter() {
buf.bind();
buf.set_vertex_attrib_pointer_by_name::<f32>(self.shader, attr);
}
let e = self.vao.element_array_buffer.as_ref().unwrap_abort();
e.bind();
let num_elements = num_elements.unwrap_or(self.vao.num_elements() as i32);
self.vao
.gl
.draw_elements_with_i32(mode, num_elements, type_, byte_offset);
}
pub fn draw_elements_instanced_with_i32(
&self,
mode: u32,
offset_element_idx: i32,
num_instances: i32,
) {
for (attr, buf) in self.vao.array_buffer.iter() {
buf.bind();
buf.set_vertex_attrib_pointer_by_name::<f32>(self.shader, attr);
}
for (attr, inst_buf) in self.vao.array_buffer_instanced.iter() {
inst_buf.bind();
inst_buf.set_vertex_attrib_pointer_by_name::<f32>(self.shader, attr);
}
let e = self.vao.element_array_buffer.as_ref().unwrap_abort();
e.bind();
self.vao
.gl
.ext
.angles
.draw_elements_instanced_angle_with_i32(
mode,
self.vao.num_elements() as i32,
WebGlRenderingCtx::UNSIGNED_SHORT,
offset_element_idx,
num_instances,
);
}
pub fn unbind(&self) {
//self.vao.gl.bind_vertex_array(None);
}
}
impl<'a, 'b> Drop for ShaderVertexArrayObjectBoundRef<'a, 'b> {
fn drop(&mut self) {
self.unbind();
}
}
// Struct defined when only the Vertex Array Object is
// defined
pub struct VertexArrayObjectBound<'a> {
vao: &'a mut VertexArrayObject,
}
impl<'a> VertexArrayObjectBound<'a> {
/// Precondition: self must be bound
pub fn add_array_buffer<T: VertexAttribPointerType, B: BufferDataStorage<'a, T>>(
&mut self,
size: usize,
attr: &'static str,
usage: u32,
data: B,
) -> &mut Self {
let array_buffer =
ArrayBuffer::new(&self.vao.gl, self.vao.idx, 0, &[size], &[0], usage, data);
// Update the number of vertex attrib
self.vao.idx += 1;
self.vao.array_buffer.insert(attr, array_buffer);
self
}
/// Precondition: self must be bound
pub fn add_instanced_array_buffer<B: BufferDataStorage<'a, f32>>(
&mut self,
size: usize,
attr: &'static str,
usage: u32,
data: B,
) -> &mut Self {
let array_buffer = ArrayBufferInstanced::new(
&self.vao.gl,
self.vao.idx,
0,
&[size],
&[0],
usage,
data,
);
// Update the number of vertex attrib
self.vao.idx += 1;
self.vao.array_buffer_instanced.insert(attr, array_buffer);
self
}
/// Precondition: self must be bound
pub fn add_element_buffer<T: VertexAttribPointerType, B: BufferDataStorage<'a, T>>(
&mut self,
usage: u32,
data: B,
) -> &mut Self {
let element_buffer = ElementArrayBuffer::new(&self.vao.gl, usage, data);
self.vao.element_array_buffer = Some(element_buffer);
self
}
pub fn update_array<T: VertexAttribPointerType, B: BufferDataStorage<'a, T>>(
&mut self,
attr: &'static str,
usage: u32,
array_data: B,
) -> &mut Self {
self.vao
.array_buffer
.get_mut(attr)
.expect("cannot get attribute from the array buffer")
.update(usage, array_data);
self
}
pub fn update_element_array<T: VertexAttribPointerType, B: BufferDataStorage<'a, T>>(
&mut self,
usage: u32,
element_data: B,
) -> &mut Self {
if let Some(ref mut element_array_buffer) = self.vao.element_array_buffer {
element_array_buffer.update(usage, element_data);
}
self
}
pub fn update_instanced_array<B: BufferDataStorage<'a, f32>>(
&mut self,
attr: &'static str,
array_data: B,
) -> &mut Self {
self.vao
.array_buffer_instanced
.get_mut(attr)
.expect("cannot get attribute from the array buffer")
.update(array_data);
self
}
/*pub fn append_to_instanced_array<B: BufferDataStorage<'a, f32>>(
&mut self,
idx: usize,
buffer: B,
) -> &mut Self {
self.vao.array_buffer_instanced[idx].append(buffer);
self
}*/
pub fn unbind(&self) {
//self.vao.gl.bind_vertex_array(None);
}
}
impl<'a> Drop for VertexArrayObjectBound<'a> {
fn drop(&mut self) {
self.unbind();
}
}
}

View File

@@ -1,404 +0,0 @@
use al_api::hips::GrayscaleColor;
use web_sys::{WebGlProgram, WebGlShader, WebGlUniformLocation};
use crate::webgl_ctx::WebGlRenderingCtx;
fn compile_shader(
gl: &WebGlContext,
shader_type: u32,
source: &str,
) -> Result<WebGlShader, String> {
let shader = gl
.create_shader(shader_type)
.ok_or_else(|| String::from("Unable to create shader object"))?;
gl.shader_source(&shader, source);
gl.compile_shader(&shader);
if gl
.get_shader_parameter(&shader, WebGlRenderingCtx::COMPILE_STATUS)
.as_bool()
.unwrap_or(false)
{
Ok(shader)
} else {
Err(gl
.get_shader_info_log(&shader)
.unwrap_or_else(|| String::from("Unknown error creating shader")))
}
}
fn link_program<'a, T: IntoIterator<Item = &'a WebGlShader>>(
gl: &WebGlContext,
shaders: T,
) -> Result<WebGlProgram, String> {
let program = gl
.create_program()
.ok_or_else(|| String::from("Unable to create shader object"))?;
for shader in shaders {
gl.attach_shader(&program, shader)
}
gl.link_program(&program);
if gl
.get_program_parameter(&program, WebGlRenderingCtx::LINK_STATUS)
.as_bool()
.unwrap_or(false)
{
Ok(program)
} else {
Err(gl
.get_program_info_log(&program)
.unwrap_or_else(|| String::from("Unknown error creating program object")))
}
}
type UniformLocations = HashMap<String, Option<WebGlUniformLocation>>;
fn get_active_uniform_locations(gl: &WebGlContext, program: &WebGlProgram) -> UniformLocations {
let num_uniforms = gl
.get_program_parameter(program, WebGlRenderingCtx::ACTIVE_UNIFORMS)
.as_f64()
.unwrap_abort();
(0..num_uniforms as u32)
.map(|idx_uniform| {
let active_uniform = gl.get_active_uniform(program, idx_uniform).unwrap_abort();
let name_uniform = active_uniform.name();
// Get the location by the name of the active uniform
let location_uniform = gl.get_uniform_location(program, &name_uniform);
(name_uniform, location_uniform)
})
.collect::<HashMap<_, _>>()
}
use std::collections::HashMap;
pub struct Shader {
pub program: WebGlProgram,
uniform_locations: UniformLocations,
}
use crate::webgl_ctx::WebGlContext;
impl Shader {
pub fn new(gl: &WebGlContext, vert_src: &str, frag_src: &str) -> Result<Shader, String> {
let vert_shader = compile_shader(gl, WebGlRenderingCtx::VERTEX_SHADER, vert_src)?;
let frag_shader = compile_shader(gl, WebGlRenderingCtx::FRAGMENT_SHADER, frag_src)?;
let program = link_program(gl, &[vert_shader, frag_shader])?;
// Get the active uniforms
let uniform_locations = get_active_uniform_locations(gl, &program);
Ok(Shader {
program,
uniform_locations,
})
}
pub fn bind<'a>(&'a self, gl: &WebGlContext) -> ShaderBound<'a> {
unsafe { CUR_IDX_TEX_UNIT = 0 };
gl.use_program(Some(&self.program));
let gl = gl.clone();
ShaderBound { shader: self, gl }
}
pub fn get_attrib_location(&self, gl: &WebGlContext, name: &str) -> i32 {
gl.get_attrib_location(&self.program, name)
}
}
pub trait UniformType {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, value: &Self);
fn attach_uniform<'a>(name: &str, value: &Self, shader: &ShaderBound<'a>) {
let location = shader.get_uniform_location(name);
Self::uniform(&shader.gl, location, value);
}
}
impl UniformType for bool {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, value: &Self) {
gl.uniform1i(location, *value as i32);
}
}
impl UniformType for i32 {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, value: &Self) {
gl.uniform1i(location, *value);
}
}
impl UniformType for f32 {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, value: &Self) {
gl.uniform1f(location, *value);
}
}
impl UniformType for f64 {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, value: &Self) {
gl.uniform1f(location, *value as f32);
}
}
impl UniformType for &[f32] {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, value: &Self) {
gl.uniform1fv_with_f32_array(location, value);
}
}
impl UniformType for &[f64] {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, value: &Self) {
let values_f32 = value.iter().map(|i| *i as f32).collect::<Vec<_>>();
gl.uniform1fv_with_f32_array(location, values_f32.as_slice());
}
}
impl UniformType for &[i32] {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, value: &Self) {
gl.uniform1iv_with_i32_array(location, value);
}
}
use cgmath::Vector2;
impl UniformType for Vector2<f32> {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, value: &Self) {
gl.uniform2f(location, value.x, value.y);
}
}
impl UniformType for Vector2<f64> {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, value: &Self) {
gl.uniform2f(location, value.x as f32, value.y as f32);
}
}
use cgmath::Vector3;
impl UniformType for Vector3<f32> {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, value: &Self) {
gl.uniform3f(location, value.x, value.y, value.z);
}
}
impl UniformType for Vector3<f64> {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, value: &Self) {
gl.uniform3f(location, value.x as f32, value.y as f32, value.z as f32);
}
}
impl UniformType for [f32; 3] {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, value: &Self) {
gl.uniform3f(location, value[0], value[1], value[2]);
}
}
impl UniformType for [f32; 4] {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, v: &Self) {
gl.uniform4f(location, v[0], v[1], v[2], v[3]);
}
}
use cgmath::Vector4;
impl UniformType for Vector4<f32> {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, value: &Self) {
gl.uniform4f(location, value.x, value.y, value.z, value.w);
}
}
impl UniformType for Vector4<f64> {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, value: &Self) {
gl.uniform4f(
location,
value.x as f32,
value.y as f32,
value.z as f32,
value.w as f32,
);
}
}
use cgmath::Matrix2;
impl UniformType for Matrix2<f32> {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, value: &Self) {
gl.uniform_matrix2fv_with_f32_array(location, false, value.as_ref() as &[f32; 4]);
}
}
use cgmath::Matrix4;
impl UniformType for Matrix4<f32> {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, value: &Self) {
gl.uniform_matrix4fv_with_f32_array(location, false, value.as_ref() as &[f32; 16]);
}
}
use crate::Abort;
impl UniformType for Matrix4<f64> {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, value: &Self) {
// Cast the matrix
let mat_f32 = value.cast::<f32>().unwrap_abort();
gl.uniform_matrix4fv_with_f32_array(location, false, mat_f32.as_ref() as &[f32; 16]);
}
}
use super::texture::Texture2D;
use super::texture::CUR_IDX_TEX_UNIT;
impl UniformType for Texture2D {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, tex: &Self) {
unsafe {
let _ = tex
// 1. Active the texture unit of the texture
.active_texture(CUR_IDX_TEX_UNIT)
// 2. Bind the texture to that texture unit
.bind();
gl.uniform1i(location, CUR_IDX_TEX_UNIT as i32);
CUR_IDX_TEX_UNIT += 1;
};
}
}
use al_api::color::ColorRGB;
impl UniformType for ColorRGB {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, value: &Self) {
gl.uniform3f(location, value.r, value.g, value.b);
}
}
impl<'a> UniformType for &'a ColorRGB {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, value: &Self) {
gl.uniform3f(location, value.r, value.g, value.b);
}
}
use al_api::color::ColorRGBA;
impl UniformType for ColorRGBA {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, value: &Self) {
gl.uniform4f(location, value.r, value.g, value.b, value.a);
}
}
impl<'a> UniformType for &'a ColorRGBA {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, value: &Self) {
gl.uniform4f(location, value.r, value.g, value.b, value.a);
}
}
use al_api::hips::TransferFunction;
impl SendUniforms for TransferFunction {
fn attach_uniforms<'a>(&self, shader: &'a ShaderBound<'a>) -> &'a ShaderBound<'a> {
shader.attach_uniform("H", self);
shader
}
}
impl UniformType for TransferFunction {
fn uniform(gl: &WebGlContext, location: Option<&WebGlUniformLocation>, value: &Self) {
gl.uniform1i(location, *value as i32);
}
}
/*use al_api::hips::GrayscaleParameter;
impl SendUniforms for GrayscaleParameter {
fn attach_uniforms<'a>(&self, shader: &'a ShaderBound<'a>) -> &'a ShaderBound<'a> {
shader
.attach_uniforms_from(&self.h)
.attach_uniform("min_value", &self.min_value)
.attach_uniform("max_value", &self.max_value);
shader
}
}*/
use al_api::colormap::Colormap;
use al_api::hips::HiPSColor;
impl SendUniforms for HiPSColor {
fn attach_uniforms<'a>(&self, shader: &'a ShaderBound<'a>) -> &'a ShaderBound<'a> {
match self {
HiPSColor::Color => (),
HiPSColor::Grayscale {
tf,
min_cut,
max_cut,
color,
} => match color {
GrayscaleColor::Color(color) => {
shader
.attach_uniform("H", tf)
.attach_uniform("min_value", &min_cut.unwrap_or(0.0))
.attach_uniform("max_value", &max_cut.unwrap_or(1.0))
.attach_uniform("C", color)
.attach_uniform("K", &1.0_f32);
}
GrayscaleColor::Colormap { reversed, name } => {
let reversed = *reversed as u8 as f32;
shader
.attach_uniforms_from(name)
.attach_uniform("H", tf)
.attach_uniform("min_value", &min_cut.unwrap_or(0.0))
.attach_uniform("max_value", &max_cut.unwrap_or(1.0))
.attach_uniform("reversed", &reversed);
}
},
}
shader
}
}
impl SendUniforms for Colormap {
fn attach_uniforms<'a>(&self, shader: &'a ShaderBound<'a>) -> &'a ShaderBound<'a> {
shader.attach_uniform("colormap_id", &((*self as i32) as f32));
shader
}
}
pub struct ShaderBound<'a> {
pub shader: &'a Shader,
gl: WebGlContext,
}
use crate::object::{
ShaderVertexArrayObjectBound, ShaderVertexArrayObjectBoundRef, VertexArrayObject,
};
impl<'a> ShaderBound<'a> {
fn get_uniform_location(&self, name: &str) -> Option<&WebGlUniformLocation> {
if let Some(location) = self.shader.uniform_locations.get(name) {
location.as_ref()
} else {
None
}
}
pub fn attach_uniform<T: UniformType>(&self, name: &str, value: &T) -> &Self {
T::attach_uniform(name, value, self);
self
}
pub fn attach_uniforms_from<T: SendUniforms>(&'a self, t: &T) -> &'a Self {
t.attach_uniforms(self);
self
}
pub fn bind_vertex_array_object<'b>(
&'a self,
vao: &'b mut VertexArrayObject,
) -> ShaderVertexArrayObjectBound<'b, 'a> {
vao.bind(self)
}
pub fn bind_vertex_array_object_ref<'b>(
&'a self,
vao: &'b VertexArrayObject,
) -> ShaderVertexArrayObjectBoundRef<'b, 'a> {
vao.bind_ref(self)
}
pub fn unbind(&'a self, gl: &WebGlContext) -> &'a Shader {
gl.use_program(None);
self.shader
}
pub fn get_attrib_location(&self, gl: &WebGlContext, name: &str) -> i32 {
self.shader.get_attrib_location(gl, name)
}
}
impl<'a> Drop for ShaderBound<'a> {
fn drop(&mut self) {
self.unbind(&self.gl);
}
}
pub trait SendUniforms {
fn attach_uniforms<'a>(&self, shader: &'a ShaderBound<'a>) -> &'a ShaderBound<'a>;
}

View File

@@ -1,171 +0,0 @@
#[derive(Serialize, Deserialize)]
pub struct LetterTexPosition {
pub x_min: u32,
pub x_max: u32,
pub y_min: u32,
pub y_max: u32,
pub x_advance: u32,
pub y_advance: u32,
pub w: u32,
pub h: u32,
pub bound_xmin: f32,
pub bound_ymin: f32,
}
use std::collections::HashMap;
use serde::{Serialize, Deserialize};
pub struct Font {
pub bitmap: Vec<u8>,
pub letters: HashMap<char, LetterTexPosition>,
}
pub const TEX_SIZE: usize = 256;
mod tests {
#[test]
pub fn rasterize_font() {
#[derive(PartialEq)]
struct Letter {
pub l: char,
pub w: u32,
pub h: u32,
pub x_advance: u32,
pub y_advance: u32,
pub bitmap: Vec<u8>,
pub bounds: fontdue::OutlineBounds,
}
use std::cmp::Ordering;
impl PartialOrd for Letter {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
let w_cmp = other.w.cmp(&self.w);
if Ordering::Equal == w_cmp {
Some(other.h.cmp(&self.h))
} else {
Some(w_cmp)
}
}
}
use super::TEX_SIZE;
use super::LetterTexPosition;
use std::collections::HashMap;
use std::io::Write;
// Read the font data.
let font = include_bytes!("../resources/arial.ttf") as &[u8];
// Parse it into the font type.
let font = fontdue::Font::from_bytes(font, fontdue::FontSettings::default()).unwrap();
// Rasterize and get the layout metrics for the letter 'g' at 17px.
let mut w = 0;
let mut h = 0;
let mut letters = Vec::new();
for c in 0_u8..255_u8 {
let (metrics, bitmap) = font.rasterize(c as char, 16.0);
letters.push(Letter {
w: metrics.width as u32,
h: metrics.height as u32,
x_advance: metrics.advance_width as u32,
y_advance: metrics.advance_height as u32,
bounds: metrics.bounds,
l: c as char,
bitmap,
});
h += metrics.height;
w = std::cmp::max(w, metrics.width);
}
letters.sort_unstable_by(|l, r| {
let w_cmp = r.w.cmp(&l.w);
if Ordering::Equal == w_cmp {
r.h.cmp(&l.h)
} else {
w_cmp
}
});
let mut letters_tex = HashMap::new();
let mut x_min = 0;
let mut y_min = 0;
let mut size_col = letters[0].w;
let mut img = vec![0; TEX_SIZE * TEX_SIZE * 4];
for Letter {
l,
w,
h,
x_advance,
y_advance,
bitmap,
bounds,
} in letters.into_iter()
{
let mut i = 0;
let mut y_max = y_min + h;
if y_max >= TEX_SIZE as u32 {
y_min = 0;
y_max = h;
x_min += size_col;
size_col = w;
}
// Draw here the letter in the tex
let x_max = x_min + w;
letters_tex.insert(
l,
LetterTexPosition {
x_min,
x_max,
y_min,
y_max,
x_advance,
y_advance,
w: x_max - x_min,
h: y_max - y_min,
bound_xmin: bounds.xmin,
bound_ymin: bounds.ymin,
},
);
for y in (y_min as usize)..(y_max as usize) {
for x in (x_min as usize)..(x_max as usize) {
img[4 * (x + TEX_SIZE * y)] = bitmap[i];
img[4 * (x + TEX_SIZE * y) + 1] = bitmap[i];
img[4 * (x + TEX_SIZE * y) + 2] = bitmap[i];
img[4 * (x + TEX_SIZE * y) + 3] = bitmap[i];
i += 1;
}
}
y_min += h;
}
/* Save the jpeg file */
use std::fs::File;
use std::io::BufWriter;
let file = File::create("letters.png").unwrap();
let ref mut w = BufWriter::new(file);
let mut encoder = png::Encoder::new(w, TEX_SIZE as u32, TEX_SIZE as u32); // Width is 2 pixels and height is 1.
encoder.set_color(png::ColorType::Rgba);
encoder.set_depth(png::BitDepth::Eight);
let mut writer = encoder.write_header().unwrap();
writer.write_image_data(&img).unwrap(); // Save
/* Save the letters position */
let letters_tex_serialized = serde_json::to_string(&letters_tex).unwrap();
let mut file = File::create("letters.json").unwrap();
write!(file, "{}", letters_tex_serialized).unwrap();
}
}

View File

@@ -1,581 +0,0 @@
pub mod texture_array;
pub use texture_array::Texture2DArray;
pub mod pixel;
pub use pixel::*;
use crate::webgl_ctx::WebGlContext;
use crate::webgl_ctx::WebGlRenderingCtx;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use web_sys::HtmlImageElement;
pub static mut CUR_IDX_TEX_UNIT: u8 = 0;
#[derive(Clone)]
#[allow(dead_code)]
struct Texture2DMeta {
pub format: u32,
pub internal_format: i32,
pub type_: u32,
pub width: u32,
pub height: u32,
}
use web_sys::WebGlTexture;
pub struct Texture2D {
pub texture: Option<WebGlTexture>,
gl: WebGlContext,
metadata: Option<Rc<RefCell<Texture2DMeta>>>,
}
use crate::image::format::ImageFormat;
//use super::pixel::PixelType;
use std::path::Path;
use std::rc::Rc;
use std::cell::RefCell;
impl Texture2D {
pub fn create_from_path<P: AsRef<Path>, F: ImageFormat>(
gl: &WebGlContext,
name: &'static str,
src: &P,
tex_params: &'static [(u32, u32)],
) -> Result<Texture2D, JsValue> {
let image = HtmlImageElement::new().unwrap_abort();
let texture = gl.create_texture();
let onerror = {
Closure::wrap(Box::new(move || {
println!("Cannot load texture located at: {:?}", name);
}) as Box<dyn Fn()>)
};
let width = image.width();
let height = image.height();
let metadata = Rc::new(RefCell::new(Texture2DMeta {
width: width,
height: height,
internal_format: F::INTERNAL_FORMAT,
format: F::FORMAT,
type_: F::TYPE,
}));
let onload = {
let image = image.clone();
let gl = gl.clone();
let texture = texture.clone();
let metadata = metadata.clone();
Closure::wrap(Box::new(move || {
gl.bind_texture(WebGlRenderingCtx::TEXTURE_2D, texture.as_ref());
for (pname, param) in tex_params.iter() {
gl.tex_parameteri(WebGlRenderingCtx::TEXTURE_2D, *pname, *param as i32);
}
#[cfg(feature = "webgl2")]
gl.tex_image_2d_with_u32_and_u32_and_html_image_element(
WebGlRenderingCtx::TEXTURE_2D,
0,
F::INTERNAL_FORMAT,
F::FORMAT,
F::TYPE,
&image,
)
.expect("Texture 2D");
#[cfg(feature = "webgl1")]
gl.tex_image_2d_with_u32_and_u32_and_image(
WebGlRenderingCtx::TEXTURE_2D,
0,
F::INTERNAL_FORMAT,
F::FORMAT,
F::TYPE,
&image,
)
.expect("Texture 2D");
metadata.borrow_mut().width = image.width();
metadata.borrow_mut().height = image.height();
//gl.generate_mipmap(WebGl2RenderingContext::TEXTURE_2D);
}) as Box<dyn Fn()>)
};
image.set_onload(Some(onload.as_ref().unchecked_ref()));
image.set_onerror(Some(onerror.as_ref().unchecked_ref()));
image.set_cross_origin(Some(""));
image.set_src(src.as_ref().to_str().unwrap_abort());
onload.forget();
onerror.forget();
let gl = gl.clone();
Ok(Texture2D {
texture,
gl,
metadata: Some(metadata),
})
}
pub fn create_from_raw_pixels<F: ImageFormat>(
gl: &WebGlContext,
width: i32,
height: i32,
tex_params: &'static [(u32, u32)],
pixels: Option<&[u8]>,
) -> Result<Texture2D, JsValue> {
let texture = gl.create_texture();
gl.bind_texture(WebGlRenderingCtx::TEXTURE_2D, texture.as_ref());
for (pname, param) in tex_params.iter() {
gl.tex_parameteri(WebGlRenderingCtx::TEXTURE_2D, *pname, *param as i32);
}
gl.tex_image_2d_with_i32_and_i32_and_i32_and_format_and_type_and_opt_u8_array(
WebGlRenderingCtx::TEXTURE_2D,
0,
F::INTERNAL_FORMAT,
width,
height,
0,
F::FORMAT,
F::TYPE,
pixels,
)
.expect("Texture 2D");
let gl = gl.clone();
let metadata = Some(Rc::new(RefCell::new(Texture2DMeta {
width: width as u32,
height: height as u32,
internal_format: F::INTERNAL_FORMAT,
format: F::FORMAT,
type_: F::TYPE,
})));
Ok(Texture2D {
texture,
gl,
metadata,
})
}
pub fn create_empty_unsized(
gl: &WebGlContext,
tex_params: &'static [(u32, u32)],
) -> Result<Texture2D, JsValue> {
let texture = gl.create_texture();
gl.bind_texture(WebGlRenderingCtx::TEXTURE_2D, texture.as_ref());
for (pname, param) in tex_params.iter() {
gl.tex_parameteri(WebGlRenderingCtx::TEXTURE_2D, *pname, *param as i32);
}
let gl = gl.clone();
let metadata = None;
Ok(Texture2D {
texture,
gl,
metadata,
})
}
pub fn create_empty_with_format<F: ImageFormat>(
gl: &WebGlContext,
width: i32,
height: i32,
tex_params: &'static [(u32, u32)],
) -> Result<Texture2D, JsValue> {
let texture = gl.create_texture();
gl.bind_texture(WebGlRenderingCtx::TEXTURE_2D, texture.as_ref());
for (pname, param) in tex_params.iter() {
gl.tex_parameteri(WebGlRenderingCtx::TEXTURE_2D, *pname, *param as i32);
}
gl.tex_image_2d_with_i32_and_i32_and_i32_and_format_and_type_and_opt_u8_array(
WebGlRenderingCtx::TEXTURE_2D,
0,
F::INTERNAL_FORMAT,
width,
height,
0,
F::FORMAT,
F::TYPE,
None,
)
.expect("Texture 2D");
//gl.generate_mipmap(WebGl2RenderingContext::TEXTURE_2D);
let gl = gl.clone();
let metadata = Some(Rc::new(RefCell::new(Texture2DMeta {
width: width as u32,
height: height as u32,
internal_format: F::INTERNAL_FORMAT,
format: F::FORMAT,
type_: F::TYPE,
})));
Ok(Texture2D {
texture,
gl,
metadata,
})
}
pub fn attach_to_framebuffer(&self) {
self.gl.framebuffer_texture_2d(
WebGlRenderingCtx::FRAMEBUFFER,
WebGlRenderingCtx::COLOR_ATTACHMENT0,
WebGlRenderingCtx::TEXTURE_2D,
self.texture.as_ref(),
0,
);
}
pub fn get_size(&self) -> (u32, u32) {
(
self.metadata.as_ref().unwrap_abort().borrow().width,
self.metadata.as_ref().unwrap_abort().borrow().height,
)
}
pub fn width(&self) -> u32 {
self.metadata.as_ref().unwrap_abort().borrow().width
}
pub fn height(&self) -> u32 {
self.metadata.as_ref().unwrap_abort().borrow().height
}
pub fn active_texture(&self, idx_tex_unit: u8) -> &Self {
self.gl
.active_texture(WebGlRenderingCtx::TEXTURE0 + idx_tex_unit as u32);
self
}
pub fn bind(&self) -> Texture2DBound {
self.gl
.bind_texture(WebGlRenderingCtx::TEXTURE_2D, self.texture.as_ref());
Texture2DBound { texture_2d: self }
}
pub fn bind_mut(&mut self) -> Texture2DBoundMut {
self.gl
.bind_texture(WebGlRenderingCtx::TEXTURE_2D, self.texture.as_ref());
Texture2DBoundMut { texture_2d: self }
}
pub fn read_pixel(&self, x: i32, y: i32) -> Result<JsValue, JsValue> {
// Create and bind the framebuffer
let reader = self.gl.create_framebuffer();
self.gl
.bind_framebuffer(WebGlRenderingCtx::FRAMEBUFFER, reader.as_ref());
// Attach the texture as the first color attachment
//self.attach_to_framebuffer();
self.gl.framebuffer_texture_2d(
WebGlRenderingCtx::READ_FRAMEBUFFER,
WebGlRenderingCtx::COLOR_ATTACHMENT0,
WebGlRenderingCtx::TEXTURE_2D,
self.texture.as_ref(),
0,
);
let status = self
.gl
.check_framebuffer_status(WebGlRenderingCtx::FRAMEBUFFER);
if status != WebGlRenderingCtx::FRAMEBUFFER_COMPLETE {
// Unbind the framebuffer
self.gl
.bind_framebuffer(WebGlRenderingCtx::FRAMEBUFFER, None);
// Delete the framebuffer
self.gl.delete_framebuffer(reader.as_ref());
Err(JsValue::from_str("incomplete framebuffer"))
} else {
// set the viewport as the FBO won't be the same dimension as the screen
let metadata = self.metadata.as_ref().unwrap_abort().borrow();
self.gl.viewport(x, y, metadata.width as i32, metadata.height as i32);
#[cfg(feature = "webgl2")]
let value = match (metadata.format, metadata.type_) {
(WebGlRenderingCtx::RED_INTEGER, WebGlRenderingCtx::UNSIGNED_BYTE) => {
let p = <[u8; 1]>::read_pixel(&self.gl, x, y)?;
Ok(serde_wasm_bindgen::to_value(&p[0])?)
}
(WebGlRenderingCtx::RED_INTEGER, WebGlRenderingCtx::SHORT) => {
let p = <[i16; 1]>::read_pixel(&self.gl, x, y)?;
Ok(serde_wasm_bindgen::to_value(&p[0])?)
}
(WebGlRenderingCtx::RED_INTEGER, WebGlRenderingCtx::INT) => {
let p = <[i32; 1]>::read_pixel(&self.gl, x, y)?;
Ok(serde_wasm_bindgen::to_value(&p[0])?)
}
(WebGlRenderingCtx::RED, WebGlRenderingCtx::FLOAT) => {
let p = <[f32; 1]>::read_pixel(&self.gl, x, y)?;
Ok(serde_wasm_bindgen::to_value(&p[0])?)
}
(WebGlRenderingCtx::RGB, WebGlRenderingCtx::UNSIGNED_BYTE) => {
let p = <[u8; 3]>::read_pixel(&self.gl, x, y)?;
Ok(serde_wasm_bindgen::to_value(&p)?)
}
(WebGlRenderingCtx::RGBA, WebGlRenderingCtx::UNSIGNED_BYTE) => {
let p = <[u8; 4]>::read_pixel(&self.gl, x, y)?;
Ok(serde_wasm_bindgen::to_value(&p)?)
}
_ => Err(JsValue::from_str(
"Pixel retrieval not implemented for that texture format.",
)),
};
#[cfg(feature = "webgl1")]
let value = match (*format, *type_) {
(WebGlRenderingCtx::LUMINANCE_ALPHA, WebGlRenderingCtx::FLOAT) => {
let p = <[f32; 1]>::read_pixel(&self.gl, x, y)?;
Ok(serde_wasm_bindgen::to_value(&p)?)
}
(WebGlRenderingCtx::RGB, WebGlRenderingCtx::UNSIGNED_BYTE) => {
let p = <[u8; 3]>::read_pixel(&self.gl, x, y)?;
Ok(serde_wasm_bindgen::to_value(&p)?)
}
(WebGlRenderingCtx::RGBA, WebGlRenderingCtx::UNSIGNED_BYTE) => {
let p = <[u8; 4]>::read_pixel(&self.gl, x, y)?;
Ok(serde_wasm_bindgen::to_value(&p)?)
}
_ => Err(JsValue::from_str(
"Pixel retrieval not implemented for that texture format.",
)),
};
// Unbind the framebuffer
self.gl
.bind_framebuffer(WebGlRenderingCtx::FRAMEBUFFER, None);
// Delete the framebuffer
self.gl.delete_framebuffer(reader.as_ref());
// set the viewport as the FBO won't be the same dimension as the screen
let canvas = self
.gl
.canvas()
.unwrap_abort()
.dyn_into::<web_sys::HtmlCanvasElement>()
.unwrap_abort();
self.gl
.viewport(0, 0, canvas.width() as i32, canvas.height() as i32);
value
}
}
}
impl Drop for Texture2D {
fn drop(&mut self) {
self.gl.delete_texture(self.texture.as_ref());
// free the texture unit
/*let i = (self.idx_texture_unit - WebGl2RenderingContext::TEXTURE0) as usize;
unsafe {
AVAILABLE_TEX_UNITS[i] = Some(self.idx_texture_unit);
}*/
}
}
use crate::Abort;
pub struct Texture2DBound<'a> {
texture_2d: &'a Texture2D,
//idx_tex_unit: u8
}
impl<'a> Texture2DBound<'a> {
/*pub fn get_idx_sampler(&self) -> i32 {
self.idx_tex_unit as i32
}*/
pub fn tex_sub_image_2d_with_u32_and_u32_and_html_image_element(
&self,
dx: i32,
dy: i32,
image: &HtmlImageElement,
) {
let metadata = self.texture_2d.metadata.as_ref().unwrap_abort().borrow();
#[cfg(feature = "webgl2")]
self.texture_2d
.gl
.tex_sub_image_2d_with_u32_and_u32_and_html_image_element(
WebGlRenderingCtx::TEXTURE_2D,
0,
dx,
dy,
metadata.format,
metadata.type_,
image,
)
.expect("Sub texture 2d");
#[cfg(feature = "webgl1")]
self.texture_2d
.gl
.tex_sub_image_2d_with_u32_and_u32_and_image(
WebGlRenderingCtx::TEXTURE_2D,
0,
dx,
dy,
metadata.format,
metadata.type_,
image,
)
.expect("Sub texture 2d");
//self.texture_2d.gl.flush();
}
pub fn tex_sub_image_2d_with_u32_and_u32_and_image_bitmap(
&self,
dx: i32,
dy: i32,
image: &web_sys::ImageBitmap,
) {
let metadata = self.texture_2d.metadata.as_ref().unwrap_abort().borrow();
#[cfg(feature = "webgl2")]
self.texture_2d
.gl
.tex_sub_image_2d_with_u32_and_u32_and_image_bitmap(
WebGlRenderingCtx::TEXTURE_2D,
0,
dx,
dy,
metadata.format,
metadata.type_,
image,
)
.expect("Sub texture 2d");
#[cfg(feature = "webgl1")]
self.texture_2d
.gl
.tex_sub_image_2d_with_u32_and_u32_and_image_bitmap(
WebGlRenderingCtx::TEXTURE_2D,
0,
dx,
dy,
metadata.format,
metadata.type_,
image,
)
.expect("Sub texture 2d");
}
pub fn tex_sub_image_2d_with_i32_and_i32_and_u32_and_type_and_opt_array_buffer_view(
&self,
dx: i32,
dy: i32,
width: i32, // Width of the image
height: i32, // Height of the image
image: Option<&js_sys::Object>,
) {
let metadata = self.texture_2d.metadata.as_ref().unwrap_abort().borrow();
self.texture_2d
.gl
.tex_sub_image_2d_with_i32_and_i32_and_u32_and_type_and_opt_array_buffer_view(
WebGlRenderingCtx::TEXTURE_2D,
0,
dx,
dy,
width,
height,
metadata.format,
metadata.type_,
image,
)
.expect("Sub texture 2d");
}
#[allow(dead_code)]
pub fn tex_sub_image_2d_with_i32_and_i32_and_u32_and_type_and_opt_u8_array(
&self,
dx: i32,
dy: i32,
width: i32, // Width of the image
height: i32, // Height of the image
pixels: Option<&[u8]>,
) {
let metadata = self.texture_2d.metadata.as_ref().unwrap_abort().borrow();
self.texture_2d
.gl
.tex_sub_image_2d_with_i32_and_i32_and_u32_and_type_and_opt_u8_array(
WebGlRenderingCtx::TEXTURE_2D,
0,
dx,
dy,
width,
height,
metadata.format,
metadata.type_,
pixels,
)
.expect("Sub texture 2d");
}
}
pub struct Texture2DBoundMut<'a> {
texture_2d: &'a mut Texture2D,
}
impl<'a> Texture2DBoundMut<'a> {
#[allow(dead_code)]
pub fn tex_image_2d_with_i32_and_i32_and_i32_and_format_and_type_and_opt_u8_array(
&mut self,
width: i32, // Width of the image
height: i32, // Height of the image
internal_format: i32,
src_format: u32,
src_type: u32,
pixels: Option<&[u8]>,
) {
//let Texture2DMeta {format, type_, ..} = self.texture_2d.metadata.unwrap_abort();
/*self.texture_2d
.gl
.pixel_storei(WebGlRenderingCtx::UNPACK_ALIGNMENT, 1);*/
self.texture_2d
.gl
.tex_image_2d_with_i32_and_i32_and_i32_and_format_and_type_and_opt_u8_array(
WebGlRenderingCtx::TEXTURE_2D,
0,
internal_format as i32,
width as i32,
height as i32,
0,
src_format,
src_type,
pixels,
)
.expect("Sub texture 2d");
//self.texture_2d.gl.generate_mipmap(WebGlRenderingCtx::TEXTURE_2D);
self.texture_2d.metadata = Some(Rc::new(RefCell::new(Texture2DMeta {
format: src_format,
internal_format,
type_: src_type,
width: width as u32,
height: height as u32,
})));
}
}

View File

@@ -1,282 +0,0 @@
use crate::image::{ArrayBuffer, ArrayF32, ArrayI16, ArrayI32, ArrayU8};
use crate::webgl_ctx::WebGlRenderingCtx;
use wasm_bindgen::JsValue;
use crate::webgl_ctx::WebGlContext;
pub trait Pixel:
AsRef<[Self::Item]>
+ Default
+ std::cmp::PartialEq
+ std::fmt::Debug
+ std::clone::Clone
{
type Item: std::cmp::PartialOrd + Clone + Copy + std::fmt::Debug + cgmath::Zero;
type Container: ArrayBuffer<Item = Self::Item>;
const BLACK: Self;
fn read_pixel(gl: &WebGlContext, x: i32, y: i32) -> Result<Self, JsValue>;
}
impl Pixel for [f32; 4] {
type Item = f32;
type Container = ArrayF32;
const BLACK: Self = [std::f32::NAN; 4];
fn read_pixel(gl: &WebGlContext, x: i32, y: i32) -> Result<Self, JsValue> {
let pixels = js_sys::Float32Array::new_with_length(4);
#[cfg(feature = "webgl2")]
gl.read_pixels_with_opt_array_buffer_view(
x,
y,
1,
1,
WebGlRenderingCtx::RGBA32F,
WebGlRenderingCtx::FLOAT,
Some(&pixels),
)?;
#[cfg(feature = "webgl1")]
gl.read_pixels_with_opt_array_buffer_view(
x,
y,
1,
1,
WebGlRenderingCtx::RGBA,
WebGlRenderingCtx::FLOAT,
Some(&pixels),
)?;
let pixels = pixels.to_vec();
Ok([pixels[0], pixels[1], pixels[2], pixels[3]])
}
}
impl Pixel for [f32; 3] {
type Item = f32;
type Container = ArrayF32;
const BLACK: Self = [std::f32::NAN; 3];
fn read_pixel(gl: &WebGlContext, x: i32, y: i32) -> Result<Self, JsValue> {
let pixels = js_sys::Float32Array::new_with_length(3);
#[cfg(feature = "webgl2")]
gl.read_pixels_with_opt_array_buffer_view(
x,
y,
1,
1,
WebGlRenderingCtx::RGB32F,
WebGlRenderingCtx::FLOAT,
Some(&pixels),
)?;
#[cfg(feature = "webgl1")]
gl.read_pixels_with_opt_array_buffer_view(
x,
y,
1,
1,
WebGlRenderingCtx::RGB,
WebGlRenderingCtx::FLOAT,
Some(&pixels),
)?;
let pixels = pixels.to_vec();
Ok([pixels[0], pixels[1], pixels[2]])
}
}
impl Pixel for [f32; 1] {
type Item = f32;
type Container = ArrayF32;
const BLACK: Self = [std::f32::NAN];
fn read_pixel(gl: &WebGlContext, x: i32, y: i32) -> Result<Self, JsValue> {
let pixels = js_sys::Float32Array::new_with_length(1);
#[cfg(feature = "webgl2")]
gl.read_pixels_with_opt_array_buffer_view(
x,
y,
1,
1,
WebGlRenderingCtx::RED,
WebGlRenderingCtx::FLOAT,
Some(&pixels),
)?;
#[cfg(feature = "webgl1")]
gl.read_pixels_with_opt_array_buffer_view(
x,
y,
1,
1,
WebGlRenderingCtx::LUMINANCE_ALPHA,
WebGlRenderingCtx::FLOAT,
Some(&pixels),
)?;
Ok([pixels.to_vec()[0]])
}
}
/*use crate::image::ArrayF64;
impl Pixel for [f64; 1] {
type Item = f64;
type Container = ArrayF64;
const BLACK: Self = [std::f64::NAN];
fn read_pixel(gl: &WebGlContext, x: i32, y: i32) -> Result<Self, JsValue> {
let pixels = js_sys::Float32Array::new_with_length(1);
#[cfg(feature = "webgl2")]
gl.read_pixels_with_opt_array_buffer_view(
x,
y,
1,
1,
WebGlRenderingCtx::RED,
WebGlRenderingCtx::FLOAT,
Some(&pixels),
)?;
#[cfg(feature = "webgl1")]
gl.read_pixels_with_opt_array_buffer_view(
x,
y,
1,
1,
WebGlRenderingCtx::LUMINANCE_ALPHA,
WebGlRenderingCtx::FLOAT,
Some(&pixels),
)?;
Ok([pixels.to_vec()[0] as f64])
}
}*/
impl Pixel for [u8; 4] {
type Item = u8;
type Container = ArrayU8;
// Transparency handled
const BLACK: Self = [0, 0, 0, 0];
fn read_pixel(gl: &WebGlContext, x: i32, y: i32) -> Result<Self, JsValue> {
let pixels = js_sys::Uint8Array::new_with_length(4);
gl.read_pixels_with_opt_array_buffer_view(
x,
y,
1,
1,
WebGlRenderingCtx::RGBA,
WebGlRenderingCtx::UNSIGNED_BYTE,
Some(&pixels),
)?;
let pixels = pixels.to_vec();
Ok([pixels[0], pixels[1], pixels[2], pixels[3]])
}
}
impl Pixel for [u8; 3] {
type Item = u8;
type Container = ArrayU8;
const BLACK: Self = [0, 0, 0];
fn read_pixel(gl: &WebGlContext, x: i32, y: i32) -> Result<Self, JsValue> {
let pixels = js_sys::Uint8Array::new_with_length(3);
gl.read_pixels_with_opt_array_buffer_view(
x,
y,
1,
1,
WebGlRenderingCtx::RGB,
WebGlRenderingCtx::UNSIGNED_BYTE,
Some(&pixels),
)?;
let pixels = pixels.to_vec();
Ok([pixels[0], pixels[1], pixels[2]])
}
}
#[cfg(feature = "webgl2")]
impl Pixel for [u8; 1] {
type Item = u8;
type Container = ArrayU8;
const BLACK: Self = [0];
fn read_pixel(gl: &WebGlContext, x: i32, y: i32) -> Result<Self, JsValue> {
let pixels = js_sys::Uint8Array::new_with_length(1);
gl.read_pixels_with_opt_array_buffer_view(
x,
y,
1,
1,
WebGlRenderingCtx::RED_INTEGER,
WebGlRenderingCtx::UNSIGNED_BYTE,
Some(&pixels),
)?;
Ok([pixels.to_vec()[0]])
}
}
#[cfg(feature = "webgl2")]
impl Pixel for [i16; 1] {
type Item = i16;
type Container = ArrayI16;
const BLACK: Self = [std::i16::MIN];
fn read_pixel(gl: &WebGlContext, x: i32, y: i32) -> Result<Self, JsValue> {
let pixels = js_sys::Int16Array::new_with_length(1);
gl.read_pixels_with_opt_array_buffer_view(
x,
y,
1,
1,
WebGlRenderingCtx::RED_INTEGER,
WebGlRenderingCtx::SHORT,
Some(&pixels),
)?;
Ok([pixels.to_vec()[0]])
}
}
#[cfg(feature = "webgl2")]
impl Pixel for [i32; 1] {
type Item = i32;
type Container = ArrayI32;
const BLACK: Self = [std::i32::MIN];
fn read_pixel(gl: &WebGlContext, x: i32, y: i32) -> Result<Self, JsValue> {
let pixels = js_sys::Int32Array::new_with_length(1);
gl.read_pixels_with_opt_array_buffer_view(
x,
y,
1,
1,
WebGlRenderingCtx::RED_INTEGER,
WebGlRenderingCtx::INT,
Some(&pixels),
)?;
Ok([pixels.to_vec()[0]])
}
}
/*impl From<T> for JsValue
where
T: Pixel
{
fn from(p: T) -> Self {
JsValue::from_serde(&p).unwrap_abort()
}
}*/
/*
pub enum PixelType {
RU8([u8; 1]),
RI16([i16; 1]),
RI32([i32; 1]),
RF32([f32; 1]),
RGBU8([u8; 3]),
RGBAU8([u8; 4]),
}
impl From<PixelType> for JsValue {
fn from(p: PixelType) -> Self {
match p {
PixelType::RU8(v) => JsValue::from_serde(&v).unwrap_abort(),
PixelType::RI16(v) => JsValue::from_serde(&v).unwrap_abort(),
PixelType::RI32(v) => JsValue::from_serde(&v).unwrap_abort(),
PixelType::RF32(v) => JsValue::from_serde(&v).unwrap_abort(),
PixelType::RGBU8(v) => JsValue::from_serde(&v).unwrap_abort(),
PixelType::RGBAU8(v) => JsValue::from_serde(&v).unwrap_abort(),
}
}
}*/

View File

@@ -1,55 +0,0 @@
use crate::image::format::ImageFormat;
use crate::webgl_ctx::WebGlContext;
pub struct Texture2DArray {
pub textures: Vec<Texture2D>,
}
use std::ops::Index;
impl Index<usize> for Texture2DArray {
type Output = Texture2D;
fn index(&self, idx: usize) -> &Self::Output {
&self.textures[idx]
}
}
use super::Texture2D;
use wasm_bindgen::prelude::*;
impl Texture2DArray {
pub fn create_empty<F: ImageFormat>(
gl: &WebGlContext,
// The weight of the individual textures
width: i32,
// Their height
height: i32,
// How many texture slices it contains
num_slices: i32,
tex_params: &'static [(u32, u32)],
) -> Result<Texture2DArray, JsValue> {
let mut textures = vec![];
for _ in 0..num_slices {
let texture = Texture2D::create_from_raw_pixels::<F>(gl, width, height, tex_params, None)?;
textures.push(texture);
}
Ok(Texture2DArray { textures })
}
}
const TEX_UNIFORMS_NAME: &[&str] = &["tex1", "tex2", "tex3", "tex4", "tex5"];
use crate::shader::{SendUniforms, ShaderBound};
impl SendUniforms for Texture2DArray {
fn attach_uniforms<'a>(&self, shader: &'a ShaderBound<'a>) -> &'a ShaderBound<'a> {
let num_tex = self.textures.len();
for (idx, tex) in self.textures.iter().enumerate() {
let loc = TEX_UNIFORMS_NAME[idx];
shader.attach_uniform(loc, tex);
}
shader.attach_uniform("num_tex", &(num_tex as i32));
shader
}
}

View File

@@ -1,156 +0,0 @@
use al_api::blend::BlendFunc;
use std::rc::Rc;
use wasm_bindgen::JsCast;
use wasm_bindgen::JsValue;
#[cfg(feature = "webgl2")]
pub type WebGlRenderingCtx = web_sys::WebGl2RenderingContext;
#[cfg(feature = "webgl1")]
pub type WebGlRenderingCtx = web_sys::WebGlRenderingContext;
#[derive(Clone)]
pub struct WebGlContext {
inner: Rc<WebGlRenderingCtx>,
#[cfg(feature = "webgl1")]
pub ext: WebGlExt,
}
#[derive(Clone)]
pub struct WebGlExt {
#[cfg(feature = "webgl1")]
pub angles: web_sys::AngleInstancedArrays,
}
use crate::Abort;
impl WebGlContext {
pub fn new(aladin_div_name: &str) -> Result<WebGlContext, JsValue> {
let window = web_sys::window().unwrap_abort();
let document = window.document().unwrap_abort();
let canvas = document
// Get the aladin div element
.get_element_by_id(aladin_div_name)
.unwrap_abort()
// Inside it, retrieve the canvas
.get_elements_by_class_name("aladin-imageCanvas")
.get_with_index(0)
.unwrap_abort();
let canvas = canvas.dyn_into::<web_sys::HtmlCanvasElement>().unwrap_abort();
// See https://stackoverflow.com/a/26790802/13456997
// preserveDrawingBuffer enabled for exporting the view as a PNG
let context_options =
js_sys::JSON::parse("{\"antialias\":false, \"preserveDrawingBuffer\": true}")?;
#[cfg(feature = "webgl1")]
let gl = Rc::new(
canvas
.get_context_with_context_options("webgl", context_options.as_ref())?
.unwrap_abort()
.dyn_into::<WebGlRenderingCtx>()
.unwrap_abort(),
);
#[cfg(feature = "webgl2")]
let gl = Rc::new(
canvas
.get_context_with_context_options("webgl2", context_options.as_ref())?
.unwrap_abort()
.dyn_into::<WebGlRenderingCtx>()
.unwrap_abort(),
);
#[cfg(feature = "webgl2")]
{
if let Ok(r) = get_extension::<web_sys::ExtColorBufferFloat>(&gl, "EXT_color_buffer_float") {
let _ = r;
}
let ctx = WebGlContext { inner: gl };
Ok(ctx)
}
#[cfg(feature = "webgl1")]
{
let angles_ext = get_extension::<web_sys::AngleInstancedArrays>(&gl, "ANGLE_instanced_arrays")?;
let _ = get_extension::<web_sys::OesTextureFloat>(&gl, "OES_texture_float")?;
let _ = get_extension::<web_sys::ExtSRgb>(&gl, "EXT_sRGB")?;
Ok(WebGlContext {
inner: gl,
ext: WebGlExt { angles: angles_ext },
})
}
}
}
fn get_extension<T>(context: &WebGlRenderingCtx, name: &str) -> Result<T, JsValue>
where
T: wasm_bindgen::JsCast,
{
// `unchecked_into` is used here because WebGL extensions aren't actually JS classes
// these objects are duck-type representations of the actual Rust classes
// https://github.com/rustwasm/wasm-bindgen/pull/1449
context
.get_extension(name)
.ok()
.and_then(|maybe_ext| maybe_ext.map(|ext| ext.unchecked_into::<T>()))
.ok_or_else(|| JsValue::from_str("Failed to load ext"))
}
use std::ops::Deref;
impl Deref for WebGlContext {
type Target = WebGlRenderingCtx;
fn deref(&self) -> &WebGlRenderingCtx {
&self.inner
}
}
pub trait GlWrapper {
fn enable(&self, gl: &WebGlContext, f: impl FnOnce());
}
use al_api::blend::{BlendCfg, BlendFactor};
impl GlWrapper for BlendCfg {
fn enable(&self, gl: &WebGlContext, f: impl FnOnce()) {
let blend_factor_f = |f: &BlendFactor| -> u32 {
match f {
BlendFactor::ConstantAlpha => WebGlRenderingCtx::CONSTANT_ALPHA,
BlendFactor::ConstantColor => WebGlRenderingCtx::CONSTANT_COLOR,
BlendFactor::Zero => WebGlRenderingCtx::ZERO,
BlendFactor::One => WebGlRenderingCtx::ONE,
BlendFactor::DstAlpha => WebGlRenderingCtx::DST_ALPHA,
BlendFactor::DstColor => WebGlRenderingCtx::DST_COLOR,
BlendFactor::OneMinusConstantAlpha => WebGlRenderingCtx::ONE_MINUS_CONSTANT_ALPHA,
BlendFactor::OneMinusDstColor => WebGlRenderingCtx::ONE_MINUS_DST_COLOR,
BlendFactor::OneMinusDstAlpha => WebGlRenderingCtx::ONE_MINUS_DST_ALPHA,
BlendFactor::SrcAlpha => WebGlRenderingCtx::SRC_ALPHA,
BlendFactor::SrcColor => WebGlRenderingCtx::SRC_COLOR,
BlendFactor::OneMinusSrcColor => WebGlRenderingCtx::ONE_MINUS_SRC_COLOR,
BlendFactor::OneMinusSrcAlpha => WebGlRenderingCtx::ONE_MINUS_SRC_ALPHA,
BlendFactor::OneMinusConstantColor => WebGlRenderingCtx::ONE_MINUS_CONSTANT_ALPHA,
}
};
let blend_func_f = |f: &BlendFunc| -> u32 {
match f {
BlendFunc::FuncAdd => WebGlRenderingCtx::FUNC_ADD,
BlendFunc::FuncReverseSubstract => WebGlRenderingCtx::FUNC_REVERSE_SUBTRACT,
BlendFunc::FuncSubstract => WebGlRenderingCtx::FUNC_SUBTRACT,
}
};
gl.blend_equation(blend_func_f(&self.func));
gl.blend_func_separate(
blend_factor_f(&self.src_color_factor),
blend_factor_f(&self.dst_color_factor),
WebGlRenderingCtx::ONE,
WebGlRenderingCtx::ONE,
);
f();
gl.blend_equation(blend_func_f(&BlendFunc::FuncAdd));
}
}

View File

@@ -1,21 +0,0 @@
[package]
name = "al-task-exec"
version = "0.1.0"
authors = ["Matthieu Baumann <matthieu.baumann@astro.unistra.fr>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
futures = "0.3.5"
futures-task = "0.3.5"
wasm-bindgen = "0.2.79"
[dependencies.web-sys]
version = "0.3.40"
features = [
'Document',
'Window',
'PerformanceTiming',
'Performance',
]

View File

@@ -1,338 +0,0 @@
use {
futures::{
future::FutureExt,
task::{waker_ref, ArcWake},
},
std::{
future::Future,
sync::Arc,
task::{Context, Poll},
},
};
struct Thread {
_thread: std::thread::Thread,
}
use std::thread;
thread_local! {
static CURRENT_THREAD_NOTIFY: Arc<Thread> = Arc::new(Thread {
_thread: thread::current(),
});
}
impl ArcWake for Thread {
fn wake_by_ref(_arc_self: &Arc<Self>) {}
}
use std::cell::RefCell;
/// `Spawner` spawns new futures onto the task channel.
use std::collections::VecDeque;
use std::pin::Pin;
use std::rc::{Rc, Weak};
use std::collections::HashMap;
// A queue that contains keyed element
struct KeyedVecDeque<K, V>
where
K: Hash + Eq + Clone,
{
keys: VecDeque<K>,
values: HashMap<K, V>,
}
use std::hash::Hash;
impl<K, V> KeyedVecDeque<K, V>
where
K: Hash + Eq + Clone,
{
fn new() -> Self {
let keys = VecDeque::new();
let values = HashMap::new();
Self { keys, values }
}
fn push_front(&mut self, key: K, value: V) {
self.keys.push_front(key.clone());
self.values.insert(key, value);
}
fn pop_back(&mut self) -> Option<(K, V)> {
if self.keys.is_empty() {
None
} else {
let mut v = None;
while !self.keys.is_empty() && v.is_none() {
let k = self.keys.pop_back().unwrap();
v = self.values.remove(&k).map(|v| (k, v));
}
v
}
}
fn remove(&mut self, k: &K) -> Option<V> {
self.values.remove(k)
}
}
type Incoming<K, T> = RefCell<KeyedVecDeque<K, Pin<Box<dyn Future<Output = T> + 'static>>>>;
#[derive(Clone)]
pub struct Spawner<K, T>
where
K: Hash + Eq + Clone,
{
tasks: Weak<Incoming<K, T>>,
}
impl<K, T> Spawner<K, T>
where
K: Hash + Eq + Clone,
{
pub fn spawn(&mut self, key: K, future: impl Future<Output = T> + 'static) {
let future = future.boxed_local();
self.tasks
.upgrade() // convert to Rc
.unwrap()
.borrow_mut() // Push the new task to the front of the queue
.push_front(key, future);
}
}
/// Task executor that receives tasks off of a channel and runs them.
pub struct Executor<K, T>
where
K: Hash + Eq + Clone,
{
tasks: Rc<Incoming<K, T>>,
spawner: Spawner<K, T>,
}
impl<K, T> Default for Executor<K, T>
where
K: Hash + Eq + Clone,
{
fn default() -> Self {
let tasks = Rc::new(RefCell::new(KeyedVecDeque::new()));
let spawner = Spawner {
tasks: Rc::downgrade(&tasks),
};
Executor { tasks, spawner }
}
}
impl<K, T> Executor<K, T>
where
K: Hash + Eq + Clone + Sized,
{
pub fn new() -> Self {
Self::default()
}
pub fn spawner(&mut self) -> &mut Spawner<K, T> {
&mut self.spawner
}
pub fn run(&mut self, timeout: f32) -> Vec<T> {
let mut results = vec![];
CURRENT_THREAD_NOTIFY.with(|thread| {
// Create a `LocalWaker` from the current thread itself
let waker = waker_ref(thread);
let mut cx = Context::from_waker(&waker);
// Take all the task available from the channel
// Exit the loop when either the channel is disconnected or
// there are no tasks available to process.
let mut tasks = self.tasks.borrow_mut();
let window = web_sys::window().expect("should have a window in this context");
let performance = window
.performance()
.expect("performance should be available");
let start = performance.now() as f32;
while let Some((k, mut task)) = tasks.pop_back() {
// Take the future, and if it has not yet completed (is still Some),
// poll it in an attempt to complete it.
// We store `Pin<Box<dyn Future<Output = T> + 'static>>`.
// We can get a `Pin<&mut dyn Future + 'static>`
// from it by calling the `Pin::as_mut` method.
let r = task.as_mut().poll(&mut cx);
match r {
Poll::Pending => {
// Wake up the task pending immediately
cx.waker().clone().wake();
// Reinsert not finished futures into the tasks queue
tasks.push_front(k, task);
}
Poll::Ready(result) => {
// If the future is completed, get the result
// and return it to the user
results.push(result);
}
}
let now = performance.now() as f32;
// Break the running if we exceed the timeout
if (now - start) >= timeout {
break;
}
}
});
results
}
// Remove a task from the executor so that
// it won't be polled anymore
pub fn remove(&mut self, k: &K) {
self.tasks.borrow_mut().remove(k);
}
}
#[cfg(test)]
mod tests {
use super::Executor;
use futures::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
// Define some futures to run concurrently on a single thread
struct LearnTask(usize);
impl LearnTask {
fn new() -> Self {
LearnTask(0)
}
}
impl Future for LearnTask {
type Output = u8;
fn poll(mut self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Self::Output> {
self.0 += 1;
println!("I'm learning {}", self.0);
if self.0 == 10000 {
Poll::Ready(0)
} else {
//cx.waker().clone().wake();
Poll::Pending
}
}
}
struct DanceTask(usize);
impl DanceTask {
fn new() -> Self {
DanceTask(0)
}
}
impl Future for DanceTask {
type Output = u8;
fn poll(mut self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Self::Output> {
self.0 += 1;
println!("I'm dancing {}", self.0);
if self.0 == 10000 {
Poll::Ready(0)
} else {
//cx.waker().clone().wake();
Poll::Pending
}
}
}
#[test]
fn it_works() {
let mut executor = Executor::new();
let spawner = executor.spawner();
// Spawn a task to print before and after waiting on a timer.
spawner.spawn("learning", async {
println!("LEARN begin!");
// Wait for our timer future to complete after two seconds.
LearnTask::new().await;
println!("LEARN done!");
10
});
spawner.spawn("dancing", async {
println!("DANCE begin!");
// Wait for our timer future to complete after two seconds.
DanceTask::new().await;
println!("DANCE done!");
10
});
// Run the executor for a duration of 5 milliseconds
executor.run(5_f32);
}
use futures::stream::Stream;
pub struct ParseTable {
table: Vec<u32>,
ready: bool,
idx: u32,
}
impl ParseTable {
pub fn new(table: Vec<u32>) -> Self {
let idx = 0;
let ready = false;
Self { table, idx, ready }
}
}
impl Stream for ParseTable {
type Item = u32;
/// Attempt to resolve the next item in the stream.
/// Returns `Poll::Pending` if not ready, `Poll::Ready(Some(x))` if a value
/// is ready, and `Poll::Ready(None)` if the stream has completed.
fn poll_next(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
// Deserialize row by row.
let len = self.table.len();
let idx = self.idx as usize;
while self.idx < len as u32 {
if !self.ready {
self.table[idx] += 10;
self.ready = true;
return Poll::Pending;
} else {
println!("{}", idx);
let row = self.table[idx];
self.idx += 1;
self.ready = false;
return Poll::Ready(Some(row));
}
}
Poll::Ready(None)
}
}
use futures::stream::StreamExt; // for `next`
#[test]
fn it_works2() {
let mut executor = Executor::new();
let spawner = executor.spawner();
// Spawn a task to print before and after waiting on a timer.
spawner.spawn("parsing", async {
println!("BEGIN parsing!");
let mut stream = ParseTable::new((0..100000).collect());
let mut results: Vec<u32> = vec![];
while let Some(item) = stream.next().await {
results.push(item);
}
println!("END parsing!");
10
});
// Run the executor for a duration of 5 milliseconds
executor.run(50_f32);
}
}

View File

@@ -1,106 +0,0 @@
[package]
name = "al-ui"
version = "0.1.0"
authors = ["baumannmatthieu0@gmail.com", "matthieu.baumann@astro.unistra.fr"]
edition = "2018"
[dependencies]
console_error_panic_hook = "0.1.6"
futures = "0.3.12"
js-sys = "0.3.47"
wasm-bindgen-futures = "0.4.20"
cgmath = "*"
itertools-num = "0.1.3"
healpix = { package = "cdshealpix", git = 'https://github.com/cds-astro/cds-healpix-rust', branch = 'master' }
serde = { version = "^1.0.59", features = ["derive"] }
serde_json = "1.0"
serde-wasm-bindgen = "0.4"
num = "*"
fitsrs = { package = "fitsrs", git = 'https://github.com/cds-astro/fitsrs', branch = 'master' }
num-traits = "0.2.14"
image-decoder = { package = "image", version = "0.24.*", default-features = false, features = ["jpeg", "png"] }
egui = "0.15.0"
epi = "0.15.0"
egui_web = "0.15.0"
al-core = { path = "../al-core" }
al-api = { path = "../al-api" }
wasm-bindgen = "0.2.79"
[dependencies.web-sys]
version = "0.3.56"
features = [
'console',
'CssStyleDeclaration',
'Document',
'Element',
'HtmlCollection',
'HtmlElement',
'HtmlImageElement',
'HtmlCanvasElement',
'Blob',
'ImageBitmap',
'ImageData',
'CanvasRenderingContext2d',
'MouseEvent',
'WheelEvent',
'WebGlBuffer',
'WebGlContextAttributes',
'WebGlFramebuffer',
'WebGlProgram',
'WebGlShader',
'WebGlUniformLocation',
'WebGlTexture',
'WebGlActiveInfo',
'Window',
'Request',
'RequestInit',
'RequestMode',
'Response',
'XmlHttpRequest',
'XmlHttpRequestResponseType',
'PerformanceTiming',
'Performance',
'Url',
]
[features]
webgl1 = [
"web-sys/WebGlRenderingContext",
"web-sys/AngleInstancedArrays", # Enabling instancing features
"web-sys/ExtSRgb", # Enabling SRGB8_ALPHA8 internal format
"web-sys/OesTextureFloat"
]
webgl2 = [
"web-sys/WebGl2RenderingContext",
"web-sys/WebGlVertexArrayObject",
"web-sys/ExtColorBufferFloat",
]
[profile.dev]
opt-level = 's'
debug = true
debug-assertions = true
overflow-checks = true
lto = false
panic = 'unwind'
incremental = true
codegen-units = 256
rpath = false
[profile.release]
opt-level = 3
debug = false
debug-assertions = false
overflow-checks = false
lto = false
panic = 'unwind'
incremental = false
codegen-units = 16
rpath = false
[package.metadata.wasm-pack.profile.release]
wasm-opt = true

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Some files were not shown because too many files have changed in this diff Show More