@aics/vole-app 3.3.1 → 3.4.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.
Files changed (38) hide show
  1. package/es/aics-image-viewer/components/App/index.js +1 -0
  2. package/es/aics-image-viewer/components/BottomPanel/index.js +48 -19
  3. package/es/aics-image-viewer/components/BottomPanel/styles.css +16 -7
  4. package/es/aics-image-viewer/components/CellViewerCanvasWrapper/index.js +39 -19
  5. package/es/aics-image-viewer/components/ControlPanel/index.js +2 -0
  6. package/es/aics-image-viewer/components/dimension_sliders/AxisClipSliders.js +148 -0
  7. package/es/aics-image-viewer/components/dimension_sliders/RotationSliders.js +167 -0
  8. package/es/aics-image-viewer/components/dimension_sliders/SliderRows.js +167 -0
  9. package/es/aics-image-viewer/components/{AxisClipSliders → dimension_sliders}/styles.css +7 -1
  10. package/es/aics-image-viewer/components/shared/NumericInput/index.js +4 -2
  11. package/es/aics-image-viewer/components/shared/SliderRow/index.js +2 -0
  12. package/es/aics-image-viewer/components/shared/SliderRow/styles.css +2 -1
  13. package/es/aics-image-viewer/shared/constants.js +1 -1
  14. package/es/aics-image-viewer/shared/utils/camera.js +122 -0
  15. package/es/aics-image-viewer/shared/utils/test/camera.test.js +127 -0
  16. package/es/aics-image-viewer/shared/utils/test/urlParsing.test.js +23 -702
  17. package/es/aics-image-viewer/shared/utils/urlParsing.js +14 -828
  18. package/es/aics-image-viewer/state/deserialize.js +437 -0
  19. package/es/aics-image-viewer/state/serialize.js +145 -0
  20. package/es/aics-image-viewer/state/test/deserialize.test.js +432 -0
  21. package/es/aics-image-viewer/state/test/serialize.test.js +97 -0
  22. package/es/aics-image-viewer/state/test/test_data.js +168 -0
  23. package/es/aics-image-viewer/state/types.js +265 -1
  24. package/package.json +2 -1
  25. package/type-declarations/aics-image-viewer/components/App/types.d.ts +1 -1
  26. package/type-declarations/aics-image-viewer/components/BottomPanel/index.d.ts +6 -3
  27. package/type-declarations/aics-image-viewer/components/CellViewerCanvasWrapper/index.d.ts +1 -0
  28. package/type-declarations/aics-image-viewer/components/{AxisClipSliders/index.d.ts → dimension_sliders/AxisClipSliders.d.ts} +2 -3
  29. package/type-declarations/aics-image-viewer/components/dimension_sliders/RotationSliders.d.ts +6 -0
  30. package/type-declarations/aics-image-viewer/components/dimension_sliders/SliderRows.d.ts +31 -0
  31. package/type-declarations/aics-image-viewer/components/shared/NumericInput/index.d.ts +1 -0
  32. package/type-declarations/aics-image-viewer/components/shared/SliderRow/index.d.ts +3 -1
  33. package/type-declarations/aics-image-viewer/shared/utils/camera.d.ts +19 -0
  34. package/type-declarations/aics-image-viewer/shared/utils/urlParsing.d.ts +1 -307
  35. package/type-declarations/aics-image-viewer/state/deserialize.d.ts +70 -0
  36. package/type-declarations/aics-image-viewer/state/serialize.d.ts +20 -0
  37. package/type-declarations/aics-image-viewer/state/types.d.ts +216 -0
  38. package/es/aics-image-viewer/components/AxisClipSliders/index.js +0 -295
