react-moveable
Version:
A React Component that create Moveable, Draggable, Resizable, Scalable, Rotatable, Warpable, Pinchable, Groupable.
91 lines (78 loc) • 2.6 kB
text/typescript
import { find, getWindow } from "@daybrush/utils";
import { getClientRect } from "../utils";
import { MoveableClientRect } from "../types";
import { getMatrixStackInfo, MatrixStackInfo } from "../utils/getMatrixStackInfo";
let cacheStyleMap: Map<Element, {
style: CSSStyleDeclaration;
cached: Record<string, any>;
}> | null = null;
let clientRectStyleMap: Map<Element, MoveableClientRect> | null = null;
let matrixContainerInfos: Array<[
[SVGElement | HTMLElement, SVGElement | HTMLElement | null | undefined],
MatrixStackInfo
]> | null = null;
export type GetStyle = (propertyName: string) => any;
export function setStoreCache(useCache?: boolean) {
if (useCache) {
if (window.Map) {
cacheStyleMap = new Map();
clientRectStyleMap = new Map();
}
matrixContainerInfos = [];
} else {
cacheStyleMap = null;
matrixContainerInfos = null;
clientRectStyleMap = null;
}
}
export function getCachedClientRect(el: HTMLElement | SVGElement): MoveableClientRect {
const clientRect = clientRectStyleMap?.get(el);
if (clientRect) {
return clientRect;
}
const nextClientRect = getClientRect(el, true);
if (clientRectStyleMap) {
clientRectStyleMap.set(el, nextClientRect);
}
return nextClientRect;
}
export function getCachedMatrixContainerInfo(
target: SVGElement | HTMLElement,
container?: SVGElement | HTMLElement | null,
) {
if (matrixContainerInfos) {
const result = find(matrixContainerInfos, info => info[0][0] == target && info[0][1] == container);
if (result) {
return result[1];
}
}
const result = getMatrixStackInfo(target, container, true);
if (matrixContainerInfos) {
matrixContainerInfos.push([[target, container], result]);
}
return result;
}
export function getCachedStyle(element: Element): GetStyle {
let cache = cacheStyleMap?.get(element);
if (!cache) {
const nextStyle = getWindow(element).getComputedStyle(element);
if (!cacheStyleMap) {
return (property: string) => {
return (nextStyle as any)[property];
};
}
cache = {
style: nextStyle,
cached: {},
};
cacheStyleMap.set(element, cache);
}
const cached = cache.cached;
const style = cache.style;
return (property: string) => {
if (!(property in cached)) {
cached[property] = (style as any)[property];
}
return cached[property];
};
}