Skip to content

Commit

Permalink
feat: React Examples Components (DT-7024) (#49)
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMooseman authored Jan 30, 2025
1 parent 0c63670 commit 81b2d6b
Show file tree
Hide file tree
Showing 23 changed files with 1,913 additions and 1,869 deletions.
17 changes: 0 additions & 17 deletions examples/dzi.html

This file was deleted.

12 changes: 5 additions & 7 deletions examples/index.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
<!doctype html>
<html>
<body>
EXAMPLES
<br />
<ul>
<li><a href="/dzi">Deep Zoom Image</a><br /></li>
<li><a href="/omezarr">OMEZARR</a><br /></li>
<li><a href="/layers">Layers</a><br /></li>
</ul>
<div id="app"></div>
<script
type="module"
src="/src/index.tsx"
></script>
</body>
</html>
17 changes: 0 additions & 17 deletions examples/omezarr.html

This file was deleted.

5 changes: 3 additions & 2 deletions examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@
"vite": "^5.3.5"
},
"dependencies": {
"@alleninstitute/vis-geometry": "workspace:*",
"@alleninstitute/vis-scatterbrain": "workspace:*",
"@alleninstitute/vis-dzi": "workspace:*",
"@alleninstitute/vis-geometry": "workspace:*",
"@alleninstitute/vis-omezarr": "workspace:*",
"@alleninstitute/vis-scatterbrain": "workspace:*",
"@czi-sds/components": "^20.0.1",
"@emotion/css": "^11.11.2",
"@emotion/react": "^11.11.4",
Expand All @@ -61,6 +61,7 @@
"lodash": "^4.17.21",
"react": "^18.3.0",
"react-dom": "^18.3.0",
"react-router": "^7.0.2",
"regl": "^2.1.0",
"zarrita": "0.4.0-next.14"
}
Expand Down
17 changes: 0 additions & 17 deletions examples/public/layers.html

This file was deleted.

75 changes: 22 additions & 53 deletions examples/src/app.tsx
Original file line number Diff line number Diff line change
@@ -1,58 +1,27 @@
import React from 'react';
import { SliceViewLayer } from './ui/slice-ui';
import type { Demo } from './layers';
import { AnnotationGrid } from './ui/annotation-grid';
import { ContactSheetUI } from './ui/contact-sheet';
import { ScatterplotUI } from './ui/scatterplot-ui';
import { Button } from '@czi-sds/components';
import { BrowserRouter, Route, Routes } from 'react-router';
import { Home } from './home';
import { OmezarrDemo } from './omezarr/omezarr-demo';
import { DziDemo } from './dzi/dzi-demo';

