In one of many in style PDF viewers, Acrobat Reader, there’s a instrument referred to as the “Hand Tool.” It permits you to navigate by means of the doc by dragging and dropping whereas holding down the mouse button. You may activate the “Hand Tool” by clicking the corresponding button on the toolbar.
“Hand Tool” button in Acrobat Reader
On this article, we are going to implement comparable habits utilizing the Konva.js library.
Tutorial
First off, we have to implement the flexibility to view doc pages. To attain this, we are going to outline a listing of pages utilizing the next array:
const pages = [
{ pageId: 1, width: 2016, height: 2264, imageURL, offsetY: 0 },
{ pageId: 2, width: 2016, height: 2264, imageURL, offsetY: 2264 },
{ pageId: 3, width: 2016, height: 2264, imageURL, offsetY: 4528 }
];
Right here, for every web page, the web page picture URL imageURL
and the offset from the start of the doc offsetY
are specified. Then, we are going to implement a element liable for displaying the web page:
import { Picture } from "react-konva";
import useImage from "use-image";
export default perform Web page({ width, top, imageURL, offsetY }) {
const [image] = useImage(imageURL);
if (!picture) {
return null;
}
return (
);
}
To load a picture by URL, the useImage
hook is used. Then, the loaded picture is handed to the Picture
element from the Konva.js library for show.
When working with the “Hand Tool” instrument, the place of the doc adjustments, and accordingly, the place of the scroll adjustments. Due to this fact, the subsequent step is to implement the flexibility to scroll the doc. For this, we are going to use an answer specified within the official documentation of the library and adapt it to our React utility:
export default perform App() {
const [scroll, setScroll] = useState({ left: 0, prime: 0 });
const handleScroll = useCallback((occasion) => {
const { scrollLeft, scrollTop } = occasion.currentTarget;
setScroll({ left: scrollLeft, prime: scrollTop });
}, []);
const stageStyles = useMemo(() => {
return { rework: `translate(${scroll.left}px, ${scroll.prime}px)` };
}, [scroll]);
return (
{pages.map((web page, index) => (
))}
);
}
The primary thought is that when scrolling, the place of the Stage
adjustments, and on the identical time, the place of the father or mother ingredient that wraps the Stage
adjustments.
The final step is to implement the “Hand Tool” instrument, however first, let’s work out the way it works: this may assist us perceive find out how to implement it. When the instrument is lively, it permits the consumer to carry down the doc with the mouse button, as in Drag and Drop, and transfer across the doc by dragging it, i.e., altering its place, specified by the purpose with coordinates X and Y.
From right here, it follows that we have to deal with the drag-and-drop occasion and alter the place of the doc. The Konva.js library offers corresponding handlers for the drag-and-drop occasion, however we are going to use the dragBoundFunc
perform. This perform is used to override the place throughout the drag-and-drop occasion. Overriding the place is critical for extra validation to forestall the scene place from being moved past the doc boundaries.
Let’s transfer on to the implementation, after which we’ll talk about it:
export default perform App() {
const rootRef = useRef(null);
const [isHandToolOn, setHandToolStatus] = useState(false);
const [scroll, setScroll] = useState({ left: 0, prime: 0 });
const handleClick = useCallback(() => {
setHandToolStatus((prev) => !prev);
}, []);
const handleScroll = useCallback((occasion) => {
const { scrollLeft, scrollTop } = occasion.currentTarget;
setScroll({ left: scrollLeft, prime: scrollTop });
}, []);
const stageStyles = useMemo(() => {
return { rework: `translate(${scroll.left}px, ${scroll.prime}px)` };
}, [scroll]);
const scrollTo = useCallback(({ left, prime }) => {
rootRef.present.scrollLeft = left;
rootRef.present.scrollTop = prime;
setScroll({ left, prime });
}, []);
const handleDrag = useCallback(
(dragPosition) => {
const {
scrollHeight,
scrollWidth,
clientHeight: rootHeight,
clientWidth: rootWidth
} = rootRef.present;
const scrollableWidth = Math.max(0, scrollWidth - rootWidth);
const scrollableHeight = Math.max(0, scrollHeight - rootHeight);
const leftMin = Math.max(0, -dragPosition.x);
const topMin = Math.max(0, -dragPosition.y);
const left = Math.min(leftMin, scrollableWidth);
const prime = Math.min(topMin, scrollableHeight);
scrollTo({ left, prime });
return { x: -left, y: -top };
},
[scrollTo]
);
return (
{pages.map((web page, index) => (
))}
);
}
We’ve added a “Hand Tool: On/Off” button to the web page, which can be utilized to activate the “Hand Tool.” If the “Hand Tool” is lively, the scene can be moved utilizing habits just like the drag and drop occasion. Then we added the corresponding handleDrag
handler, during which we checked that the place of the Stage
doesn’t transcend the doc boundaries and replace the place of the doc and the scrollbar. The “Hand Tool” instrument is prepared, and now the doc could be moved not solely utilizing the scrollbar but additionally by dragging the doc pages with the mouse. Yow will discover the total supply code and instance on CodeSandbox.
Closing Thought
I hope that you just discovered this text helpful and fascinating. Within the subsequent article, we are going to proceed to implement varied performance utilizing the Konva.js library.