react-pan-zoom-hoc
Version:
This is a HOC to make your beautiful React components pannable and zoomable by mouse.
86 lines • 3.3 kB
JavaScript
;
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
t[p[i]] = s[p[i]];
return t;
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = __importStar(require("react"));
const style = {
container: {
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0
}
};
const withPanAndZoom = (WrappedComponent) => (_a) => {
var { ResetButton, state, onChange } = _a, props = __rest(_a, ["ResetButton", "state", "onChange"]);
const [panning, setPanning] = react_1.useState(false);
const [pan_zoom, setPosScale] = state
? state
: react_1.useState({ y: 0, x: 0, scale: 1 });
react_1.useEffect(() => {
onChange && onChange(pan_zoom);
}, [pan_zoom]);
const onMouseLeave = () => {
setPanning(false);
};
const onPanStart = (e) => {
setPanning(true);
};
const onPanStop = (e) => {
setPanning(false);
};
const onPan = (e) => {
panning &&
setPosScale(Object.assign({}, pan_zoom, { y: pan_zoom.y + e.movementY, x: pan_zoom.x + e.movementX }));
};
const onZoom = (e) => {
const scale_by = 1.05;
const mousePointTo = {
x: e.pageX / pan_zoom.scale - pan_zoom.x / pan_zoom.scale,
y: e.pageY / pan_zoom.scale - pan_zoom.y / pan_zoom.scale
};
const new_scale = e.deltaY < 0 ? pan_zoom.scale * scale_by : pan_zoom.scale / scale_by;
setPosScale({
scale: new_scale,
x: -(mousePointTo.x - e.pageX / new_scale) * new_scale,
y: -(mousePointTo.y - e.pageY / new_scale) * new_scale
});
};
const onReset = (e) => {
setPosScale({
scale: 1,
x: 0,
y: 0
});
};
return (react_1.default.createElement("div", { style: style.container, onMouseLeave: onMouseLeave, onMouseDown: onPanStart, onMouseMove: onPan, onMouseUp: onPanStop, onWheel: onZoom },
react_1.default.createElement("div", { style: {
position: "absolute",
top: pan_zoom.y,
left: pan_zoom.x,
transform: "scale(" + pan_zoom.scale + ")",
minHeight: "100%",
minWidth: "100%"
} },
react_1.default.createElement(WrappedComponent, Object.assign({}, props))),
!state &&
ResetButton &&
react_1.cloneElement(ResetButton, Object.assign({}, ResetButton.props, { onClick: onReset }))));
};
exports.default = withPanAndZoom;
//# sourceMappingURL=HOC.js.map