mirror of
https://github.com/cds-astro/aladin-lite.git
synced 2025-12-25 20:34:50 -08:00
Compare commits
5 Commits
21/10/2022
...
v2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
64fcc777de | ||
|
|
0f74b5e94f | ||
|
|
5799482dde | ||
|
|
416c20cecc | ||
|
|
09ef8418bb |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +0,0 @@
|
||||
node_modules
|
||||
96
README.md
96
README.md
@@ -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
|
||||
```
|
||||
@@ -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
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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> <br><button id="stop">Stop</button>
|
||||
<br>
|
||||
<div id="coo_epoca">
|
||||
<a class="pure-button nav-button nav-goto" href="#">De Epoca</a><br>
|
||||
→ <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>
|
||||
→ <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>
|
||||
→ <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>
|
||||
→ <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>
|
||||
→ <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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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'> </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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
for filename in *.html; do
|
||||
google-chrome http://localhost:8080/${filename}
|
||||
done
|
||||
@@ -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>
|
||||
31
package.json
31
package.json
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
2020-08
|
||||
- polyline improvements (by @imbasimba)
|
||||
|
||||
2020-07
|
||||
- new method stopAnimation
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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],
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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.
Binary file not shown.
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}*/
|
||||
}
|
||||
@@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 ),* ) );
|
||||
};
|
||||
}
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
};
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>;
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
})));
|
||||
}
|
||||
}
|
||||
@@ -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(),
|
||||
}
|
||||
}
|
||||
}*/
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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',
|
||||
]
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user