grungnet/src/hooks/useImageCenter.ts

87 lines
2.4 KiB
TypeScript
Raw Permalink Normal View History

2021-07-16 11:39:45 +00:00
import Konva from "konva";
import { useEffect, useRef } from "react";
2021-07-16 06:58:14 +00:00
import { MapStage } from "../contexts/MapStageContext";
import Vector2 from "../helpers/Vector2";
type ImageData = {
id: string;
width: number;
height: number;
};
2021-07-16 04:55:33 +00:00
function useImageCenter(
2021-07-17 07:25:41 +00:00
data: ImageData | null,
2021-07-16 06:58:14 +00:00
stageRef: MapStage,
stageWidth: number,
stageHeight: number,
stageTranslateRef: React.MutableRefObject<Vector2>,
setStageScale: React.Dispatch<React.SetStateAction<number>>,
2021-07-16 11:39:45 +00:00
imageLayerRef: React.RefObject<Konva.Layer>,
2021-07-16 06:58:14 +00:00
containerRef: React.RefObject<HTMLDivElement>,
responsive = false
) {
const stageRatio = stageWidth / stageHeight;
const imageRatio = data ? data.width / data.height : 1;
2021-07-16 04:55:33 +00:00
let imageWidth: number;
let imageHeight: number;
if (stageRatio > imageRatio) {
imageWidth = data ? stageHeight / (data.height / data.width) : stageWidth;
imageHeight = stageHeight;
} else {
imageWidth = stageWidth;
imageHeight = data ? stageWidth * (data.height / data.width) : stageHeight;
}
2020-10-22 05:11:44 +00:00
// Reset image translate and stage scale
2021-07-16 06:58:14 +00:00
const previousDataIdRef = useRef<string>();
const previousStageRatioRef = useRef(stageRatio);
useEffect(() => {
if (!data) {
return;
}
const layer = imageLayerRef.current;
2021-07-16 06:58:14 +00:00
const container = containerRef.current;
const stage = stageRef.current;
if (!container || !stage) {
return;
}
const containerRect = container.getBoundingClientRect();
const previousDataId = previousDataIdRef.current;
const previousStageRatio = previousStageRatioRef.current;
// Update when the id has changed and if responsive update when the stage changes
const shouldUpdate = responsive
? previousDataId !== data.id || previousStageRatio !== stageRatio
: previousDataId !== data.id;
if (layer && shouldUpdate) {
let newTranslate;
if (stageRatio > imageRatio) {
newTranslate = {
x: -(imageWidth - containerRect.width) / 2,
y: 0,
};
} else {
newTranslate = {
x: 0,
y: -(imageHeight - containerRect.height) / 2,
};
}
layer.position(newTranslate);
2021-07-16 06:58:14 +00:00
stage.position({ x: 0, y: 0 });
stageTranslateRef.current = { x: 0, y: 0 };
setStageScale(1);
}
previousDataIdRef.current = data.id;
previousStageRatioRef.current = stageRatio;
});
return [imageWidth, imageHeight];
}
export default useImageCenter;