2026-05-08-03-03-52 修正DICOM切片范围为单范围条
This commit is contained in:
@@ -818,6 +818,8 @@ export default function ReverseWorkspace({ projectId }: { projectId: string }) {
|
||||
const safeSliceEnd = clamp(sliceEnd, 0, maxSlice);
|
||||
const displayStart = Math.min(safeSliceStart, safeSliceEnd);
|
||||
const displayEnd = Math.max(safeSliceStart, safeSliceEnd);
|
||||
const rangeStartPercent = maxSlice > 0 ? (displayStart / maxSlice) * 100 : 0;
|
||||
const rangeEndPercent = maxSlice > 0 ? (displayEnd / maxSlice) * 100 : 0;
|
||||
const selectedDisplay = displayOptions.find((item) => item.id === displayLevel) ?? displayOptions[0];
|
||||
const selectedDicomOpacity = dicomOpacityOptions.find((item) => item.id === dicomOpacityLevel) ?? dicomOpacityOptions[0];
|
||||
const preloadPoints = [0.2, 0.4, 0.6, 0.8, 1].map((ratio) => clamp(Math.max(0, Math.round((project?.dicomCount ?? 1) * ratio) - 1), 0, maxSlice));
|
||||
@@ -924,30 +926,43 @@ export default function ReverseWorkspace({ projectId }: { projectId: string }) {
|
||||
{displayStart + 1} - {displayEnd + 1} / {project?.dicomCount ?? 0}
|
||||
</span>
|
||||
</div>
|
||||
<label className="grid grid-cols-[76px_1fr_64px] items-center gap-3 text-[10px] font-bold text-slate-500">
|
||||
起点
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
max={maxSlice}
|
||||
value={safeSliceStart}
|
||||
onChange={(event) => setSliceStart(Number(event.target.value))}
|
||||
className="accent-blue-600"
|
||||
/>
|
||||
<span className="text-right font-mono">{safeSliceStart + 1}</span>
|
||||
</label>
|
||||
<label className="mt-2 grid grid-cols-[76px_1fr_64px] items-center gap-3 text-[10px] font-bold text-slate-500">
|
||||
终点
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
max={maxSlice}
|
||||
value={safeSliceEnd}
|
||||
onChange={(event) => setSliceEnd(Number(event.target.value))}
|
||||
className="accent-blue-600"
|
||||
/>
|
||||
<span className="text-right font-mono">{safeSliceEnd + 1}</span>
|
||||
</label>
|
||||
<div className="py-1">
|
||||
<div className="relative h-10">
|
||||
<div className="absolute inset-x-0 top-1/2 h-2 -translate-y-1/2 rounded-full bg-slate-200" />
|
||||
<div
|
||||
className="absolute top-1/2 h-2 -translate-y-1/2 rounded-full bg-blue-600"
|
||||
style={{
|
||||
left: `${rangeStartPercent}%`,
|
||||
right: `${100 - rangeEndPercent}%`,
|
||||
}}
|
||||
/>
|
||||
<input
|
||||
type="range"
|
||||
aria-label="DICOM 切片范围起点"
|
||||
min="0"
|
||||
max={maxSlice}
|
||||
value={safeSliceStart}
|
||||
onChange={(event) => setSliceStart(Number(event.target.value))}
|
||||
className="dicom-range-input"
|
||||
style={{ zIndex: safeSliceStart >= safeSliceEnd ? 5 : 4 }}
|
||||
/>
|
||||
<input
|
||||
type="range"
|
||||
aria-label="DICOM 切片范围终点"
|
||||
min="0"
|
||||
max={maxSlice}
|
||||
value={safeSliceEnd}
|
||||
onChange={(event) => setSliceEnd(Number(event.target.value))}
|
||||
className="dicom-range-input"
|
||||
style={{ zIndex: safeSliceStart >= safeSliceEnd ? 4 : 5 }}
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-1 grid grid-cols-3 text-[10px] font-bold text-slate-500">
|
||||
<span>起点 {safeSliceStart + 1}</span>
|
||||
<span className="text-center text-blue-600">范围</span>
|
||||
<span className="text-right">终点 {safeSliceEnd + 1}</span>
|
||||
</div>
|
||||
</div>
|
||||
<p className="mt-3 text-[10px] leading-5 text-slate-400">
|
||||
显示范围支持 M-N,两个端点可双向调整;范围变化只改变可视化切片,不改变模型原始位姿。
|
||||
</p>
|
||||
|
||||
@@ -1 +1,61 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
.dicom-range-input {
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
background: transparent;
|
||||
height: 100%;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.dicom-range-input:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.dicom-range-input::-webkit-slider-runnable-track {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
.dicom-range-input::-webkit-slider-thumb {
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
background: #2563eb;
|
||||
border: 3px solid #ffffff;
|
||||
border-radius: 9999px;
|
||||
box-shadow: 0 2px 8px rgba(37, 99, 235, 0.28);
|
||||
cursor: grab;
|
||||
height: 20px;
|
||||
margin-top: -6px;
|
||||
pointer-events: auto;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.dicom-range-input::-moz-range-track {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
.dicom-range-input::-moz-range-thumb {
|
||||
background: #2563eb;
|
||||
border: 3px solid #ffffff;
|
||||
border-radius: 9999px;
|
||||
box-shadow: 0 2px 8px rgba(37, 99, 235, 0.28);
|
||||
cursor: grab;
|
||||
height: 14px;
|
||||
pointer-events: auto;
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
.dicom-range-input:active::-webkit-slider-thumb {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.dicom-range-input:active::-moz-range-thumb {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user