react-prismazoom
Advanced tools
Comparing version 1.0.2 to 1.0.3
# Changelog | ||
## [1.0.3] - 2018-08-10 | ||
- Add unit tests using [Intern](https://theintern.io/) | ||
- Improve performances with translate3d and will-change CSS properties | ||
- Fix a bug on panning when the element is not centered | ||
## [1.0.2] - 2018-08-08 | ||
@@ -4,0 +9,0 @@ - Fix on README documentation |
@@ -1,18 +0,60 @@ | ||
var _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; }; | ||
'use strict'; | ||
import React, { PureComponent } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
var _extends2 = require('babel-runtime/helpers/extends'); | ||
var _extends3 = _interopRequireDefault(_extends2); | ||
var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray'); | ||
var _slicedToArray3 = _interopRequireDefault(_slicedToArray2); | ||
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); | ||
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); | ||
var _createClass2 = require('babel-runtime/helpers/createClass'); | ||
var _createClass3 = _interopRequireDefault(_createClass2); | ||
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); | ||
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); | ||
var _inherits2 = require('babel-runtime/helpers/inherits'); | ||
var _inherits3 = _interopRequireDefault(_inherits2); | ||
var _react = require('react'); | ||
var _react2 = _interopRequireDefault(_react); | ||
var _propTypes = require('prop-types'); | ||
var _propTypes2 = _interopRequireDefault(_propTypes); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
// Max delay between two taps to consider a double tap (in milliseconds) | ||
const doubleTouchMaxDelay = 300; | ||
var doubleTouchMaxDelay = 300; | ||
export default class PrismaZoom extends PureComponent { | ||
var PrismaZoom = function (_PureComponent) { | ||
(0, _inherits3.default)(PrismaZoom, _PureComponent); | ||
constructor(props) { | ||
super(props); | ||
function PrismaZoom(props) { | ||
(0, _classCallCheck3.default)(this, PrismaZoom); | ||
// Last cursor position | ||
var _this = (0, _possibleConstructorReturn3.default)(this, (PrismaZoom.__proto__ || Object.getPrototypeOf(PrismaZoom)).call(this, props)); | ||
this.getNewPosition = (rect, x, y, zoom) => { | ||
const [prevZoom, prevPosX, prevPosY] = [this.state.zoom, this.state.posX, this.state.posY]; | ||
_this.getNewPosition = function (rect, x, y, zoom) { | ||
var _ref = [_this.state.zoom, _this.state.posX, _this.state.posY], | ||
prevZoom = _ref[0], | ||
prevPosX = _ref[1], | ||
prevPosY = _ref[2]; | ||
if (zoom === 1) { | ||
@@ -24,8 +66,13 @@ return [0, 0]; | ||
// Retrieve rectangle dimensions and mouse position | ||
const [centerX, centerY] = [rect.width / 2, rect.height / 2]; | ||
const [relativeX, relativeY] = [x - rect.left, y - rect.top]; | ||
var centerX = rect.width / 2, | ||
centerY = rect.height / 2; | ||
var relativeX = x - rect.left, | ||
relativeY = y - rect.top; | ||
// If we are zooming down, we must try to center to mouse position | ||
const [absX, absY] = [(centerX - relativeX) / prevZoom, (centerY - relativeY) / prevZoom]; | ||
const ratio = zoom - prevZoom; | ||
var absX = (centerX - relativeX) / prevZoom, | ||
absY = (centerY - relativeY) / prevZoom; | ||
var ratio = zoom - prevZoom; | ||
return [prevPosX + absX * ratio, prevPosY + absY * ratio]; | ||
@@ -38,3 +85,3 @@ } else { | ||
this.getLimitedShift = (shift, minLimit, maxLimit, minElement, maxElement) => { | ||
_this.getLimitedShift = function (shift, minLimit, maxLimit, minElement, maxElement) { | ||
if (shift > 0) { | ||
@@ -61,3 +108,3 @@ if (minElement > minLimit) { | ||
this.getCursor = (canMoveOnX, canMoveOnY) => { | ||
_this.getCursor = function (canMoveOnX, canMoveOnY) { | ||
if (canMoveOnX && canMoveOnY) { | ||
@@ -74,70 +121,93 @@ return 'move'; | ||
this.fullZoomInOnPosition = (rect, x, y) => { | ||
const { maxZoom } = this.props; | ||
_this.fullZoomInOnPosition = function (rect, x, y) { | ||
var maxZoom = _this.props.maxZoom; | ||
const zoom = maxZoom; | ||
const [posX, posY] = this.getNewPosition(rect, x, y, zoom); | ||
this.setState({ zoom, posX, posY, useTransition: true }); | ||
var zoom = maxZoom; | ||
var _this$getNewPosition = _this.getNewPosition(rect, x, y, zoom), | ||
_this$getNewPosition2 = (0, _slicedToArray3.default)(_this$getNewPosition, 2), | ||
posX = _this$getNewPosition2[0], | ||
posY = _this$getNewPosition2[1]; | ||
_this.setState({ zoom: zoom, posX: posX, posY: posY, useTransition: true }); | ||
}; | ||
this.move = (rect, shiftX, shiftY) => { | ||
const { leftBoundary, rightBoundary, topBoundary, bottomBoundary } = this.props; | ||
let { posX, posY } = this.state; | ||
_this.move = function (rect, shiftX, shiftY) { | ||
var parentRect = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; | ||
var _this$props = _this.props, | ||
leftBoundary = _this$props.leftBoundary, | ||
rightBoundary = _this$props.rightBoundary, | ||
topBoundary = _this$props.topBoundary, | ||
bottomBoundary = _this$props.bottomBoundary; | ||
var _this$state = _this.state, | ||
posX = _this$state.posX, | ||
posY = _this$state.posY; | ||
// Get container coordinates | ||
if (!parentRect) { | ||
parentRect = _this.refs.layout.parentNode.getBoundingClientRect(); | ||
} | ||
// Get horizontal limits using specified horizontal boundaries | ||
const [leftLimit, rightLimit] = [leftBoundary, document.body.clientWidth - rightBoundary]; | ||
var leftLimit = leftBoundary, | ||
rightLimit = document.body.clientWidth - rightBoundary; | ||
var isLarger = | ||
// Check if the element is larger than its container | ||
rect.width > rightLimit - leftLimit, | ||
isOutLeftBoundary = | ||
// Check if the element is out its container left boundary | ||
shiftX > 0 && rect.left - parentRect.left < 0, | ||
isOutRightBoundary = | ||
// Check if the element is out its container right boundary | ||
shiftX < 0 && rect.right - parentRect.right > 0; | ||
let canMoveOnX = false; | ||
// Check if the element is larger than the layout zone | ||
if (rect.width > rightLimit - leftLimit) { | ||
// If the element is bigger than its container, allow moves | ||
canMoveOnX = true; | ||
// Limit the shift considering boudaries | ||
posX += this.getLimitedShift(shiftX, leftLimit, rightLimit, rect.left, rect.right); | ||
} else if (posX > 0 && shiftX < 0 || posX < 0 && shiftX > 0) { | ||
// If the element is smaller than its container, allow only centering moves | ||
canMoveOnX = true; | ||
if (Math.abs(posX) > 5) { | ||
posX += shiftX; | ||
} else { | ||
posX = 0; | ||
} | ||
var canMoveOnX = isLarger || isOutLeftBoundary || isOutRightBoundary; | ||
if (canMoveOnX) { | ||
posX += _this.getLimitedShift(shiftX, leftLimit, rightLimit, rect.left, rect.right); | ||
} | ||
// Get vertical limits using specified vertical boundaries | ||
const [topLimit, bottomLimit] = [topBoundary, document.body.clientHeight - bottomBoundary]; | ||
var topLimit = topBoundary, | ||
bottomLimit = document.body.clientHeight - bottomBoundary; | ||
var isHigher = | ||
// Check if the element is higher than its container | ||
rect.height > bottomLimit - topLimit, | ||
isOutTopBoundary = | ||
// Check if the element is out its container top boundary | ||
shiftY > 0 && rect.top - parentRect.top < 0, | ||
isOutBottomBoundary = | ||
// Check if the element is out its container bottom boundary | ||
shiftY < 0 && rect.bottom - parentRect.bottom > 0; | ||
let canMoveOnY = false; | ||
// Check if the element is higher than the layout zone | ||
if (rect.height > bottomLimit - topLimit) { | ||
// If the element is bigger than its container, allow moves | ||
canMoveOnY = true; | ||
// Limit the shift considering boudaries | ||
posY += this.getLimitedShift(shiftY, topLimit, bottomLimit, rect.top, rect.bottom); | ||
} else if (posY > 0 && shiftY < 0 || posY < 0 && shiftY > 0) { | ||
// If the element is smaller than its container, allow only centering moves | ||
canMoveOnY = true; | ||
if (Math.abs(posY) > 5) { | ||
posY += shiftY; | ||
} else { | ||
posY = 0; | ||
} | ||
var canMoveOnY = isHigher || isOutTopBoundary || isOutBottomBoundary; | ||
if (canMoveOnY) { | ||
posY += _this.getLimitedShift(shiftY, topLimit, bottomLimit, rect.top, rect.bottom); | ||
} | ||
const cursor = this.getCursor(canMoveOnX, canMoveOnY); | ||
var cursor = _this.getCursor(canMoveOnX, canMoveOnY); | ||
this.setState({ posX, posY, cursor, useTransition: false }); | ||
_this.setState({ posX: posX, posY: posY, cursor: cursor, useTransition: false }); | ||
}; | ||
this.handleMouseWheel = event => { | ||
_this.handleMouseWheel = function (event) { | ||
event.preventDefault(); | ||
const { minZoom, maxZoom, scrollVelocity } = this.props; | ||
let { zoom, posX, posY } = this.state; | ||
var _this$props2 = _this.props, | ||
minZoom = _this$props2.minZoom, | ||
maxZoom = _this$props2.maxZoom, | ||
scrollVelocity = _this$props2.scrollVelocity; | ||
var _this$state2 = _this.state, | ||
zoom = _this$state2.zoom, | ||
posX = _this$state2.posX, | ||
posY = _this$state2.posY; | ||
// Keep the previous zoom value | ||
const prevZoom = zoom; | ||
var prevZoom = zoom; | ||
// Determine if we are increasing or decreasing the zoom | ||
const increaseZoom = event.deltaY < 0; | ||
var increaseZoom = event.deltaY < 0; | ||
@@ -152,84 +222,101 @@ // Set the new zoom value | ||
if (zoom !== prevZoom) { | ||
const rect = event.currentTarget.getBoundingClientRect(); | ||
var rect = event.currentTarget.getBoundingClientRect(); | ||
if (zoom !== minZoom) { | ||
[posX, posY] = this.getNewPosition(rect, event.pageX, event.pageY, zoom); | ||
var _this$getNewPosition3 = _this.getNewPosition(rect, event.pageX, event.pageY, zoom); | ||
var _this$getNewPosition4 = (0, _slicedToArray3.default)(_this$getNewPosition3, 2); | ||
posX = _this$getNewPosition4[0]; | ||
posY = _this$getNewPosition4[1]; | ||
} else { | ||
var _ref2 = [_this.constructor.defaultState.posX, _this.constructor.defaultState.posY]; | ||
// Reset to original position | ||
[posX, posY] = [this.constructor.defaultState.posX, this.constructor.defaultState.posY]; | ||
posX = _ref2[0]; | ||
posY = _ref2[1]; | ||
} | ||
} | ||
this.setState({ zoom, posX, posY, useTransition: false }); | ||
_this.setState({ zoom: zoom, posX: posX, posY: posY, useTransition: false }); | ||
}; | ||
this.handleDoubleClick = event => { | ||
_this.handleDoubleClick = function (event) { | ||
event.preventDefault(); | ||
const rect = event.currentTarget.getBoundingClientRect(); | ||
if (this.state.zoom === this.props.minZoom) { | ||
this.fullZoomInOnPosition(rect, event.pageX, event.pageY); | ||
var rect = event.currentTarget.getBoundingClientRect(); | ||
if (_this.state.zoom === _this.props.minZoom) { | ||
_this.fullZoomInOnPosition(rect, event.pageX, event.pageY); | ||
} else { | ||
this.reset(); | ||
_this.reset(); | ||
} | ||
}; | ||
this.handleMouseStart = event => { | ||
_this.handleMouseStart = function (event) { | ||
event.preventDefault(); | ||
this.lastCursor = { posX: event.pageX, posY: event.pageY }; | ||
_this.lastCursor = { posX: event.pageX, posY: event.pageY }; | ||
}; | ||
this.handleMouseMove = event => { | ||
_this.handleMouseMove = function (event) { | ||
event.preventDefault(); | ||
if (!this.lastCursor) { | ||
if (!_this.lastCursor) { | ||
return; | ||
} | ||
const [posX, posY] = [event.pageX, event.pageY]; | ||
const rect = event.currentTarget.getBoundingClientRect(); | ||
const shiftX = posX - this.lastCursor.posX; | ||
const shiftY = posY - this.lastCursor.posY; | ||
var _ref3 = [event.pageX, event.pageY], | ||
posX = _ref3[0], | ||
posY = _ref3[1]; | ||
this.move(rect, shiftX, shiftY); | ||
this.lastCursor = { posX, posY }; | ||
var rect = event.currentTarget.getBoundingClientRect(); | ||
var shiftX = posX - _this.lastCursor.posX; | ||
var shiftY = posY - _this.lastCursor.posY; | ||
_this.move(rect, shiftX, shiftY); | ||
_this.lastCursor = { posX: posX, posY: posY }; | ||
}; | ||
this.handleMouseStop = event => { | ||
_this.handleMouseStop = function (event) { | ||
event.preventDefault(); | ||
this.lastCursor = null; | ||
this.setState({ cursor: 'auto' }); | ||
_this.lastCursor = null; | ||
_this.setState({ cursor: 'auto' }); | ||
}; | ||
this.handleTouchStart = event => { | ||
_this.handleTouchStart = function (event) { | ||
event.preventDefault(); | ||
const [posX, posY] = [event.touches[0].pageX, event.touches[0].pageY]; | ||
var _ref4 = [event.touches[0].pageX, event.touches[0].pageY], | ||
posX = _ref4[0], | ||
posY = _ref4[1]; | ||
if (event.touches.length === 1) { | ||
// Check if it is a double tap | ||
const touchTime = new Date().getTime(); | ||
if (touchTime - this.lastTouchTime < doubleTouchMaxDelay && touchTime - this.lastDoubleTapTime > doubleTouchMaxDelay) { | ||
const rect = event.currentTarget.getBoundingClientRect(); | ||
if (this.state.zoom === this.props.minZoom) { | ||
this.fullZoomInOnPosition(rect, posX, posY); | ||
var touchTime = new Date().getTime(); | ||
if (touchTime - _this.lastTouchTime < doubleTouchMaxDelay && touchTime - _this.lastDoubleTapTime > doubleTouchMaxDelay) { | ||
var rect = event.currentTarget.getBoundingClientRect(); | ||
if (_this.state.zoom === _this.props.minZoom) { | ||
_this.fullZoomInOnPosition(rect, posX, posY); | ||
} else { | ||
this.reset(); | ||
_this.reset(); | ||
} | ||
this.lastDoubleTapTime = touchTime; | ||
_this.lastDoubleTapTime = touchTime; | ||
} | ||
this.lastTouchTime = touchTime; | ||
_this.lastTouchTime = touchTime; | ||
} | ||
this.lastTouch = { posX, posY }; | ||
_this.lastTouch = { posX: posX, posY: posY }; | ||
}; | ||
this.handleTouchMove = event => { | ||
_this.handleTouchMove = function (event) { | ||
event.preventDefault(); | ||
const { maxZoom, minZoom } = this.props; | ||
let { zoom } = this.state; | ||
var _this$props3 = _this.props, | ||
maxZoom = _this$props3.maxZoom, | ||
minZoom = _this$props3.minZoom; | ||
var zoom = _this.state.zoom; | ||
if (!this.lastTouch) { | ||
if (!_this.lastTouch) { | ||
return; | ||
@@ -239,21 +326,29 @@ } | ||
if (event.touches.length === 1) { | ||
const [posX, posY] = [event.touches[0].pageX, event.touches[0].pageY]; | ||
var _ref5 = [event.touches[0].pageX, event.touches[0].pageY], | ||
posX = _ref5[0], | ||
posY = _ref5[1]; | ||
// If we detect only one point, we shall just move the element | ||
const rect = event.currentTarget.getBoundingClientRect(); | ||
const shiftX = posX - this.lastTouch.posX; | ||
const shiftY = posY - this.lastTouch.posY; | ||
this.move(rect, shiftX, shiftY); | ||
var rect = event.currentTarget.getBoundingClientRect(); | ||
var shiftX = posX - _this.lastTouch.posX; | ||
var shiftY = posY - _this.lastTouch.posY; | ||
_this.move(rect, shiftX, shiftY); | ||
// Save data for the next move | ||
this.lastTouch = { posX, posY }; | ||
this.lastTouchDistance = null; | ||
_this.lastTouch = { posX: posX, posY: posY }; | ||
_this.lastTouchDistance = null; | ||
} else if (event.touches.length > 1) { | ||
// If we detect two points, we shall zoom up or down | ||
const [pos1X, pos1Y] = [event.touches[0].pageX, event.touches[0].pageY]; | ||
const [pos2X, pos2Y] = [event.touches[1].pageX, event.touches[1].pageY]; | ||
const distance = Math.sqrt(Math.pow(pos2X - pos1X, 2) + Math.pow(pos2Y - pos1Y, 2)); | ||
var _ref6 = [event.touches[0].pageX, event.touches[0].pageY], | ||
pos1X = _ref6[0], | ||
pos1Y = _ref6[1]; | ||
var _ref7 = [event.touches[1].pageX, event.touches[1].pageY], | ||
pos2X = _ref7[0], | ||
pos2Y = _ref7[1]; | ||
if (this.lastTouchDistance && distance && distance !== this.lastTouchDistance) { | ||
zoom += (distance - this.lastTouchDistance) / 100; | ||
var distance = Math.sqrt(Math.pow(pos2X - pos1X, 2) + Math.pow(pos2Y - pos1Y, 2)); | ||
if (_this.lastTouchDistance && distance && distance !== _this.lastTouchDistance) { | ||
zoom += (distance - _this.lastTouchDistance) / 100; | ||
if (zoom > maxZoom) { | ||
@@ -266,28 +361,37 @@ zoom = maxZoom; | ||
// Change position using the center point between the two fingers | ||
const rect = event.currentTarget.getBoundingClientRect(); | ||
const [centerX, centerY] = [(pos1X + pos2X) / 2, (pos1Y + pos2Y) / 2]; | ||
const [posX, posY] = this.getNewPosition(rect, centerX, centerY, zoom); | ||
var _rect = event.currentTarget.getBoundingClientRect(); | ||
var centerX = (pos1X + pos2X) / 2, | ||
centerY = (pos1Y + pos2Y) / 2; | ||
this.setState({ zoom, posX, posY, useTransition: false }); | ||
var _this$getNewPosition5 = _this.getNewPosition(_rect, centerX, centerY, zoom), | ||
_this$getNewPosition6 = (0, _slicedToArray3.default)(_this$getNewPosition5, 2), | ||
_posX = _this$getNewPosition6[0], | ||
_posY = _this$getNewPosition6[1]; | ||
_this.setState({ zoom: zoom, posX: _posX, posY: _posY, useTransition: false }); | ||
} | ||
// Save data for the next move | ||
this.lastTouch = { posX: pos1X, posY: pos1Y }; | ||
this.lastTouchDistance = distance; | ||
_this.lastTouch = { posX: pos1X, posY: pos1Y }; | ||
_this.lastTouchDistance = distance; | ||
} | ||
}; | ||
this.handleTouchStop = event => { | ||
_this.handleTouchStop = function (event) { | ||
event.preventDefault(); | ||
this.lastTouch = null; | ||
this.lastTouchDistance = null; | ||
_this.lastTouch = null; | ||
_this.lastTouchDistance = null; | ||
}; | ||
this.zoomIn = value => { | ||
const { maxZoom } = this.props; | ||
let { zoom, posX, posY } = this.state; | ||
_this.zoomIn = function (value) { | ||
var maxZoom = _this.props.maxZoom; | ||
var _this$state3 = _this.state, | ||
zoom = _this$state3.zoom, | ||
posX = _this$state3.posX, | ||
posY = _this$state3.posY; | ||
const prevZoom = zoom; | ||
var prevZoom = zoom; | ||
zoom = zoom + value < maxZoom ? zoom + value : maxZoom; | ||
@@ -300,11 +404,15 @@ | ||
this.setState({ zoom, posX, posY, useTransition: true }); | ||
_this.setState({ zoom: zoom, posX: posX, posY: posY, useTransition: true }); | ||
}; | ||
this.zoomOut = value => { | ||
const { minZoom } = this.props; | ||
let { zoom, posX, posY } = this.state; | ||
_this.zoomOut = function (value) { | ||
var minZoom = _this.props.minZoom; | ||
var _this$state4 = _this.state, | ||
zoom = _this$state4.zoom, | ||
posX = _this$state4.posX, | ||
posY = _this$state4.posY; | ||
const prevZoom = zoom; | ||
var prevZoom = zoom; | ||
zoom = zoom - value > minZoom ? zoom - value : minZoom; | ||
@@ -317,45 +425,58 @@ | ||
this.setState({ zoom, posX, posY, useTransition: true }); | ||
_this.setState({ zoom: zoom, posX: posX, posY: posY, useTransition: true }); | ||
}; | ||
this.zoomToZone = (relX, relY, relWidth, relHeight) => { | ||
const { maxZoom, leftBoundary, rightBoundary, topBoundary, bottomBoundary } = this.props; | ||
let { zoom, posX, posY } = this.state; | ||
_this.zoomToZone = function (relX, relY, relWidth, relHeight) { | ||
var _this$props4 = _this.props, | ||
maxZoom = _this$props4.maxZoom, | ||
leftBoundary = _this$props4.leftBoundary, | ||
rightBoundary = _this$props4.rightBoundary, | ||
topBoundary = _this$props4.topBoundary, | ||
bottomBoundary = _this$props4.bottomBoundary; | ||
var _this$state5 = _this.state, | ||
zoom = _this$state5.zoom, | ||
posX = _this$state5.posX, | ||
posY = _this$state5.posY; | ||
const prevZoom = zoom; | ||
var prevZoom = zoom; | ||
// Calculate zoom factor to scale the zone | ||
const optimalZoomX = (document.body.clientWidth - leftBoundary - rightBoundary) / relWidth; | ||
const optimalZoomY = (document.body.clientHeight - topBoundary - bottomBoundary) / relHeight; | ||
var optimalZoomX = (document.body.clientWidth - leftBoundary - rightBoundary) / relWidth; | ||
var optimalZoomY = (document.body.clientHeight - topBoundary - bottomBoundary) / relHeight; | ||
zoom = Math.min(optimalZoomX, optimalZoomY, maxZoom); | ||
// Calculate new position to center the zone | ||
const rect = this.refs.layout.getBoundingClientRect(); | ||
const [centerX, centerY] = [rect.width / prevZoom / 2, rect.height / prevZoom / 2]; | ||
const [zoneCenterX, zoneCenterY] = [relX + relWidth / 2, relY + relHeight / 2]; | ||
var rect = _this.refs.layout.getBoundingClientRect(); | ||
var centerX = rect.width / prevZoom / 2, | ||
centerY = rect.height / prevZoom / 2; | ||
var zoneCenterX = relX + relWidth / 2, | ||
zoneCenterY = relY + relHeight / 2; | ||
posX = (centerX - zoneCenterX) * zoom; | ||
posY = (centerY - zoneCenterY) * zoom; | ||
this.setState({ zoom, posX, posY, useTransition: true }); | ||
_this.setState({ zoom: zoom, posX: posX, posY: posY, useTransition: true }); | ||
}; | ||
this.reset = () => { | ||
this.setState(this.constructor.defaultState); | ||
_this.reset = function () { | ||
_this.setState(_this.constructor.defaultState); | ||
}; | ||
this.getZoom = () => { | ||
return this.state.zoom; | ||
_this.getZoom = function () { | ||
return _this.state.zoom; | ||
}; | ||
this.lastCursor = null; | ||
_this.lastCursor = null; | ||
// Last touch position | ||
this.lastTouch = null; | ||
_this.lastTouch = null; | ||
// Last touch time in milliseconds | ||
this.lastTouchTime = 0; | ||
_this.lastTouchTime = 0; | ||
// Last double tap time (used to limit multiple double tap) in milliseconds | ||
this.lastDoubleTapTime = 0; | ||
_this.lastDoubleTapTime = 0; | ||
// Last calculated distance between two fingers in pixels | ||
this.lastTouchDistance = null; | ||
_this.lastTouchDistance = null; | ||
this.state = _extends({}, this.constructor.defaultState); | ||
_this.state = (0, _extends3.default)({}, _this.constructor.defaultState); | ||
return _this; | ||
} | ||
@@ -490,55 +611,71 @@ | ||
componentDidUpdate(prevProps, prevState) { | ||
if (this.props.onZoomChange && this.state.zoom !== prevState.zoom) { | ||
this.props.onZoomChange(this.state.zoom); | ||
(0, _createClass3.default)(PrismaZoom, [{ | ||
key: 'componentDidUpdate', | ||
value: function componentDidUpdate(prevProps, prevState) { | ||
if (this.props.onZoomChange && this.state.zoom !== prevState.zoom) { | ||
this.props.onZoomChange(this.state.zoom); | ||
} | ||
} | ||
} | ||
}, { | ||
key: 'render', | ||
value: function render() { | ||
var _props = this.props, | ||
className = _props.className, | ||
children = _props.children, | ||
animDuration = _props.animDuration; | ||
var _state = this.state, | ||
zoom = _state.zoom, | ||
posX = _state.posX, | ||
posY = _state.posY, | ||
cursor = _state.cursor, | ||
useTransition = _state.useTransition; | ||
render() { | ||
const { className, children, animDuration } = this.props; | ||
const { zoom, posX, posY, cursor, useTransition } = this.state; | ||
const style = _extends({}, this.props.style, { | ||
transform: `translate(${posX}px, ${posY}px) scale(${zoom})`, | ||
transition: useTransition ? `transform ease-in-out ${animDuration}s` : '', | ||
cursor: cursor, | ||
touchAction: 'none' | ||
}); | ||
var style = (0, _extends3.default)({}, this.props.style, { | ||
transform: 'translate3d(' + posX + 'px, ' + posY + 'px, 0) scale(' + zoom + ')', | ||
transition: useTransition ? 'transform ease-in-out ' + animDuration + 's' : '', | ||
cursor: cursor, | ||
touchAction: 'none', | ||
willChange: 'transform' | ||
}); | ||
const attr = { | ||
ref: 'layout', | ||
style: style, | ||
className: className, | ||
onWheel: this.handleMouseWheel, | ||
onDoubleClick: this.handleDoubleClick, | ||
onMouseDown: this.handleMouseStart, | ||
onMouseMove: this.handleMouseMove, | ||
onMouseUp: this.handleMouseStop, | ||
onMouseLeave: this.handleMouseStop, | ||
onTouchStart: this.handleTouchStart, | ||
onTouchMove: this.handleTouchMove, | ||
onTouchEnd: this.handleTouchStop, | ||
onTouchCancel: this.handleTouchStop | ||
}; | ||
var attr = { | ||
ref: 'layout', | ||
style: style, | ||
className: className, | ||
onWheel: this.handleMouseWheel, | ||
onDoubleClick: this.handleDoubleClick, | ||
onMouseDown: this.handleMouseStart, | ||
onMouseMove: this.handleMouseMove, | ||
onMouseUp: this.handleMouseStop, | ||
onMouseLeave: this.handleMouseStop, | ||
onTouchStart: this.handleTouchStart, | ||
onTouchMove: this.handleTouchMove, | ||
onTouchEnd: this.handleTouchStop, | ||
onTouchCancel: this.handleTouchStop | ||
}; | ||
return React.createElement( | ||
'div', | ||
attr, | ||
children | ||
); | ||
} | ||
} | ||
return _react2.default.createElement( | ||
'div', | ||
attr, | ||
children | ||
); | ||
} | ||
}]); | ||
return PrismaZoom; | ||
}(_react.PureComponent); | ||
PrismaZoom.propTypes = { | ||
children: PropTypes.node.isRequired, | ||
className: PropTypes.string, | ||
style: PropTypes.object, | ||
minZoom: PropTypes.number, | ||
maxZoom: PropTypes.number, | ||
scrollVelocity: PropTypes.number, | ||
onZoomChange: PropTypes.func, | ||
leftBoundary: PropTypes.number, | ||
rightBoundary: PropTypes.number, | ||
topBoundary: PropTypes.number, | ||
bottomBoundary: PropTypes.number, | ||
animDuration: PropTypes.number | ||
children: _propTypes2.default.node.isRequired, | ||
className: _propTypes2.default.string, | ||
style: _propTypes2.default.object, | ||
minZoom: _propTypes2.default.number, | ||
maxZoom: _propTypes2.default.number, | ||
scrollVelocity: _propTypes2.default.number, | ||
onZoomChange: _propTypes2.default.func, | ||
leftBoundary: _propTypes2.default.number, | ||
rightBoundary: _propTypes2.default.number, | ||
topBoundary: _propTypes2.default.number, | ||
bottomBoundary: _propTypes2.default.number, | ||
animDuration: _propTypes2.default.number | ||
}; | ||
@@ -580,2 +717,3 @@ PrismaZoom.defaultProps = { | ||
useTransition: true | ||
}; | ||
}; | ||
exports.default = PrismaZoom; |
{ | ||
"name": "react-prismazoom", | ||
"version": "1.0.2", | ||
"version": "1.0.3", | ||
"description": "A pan and zoom component for React, using CSS transformations.", | ||
@@ -22,3 +22,2 @@ "author": "Sylvain DUBUS <svn.dbs@gmail.com>", | ||
"scripts": { | ||
"test": "echo \"No test specified\" && exit 0", | ||
"start": "webpack-dev-server --mode development", | ||
@@ -29,3 +28,5 @@ "transpile": "babel src -d dist --copy-file", | ||
"deploy": "gh-pages -d examples/dist", | ||
"publish-demo": "npm run build && npm run deploy" | ||
"publish-demo": "npm run build && npm run deploy", | ||
"test": "intern config='intern.json' || true", | ||
"watchTest": "watch --interval=0.5 'npm run test' src tests" | ||
}, | ||
@@ -42,2 +43,3 @@ "peerDependencies": { | ||
"babel-loader": "^7.1.5", | ||
"babel-plugin-transform-runtime": "^6.23.0", | ||
"babel-preset-env": "^1.7.0", | ||
@@ -47,2 +49,4 @@ "babel-preset-react": "^6.24.1", | ||
"css-loader": "^1.0.0", | ||
"enzyme": "^3.4.1", | ||
"enzyme-adapter-react-16": "^1.2.0", | ||
"eslint": "^4.19.1", | ||
@@ -59,2 +63,4 @@ "eslint-config-standard": "^11.0.0", | ||
"html-webpack-plugin": "^3.2.0", | ||
"intern": "^4.2.2", | ||
"jsdom": "^11.12.0", | ||
"prop-types": "^15.6", | ||
@@ -64,2 +70,3 @@ "react": "^16", | ||
"style-loader": "^0.21.0", | ||
"watch": "^1.0.2", | ||
"webpack": "^4.16.5", | ||
@@ -66,0 +73,0 @@ "webpack-cli": "^3.1.0", |
@@ -44,2 +44,14 @@ # react-prismazoom | ||
### Run unit tests | ||
You can either run all tests at once: | ||
```bash | ||
$ npm test | ||
``` | ||
Or run tests each time a change on source files occured: | ||
```bash | ||
$ npm run watchTest | ||
``` | ||
## Usage | ||
@@ -63,3 +75,3 @@ | ||
| className | string | None | Class name to apply on the zoom wrapper. | | ||
| style | object | None | Style to apply on the zoom wrapper. Note that *transform*, *transition*, *cursor* and *touch-action* cannot be overridden. Example: `style={{backgroundColor: 'red'}}`. | | ||
| style | object | None | Style to apply on the zoom wrapper. Note that *transform*, *transition*, *cursor*, *touch-action* and *will-change* cannot be overridden. Example: `style={{backgroundColor: 'red'}}`. | | ||
| minZoom | number | 1 | Minimum zoom ratio. | | ||
@@ -66,0 +78,0 @@ | maxZoom | number | 5 | Maximum zoom ratio. | |
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
29308
552
1
115
32
6