(props: ImageSwipeProps)
| 16 | // Two images on top of one another with a slider to move the divider from left |
| 17 | // to right. |
| 18 | export function ImageSwipe(props: ImageSwipeProps) { |
| 19 | const mode = props.mode ?? 'swipe'; |
| 20 | const [rangePosition, setRangePosition] = React.useState<number | null>(null); |
| 21 | const sliderRef = React.createRef<HTMLInputElement>(); |
| 22 | const onSlide = () => { |
| 23 | if (sliderRef.current) { |
| 24 | setRangePosition(Number(sliderRef.current.value)); |
| 25 | } |
| 26 | }; |
| 27 | |
| 28 | const pair = props.filePair; |
| 29 | const imA = _.clone(pair.image_a); |
| 30 | const imB = _.clone(pair.image_b); |
| 31 | let containerWidth = Math.max(imA.width, imB.width); |
| 32 | const rangeMax = containerWidth; |
| 33 | const pct = 100.0 * ((rangePosition ?? rangeMax / 2) / rangeMax); |
| 34 | const frac = pct / 100.0; |
| 35 | let scaleDown = 1; |
| 36 | if (props.shrinkToFit) { |
| 37 | scaleDown = Math.min(1.0, (window.innerWidth - 30) / containerWidth); |
| 38 | imA.width *= scaleDown; |
| 39 | imA.height *= scaleDown; |
| 40 | imB.width *= scaleDown; |
| 41 | imB.height *= scaleDown; |
| 42 | containerWidth = Math.max(imA.width, imB.width); |
| 43 | } |
| 44 | const diffBoxDiv = makePerceptualBoxDiv(props.pdiffMode, pair, scaleDown); |
| 45 | const urlA = `/a/image/${pair.a}`; |
| 46 | const urlB = `/b/image/${pair.b}`; |
| 47 | const styleA: React.CSSProperties & {backgroundSize: string; backgroundImage: string} = { |
| 48 | backgroundImage: `url(${urlA})`, |
| 49 | backgroundSize: `${imA.width}px ${imA.height}px`, |
| 50 | width: `${imA.width}px`, |
| 51 | height: `${imA.height}px`, |
| 52 | }; |
| 53 | const styleB: React.CSSProperties & {backgroundSize: string; backgroundImage: string} = { |
| 54 | backgroundImage: `url(${urlB})`, |
| 55 | backgroundSize: `${imB.width}px ${imB.height}px`, |
| 56 | width: `${imB.width}px`, |
| 57 | height: `${imB.height}px`, |
| 58 | }; |
| 59 | const styleContainer: React.CSSProperties = { |
| 60 | width: containerWidth, |
| 61 | height: Math.max(imA.height, imB.height), |
| 62 | }; |
| 63 | if (mode === 'swipe') { |
| 64 | _.extend(styleA, { |
| 65 | width: Math.floor(frac * imA.width), |
| 66 | }); |
| 67 | const bgTop = -Math.floor(frac * imB.width); |
| 68 | _.extend(styleB, { |
| 69 | left: Math.floor(frac * imB.width), |
| 70 | width: null, |
| 71 | right: containerWidth - imB.width, |
| 72 | backgroundPosition: `${bgTop} px top`, |
| 73 | }); |
| 74 | } else { |
| 75 | _.extend(styleB, {opacity: frac}); |
nothing calls this directly
no test coverage detected