added zoom functionality inside prevw documents
This commit is contained in:
parent
b4f1c48293
commit
d7caf47498
@ -1,54 +1,128 @@
|
|||||||
import { useState } from "react";
|
import { useState, useRef } from "react";
|
||||||
|
|
||||||
const PreviewDocument = ({ imageUrl }) => {
|
const PreviewDocument = ({ imageUrl }) => {
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [rotation, setRotation] = useState(0);
|
const [rotation, setRotation] = useState(0);
|
||||||
|
const [zoom, setZoom] = useState(1);
|
||||||
|
const [position, setPosition] = useState({ x: 0, y: 0 });
|
||||||
|
const [isDragging, setIsDragging] = useState(false);
|
||||||
|
const [startPos, setStartPos] = useState({ x: 0, y: 0 });
|
||||||
|
const containerRef = useRef(null);
|
||||||
|
|
||||||
|
// Zoom handlers
|
||||||
|
const handleZoomIn = () => setZoom((prev) => Math.min(prev + 0.2, 3));
|
||||||
|
const handleZoomOut = () => setZoom((prev) => Math.max(prev - 0.2, 0.5));
|
||||||
|
|
||||||
|
// Mouse wheel zoom
|
||||||
|
const handleWheel = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const delta = e.deltaY > 0 ? -0.1 : 0.1;
|
||||||
|
setZoom((prev) => Math.min(Math.max(prev + delta, 0.5), 3));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseDown = (e) => {
|
||||||
|
if (zoom <= 1) return;
|
||||||
|
setIsDragging(true);
|
||||||
|
setStartPos({
|
||||||
|
x: e.clientX - position.x,
|
||||||
|
y: e.clientY - position.y,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseMove = (e) => {
|
||||||
|
if (!isDragging) return;
|
||||||
|
setPosition({
|
||||||
|
x: e.clientX - startPos.x,
|
||||||
|
y: e.clientY - startPos.y,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseUp = () => setIsDragging(false);
|
||||||
|
const handleMouseLeave = () => setIsDragging(false);
|
||||||
|
|
||||||
|
const handleReset = () => {
|
||||||
|
setRotation(0);
|
||||||
|
setZoom(1);
|
||||||
|
setPosition({ x: 0, y: 0 });
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="d-flex justify-content-start">
|
<div className="d-flex justify-content-start align-items-center gap-3 mb-2 px-3 py-2 px-md-0 py-md-0">
|
||||||
<i
|
<i
|
||||||
className="bx bx-rotate-right cursor-pointer"
|
className="bx bx-rotate-right fs-4 cursor-pointer"
|
||||||
|
title="Rotate Right"
|
||||||
onClick={() => setRotation((prev) => prev + 90)}
|
onClick={() => setRotation((prev) => prev + 90)}
|
||||||
></i>
|
></i>
|
||||||
|
<i
|
||||||
|
className="bx bx-zoom-in fs-4 cursor-pointer"
|
||||||
|
title="Zoom In"
|
||||||
|
onClick={handleZoomIn}
|
||||||
|
></i>
|
||||||
|
<i
|
||||||
|
className="bx bx-zoom-out fs-4 cursor-pointer"
|
||||||
|
title="Zoom Out"
|
||||||
|
onClick={handleZoomOut}
|
||||||
|
></i>
|
||||||
|
<i
|
||||||
|
className="bx bx-reset fs-4 cursor-pointer"
|
||||||
|
title="Reset"
|
||||||
|
onClick={handleReset}
|
||||||
|
></i>
|
||||||
</div>
|
</div>
|
||||||
<div
|
|
||||||
className="d-flex flex-column justify-content-center align-items-center"
|
|
||||||
style={{ minHeight: "60%" }}
|
|
||||||
>
|
|
||||||
|
|
||||||
{loading && (
|
<div
|
||||||
<div className="text-secondary text-center mb-2">Loading...</div>
|
ref={containerRef}
|
||||||
)}
|
onWheel={handleWheel}
|
||||||
|
onMouseDown={handleMouseDown}
|
||||||
<div className="mb-3 d-flex justify-content-center align-items-center">
|
onMouseMove={handleMouseMove}
|
||||||
|
onMouseUp={handleMouseUp}
|
||||||
|
onMouseLeave={handleMouseLeave}
|
||||||
|
className="d-flex justify-content-center align-items-center overflow-hidden border rounded"
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
height: "80vh",
|
||||||
|
background: "#f8f9fa",
|
||||||
|
cursor: zoom > 1 ? (isDragging ? "grabbing" : "grab") : "default",
|
||||||
|
userSelect: "none",
|
||||||
|
position: "relative",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{loading && (
|
||||||
|
<div className="text-secondary text-center position-absolute">
|
||||||
|
Loading...
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<img
|
<img
|
||||||
src={imageUrl}
|
src={imageUrl}
|
||||||
alt="Full View"
|
alt="Preview"
|
||||||
className="img-fluid"
|
|
||||||
style={{
|
|
||||||
maxHeight: "80vh",
|
|
||||||
objectFit: "contain",
|
|
||||||
display: loading ? "none" : "block",
|
|
||||||
transform: `rotate(${rotation}deg)`,
|
|
||||||
transition: "transform 0.3s ease",
|
|
||||||
}}
|
|
||||||
onLoad={() => setLoading(false)}
|
onLoad={() => setLoading(false)}
|
||||||
|
style={{
|
||||||
|
transform: `translate(${position.x}px, ${position.y}px) rotate(${rotation}deg) scale(${zoom})`,
|
||||||
|
transition: isDragging ? "none" : "transform 0.3s ease",
|
||||||
|
objectFit: "contain",
|
||||||
|
maxWidth: "100%",
|
||||||
|
maxHeight: "100%",
|
||||||
|
display: loading ? "none" : "block",
|
||||||
|
pointerEvents: "none",
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="d-flex justify-content-center gap-2">
|
{/* <div className="d-flex justify-content-center gap-2 mt-2">
|
||||||
<button
|
<button
|
||||||
className="btn btn-sm btn-outline-secondary"
|
className="btn btn-sm btn-outline-secondary"
|
||||||
onClick={() => setRotation(0)}
|
onClick={handleReset}
|
||||||
title="Reset Rotation"
|
title="Reset View"
|
||||||
>
|
>
|
||||||
<i className="bx bx-reset"></i> Reset
|
<i className="bx bx-reset"></i> Reset View
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div> */}
|
||||||
</div>
|
</>
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default PreviewDocument;
|
export default PreviewDocument;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user