export function AppUi(props: { demo: Demo }) {
const { demo } = props;
export function App() {
return (
<div>
<Button
onClick={() => {
demo.requestSnapshot(3000);
}}
>
{'📸'}
</Button>
<label>{`Layer ${demo.selectedLayer}`}</label>
<Button
onClick={() => {
demo.selectLayer(demo.selectedLayer - 1);
}}
>
{'<-'}
</Button>
<Button
onClick={() => {
demo.selectLayer(demo.selectedLayer + 1);
}}
>
{'->'}
</Button>
<LayerUi demo={demo} />
</div>
<BrowserRouter>
<Routes>
<Route
index
element={<Home />}
/>
<Route
path="/dzi"
element={<DziDemo />}
/>
<Route
path="/omezarr"
element={<OmezarrDemo />}
/>
<Route path="/layers" />
</Routes>
</BrowserRouter>
);
}
function LayerUi(props: { demo: Demo }) {
const { demo } = props;
const layer = demo.layers[demo.selectedLayer];
if (layer) {
switch (layer.type) {
case 'annotationGrid':
return <AnnotationGrid demo={demo} />;
case 'volumeGrid':
return <ContactSheetUI demo={demo} />;
case 'volumeSlice':
return <SliceViewLayer demo={demo} />;
case 'scatterplot':
case 'scatterplotGrid':
return <ScatterplotUI demo={demo} />;
default:
return null;
}
}
return <SliceViewLayer demo={props.demo} />;
}
37 changes: 36 additions & 1 deletion examples/src/common/camera.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,43 @@
import type { box2D, vec2 } from '@alleninstitute/vis-geometry';
import { Box2D, Vec2, type box2D, type vec2 } from '@alleninstitute/vis-geometry';

// a basic camera, for viewing slices
export type Camera = {
readonly view: box2D; // a view in 'data space'
readonly screen: vec2; // what that view projects to in display space, aka pixels
readonly projection: 'webImage' | 'cartesian';
};
/**
* Zooms relative to your current mouse position
* @param view box2d in dataspace that is mapped to the canvas
* @param screenSize in pixels
* @param zoomScale
* @param mousePos mouse position in pixels
*/
export function zoom(view: box2D, screenSize: vec2, zoomScale: number, mousePos: vec2): box2D {
// translate mouse pos to data space
// offset divided by screen size gives us a percentage of the canvas where the mouse is
// multiply percentage by view size to make it data space
// add offset of the min corner so that the position takes into account any box offset
const zoomPoint: vec2 = Vec2.add(view.minCorner, Vec2.mul(Vec2.div(mousePos, screenSize), Box2D.size(view)));

// scale the box with our new zoom point as the center
const newView = Box2D.translate(
Box2D.scale(Box2D.translate(view, Vec2.scale(zoomPoint, -1)), [zoomScale, zoomScale]),
zoomPoint
);

return newView;
}

/**
*
* @param view box2d in dataspace that is mapped to the canvas
* @param screenSize
* @param mousePos mouse position in pixels
*/
export function pan(view: box2D, screenSize: vec2, mousePos: vec2): box2D {
const relativePos = Vec2.div(Vec2.mul(mousePos, [-1, -1]), screenSize);
const scaledOffset = Vec2.mul(relativePos, Box2D.size(view));
const newView = Box2D.translate(view, scaledOffset);
return newView;
}
6 changes: 0 additions & 6 deletions examples/src/dzi/app.tsx

This file was deleted.

81 changes: 81 additions & 0 deletions examples/src/dzi/decode-dzi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import type { DziImage } from '@alleninstitute/vis-dzi';

// DZI files will come with XML or JSON to give you important information such as the width, height, and format.
// Below is a function for parsing an xml with that data, althought sometimes it comes in JSON format.
// At the end of the file you can see two examples of the metadata format you might see, one as XML and another as JSON
/**
* This function helps decode xml metadata for a dzi file.
* @param s the contents of the url param - expected to be an XML doc describing the DZI image
* @param url location of the .dzi file
* @returns formatted dzi image data
*/
function decodeDziXml(s: string, url: string): DziImage | undefined {
const parser = new DOMParser();
const doc = parser.parseFromString(s, 'text/xml');
// catch any errors if the xml is malformed
const err = doc.querySelector('Error');
if (err) return undefined;

if (doc) {
const img = doc.getElementsByTagName('Image')[0];
const size = doc.getElementsByTagName('Size')[0];
// format: as jpg/png
// overlap: how much overlap there is between images so that we can compensate the rendering
// tile size: how big in pixels each tile is
const [format, overlap, tileSize] = [
img.getAttribute('Format'),
img.getAttribute('Overlap'),
img.getAttribute('TileSize'),
];
if (size && format && overlap && tileSize) {
// width and height of the image, so we can properly size the view
const width = size.getAttribute('Width');
const height = size.getAttribute('Height');

// the url ends with .dzi to denote that we're reaching for a dzi file
// in order to get the images from that url we need to remove the .dzi
// and replace it with _files/ so that the image viewer knows where to look
const dataLoc = url.split('.dzi')[0];
if (width && height && dataLoc) {
return {
imagesUrl: `${dataLoc}_files/`,
format: format as 'jpeg' | 'png' | 'jpg' | 'JPG' | 'PNG',
overlap: Number.parseInt(overlap, 10),
tileSize: Number.parseInt(tileSize, 10),
size: {
width: Number.parseInt(width, 10),
height: Number.parseInt(height, 10),
},
};
}
}
}

return undefined;
}

/* Example XML
<?xml version="1.0" encoding="UTF-8"?>
<Image xmlns="http://schemas.microsoft.com/deepzoom/2008"
Format="jpg"
Overlap="2"
TileSize="256" >
<Size Height="9221"
Width="7026"/>
</Image>
*/

/* Example JSON
{
"Image": {
"xmlns": "http://schemas.microsoft.com/deepzoom/2008",
"Format": "jpg",
"Overlap": "2",
"TileSize": "256",
"Size": {
"Height": "9221",
"Width": "7026"
}
}
}
*/
81 changes: 0 additions & 81 deletions examples/src/dzi/double.tsx

This file was deleted.

Loading

0 comments on commit 81b2d6b

Please sign in to comment.