New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

react-easy-panzoom

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-easy-panzoom - npm Package Compare versions

Comparing version 0.2.5 to 0.3.0

src/PanZoom.test.js

266

lib/PanZoom.js

@@ -10,8 +10,16 @@ "use strict";

var _warning = _interopRequireDefault(require("warning"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }

@@ -84,6 +92,2 @@

return function (element) {
if (!element) {
return null;
}
var clientTop = element.clientTop,

@@ -149,7 +153,10 @@ clientLeft = element.clientLeft,

_defineProperty(_assertThisInitialized(_this), "container", null);
_defineProperty(_assertThisInitialized(_this), "container", React.createRef());
_defineProperty(_assertThisInitialized(_this), "dragContainer", null);
_defineProperty(_assertThisInitialized(_this), "dragContainer", React.createRef());
_defineProperty(_assertThisInitialized(_this), "mousePos", null);
_defineProperty(_assertThisInitialized(_this), "mousePos", {
x: 0,
y: 0
});

@@ -173,5 +180,5 @@ _defineProperty(_assertThisInitialized(_this), "panning", false);

_defineProperty(_assertThisInitialized(_this), "transformMatrixString", null);
_defineProperty(_assertThisInitialized(_this), "transformMatrixString", "matrix(1, 0, 0, 1, 0, 0)");
_defineProperty(_assertThisInitialized(_this), "intermediateTransformMatrixString", null);
_defineProperty(_assertThisInitialized(_this), "intermediateTransformMatrixString", "matrix(1, 0, 0, 1, 0, 0)");

@@ -186,4 +193,15 @@ _defineProperty(_assertThisInitialized(_this), "state", {

_defineProperty(_assertThisInitialized(_this), "onDoubleClick", function (e) {
var doubleZoomSpeed = _this.props.doubleZoomSpeed;
var _this$props = _this.props,
onDoubleClick = _this$props.onDoubleClick,
disableDoubleClickZoom = _this$props.disableDoubleClickZoom,
doubleZoomSpeed = _this$props.doubleZoomSpeed;
if (typeof onDoubleClick === 'function') {
onDoubleClick(e);
}
if (disableDoubleClickZoom) {
return;
}
var offset = _this.getOffset(e);

@@ -195,4 +213,10 @@

_defineProperty(_assertThisInitialized(_this), "onMouseDown", function (e) {
var preventPan = _this.props.preventPan;
var _this$props2 = _this.props,
preventPan = _this$props2.preventPan,
onMouseDown = _this$props2.onMouseDown;
if (typeof onMouseDown === 'function') {
onMouseDown(e);
}
if (_this.props.disabled) {

@@ -218,3 +242,3 @@ return;

if (preventPan(e, offset.x, offset.y)) {
if (preventPan && preventPan(e, offset.x, offset.y)) {
return;

@@ -289,6 +313,11 @@ }

_defineProperty(_assertThisInitialized(_this), "onKeyDown", function (e) {
var _this$props = _this.props,
keyMapping = _this$props.keyMapping,
disableKeyInteraction = _this$props.disableKeyInteraction;
var _this$props3 = _this.props,
keyMapping = _this$props3.keyMapping,
disableKeyInteraction = _this$props3.disableKeyInteraction,
onKeyDown = _this$props3.onKeyDown;
if (typeof onKeyDown === 'function') {
onKeyDown(e);
}
if (disableKeyInteraction) {

@@ -357,4 +386,4 @@ return;

if (_x || _y) {
var containerRect = _this.container.getBoundingClientRect();
if ((_x || _y) && _this.container.current) {
var containerRect = _this.container.current.getBoundingClientRect();

@@ -376,4 +405,10 @@ var offset = Math.min(containerRect.width, containerRect.height);

_defineProperty(_assertThisInitialized(_this), "onTouchStart", function (e) {
var preventPan = _this.props.preventPan;
var _this$props4 = _this.props,
preventPan = _this$props4.preventPan,
onTouchStart = _this$props4.onTouchStart;
if (typeof onTouchStart === 'function') {
onTouchStart(e);
}
if (e.touches.length === 1) {

@@ -385,3 +420,3 @@ // Drag

if (preventPan(e, offset.x, offset.y)) {
if (preventPan && preventPan(e, offset.x, offset.y)) {
return;

@@ -412,5 +447,5 @@ }

_defineProperty(_assertThisInitialized(_this), "onToucheMove", function (e) {
var _this$props2 = _this.props,
realPinch = _this$props2.realPinch,
noStateUpdate = _this$props2.noStateUpdate;
var _this$props5 = _this.props,
realPinch = _this$props5.realPinch,
noStateUpdate = _this$props5.noStateUpdate;

@@ -598,13 +633,35 @@ if (e.touches.length === 1) {

_defineProperty(_assertThisInitialized(_this), "getContainer", function () {
var container = _this.container.current;
if (!container) {
throw new Error("Could not find container DOM element.");
}
return container;
});
_defineProperty(_assertThisInitialized(_this), "getDragContainer", function () {
var dragContainer = _this.dragContainer.current;
if (!dragContainer) {
throw new Error("Could not find dragContainer DOM element.");
}
return dragContainer;
});
_defineProperty(_assertThisInitialized(_this), "autoCenter", function () {
var zoomLevel = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
var _this$props3 = _this.props,
minZoom = _this$props3.minZoom,
maxZoom = _this$props3.maxZoom;
var containerRect = _this.container.getBoundingClientRect();
var container = _this.getContainer();
var _this$dragContainer = _this.dragContainer,
clientWidth = _this$dragContainer.clientWidth,
clientHeight = _this$dragContainer.clientHeight;
var dragContainer = _this.getDragContainer();
var _this$props6 = _this.props,
minZoom = _this$props6.minZoom,
maxZoom = _this$props6.maxZoom;
var containerRect = container.getBoundingClientRect();
var clientWidth = dragContainer.clientWidth,
clientHeight = dragContainer.clientHeight;
var widthRatio = containerRect.width / clientWidth;

@@ -636,4 +693,5 @@ var heightRatio = containerRect.height / clientHeight;

var containerRect = _this.container.getBoundingClientRect();
var container = _this.getContainer();
var containerRect = container.getBoundingClientRect();
var offset = Math.min(containerRect.width, containerRect.height);

@@ -646,3 +704,4 @@ var dx = offset * moveSpeedRatio * x;

_defineProperty(_assertThisInitialized(_this), "moveBy", function (dx, dy, noStateUpdate) {
_defineProperty(_assertThisInitialized(_this), "moveBy", function (dx, dy) {
var noStateUpdate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
var _this$state = _this.state,

@@ -707,6 +766,8 @@ x = _this$state.x,

var rotate = _this.state.rotate;
var newAngle = value;
var newAngle;
if (typeof value === 'function') {
newAngle = value(rotate);
} else {
newAngle = value;
}

@@ -724,5 +785,5 @@

_defineProperty(_assertThisInitialized(_this), "zoomTo", function (x, y, ratio) {
var _this$props4 = _this.props,
minZoom = _this$props4.minZoom,
maxZoom = _this$props4.maxZoom;
var _this$props7 = _this.props,
minZoom = _this$props7.minZoom,
maxZoom = _this$props7.maxZoom;
var _this$state2 = _this.state,

@@ -766,5 +827,7 @@ transformX = _this$state2.x,

_defineProperty(_assertThisInitialized(_this), "centeredZoom", function (delta) {
var container = _this.getContainer();
var scaleMultiplier = _this.getScaleMultiplier(delta);
var containerRect = _this.container.getBoundingClientRect();
var containerRect = container.getBoundingClientRect();

@@ -792,3 +855,3 @@ _this.zoomTo(containerRect.width / 2, containerRect.height / 2, scaleMultiplier);

_defineProperty(_assertThisInitialized(_this), "getOffset", function (e) {
var containerRect = _this.container.getBoundingClientRect();
var containerRect = _this.getContainer().getBoundingClientRect();

@@ -804,3 +867,3 @@ var offsetX = e.clientX - containerRect.left;

_defineProperty(_assertThisInitialized(_this), "getTransformMatrix", function (x, y, scale, rotate) {
if (!_this.dragContainer) {
if (!_this.dragContainer.current) {
return {

@@ -816,5 +879,6 @@ a: scale,

var _this$dragContainer2 = _this.dragContainer,
clientWidth = _this$dragContainer2.clientWidth,
clientHeight = _this$dragContainer2.clientHeight;
var _this$getDragContaine = _this.getDragContainer(),
clientWidth = _this$getDragContaine.clientWidth,
clientHeight = _this$getDragContaine.clientHeight;
var centerX = clientWidth / 2;

@@ -830,3 +894,3 @@ var centerY = clientHeight / 2;

_defineProperty(_assertThisInitialized(_this), "applyTransform", function () {
_this.dragContainer.style.transform = _this.transformMatrixString;
_this.getDragContainer().style.transform = _this.transformMatrixString;
_this.frameAnimation = 0;

@@ -836,3 +900,3 @@ });

_defineProperty(_assertThisInitialized(_this), "applyIntermediateTransform", function () {
_this.dragContainer.style.transform = _this.intermediateTransformMatrixString;
_this.getDragContainer().style.transform = _this.intermediateTransformMatrixString;
_this.intermediateFrameAnimation = 0;

@@ -845,6 +909,6 @@ });

var offsetY = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;
var _this$props5 = _this.props,
enableBoundingBox = _this$props5.enableBoundingBox,
boundaryRatioVertical = _this$props5.boundaryRatioVertical,
boundaryRatioHorizontal = _this$props5.boundaryRatioHorizontal;
var _this$props8 = _this.props,
enableBoundingBox = _this$props8.enableBoundingBox,
boundaryRatioVertical = _this$props8.boundaryRatioVertical,
boundaryRatioHorizontal = _this$props8.boundaryRatioHorizontal;

@@ -860,7 +924,7 @@ if (!enableBoundingBox) {

var _this$container$getBo = _this.container.getBoundingClientRect(),
containerHeight = _this$container$getBo.height,
containerWidth = _this$container$getBo.width;
var _this$getContainer$ge = _this.getContainer().getBoundingClientRect(),
containerHeight = _this$getContainer$ge.height,
containerWidth = _this$getContainer$ge.width;
var _getTransformedElemen = getTransformedElementCoordinates(rotate, newScale, offsetX, offsetY)(_this.dragContainer),
var _getTransformedElemen = getTransformedElementCoordinates(rotate, newScale, offsetX, offsetY)(_this.getDragContainer()),
top = _getTransformedElemen.top,

@@ -903,11 +967,14 @@ left = _getTransformedElemen.left,

value: function componentDidMount() {
var _this$props6 = this.props,
autoCenter = _this$props6.autoCenter,
autoCenterZoomLevel = _this$props6.autoCenterZoomLevel,
minZoom = _this$props6.minZoom,
maxZoom = _this$props6.maxZoom;
this.container.addEventListener('mousewheel', this.onWheel, {
passive: false
});
var _this$props9 = this.props,
autoCenter = _this$props9.autoCenter,
autoCenterZoomLevel = _this$props9.autoCenterZoomLevel,
minZoom = _this$props9.minZoom,
maxZoom = _this$props9.maxZoom;
if (this.container.current) {
this.container.current.addEventListener('wheel', this.onWheel, {
passive: false
});
}
if (maxZoom < minZoom) {

@@ -923,6 +990,15 @@ throw new Error('[PanZoom]: maxZoom props cannot be inferior to minZoom');

key: "componentDidUpdate",
value: function componentDidUpdate(prevProps) {
value: function componentDidUpdate(prevProps, prevState) {
if (prevProps.autoCenter !== this.props.autoCenter && this.props.autoCenter) {
this.autoCenter(this.props.autoCenterZoomLevel);
}
if ((prevState.x !== this.state.x || prevState.y !== this.state.y || prevState.scale !== this.state.scale || prevState.rotate !== this.state.rotate) && this.props.onStateChange) {
this.props.onStateChange({
x: this.state.x,
y: this.state.y,
scale: this.state.scale,
rotate: this.state.rotate
});
}
}

@@ -935,5 +1011,8 @@ }, {

this.releaseTextSelection();
this.container.removeEventListener('mousewheel', this.onWheel, {
passive: false
});
if (this.container.current) {
this.container.current.removeEventListener('wheel', this.onWheel, {
passive: false
});
}
}

@@ -943,9 +1022,31 @@ }, {

value: function render() {
var _this2 = this;
var _this$props10 = this.props,
children = _this$props10.children,
autoCenter = _this$props10.autoCenter,
autoCenterZoomLevel = _this$props10.autoCenterZoomLevel,
zoomSpeed = _this$props10.zoomSpeed,
doubleZoomSpeed = _this$props10.doubleZoomSpeed,
disabled = _this$props10.disabled,
disableDoubleClickZoom = _this$props10.disableDoubleClickZoom,
disableKeyInteraction = _this$props10.disableKeyInteraction,
realPinch = _this$props10.realPinch,
keyMapping = _this$props10.keyMapping,
minZoom = _this$props10.minZoom,
maxZoom = _this$props10.maxZoom,
enableBoundingBox = _this$props10.enableBoundingBox,
boundaryRatioVertical = _this$props10.boundaryRatioVertical,
boundaryRatioHorizontal = _this$props10.boundaryRatioHorizontal,
noStateUpdate = _this$props10.noStateUpdate,
onPanStart = _this$props10.onPanStart,
onPan = _this$props10.onPan,
onPanEnd = _this$props10.onPanEnd,
preventPan = _this$props10.preventPan,
style = _this$props10.style,
onDoubleClick = _this$props10.onDoubleClick,
onMouseDown = _this$props10.onMouseDown,
onKeyDown = _this$props10.onKeyDown,
onTouchStart = _this$props10.onTouchStart,
onStateChange = _this$props10.onStateChange,
restPassThroughProps = _objectWithoutProperties(_this$props10, ["children", "autoCenter", "autoCenterZoomLevel", "zoomSpeed", "doubleZoomSpeed", "disabled", "disableDoubleClickZoom", "disableKeyInteraction", "realPinch", "keyMapping", "minZoom", "maxZoom", "enableBoundingBox", "boundaryRatioVertical", "boundaryRatioHorizontal", "noStateUpdate", "onPanStart", "onPan", "onPanEnd", "preventPan", "style", "onDoubleClick", "onMouseDown", "onKeyDown", "onTouchStart", "onStateChange"]);
var _this$props7 = this.props,
children = _this$props7.children,
style = _this$props7.style,
disabled = _this$props7.disabled,
disableKeyInteraction = _this$props7.disableKeyInteraction;
var _this$state3 = this.state,

@@ -966,6 +1067,12 @@ x = _this$state3.x,

var transform = this.getTransformMatrixString(a, b, c, d, transformX, transformY);
if (process.env.NODE_ENV !== 'production') {
(0, _warning.default)(onDoubleClick === undefined || typeof onDoubleClick === 'function', "Expected `onDoubleClick` listener to be a function, instead got a value of `%s` type.", _typeof(onDoubleClick));
(0, _warning.default)(onMouseDown === undefined || typeof onMouseDown === 'function', "Expected `onMouseDown` listener to be a function, instead got a value of `%s` type.", _typeof(onMouseDown));
(0, _warning.default)(onKeyDown === undefined || typeof onKeyDown === 'function', "Expected `onKeyDown` listener to be a function, instead got a value of `%s` type.", _typeof(onKeyDown));
(0, _warning.default)(onTouchStart === undefined || typeof onTouchStart === 'function', "Expected `onTouchStart` listener to be a function, instead got a value of `%s` type.", _typeof(onTouchStart));
}
return React.createElement("div", _extends({
ref: function ref(_ref2) {
return _this2.container = _ref2;
}
ref: this.container
}, disableKeyInteraction ? {} : {

@@ -989,6 +1096,4 @@ tabIndex: 0 // enable onKeyDown event

}, style)
}), React.createElement("div", {
ref: function ref(_ref) {
return _this2.dragContainer = _ref;
},
}, restPassThroughProps), React.createElement("div", {
ref: this.dragContainer,
style: {

@@ -1008,5 +1113,6 @@ display: 'inline-block',

PanZoom.defaultProps = {
_defineProperty(PanZoom, "defaultProps", {
zoomSpeed: 1,
doubleZoomSpeed: 1.75,
disabled: false,
minZoom: 0,

@@ -1017,7 +1123,9 @@ maxZoom: Infinity,

boundaryRatioHorizontal: 0.8,
disableDoubleClickZoom: false,
preventPan: function preventPan() {
return false;
}
};
});
var _default = PanZoom;
exports.default = _default;
{
"name": "react-easy-panzoom",
"version": "0.2.5",
"version": "0.3.0",
"description": "Wrapper to enable pan and zoom for any React component",

@@ -18,2 +18,4 @@ "main": "./lib/index.js",

"build": "webpack",
"test": "jest",
"flow": "flow",
"build:cjs": "cross-env NODE_ENV=production babel --config-file ./babel.config.js ./src --out-dir ./lib --ignore \"**/*.test.js\""

@@ -38,3 +40,5 @@ },

},
"dependencies": {},
"dependencies": {
"warning": "4.0.3"
},
"devDependencies": {

@@ -48,11 +52,12 @@ "@babel/cli": "^7.2.3",

"@babel/preset-react": "^7.0.0",
"@storybook/addon-actions": "^5.0.1",
"@storybook/addon-knobs": "^5.0.1",
"@storybook/addon-links": "^5.0.1",
"@storybook/addons": "^5.0.1",
"@storybook/react": "^5.0.1",
"@storybook/theming": "^5.0.1",
"@storybook/addon-actions": "^5.1.3",
"@storybook/addon-knobs": "^5.1.3",
"@storybook/addon-links": "^5.1.3",
"@storybook/addons": "^5.1.3",
"@storybook/react": "^5.1.3",
"@storybook/theming": "^5.1.3",
"babel-loader": "^8.0.5",
"cross-env": "^5.2.0",
"flow-bin": "^0.95.1",
"jest": "^24.8.0",
"react": "^16.8.4",

@@ -59,0 +64,0 @@ "react-dom": "^16.8.4",

@@ -6,2 +6,3 @@ # react-easy-panzoom

[![Code](https://img.shields.io/npm/dt/react-easy-panzoom.svg?style=plastic)](https://www.npmjs.com/package/react-easy-panzoom)
[![Code](https://travis-ci.com/mnogueron/react-easy-panzoom.svg?branch=master)](https://travis-ci.com/mnogueron/react-easy-panzoom)

@@ -141,2 +142,3 @@ ![react-easy-panzoom-demo](https://user-images.githubusercontent.com/8511318/55997819-2ff98700-5cbc-11e9-99f5-67ea295f4f92.gif)

|disableKeyInteraction|`bool`|false|Disable keyboard interaction|
|disableDoubleClickZoom|`bool`|false|Disable zoom when performing a double click|
|realPinch|`bool`|false|Enable real pinch interaction for touch events|

@@ -155,3 +157,6 @@ |keyMapping|`object`|false|Define specific key mapping for keyboard interaction (e.g. `{ '<keyCode>': { x: 0, y: 1, z: 0 } }`, with `<keyCode>` being the key code to map)|

|style|`object`| |Override the inline-styles of the root element|
|onStateChange|`func`| |Called after the state of the component has changed|
You can also pass in every other props you would pass to a `div` element. Those will be passed through to the container component. This is helpful for adding custom event handlers.
## Methods

@@ -158,0 +163,0 @@ By using `ref`, methods from `PanZoom` can be accessed and called to trigger manipulation functions.

// @flow
import * as React from 'react'
import warning from 'warning'
type OnStateChangeData = {
x: number,
y: number,
scale: number,
rotate: number
}
type Props = {
zoomSpeed?: number,
doubleZoomSpeed?: number,
zoomSpeed: number,
doubleZoomSpeed: number,
disabled?: boolean,

@@ -11,8 +19,11 @@ autoCenter?: boolean,

disableKeyInteraction?: boolean,
disableDoubleClickZoom?: boolean,
realPinch?: boolean,
keyMapping?: { [string]: { x: number, y: number, z: number }},
minZoom?: number,
maxZoom?: number,
preventPan?: (event: SyntheticEvent, x: number, y: number) => boolean,
noStateUpdate?: boolean,
minZoom: number,
maxZoom: number,
preventPan: (event: SyntheticTouchEvent<HTMLDivElement> | MouseEvent, x: number, y: number) => boolean,
noStateUpdate: boolean,
boundaryRatioVertical: number,
boundaryRatioHorizontal: number,

@@ -22,2 +33,10 @@ onPanStart?: (any) => void,

onPanEnd?: (any) => void,
onStateChange?: (data: OnStateChangeData) => void,
} & React.ElementProps<'div'>
type State = {
x: number,
y: number,
scale: number,
rotate: number
}

@@ -49,7 +68,10 @@

const getTransformedElementCoordinates = (angle, scale, offsetX, offsetY) => (element) => {
if (!element) {
return null
}
type TransformCoordinates = {
top: number,
left: number,
width: number,
height: number,
}
const getTransformedElementCoordinates = (angle, scale, offsetX, offsetY) => (element: HTMLElement): TransformCoordinates => {
const { clientTop, clientLeft, clientWidth, clientHeight } = element

@@ -78,8 +100,23 @@ const centerX = clientWidth / 2

class PanZoom extends React.Component<Props> {
class PanZoom extends React.Component<Props, State> {
static defaultProps = {
zoomSpeed: 1,
doubleZoomSpeed: 1.75,
disabled: false,
minZoom: 0,
maxZoom: Infinity,
noStateUpdate: true,
boundaryRatioVertical: 0.8,
boundaryRatioHorizontal: 0.8,
disableDoubleClickZoom: false,
preventPan: () => false,
}
container = null
dragContainer = null
container = React.createRef<HTMLDivElement>()
dragContainer = React.createRef<HTMLDivElement>()
mousePos = null
mousePos = {
x: 0,
y: 0
}
panning = false

@@ -99,6 +136,6 @@ touchInProgress = false

transformMatrixString = null
intermediateTransformMatrixString = null
transformMatrixString = `matrix(1, 0, 0, 1, 0, 0)`
intermediateTransformMatrixString = `matrix(1, 0, 0, 1, 0, 0)`
state = {
state: State = {
x: 0,

@@ -113,3 +150,5 @@ y: 0,

this.container.addEventListener('mousewheel', this.onWheel, { passive: false })
if (this.container.current) {
this.container.current.addEventListener('wheel', this.onWheel, { passive: false })
}

@@ -124,3 +163,3 @@ if (maxZoom < minZoom) {

componentDidUpdate(prevProps): void {
componentDidUpdate(prevProps: Props, prevState: State): void {
if (prevProps.autoCenter !== this.props.autoCenter

@@ -130,2 +169,16 @@ && this.props.autoCenter) {

}
if (
(prevState.x !== this.state.x
|| prevState.y !== this.state.y
|| prevState.scale !== this.state.scale
|| prevState.rotate !== this.state.rotate)
&& this.props.onStateChange
) {
this.props.onStateChange({
x: this.state.x,
y: this.state.y,
scale: this.state.scale,
rotate: this.state.rotate
})
}
}

@@ -137,8 +190,18 @@

this.releaseTextSelection()
this.container.removeEventListener('mousewheel', this.onWheel, { passive: false })
if (this.container.current) {
this.container.current.removeEventListener('wheel', this.onWheel, { passive: false })
}
}
onDoubleClick = (e) => {
const { doubleZoomSpeed } = this.props
onDoubleClick = (e: MouseEvent) => {
const { onDoubleClick, disableDoubleClickZoom, doubleZoomSpeed } = this.props
if (typeof onDoubleClick === 'function') {
onDoubleClick(e)
}
if (disableDoubleClickZoom) {
return
}
const offset = this.getOffset(e)

@@ -148,4 +211,9 @@ this.zoomTo(offset.x, offset.y, doubleZoomSpeed)

onMouseDown = (e) => {
const { preventPan } = this.props
onMouseDown = (e: MouseEvent) => {
const { preventPan, onMouseDown } = this.props
if (typeof onMouseDown === 'function') {
onMouseDown(e)
}
if (this.props.disabled) {

@@ -170,3 +238,3 @@ return

// check if there is nothing preventing the pan
if (preventPan(e, offset.x, offset.y)) {
if (preventPan && preventPan(e, offset.x, offset.y)) {
return

@@ -194,3 +262,3 @@ }

onMouseMove = (e) => {
onMouseMove = (e: MouseEvent) => {
if (this.panning) {

@@ -217,3 +285,3 @@ const { noStateUpdate } = this.props

onMouseUp = (e) => {
onMouseUp = (e: MouseEvent) => {
// if using noStateUpdate we still need to set the new values in the state

@@ -228,3 +296,3 @@ this.dispatchStateUpdateIfNeeded()

onWheel = (e) => {
onWheel = (e: WheelEvent) => {
if (this.props.disabled) {

@@ -240,5 +308,9 @@ return

onKeyDown = (e) => {
const { keyMapping, disableKeyInteraction } = this.props
onKeyDown = (e: SyntheticKeyboardEvent<HTMLDivElement>) => {
const { keyMapping, disableKeyInteraction, onKeyDown } = this.props
if (typeof onKeyDown === 'function') {
onKeyDown(e)
}
if (disableKeyInteraction) {

@@ -266,4 +338,4 @@ return

if (x || y) {
const containerRect = this.container.getBoundingClientRect()
if ((x || y) && this.container.current) {
const containerRect = this.container.current.getBoundingClientRect()
const offset = Math.min(containerRect.width, containerRect.height)

@@ -283,4 +355,8 @@ const moveSpeedRatio = 0.05

onTouchStart = (e) => {
const { preventPan } = this.props
onTouchStart = (e: SyntheticTouchEvent<HTMLDivElement>) => {
const { preventPan, onTouchStart } = this.props
if (typeof onTouchStart === 'function') {
onTouchStart(e)
}
if (e.touches.length === 1) {

@@ -291,3 +367,3 @@ // Drag

if (preventPan(e, offset.x, offset.y)) {
if (preventPan && preventPan(e, offset.x, offset.y)) {
return

@@ -317,3 +393,3 @@ }

onToucheMove = (e) => {
onToucheMove = (e: TouchEvent) => {
const { realPinch, noStateUpdate } = this.props

@@ -368,3 +444,3 @@ if (e.touches.length === 1) {

onTouchEnd = (e) => {
onTouchEnd = (e: TouchEvent) => {
if (e.touches.length > 0) {

@@ -449,3 +525,3 @@ const offset = this.getOffset(e.touches[0])

triggerOnPanStart = (e) => {
triggerOnPanStart = (e: MouseEvent | TouchEvent) => {
const { onPanStart } = this.props

@@ -458,3 +534,3 @@ if (!this.panStartTriggered) {

triggerOnPan = (e) => {
triggerOnPan = (e: MouseEvent | TouchEvent) => {
const { onPan } = this.props

@@ -464,3 +540,3 @@ onPan && onPan(e)

triggerOnPanEnd = (e) => {
triggerOnPanEnd = (e: MouseEvent | TouchEvent) => {
const { onPanEnd } = this.props

@@ -471,3 +547,3 @@ this.panStartTriggered = false

getScaleMultiplier = (delta) => {
getScaleMultiplier = (delta: number) => {
let speed = 0.065 * this.props.zoomSpeed

@@ -484,3 +560,3 @@ let scaleMultiplier = 1

getPinchZoomLength = (finger1, finger2) => {
getPinchZoomLength = (finger1: Touch, finger2: Touch) => {
return Math.sqrt(

@@ -492,6 +568,24 @@ (finger1.clientX - finger2.clientX) * (finger1.clientX - finger2.clientX) +

autoCenter = (zoomLevel = 1) => {
getContainer = (): HTMLDivElement => {
const { current: container } = this.container
if (!container) {
throw new Error("Could not find container DOM element.")
}
return container
}
getDragContainer = (): HTMLDivElement => {
const { current: dragContainer } = this.dragContainer
if (!dragContainer) {
throw new Error("Could not find dragContainer DOM element.")
}
return dragContainer
}
autoCenter = (zoomLevel: number = 1) => {
const container = this.getContainer()
const dragContainer = this.getDragContainer()
const { minZoom, maxZoom } = this.props
const containerRect = this.container.getBoundingClientRect()
const { clientWidth, clientHeight } = this.dragContainer
const containerRect = container.getBoundingClientRect()
const { clientWidth, clientHeight } = dragContainer
const widthRatio = containerRect.width / clientWidth

@@ -515,4 +609,5 @@ const heightRatio = containerRect.height / clientHeight

moveByRatio = (x, y, moveSpeedRatio = 0.05) => {
const containerRect = this.container.getBoundingClientRect()
moveByRatio = (x: number, y: number, moveSpeedRatio: number = 0.05) => {
const container = this.getContainer()
const containerRect = container.getBoundingClientRect()
const offset = Math.min(containerRect.width, containerRect.height)

@@ -525,3 +620,3 @@ const dx = offset * moveSpeedRatio * x

moveBy = (dx, dy, noStateUpdate) => {
moveBy = (dx: number, dy: number, noStateUpdate?: boolean = true) => {
const { x, y, scale, rotate } = this.state

@@ -567,5 +662,7 @@

const { rotate } = this.state
let newAngle = value
let newAngle: number
if (typeof value === 'function') {
newAngle = value(rotate)
} else {
newAngle = value
}

@@ -575,7 +672,7 @@ this.setState({ rotate: newAngle })

zoomAbs = (x, y, zoomLevel) => {
zoomAbs = (x: number, y: number, zoomLevel: number) => {
this.zoomTo(x, y, zoomLevel / this.state.scale)
}
zoomTo = (x, y, ratio) => {
zoomTo = (x: number, y: number, ratio: number) => {
const { minZoom, maxZoom } = this.props

@@ -607,5 +704,6 @@ const { x: transformX, y: transformY, scale, rotate } = this.state

centeredZoom = (delta) => {
centeredZoom = (delta: number) => {
const container = this.getContainer()
const scaleMultiplier = this.getScaleMultiplier(delta)
const containerRect = this.container.getBoundingClientRect()
const containerRect = container.getBoundingClientRect()
this.zoomTo(containerRect.width / 2, containerRect.height / 2, scaleMultiplier)

@@ -626,4 +724,4 @@ }

getOffset = (e) => {
const containerRect = this.container.getBoundingClientRect()
getOffset = (e: MouseEvent | Touch) => {
const containerRect = this.getContainer().getBoundingClientRect()
const offsetX = e.clientX - containerRect.left

@@ -634,8 +732,8 @@ const offsetY = e.clientY - containerRect.top

getTransformMatrix = (x, y, scale, rotate) => {
if (!this.dragContainer) {
getTransformMatrix = (x: number, y: number, scale: number, rotate: number) => {
if (!this.dragContainer.current) {
return { a: scale, b: 0, c: 0, d: scale, x, y }
}
const { clientWidth, clientHeight } = this.dragContainer
const { clientWidth, clientHeight } = this.getDragContainer()
const centerX = clientWidth / 2

@@ -647,3 +745,3 @@ const centerY = clientHeight / 2

getTransformMatrixString = (a, b, c, d, x, y) => {
getTransformMatrixString = (a: number, b: number, c: number, d: number, x: number, y: number) => {
return `matrix(${a}, ${b}, ${c}, ${d}, ${x}, ${y})`

@@ -654,3 +752,3 @@ }

applyTransform = () => {
this.dragContainer.style.transform = this.transformMatrixString
this.getDragContainer().style.transform = this.transformMatrixString
this.frameAnimation = 0

@@ -661,7 +759,7 @@ }

applyIntermediateTransform = () => {
this.dragContainer.style.transform = this.intermediateTransformMatrixString
this.getDragContainer().style.transform = this.intermediateTransformMatrixString
this.intermediateFrameAnimation = 0
}
getBoundCoordinates = (x, y, newScale, rotate = 0, offsetX = 0, offsetY = 0) => {
getBoundCoordinates = (x: number, y: number, newScale: number, rotate?: number = 0, offsetX?: number = 0, offsetY?: number = 0) => {
const { enableBoundingBox, boundaryRatioVertical, boundaryRatioHorizontal } = this.props

@@ -678,4 +776,4 @@

const { height: containerHeight, width: containerWidth } = this.container.getBoundingClientRect()
const { top, left, width, height } = getTransformedElementCoordinates(rotate, newScale, offsetX, offsetY)(this.dragContainer)
const { height: containerHeight, width: containerWidth } = this.getContainer().getBoundingClientRect()
const { top, left, width, height } = getTransformedElementCoordinates(rotate, newScale, offsetX, offsetY)(this.getDragContainer())

@@ -711,3 +809,31 @@ // check that computed are inside boundaries otherwise set to the bounding box limits

render() {
const { children, style, disabled, disableKeyInteraction } = this.props
const {
children,
autoCenter,
autoCenterZoomLevel,
zoomSpeed,
doubleZoomSpeed,
disabled,
disableDoubleClickZoom,
disableKeyInteraction,
realPinch,
keyMapping,
minZoom,
maxZoom,
enableBoundingBox,
boundaryRatioVertical,
boundaryRatioHorizontal,
noStateUpdate,
onPanStart,
onPan,
onPanEnd,
preventPan,
style,
onDoubleClick,
onMouseDown,
onKeyDown,
onTouchStart,
onStateChange,
...restPassThroughProps
} = this.props
const { x, y, scale, rotate } = this.state

@@ -717,5 +843,28 @@ const { a, b, c, d, x: transformX, y: transformY} = this.getTransformMatrix(x, y, scale, rotate)

if (process.env.NODE_ENV !== 'production') {
warning(
onDoubleClick === undefined || typeof onDoubleClick === 'function',
"Expected `onDoubleClick` listener to be a function, instead got a value of `%s` type.",
typeof onDoubleClick
)
warning(
onMouseDown === undefined || typeof onMouseDown === 'function',
"Expected `onMouseDown` listener to be a function, instead got a value of `%s` type.",
typeof onMouseDown
)
warning(
onKeyDown === undefined || typeof onKeyDown === 'function',
"Expected `onKeyDown` listener to be a function, instead got a value of `%s` type.",
typeof onKeyDown
)
warning(
onTouchStart === undefined || typeof onTouchStart === 'function',
"Expected `onTouchStart` listener to be a function, instead got a value of `%s` type.",
typeof onTouchStart
)
}
return (
<div
ref={ref => this.container = ref}
ref={this.container}
{

@@ -738,5 +887,6 @@ ...(disableKeyInteraction ? {} : {

style={{ cursor: disabled ? 'initial' : 'pointer', ...style }}
{...restPassThroughProps}
>
<div
ref={ref => this.dragContainer = ref}
ref={this.dragContainer}
style={{

@@ -757,14 +907,2 @@ display: 'inline-block',

PanZoom.defaultProps = {
zoomSpeed: 1,
doubleZoomSpeed: 1.75,
minZoom: 0,
maxZoom: Infinity,
noStateUpdate: true,
boundaryRatioVertical: 0.8,
boundaryRatioHorizontal: 0.8,
preventPan: () => false,
}
export default PanZoom
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc