jeri
Version:
JavaScript Extended-Range Image viewer
141 lines • 6.8 kB
JavaScript
;
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var React = require("react");
var styled_components_1 = require("styled-components");
var ImageFrame_1 = require("./ImageFrame");
var image_loading_1 = require("../utils/image-loading");
var StretchingDiv = (_a = ["\n position: absolute;\n top: 0; bottom: 0;\n left: 0; right: 0;\n width: 100%; height: 100%;\n"], _a.raw = ["\n position: absolute;\n top: 0; bottom: 0;\n left: 0; right: 0;\n width: 100%; height: 100%;\n"], styled_components_1.default.div(_a));
var LoadingOverlay = (_b = ["\n display: block;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n right: 0;\n text-align: left;\n padding: .6em;\n background-color: rgb(64, 64, 64);\n"], _b.raw = ["\n display: block;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n right: 0;\n text-align: left;\n padding: .6em;\n background-color: rgb(64, 64, 64);\n"], styled_components_1.default.div(_b));
/**
* A wrapper around ImageFrame that deals with the loading of images
* It takes an `ImageSpec` instead of an `InputImage`.
*/
var ImageFrameWithLoading = /** @class */ (function (_super) {
__extends(ImageFrameWithLoading, _super);
function ImageFrameWithLoading(props) {
var _this = _super.call(this, props) || this;
_this.cache = new image_loading_1.ImageCache();
_this.requestId = 0;
// Counter to ensure that returning downloads are still relevant to the current app state.
_this.currentRequest = 0;
_this.state = {
isLoading: false,
errorMsg: null,
image: null,
};
_this.handleImageChange(props, false);
return _this;
}
ImageFrameWithLoading.prototype.componentWillReceiveProps = function (nextProps) {
if (nextProps.imageSpec !== this.props.imageSpec) {
this.handleImageChange(nextProps);
}
};
ImageFrameWithLoading.prototype.componentWillUnmount = function () {
// Don't handle any returning downloads anymore after unmount.
this.requestId = -1;
};
ImageFrameWithLoading.prototype.render = function () {
var _this = this;
return (React.createElement(StretchingDiv, null,
this.state.image != null ?
React.createElement(ImageFrame_1.default, { viewTransform: this.props.viewTransform, exposure: this.props.exposure, gamma: this.props.gamma, offset: this.props.offset, image: this.state.image, ref: function (frame) { return _this.imageFrame = frame; }, allowMovement: this.props.allowMovement, enableMouseEvents: this.props.enableMouseEvents })
: null,
this.state.isLoading ? React.createElement(LoadingOverlay, null, "Downloading ...") : null,
this.state.errorMsg ? React.createElement(LoadingOverlay, null, this.state.errorMsg) : null));
};
/**
* Initiate the download of the current spec.
* Sets the state in case of correct or incorrect loads.
*/
ImageFrameWithLoading.prototype.handleImageChange = function (props, shouldSetLoadingState) {
var _this = this;
if (shouldSetLoadingState === void 0) { shouldSetLoadingState = true; }
this.currentRequest++;
var handledRequest = this.currentRequest;
if (shouldSetLoadingState) {
this.setState({
isLoading: true,
errorMsg: null,
});
}
this.downloadImage(props.imageSpec)
.then(function (image) {
if (handledRequest !== _this.currentRequest) {
// This download does not correspond to the latest request, so should not be shown.
return;
}
_this.setState({
errorMsg: null,
isLoading: false,
image: image,
});
})
.catch(function (error) {
if (handledRequest !== _this.requestId) {
// This download does not correspond to the latest request, so should not be shown.
return;
}
_this.setState({
errorMsg: error.message,
isLoading: false,
});
});
};
/**
* Download an image
* @param image specification of the image to download (url or difference of two images)
* @return Promise of a loaded image
*/
ImageFrameWithLoading.prototype.downloadImage = function (spec) {
var _this = this;
if (spec.type === 'Url') {
return this.cache.get(spec.url);
}
else if (spec.type === 'Difference') {
return Promise.all([spec.urlA, spec.urlB].map(function (url) { return _this.cache.get(url); }))
.then(function (_a) {
var imageA = _a[0], imageB = _a[1];
// Make sure images have the same size and number of channels;
var height = imageA.height;
var width = imageA.width;
var nChannels = imageA.nChannels;
if (height !== imageB.height) {
throw Error(spec.urlA + " & " + spec.urlB + " with heights " + height + " & " + imageB.height + " cannot be compared.");
}
if (width !== imageB.width) {
throw Error(spec.urlA + " & " + spec.urlB + " with widths " + width + " & " + imageB.width + " cannot be compared.");
}
if (nChannels !== imageB.nChannels) {
throw Error(spec.urlA + " & " + spec.urlB + " with unequal nChannels " + nChannels + " & " + imageB.nChannels + ".");
}
return {
type: spec.type,
imageA: imageA,
imageB: imageB,
width: width,
height: height,
nChannels: nChannels,
lossFunction: spec.lossFunction,
};
});
}
else {
throw Error("Unkonwn imageSpec type for " + spec + ".");
}
};
return ImageFrameWithLoading;
}(React.Component));
exports.default = ImageFrameWithLoading;
var _a, _b;
//# sourceMappingURL=ImageFrameWithLoading.js.map