mirror of
https://github.com/documenso/documenso.git
synced 2026-07-10 13:06:00 +10:00
86 lines
2.0 KiB
TypeScript
86 lines
2.0 KiB
TypeScript
import Konva from 'konva';
|
|
import { useEffect, useMemo, useRef } from 'react';
|
|
|
|
import type { PageRenderData } from '../providers/envelope-render-provider';
|
|
|
|
type RenderFunction = (props: { stage: Konva.Stage; pageLayer: Konva.Layer }) => void;
|
|
|
|
export const usePageRenderer = (renderFunction: RenderFunction, pageData: PageRenderData) => {
|
|
const { pageWidth, pageHeight, scale, imageLoadingState, pageNumber } = pageData;
|
|
|
|
const konvaContainer = useRef<HTMLDivElement>(null);
|
|
|
|
const stage = useRef<Konva.Stage | null>(null);
|
|
const pageLayer = useRef<Konva.Layer | null>(null);
|
|
|
|
/**
|
|
* The raw viewport with no scaling. Basically the actual PDF size.
|
|
*/
|
|
const unscaledViewport = useMemo(
|
|
() => ({
|
|
scale: 1,
|
|
width: pageWidth,
|
|
height: pageHeight,
|
|
}),
|
|
[pageWidth, pageHeight],
|
|
);
|
|
|
|
/**
|
|
* The viewport scaled according to page width.
|
|
*/
|
|
const scaledViewport = useMemo(
|
|
() => ({
|
|
scale,
|
|
width: pageWidth * scale,
|
|
height: pageHeight * scale,
|
|
}),
|
|
[pageWidth, pageHeight, scale],
|
|
);
|
|
|
|
useEffect(() => {
|
|
const { current: container } = konvaContainer;
|
|
|
|
if (!container || imageLoadingState !== 'loaded') {
|
|
return;
|
|
}
|
|
|
|
stage.current = new Konva.Stage({
|
|
container,
|
|
id: `page-${pageNumber}`,
|
|
width: scaledViewport.width,
|
|
height: scaledViewport.height,
|
|
scale: {
|
|
x: scale,
|
|
y: scale,
|
|
},
|
|
});
|
|
|
|
// Create the main layer for interactive elements.
|
|
pageLayer.current = new Konva.Layer();
|
|
|
|
stage.current.add(pageLayer.current);
|
|
|
|
renderFunction({
|
|
stage: stage.current,
|
|
pageLayer: pageLayer.current,
|
|
});
|
|
|
|
void document.fonts.ready.then(() => {
|
|
pageLayer.current?.batchDraw();
|
|
});
|
|
|
|
return () => {
|
|
stage.current?.destroy();
|
|
stage.current = null;
|
|
};
|
|
}, [imageLoadingState, scaledViewport]);
|
|
|
|
return {
|
|
konvaContainer,
|
|
stage,
|
|
pageLayer,
|
|
unscaledViewport,
|
|
scaledViewport,
|
|
};
|
|
};
|