@@ -1,295 +0,0 @@
1
- function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
- function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
3
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
4
- function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
5
- function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
6
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
7
- function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
8
- function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
9
- function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
10
- function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
11
- import { CaretRightOutlined, PauseOutlined } from "@ant-design/icons";
12
- import { Button, Tooltip } from "antd";
13
- import React, { useCallback, useEffect, useState } from "react";
14
- import { activeAxisMap } from "../../shared/types";
15
- import NumericInput from "../shared/NumericInput";
16
- import SmarterSlider from "../shared/SmarterSlider";
17
- import "./styles.css";
18
- var AXES = ["x", "y", "z"];
19
- /** A single slider row, with a slider, one or two spinbox inputs, and a max value */
20
- var SliderRow = function SliderRow(_ref) {
21
- var label = _ref.label,
22
- vals = _ref.vals,
23
- _ref$valsReadout = _ref.valsReadout,
24
- valsReadout = _ref$valsReadout === void 0 ? vals : _ref$valsReadout,
25
- max = _ref.max,
26
- onSlide = _ref.onSlide,
27
- _ref$onChange = _ref.onChange,
28
- _onChange = _ref$onChange === void 0 ? onSlide : _ref$onChange,
29
- onStart = _ref.onStart,
30
- onEnd = _ref.onEnd;
31
- var isRange = vals.length > 1;
32
- // If slider is a range, handles represent slice *edges*: the range around only the 1st slice is [0, 1]; the range
33
- // around only the last is [max-1, max].
34
- // If slider is not a range, just work with slices, but don't 0-index: 1st slice is 1, last is max
35
- var min = isRange ? 0 : 1;
36
- var wrappedOnSlide = isRange ? onSlide : function (values) {
37
- return onSlide === null || onSlide === void 0 ? void 0 : onSlide([values[0] - 1]);
38
- };
39
- var wrappedOnChange = isRange ? _onChange : function (values) {
40
- return _onChange === null || _onChange === void 0 ? void 0 : _onChange([values[0] - 1]);
41
- };
42
- return /*#__PURE__*/React.createElement("span", {
43
- className: "axis-slider-container"
44
- }, /*#__PURE__*/React.createElement("span", {
45
- className: "slider-name"
46
- }, label), max <= min ? /*#__PURE__*/React.createElement("i", null, "No values to adjust") : /*#__PURE__*/React.createElement("span", {
47
- className: "axis-slider"
48
- }, /*#__PURE__*/React.createElement(SmarterSlider, {
49
- className: isRange ? "" : "slider-single-handle",
50
- connect: true,
51
- range: {
52
- min: min,
53
- max: max
54
- },
55
- start: isRange ? vals : [vals[0] + 1],
56
- step: 1,
57
- margin: 1,
58
- behaviour: "drag",
59
- pips: {
60
- mode: "positions",
61
- values: [25, 50, 75],
62
- density: 25,
63
- format: {
64
- // remove labels from pips
65
- to: function to() {
66
- return "";
67
- }
68
- }
69
- }
70
- // round slider output to nearest slice; assume any string inputs represent ints
71
- ,
72
- format: {
73
- to: Math.round,
74
- from: parseInt
75
- },
76
- onSlide: wrappedOnSlide,
77
- onChange: wrappedOnChange,
78
- onStart: onStart,
79
- onEnd: onEnd
80
- })), max > min && /*#__PURE__*/React.createElement("span", {
81
- className: "slider-values"
82
- }, /*#__PURE__*/React.createElement(NumericInput, {
83
- min: min,
84
- max: max,
85
- value: valsReadout[0] + (isRange ? 0 : 1),
86
- onChange: function onChange(value) {
87
- return _onChange === null || _onChange === void 0 ? void 0 : _onChange(isRange ? [value, vals[1]] : [value - 1]);
88
- }
89
- }), isRange && /*#__PURE__*/React.createElement(React.Fragment, null, " , ", /*#__PURE__*/React.createElement(NumericInput, {
90
- min: min,
91
- max: max,
92
- value: valsReadout[1],
93
- onChange: function onChange(value) {
94
- return _onChange === null || _onChange === void 0 ? void 0 : _onChange([vals[0], value]);
95
- }
96
- })), " / ", max));
97
- };
98
- /** Wrapper around `SliderRow` that adds a play button and accounts for the case where not all of an axis is loaded */
99
- var PlaySliderRow = function PlaySliderRow(props) {
100
- var onChange = props.onChange,
101
- onStart = props.onStart,
102
- onEnd = props.onEnd;
103
- // In partially-loaded axes, stores the displayed value of the slider while the user is sliding it
104
- var _useState = useState(props.val),
105
- _useState2 = _slicedToArray(_useState, 2),
106
- valReadout = _useState2[0],
107
- setValReadout = _useState2[1];
108
- // Tracks when the user is sliding the slider and `valReadout` may have to sub in for props
109
- var _useState3 = useState(false),
110
- _useState4 = _slicedToArray(_useState3, 2),
111
- sliderHeld = _useState4[0],
112
- setSliderHeld = _useState4[1];
113
- var wrappedOnChange = useCallback(function (_ref2) {
114
- var _ref3 = _slicedToArray(_ref2, 1),
115
- val = _ref3[0];
116
- return onChange === null || onChange === void 0 ? void 0 : onChange(val);
117
- }, [onChange]);
118
- var wrappedSetValReadout = useCallback(function (_ref4) {
119
- var _ref5 = _slicedToArray(_ref4, 1),
120
- val = _ref5[0];
121
- return setValReadout(val);
122
- }, []);
123
- var wrappedOnStart = useCallback(function () {
124
- setValReadout(props.val);
125
- setSliderHeld(true);
126
- onStart === null || onStart === void 0 || onStart();
127
- }, [onStart, props.val]);
128
- var wrappedOnEnd = useCallback(function () {
129
- setSliderHeld(false);
130
- onEnd === null || onEnd === void 0 || onEnd();
131
- }, [onEnd]);
132
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SliderRow, {
133
- label: props.label,
134
- vals: [props.val],
135
- valsReadout: props.updateWhileSliding || !sliderHeld ? undefined : [valReadout],
136
- max: props.max,
137
- onSlide: props.updateWhileSliding ? wrappedOnChange : wrappedSetValReadout,
138
- onChange: props.updateWhileSliding ? undefined : wrappedOnChange,
139
- onStart: wrappedOnStart,
140
- onEnd: wrappedOnEnd
141
- }), props.max > 1 && /*#__PURE__*/React.createElement(Tooltip, {
142
- placement: "top",
143
- title: "Play through sequence",
144
- trigger: ["hover", "focus"]
145
- }, /*#__PURE__*/React.createElement(Button, {
146
- className: "slider-play-button",
147
- onClick: function onClick() {
148
- return props.onTogglePlayback(!props.playing);
149
- },
150
- icon: props.playing ? /*#__PURE__*/React.createElement(PauseOutlined, null) : /*#__PURE__*/React.createElement(CaretRightOutlined, null),
151
- "aria-label": (props.playing ? "Pause " : "Play ") + props.label
152
- })));
153
- };
154
- var AxisClipSliders = function AxisClipSliders(props) {
155
- var activeAxis = activeAxisMap[props.mode];
156
- var pauseOnInput = function pauseOnInput(axis) {
157
- // Pause on slider input unless user is scrubbing along the playing axis (playback is held while this is happening)
158
- if (!props.playControls.playHolding || props.playingAxis !== axis) {
159
- props.playControls.pause();
160
- }
161
- };
162
- var updateRegion = function updateRegion(axis, minval, maxval) {
163
- pauseOnInput(axis);
164
- var changeViewerSetting = props.changeViewerSetting,
165
- numSlices = props.numSlices;
166
- // get a value from 0-1
167
- var max = numSlices[axis];
168
- var start = minval / max;
169
- var end = maxval / max;
170
- changeViewerSetting("region", _defineProperty({}, axis, [start, end]));
171
- };
172
- var updateSlice = function updateSlice(axis, slice) {
173
- pauseOnInput(axis);
174
- props.changeViewerSetting("slice", _defineProperty({}, axis, slice / props.numSlices[axis]));
175
- };
176
- var updateTime = function updateTime(time) {
177
- pauseOnInput("t");
178
- props.changeViewerSetting("time", time);
179
- };
180
-
181
- // Pause when view mode or volume size has changed
182
- useEffect(function () {
183
- return props.playControls.pause();
184
- }, [props.mode, props.image, props.playControls]);
185
- var handlePlayPause = function handlePlayPause(axis, willPlay) {
186
- if (willPlay) {
187
- props.playControls.play(axis);
188
- } else {
189
- props.playControls.pause();
190
- }
191
- };
192
- var create2dAxisSlider = function create2dAxisSlider(axis) {
193
- var numSlices = props.numSlices[axis];
194
- var numSlicesLoaded = props.numSlicesLoaded[axis];
195
- return /*#__PURE__*/React.createElement("div", {
196
- key: axis + numSlices + numSlicesLoaded,
197
- className: "slider-row slider-".concat(axis)
198
- }, /*#__PURE__*/React.createElement(PlaySliderRow, {
199
- label: axis.toUpperCase(),
200
- val: Math.round(props.slices[axis] * numSlices),
201
- max: numSlices,
202
- onChange: function onChange(val) {
203
- return updateSlice(axis, val);
204
- },
205
- onStart: function onStart() {
206
- return props.playControls.startHold(axis);
207
- },
208
- onEnd: function onEnd() {
209
- return props.playControls.endHold();
210
- },
211
- playing: props.playingAxis === axis,
212
- onTogglePlayback: function onTogglePlayback(willPlay) {
213
- return handlePlayPause(axis, willPlay);
214
- },
215
- updateWhileSliding: numSlices === numSlicesLoaded
216
- }));
217
- };
218
- var create3dAxisSlider = function create3dAxisSlider(axis) {
219
- var numSlices = props.numSlices[axis];
220
- if (numSlices === 1) {
221
- return null;
222
- }
223
- var region = props.region[axis];
224
- return /*#__PURE__*/React.createElement("div", {
225
- key: axis + numSlices + "3d",
226
- className: "slider-row slider-".concat(axis)
227
- }, /*#__PURE__*/React.createElement(SliderRow, {
228
- label: axis.toUpperCase(),
229
- vals: [Math.round(region[0] * numSlices), Math.round(region[1] * numSlices)],
230
- max: numSlices,
231
- onSlide: function onSlide(values) {
232
- return updateRegion(axis, values[0], values[1]);
233
- },
234
- onStart: function onStart() {
235
- return props.playControls.startHold(axis);
236
- },
237
- onEnd: function onEnd() {
238
- return props.playControls.endHold();
239
- }
240
- }));
241
- };
242
- return /*#__PURE__*/React.createElement("div", {
243
- className: activeAxis ? "clip-sliders clip-sliders-2d" : "clip-sliders"
244
- }, /*#__PURE__*/React.createElement("span", {
245
- className: "slider-group"
246
- }, /*#__PURE__*/React.createElement("h4", {
247
- className: "slider-group-title"
248
- }, "ROI"), /*#__PURE__*/React.createElement("span", {
249
- className: "slider-group-rows"
250
- }, activeAxis ? create2dAxisSlider(activeAxis) : AXES.map(create3dAxisSlider))), props.numTimesteps > 1 && /*#__PURE__*/React.createElement("span", {
251
- className: "slider-group"
252
- }, /*#__PURE__*/React.createElement("h4", {
253
- className: "slider-group-title"
254
- }, "Time"), /*#__PURE__*/React.createElement("span", {
255
- className: "slider-group-rows"
256
- }, /*#__PURE__*/React.createElement("div", {
257
- className: "slider-row slider-t"
258
- }, /*#__PURE__*/React.createElement(PlaySliderRow, {
259
- label: "",
260
- val: props.time,
261
- max: props.numTimesteps,
262
- playing: props.playingAxis === "t",
263
- onTogglePlayback: function onTogglePlayback(willPlay) {
264
- return handlePlayPause("t", willPlay);
265
- },
266
- onChange: function onChange(time) {
267
- return updateTime(time);
268
- },
269
- onStart: function onStart() {
270
- return props.playControls.startHold("t");
271
- },
272
- onEnd: function onEnd() {
273
- return props.playControls.endHold();
274
- }
275
- })))), props.numScenes > 1 && /*#__PURE__*/React.createElement("span", {
276
- className: "slider-group"
277
- }, /*#__PURE__*/React.createElement("h4", {
278
- className: "slider-group-title"
279
- }, "Scene"), /*#__PURE__*/React.createElement("span", {
280
- className: "slider-group-rows"
281
- }, /*#__PURE__*/React.createElement("div", {
282
- className: "slider-row slider-scene"
283
- }, /*#__PURE__*/React.createElement(SliderRow, {
284
- label: "",
285
- vals: [props.scene],
286
- max: props.numScenes,
287
- onChange: function onChange(_ref6) {
288
- var _ref7 = _slicedToArray(_ref6, 1),
289
- scene = _ref7[0];
290
- props.changeViewerSetting("scene", scene);
291
- props.changeViewerSetting("useExactScaleLevel", false);
292
- }
293
- })))));
294
- };
295
- export default AxisClipSliders;