标签:命令 active 渲染 block 类型 top mini let ber
ViewportDownloadForm.js
源码还是得一行一行阅读,好多自定义的函数,得找到相应的用法
import React, {
useRef,
useCallback,
useEffect,
useState,
createRef,
} from ‘react‘;
import PropTypes from ‘prop-types‘;
import { useTranslation } from ‘react-i18next‘;
import ‘./ViewportDownloadForm.styl‘;
import { TextInput, Select, Icon } from ‘@ohif/ui‘;
import classnames from ‘classnames‘;
const FILE_TYPE_OPTIONS = [
{
key: ‘jpg‘,
value: ‘jpg‘,
},
{
key: ‘png‘,
value: ‘png‘,
},
];
const DEFAULT_FILENAME = ‘image‘;
const REFRESH_VIEWPORT_TIMEOUT = 1000;
const ViewportDownloadForm = ({
activeViewport,
onClose,
updateViewportPreview,
enableViewport,
disableViewport,
toggleAnnotations,
loadImage,
downloadBlob,
defaultSize,
minimumSize,
maximumSize,
canvasClass,
}) => {
const [t] = useTranslation(‘ViewportDownloadForm‘);
const [filename, setFilename] = useState(DEFAULT_FILENAME); //文件名字,初始值image
const [fileType, setFileType] = useState(‘jpg‘); // 文件类型
const [dimensions, setDimensions] = useState({ // 尺寸
width: defaultSize,
height: defaultSize,
});
const [showAnnotations, setShowAnnotations] = useState(true); //是否显示注释
const [keepAspect, setKeepAspect] = useState(true); // 是否保持比例
const [aspectMultiplier, setAspectMultiplier] = useState({ // 比例尺寸
width: 1,
height: 1,
});
const [viewportElement, setViewportElement] = useState(); // 视图元素
const [viewportElementDimensions, setViewportElementDimensions] = useState({ //视口元素尺寸
width: defaultSize,
height: defaultSize,
});
const [downloadCanvas, setDownloadCanvas] = useState({ //下载画布
ref: createRef(), //DOM关于回调 refs
// ref: null, //DOM关于回调 refs
width: defaultSize,
height: defaultSize,
});
console.log(downloadCanvas.ref);
const [viewportPreview, setViewportPreview] = useState({ //视图预览
src: null,
width: defaultSize,
height: defaultSize,
});
const [error, setError] = useState({ // 错误信息
width: false,
height: false,
filename: false, //文件名
});
const hasError = Object.values(error).includes(true); //有错误,判断error里面是否包含true
/**
* useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内保持不变。
* @type {React.MutableRefObject}
*/
const refreshViewport = useRef(null); //刷新视图
const downloadImage = () => { //下载图片
downloadBlob(
filename || DEFAULT_FILENAME,
fileType,
viewportElement,
downloadCanvas.ref.current
);
};
/**
* @param {object} event - Input change event
* @param {object}事件-输入更改事件
* @param {string} dimension - "height" | "width"
* @param {string}尺寸-“高度” | “宽度”
*/
// 关于尺寸变化
const onDimensionsChange = (event, dimension) => {
const oppositeDimension = dimension === ‘height‘ ? ‘width‘ : ‘height‘;
const sanitizedTargetValue = event.target.value.replace(/\D/, ‘‘);
const isEmpty = sanitizedTargetValue === ‘‘; //是否为空
const newDimensions = { ...dimensions };
const updatedDimension = isEmpty
? ‘‘
: Math.min(sanitizedTargetValue, maximumSize);
if (updatedDimension === dimensions[dimension]) {
return;
}
newDimensions[dimension] = updatedDimension;
if (keepAspect && newDimensions[oppositeDimension] !== ‘‘) {
newDimensions[oppositeDimension] = Math.round(
newDimensions[dimension] * aspectMultiplier[oppositeDimension]
);
}
// In current code, keepAspect is always `true` 在当前代码中,keepAspect始终为true。
// And we always start w/ a square width/height 我们总是以/一个正方形的宽度/高度开始
setDimensions(newDimensions); //设定尺寸
// Only update if value is non-empty //仅在值非空时更新
if (!isEmpty) {
setViewportElementDimensions(newDimensions); //设置视口元素尺寸
setDownloadCanvas(state => ({ //设置下载画布
...state,
...newDimensions, //新尺寸
}));
}
};
const error_messages = { // 错误信息
width: t(‘minWidthError‘),
height: t(‘minHeightError‘),
filename: t(‘emptyFilenameError‘),
};
const renderErrorHandler = errorType => { // 渲染错误处理程序
if (!error[errorType]) {
return null;
}
return "input-error">{error_messages[errorType]}
;
};
const onKeepAspectToggle = () => { //保持纵横切换
const { width, height } = dimensions;
const aspectMultiplier = { ...aspectMultiplier };
if (!keepAspect) {
const base = Math.min(width, height);
aspectMultiplier.width = width / base;
aspectMultiplier.height = height / base;
setAspectMultiplier(aspectMultiplier);
}
setKeepAspect(!keepAspect);
};
const validSize = value => (value >= minimumSize ? value : minimumSize); // 有效尺寸
const loadAndUpdateViewports = useCallback(async () => { // 加载并更新视口
const { width: scaledWidth, height: scaledHeight } = await loadImage( //载入图片
activeViewport, // 活动视口
viewportElement, // 视口元素
dimensions.width,
dimensions.height
);
toggleAnnotations(showAnnotations, viewportElement); // 是否显示注释,切换注释
const scaledDimensions = { //比例尺
height: validSize(scaledHeight), //校验是否为有效尺寸
width: validSize(scaledWidth),//校验是否为有效尺寸
};
setViewportElementDimensions(scaledDimensions); // 设置视口元素尺寸
setDownloadCanvas(state => ({ //设置下载画布
...state,
...scaledDimensions,
}));
const {
dataUrl, //数据地址
width: viewportElementWidth, //视口元素宽度
height: viewportElementHeight,
} = await updateViewportPreview( //更新视口预览
viewportElement, //视口元素
downloadCanvas.ref.current, //下载画布,访问 Refs
fileType //文件类型
);
setViewportPreview(state => ({ // 设置视口预览
...state,
src: dataUrl,
width: validSize(viewportElementWidth), //验证宽度是否有效
height: validSize(viewportElementHeight),
}));
}, [ //inputs 变化检测
activeViewport,//活动视图
viewportElement,//视口元素
showAnnotations,//显示注释
loadImage,//加载图片
toggleAnnotations,//切换注释
updateViewportPreview,//更新视口预览
fileType,//文件类型
downloadCanvas.ref,//下载画布资源,Ref
minimumSize,//最小尺寸
maximumSize,//最大尺寸
viewportElementDimensions,//视口元素尺寸
]);
/**
* 通过使用这个 Hook,你可以告诉 React 组件需要在渲染后执行某些操作。React 会保存你传递的函数(我们将它称之为 “effect”),并且在执行 DOM 更新之后调用它。在这个 effect 中,我们设置了 document 的 title 属性,不过我们也可以执行数据获取或调用其他命令式的 API。
*/
useEffect(() => {
enableViewport(viewportElement);//启用视口
return () => {
disableViewport(viewportElement);//禁用视口 useEffect 可以在组件渲染后实现各种不同的副作用。有些副作用可能需要清除,所以需要返回一个函数:
};
}, [disableViewport, enableViewport, viewportElement]);//这里是检测
useEffect(() => {
if (refreshViewport.current !== null) {
clearTimeout(refreshViewport.current);
}
refreshViewport.current = setTimeout(() => {
refreshViewport.current = null;
loadAndUpdateViewports();
}, REFRESH_VIEWPORT_TIMEOUT);//刷新视口超时时间
}, [ //检测
activeViewport,
viewportElement,
showAnnotations,
dimensions,
loadImage,
toggleAnnotations,
updateViewportPreview,
fileType,
downloadCanvas.ref,
minimumSize,
maximumSize,
]);
useEffect(() => { //Effect Hook 可以让你在函数组件中执行副作用操作
const { width, height } = dimensions; // 尺寸
const hasError = { //错误信息
width: width //小于最小尺寸
height: height minimumSize,
filename: !filename,
};
setError({ ...hasError });//设置错误信息 对象的扩展运算符(...)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中。
}, [dimensions, filename, minimumSize]);
return (
console.log(viewportPreview.src),
console.log(viewportElement),
// console.log(activeViewport),
// console.log(downloadCanvas.ref),
"ViewportDownloadForm" >
div
style={{
height: viewportElementDimensions.height,
width: viewportElementDimensions.width,
position: ‘absolute‘,
left: ‘9999px‘,
}}
ref={ref => setViewportElement(ref)}
>
canvas
className={canvasClass} //cornerstone-canvas
style={{
height: downloadCanvas.height,
width: downloadCanvas.width,
display: ‘block‘,
}}
width={downloadCanvas.width}
height={downloadCanvas.height}
ref={downloadCanvas.ref}
>
{viewportPreview.src ? (
"
preview" data-cy=
"image-preview">
"preview-header"> {t(‘imagePreview‘)}
img
className=
"viewport-preview"
src=
{viewportPreview.src}
alt={t(
‘imagePreview‘)}
data-cy=
"image-preview"
data-cy=
"viewport-preview-img"
/>
) : (
"loading-image">
"circle-notch" className="icon-spin" />
{t(‘loadingPreview‘)}
)}
"
actions">
"action-save">
button
disabled={hasError}
onClick={downloadImage}
className="btn btn-primary"
data-cy="download-btn"
>
{t(‘Buttons:Download‘)}
);
};
ViewportDownloadForm.propTypes = {
onClose: PropTypes.func.isRequired,
activeViewport: PropTypes.object,
updateViewportPreview: PropTypes.func.isRequired,
enableViewport: PropTypes.func.isRequired,
disableViewport: PropTypes.func.isRequired,
toggleAnnotations: PropTypes.func.isRequired,
loadImage: PropTypes.func.isRequired,
downloadBlob: PropTypes.func.isRequired,
/** A default width & height, between the minimum and maximum size */
defaultSize: PropTypes.number.isRequired,
minimumSize: PropTypes.number.isRequired,
maximumSize: PropTypes.number.isRequired,
canvasClass: PropTypes.string.isRequired,
};
export default ViewportDownloadForm;
[OHIF-Viewers]医疗数字阅片-医学影像-ViewportDownloadForm.js
标签:命令 active 渲染 block 类型 top mini let ber
原文地址:https://www.cnblogs.com/landv/p/13283100.html