@niivue/niivue 0.67.1-dev.0 → 0.67.1-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/drawing/index.d.ts +1 -1
- package/build/drawing/index.js.map +1 -1
- package/build/index.min.js +1 -1
- package/build/metafile-esm.json +1 -1
- package/build/niivue/index.d.ts +3 -2
- package/build/niivue/index.js +89 -13
- package/build/niivue/index.js.map +1 -1
- package/build/{nvdocument-CcP6istx.d.ts → nvdocument-B64_4nuJ.d.ts} +18 -1
- package/build/utils/index.d.ts +1 -1
- package/dist/index.d.ts +19 -1
- package/dist/index.js +89 -13
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/metafile-esm.json +1 -1
- package/dist/niivue.umd.js +28 -28
- package/package.json +2 -2
- package/src/index_zarr_viewer.html +255 -68
- package/src/niivue/descriptives.ts +1 -1
- package/src/niivue/index.ts +22 -2
- package/src/nvimage/index.ts +1 -1
- package/src/nvimage/zarr/NVZarrHelper.ts +103 -12
- package/src/index_zarr.html +0 -152
|
@@ -770,6 +770,7 @@ declare class NVZarrHelper {
|
|
|
770
770
|
onAllChunksLoaded?: () => void;
|
|
771
771
|
private constructor();
|
|
772
772
|
static create(hostImage: NVImage, url: string, options: NVZarrHelperOptions): Promise<NVZarrHelper>;
|
|
773
|
+
loadInitialChunks(): Promise<void>;
|
|
773
774
|
private updateLevelInfo;
|
|
774
775
|
private configureHostImage;
|
|
775
776
|
/** Get unit-converted voxel scales */
|
|
@@ -791,6 +792,7 @@ declare class NVZarrHelper {
|
|
|
791
792
|
*/
|
|
792
793
|
private updateAffine;
|
|
793
794
|
beginDrag(): void;
|
|
795
|
+
endDrag(): void;
|
|
794
796
|
panBy(dx: number, dy: number, dz?: number): Promise<void>;
|
|
795
797
|
panTo(newCenterX: number, newCenterY: number, newCenterZ?: number): Promise<void>;
|
|
796
798
|
setPyramidLevel(level: number): Promise<void>;
|
|
@@ -812,6 +814,21 @@ declare class NVZarrHelper {
|
|
|
812
814
|
height: number;
|
|
813
815
|
depth: number;
|
|
814
816
|
};
|
|
817
|
+
/**
|
|
818
|
+
* Convert physical (mm) coordinates back to real zarr level pixel coordinates.
|
|
819
|
+
* Inverts the affine: levelPixel = (mm - OME_translation) / scale
|
|
820
|
+
*/
|
|
821
|
+
mmToLevelCoords(mmX: number, mmY: number, mmZ: number): {
|
|
822
|
+
width: number;
|
|
823
|
+
height: number;
|
|
824
|
+
depth: number;
|
|
825
|
+
level: number;
|
|
826
|
+
levelDims: {
|
|
827
|
+
width: number;
|
|
828
|
+
height: number;
|
|
829
|
+
depth: number;
|
|
830
|
+
};
|
|
831
|
+
};
|
|
815
832
|
private clampCenter;
|
|
816
833
|
private getVisibleChunks;
|
|
817
834
|
private updateVolume;
|
|
@@ -879,7 +896,7 @@ declare function copyAffine(affine: number[][]): number[][];
|
|
|
879
896
|
*/
|
|
880
897
|
declare function transformsEqual(a: AffineTransform, b: AffineTransform, epsilon?: number): boolean;
|
|
881
898
|
|
|
882
|
-
type TypedVoxelArray = Float32Array | Uint8Array | Int16Array | Float64Array | Uint16Array;
|
|
899
|
+
type TypedVoxelArray = Float32Array | Uint8Array | Int16Array | Float64Array | Uint16Array | Int32Array | Uint32Array;
|
|
883
900
|
/**
|
|
884
901
|
* a NVImage encapsulates some image data and provides methods to query and operate on images
|
|
885
902
|
*/
|
package/build/utils/index.d.ts
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -567,6 +567,7 @@ declare class NVZarrHelper {
|
|
|
567
567
|
onAllChunksLoaded?: () => void;
|
|
568
568
|
private constructor();
|
|
569
569
|
static create(hostImage: NVImage, url: string, options: NVZarrHelperOptions): Promise<NVZarrHelper>;
|
|
570
|
+
loadInitialChunks(): Promise<void>;
|
|
570
571
|
private updateLevelInfo;
|
|
571
572
|
private configureHostImage;
|
|
572
573
|
/** Get unit-converted voxel scales */
|
|
@@ -588,6 +589,7 @@ declare class NVZarrHelper {
|
|
|
588
589
|
*/
|
|
589
590
|
private updateAffine;
|
|
590
591
|
beginDrag(): void;
|
|
592
|
+
endDrag(): void;
|
|
591
593
|
panBy(dx: number, dy: number, dz?: number): Promise<void>;
|
|
592
594
|
panTo(newCenterX: number, newCenterY: number, newCenterZ?: number): Promise<void>;
|
|
593
595
|
setPyramidLevel(level: number): Promise<void>;
|
|
@@ -609,6 +611,21 @@ declare class NVZarrHelper {
|
|
|
609
611
|
height: number;
|
|
610
612
|
depth: number;
|
|
611
613
|
};
|
|
614
|
+
/**
|
|
615
|
+
* Convert physical (mm) coordinates back to real zarr level pixel coordinates.
|
|
616
|
+
* Inverts the affine: levelPixel = (mm - OME_translation) / scale
|
|
617
|
+
*/
|
|
618
|
+
mmToLevelCoords(mmX: number, mmY: number, mmZ: number): {
|
|
619
|
+
width: number;
|
|
620
|
+
height: number;
|
|
621
|
+
depth: number;
|
|
622
|
+
level: number;
|
|
623
|
+
levelDims: {
|
|
624
|
+
width: number;
|
|
625
|
+
height: number;
|
|
626
|
+
depth: number;
|
|
627
|
+
};
|
|
628
|
+
};
|
|
612
629
|
private clampCenter;
|
|
613
630
|
private getVisibleChunks;
|
|
614
631
|
private updateVolume;
|
|
@@ -676,7 +693,7 @@ declare function copyAffine(affine: number[][]): number[][];
|
|
|
676
693
|
*/
|
|
677
694
|
declare function transformsEqual(a: AffineTransform, b: AffineTransform, epsilon?: number): boolean;
|
|
678
695
|
|
|
679
|
-
type TypedVoxelArray = Float32Array | Uint8Array | Int16Array | Float64Array | Uint16Array;
|
|
696
|
+
type TypedVoxelArray = Float32Array | Uint8Array | Int16Array | Float64Array | Uint16Array | Int32Array | Uint32Array;
|
|
680
697
|
/**
|
|
681
698
|
* a NVImage encapsulates some image data and provides methods to query and operate on images
|
|
682
699
|
*/
|
|
@@ -2314,6 +2331,7 @@ declare class Niivue {
|
|
|
2314
2331
|
private canvasObserver;
|
|
2315
2332
|
syncOpts: SyncOpts;
|
|
2316
2333
|
readyForSync: boolean;
|
|
2334
|
+
private _skipDragInDraw;
|
|
2317
2335
|
uiData: UIData;
|
|
2318
2336
|
back: NVImage | null;
|
|
2319
2337
|
overlays: NVImage[];
|
package/dist/index.js
CHANGED
|
@@ -5249,7 +5249,7 @@ var forEach3 = (function() {
|
|
|
5249
5249
|
// package.json
|
|
5250
5250
|
var package_default = {
|
|
5251
5251
|
name: "@niivue/niivue",
|
|
5252
|
-
version: "0.67.0",
|
|
5252
|
+
version: "0.67.1-dev.0",
|
|
5253
5253
|
description: "minimal webgl2 nifti image viewer",
|
|
5254
5254
|
types: "./build/niivue/index.d.ts",
|
|
5255
5255
|
main: "./build/niivue/index.js",
|
|
@@ -31227,9 +31227,11 @@ function createTypedVoxelArray(datatypeCode, size) {
|
|
|
31227
31227
|
case 512 /* DT_UINT16 */:
|
|
31228
31228
|
return new Uint16Array(size);
|
|
31229
31229
|
case 4 /* DT_INT16 */:
|
|
31230
|
-
case 8 /* DT_INT32 */:
|
|
31231
31230
|
return new Int16Array(size);
|
|
31231
|
+
case 8 /* DT_INT32 */:
|
|
31232
|
+
return new Int32Array(size);
|
|
31232
31233
|
case 768 /* DT_UINT32 */:
|
|
31234
|
+
return new Uint32Array(size);
|
|
31233
31235
|
case 16 /* DT_FLOAT32 */:
|
|
31234
31236
|
return new Float32Array(size);
|
|
31235
31237
|
case 64 /* DT_FLOAT64 */:
|
|
@@ -31353,13 +31355,15 @@ var NVZarrHelper = class _NVZarrHelper {
|
|
|
31353
31355
|
const level = Math.max(0, Math.min(options.level, helper.pyramidInfo.levels.length - 1));
|
|
31354
31356
|
helper.pyramidLevel = level;
|
|
31355
31357
|
helper.updateLevelInfo();
|
|
31356
|
-
helper.centerX = helper.
|
|
31357
|
-
helper.centerY = helper.
|
|
31358
|
-
helper.centerZ = helper.
|
|
31358
|
+
helper.centerX = helper.volumeDims.width / 2;
|
|
31359
|
+
helper.centerY = helper.volumeDims.height / 2;
|
|
31360
|
+
helper.centerZ = helper.volumeDims.depth / 2;
|
|
31359
31361
|
helper.configureHostImage();
|
|
31360
|
-
await helper.updateVolume();
|
|
31361
31362
|
return helper;
|
|
31362
31363
|
}
|
|
31364
|
+
async loadInitialChunks() {
|
|
31365
|
+
await this.updateVolume();
|
|
31366
|
+
}
|
|
31363
31367
|
updateLevelInfo() {
|
|
31364
31368
|
const levelInfo = this.pyramidInfo.levels[this.pyramidLevel];
|
|
31365
31369
|
const shape = levelInfo.shape;
|
|
@@ -31431,12 +31435,12 @@ var NVZarrHelper = class _NVZarrHelper {
|
|
|
31431
31435
|
img.img = createTypedVoxelArray(this.datatypeCode, width * height * depth);
|
|
31432
31436
|
this.updateAffine();
|
|
31433
31437
|
img.originalAffine = copyAffine(hdr.affine);
|
|
31434
|
-
img.cal_min =
|
|
31435
|
-
img.cal_max =
|
|
31436
|
-
img.robust_min =
|
|
31437
|
-
img.robust_max =
|
|
31438
|
-
img.global_min =
|
|
31439
|
-
img.global_max =
|
|
31438
|
+
img.cal_min = 0;
|
|
31439
|
+
img.cal_max = 0;
|
|
31440
|
+
img.robust_min = 0;
|
|
31441
|
+
img.robust_max = 0;
|
|
31442
|
+
img.global_min = 0;
|
|
31443
|
+
img.global_max = 0;
|
|
31440
31444
|
}
|
|
31441
31445
|
/** Get unit-converted voxel scales */
|
|
31442
31446
|
getConvertedScales() {
|
|
@@ -31555,6 +31559,9 @@ var NVZarrHelper = class _NVZarrHelper {
|
|
|
31555
31559
|
beginDrag() {
|
|
31556
31560
|
this.centerAtDragStart = { x: this.centerX, y: this.centerY, z: this.centerZ };
|
|
31557
31561
|
}
|
|
31562
|
+
endDrag() {
|
|
31563
|
+
this.centerAtDragStart = null;
|
|
31564
|
+
}
|
|
31558
31565
|
async panBy(dx, dy, dz = 0) {
|
|
31559
31566
|
this.centerX -= dx;
|
|
31560
31567
|
this.centerY -= dy;
|
|
@@ -31564,12 +31571,18 @@ var NVZarrHelper = class _NVZarrHelper {
|
|
|
31564
31571
|
await this.updateVolume();
|
|
31565
31572
|
}
|
|
31566
31573
|
async panTo(newCenterX, newCenterY, newCenterZ) {
|
|
31574
|
+
const prevX = this.centerX;
|
|
31575
|
+
const prevY = this.centerY;
|
|
31576
|
+
const prevZ = this.centerZ;
|
|
31567
31577
|
this.centerX = newCenterX;
|
|
31568
31578
|
this.centerY = newCenterY;
|
|
31569
31579
|
if (newCenterZ !== void 0) {
|
|
31570
31580
|
this.centerZ = newCenterZ;
|
|
31571
31581
|
}
|
|
31572
31582
|
this.clampCenter();
|
|
31583
|
+
if (Math.abs(this.centerX - prevX) < 1e-3 && Math.abs(this.centerY - prevY) < 1e-3 && Math.abs(this.centerZ - prevZ) < 1e-3) {
|
|
31584
|
+
return;
|
|
31585
|
+
}
|
|
31573
31586
|
this.updateAffine();
|
|
31574
31587
|
await this.updateVolume();
|
|
31575
31588
|
}
|
|
@@ -31609,6 +31622,54 @@ var NVZarrHelper = class _NVZarrHelper {
|
|
|
31609
31622
|
getVolumeDims() {
|
|
31610
31623
|
return { ...this.volumeDims };
|
|
31611
31624
|
}
|
|
31625
|
+
/**
|
|
31626
|
+
* Convert physical (mm) coordinates back to real zarr level pixel coordinates.
|
|
31627
|
+
* Inverts the affine: levelPixel = (mm - OME_translation) / scale
|
|
31628
|
+
*/
|
|
31629
|
+
mmToLevelCoords(mmX, mmY, mmZ) {
|
|
31630
|
+
const { scaleW, scaleH, scaleD } = this.getConvertedScales();
|
|
31631
|
+
const axisNames = this.pyramidInfo.axisMapping.spatialAxisNames;
|
|
31632
|
+
const mmByAxis = { x: mmX, y: mmY, z: mmZ };
|
|
31633
|
+
let levelW = 0;
|
|
31634
|
+
let levelH = 0;
|
|
31635
|
+
let levelD = 0;
|
|
31636
|
+
if (axisNames.length >= 2) {
|
|
31637
|
+
const wAxisName = axisNames[axisNames.length - 1];
|
|
31638
|
+
const hAxisName = axisNames[axisNames.length - 2];
|
|
31639
|
+
const dAxisName = axisNames.length >= 3 ? axisNames[axisNames.length - 3] : "z";
|
|
31640
|
+
const mmW = mmByAxis[wAxisName] ?? mmX;
|
|
31641
|
+
const mmH = mmByAxis[hAxisName] ?? mmY;
|
|
31642
|
+
const mmD = mmByAxis[dAxisName] ?? mmZ;
|
|
31643
|
+
if (this.hasTranslations) {
|
|
31644
|
+
const { transW, transH, transD } = this.getConvertedTranslations();
|
|
31645
|
+
levelW = scaleW !== 0 ? (mmW - transW) / scaleW : 0;
|
|
31646
|
+
levelH = scaleH !== 0 ? (mmH - transH) / scaleH : 0;
|
|
31647
|
+
levelD = scaleD !== 0 ? (mmD - transD) / scaleD : 0;
|
|
31648
|
+
} else {
|
|
31649
|
+
levelW = scaleW !== 0 ? mmW / scaleW : 0;
|
|
31650
|
+
levelH = scaleH !== 0 ? mmH / scaleH : 0;
|
|
31651
|
+
levelD = scaleD !== 0 ? mmD / scaleD : 0;
|
|
31652
|
+
}
|
|
31653
|
+
} else {
|
|
31654
|
+
if (this.hasTranslations) {
|
|
31655
|
+
const { transW, transH, transD } = this.getConvertedTranslations();
|
|
31656
|
+
levelW = scaleW !== 0 ? (mmX - transW) / scaleW : 0;
|
|
31657
|
+
levelH = scaleH !== 0 ? (mmY - transH) / scaleH : 0;
|
|
31658
|
+
levelD = scaleD !== 0 ? (mmZ - transD) / scaleD : 0;
|
|
31659
|
+
} else {
|
|
31660
|
+
levelW = scaleW !== 0 ? mmX / scaleW : 0;
|
|
31661
|
+
levelH = scaleH !== 0 ? mmY / scaleH : 0;
|
|
31662
|
+
levelD = scaleD !== 0 ? mmZ / scaleD : 0;
|
|
31663
|
+
}
|
|
31664
|
+
}
|
|
31665
|
+
return {
|
|
31666
|
+
width: Math.round(levelW),
|
|
31667
|
+
height: Math.round(levelH),
|
|
31668
|
+
depth: Math.round(levelD),
|
|
31669
|
+
level: this.pyramidLevel,
|
|
31670
|
+
levelDims: { ...this.levelDims }
|
|
31671
|
+
};
|
|
31672
|
+
}
|
|
31612
31673
|
clampCenter() {
|
|
31613
31674
|
const halfW = this.volumeDims.width / 2;
|
|
31614
31675
|
const halfH = this.volumeDims.height / 2;
|
|
@@ -43414,6 +43475,7 @@ var Niivue = class {
|
|
|
43414
43475
|
crosshair: false
|
|
43415
43476
|
});
|
|
43416
43477
|
__publicField(this, "readyForSync", false);
|
|
43478
|
+
__publicField(this, "_skipDragInDraw", false);
|
|
43417
43479
|
// UI Data
|
|
43418
43480
|
__publicField(this, "uiData", {
|
|
43419
43481
|
mousedown: false,
|
|
@@ -44510,6 +44572,9 @@ var Niivue = class {
|
|
|
44510
44572
|
}
|
|
44511
44573
|
if (this.uiData.isDragging) {
|
|
44512
44574
|
this.uiData.isDragging = false;
|
|
44575
|
+
for (const vol of this.getZarrVolumes()) {
|
|
44576
|
+
vol.zarrHelper?.endDrag();
|
|
44577
|
+
}
|
|
44513
44578
|
if (currentDragMode === 7 /* angle */) {
|
|
44514
44579
|
if (this.uiData.angleState === "drawing_first_line") {
|
|
44515
44580
|
this.uiData.angleFirstLine = [this.uiData.dragStart[0], this.uiData.dragStart[1], this.uiData.dragEnd[0], this.uiData.dragEnd[1]];
|
|
@@ -44655,6 +44720,9 @@ var Niivue = class {
|
|
|
44655
44720
|
}
|
|
44656
44721
|
if (this.uiData.isDragging) {
|
|
44657
44722
|
this.uiData.isDragging = false;
|
|
44723
|
+
for (const vol of this.getZarrVolumes()) {
|
|
44724
|
+
vol.zarrHelper?.endDrag();
|
|
44725
|
+
}
|
|
44658
44726
|
if (this.getCurrentDragMode() === 1 /* contrast */) {
|
|
44659
44727
|
this.calculateNewRange();
|
|
44660
44728
|
this.refreshLayers(this.volumes[0], 0);
|
|
@@ -44714,6 +44782,9 @@ var Niivue = class {
|
|
|
44714
44782
|
if (this.uiData.isDragging || this.uiData.mousedown) {
|
|
44715
44783
|
log.debug("Mouse left canvas during drag, resetting drag state.");
|
|
44716
44784
|
this.uiData.isDragging = false;
|
|
44785
|
+
for (const vol of this.getZarrVolumes()) {
|
|
44786
|
+
vol.zarrHelper?.endDrag();
|
|
44787
|
+
}
|
|
44717
44788
|
const resetState = createResetButtonState();
|
|
44718
44789
|
this.uiData.mouseButtonLeftDown = resetState.mouseButtonLeftDown;
|
|
44719
44790
|
this.uiData.mouseButtonCenterDown = resetState.mouseButtonCenterDown;
|
|
@@ -45866,8 +45937,11 @@ var Niivue = class {
|
|
|
45866
45937
|
if (volume.zarrHelper) {
|
|
45867
45938
|
volume.zarrHelper.onChunksUpdated = () => {
|
|
45868
45939
|
this.updateGLVolume();
|
|
45940
|
+
this._skipDragInDraw = true;
|
|
45869
45941
|
this.drawScene();
|
|
45942
|
+
this._skipDragInDraw = false;
|
|
45870
45943
|
};
|
|
45944
|
+
volume.zarrHelper.loadInitialChunks().catch((err2) => log.error("Failed to load initial zarr chunks", err2));
|
|
45871
45945
|
}
|
|
45872
45946
|
log.debug("loaded volume", volume.name);
|
|
45873
45947
|
log.debug(volume);
|
|
@@ -49994,7 +50068,9 @@ var Niivue = class {
|
|
|
49994
50068
|
}
|
|
49995
50069
|
if (panPromises.length > 0) {
|
|
49996
50070
|
Promise.all(panPromises).then(() => {
|
|
50071
|
+
this._skipDragInDraw = true;
|
|
49997
50072
|
this.drawScene();
|
|
50073
|
+
this._skipDragInDraw = false;
|
|
49998
50074
|
}).catch((err2) => {
|
|
49999
50075
|
log.error("Failed to pan Zarr:", err2);
|
|
50000
50076
|
});
|
|
@@ -53271,7 +53347,7 @@ var Niivue = class {
|
|
|
53271
53347
|
this.dragForSlicer3D([this.uiData.dragStart[0], this.uiData.dragStart[1], this.uiData.dragEnd[0], this.uiData.dragEnd[1]]);
|
|
53272
53348
|
return;
|
|
53273
53349
|
}
|
|
53274
|
-
if (this.getCurrentDragMode() === 3 /* pan */) {
|
|
53350
|
+
if (this.getCurrentDragMode() === 3 /* pan */ && !this._skipDragInDraw) {
|
|
53275
53351
|
this.dragForPanZoom([this.uiData.dragStart[0], this.uiData.dragStart[1], this.uiData.dragEnd[0], this.uiData.dragEnd[1]]);
|
|
53276
53352
|
return;
|
|
53277
53353
|
}
|