Comparing version 2.1.0 to 2.2.0
126
index.js
@@ -43,3 +43,9 @@ /* globals SVGElement */ | ||
var speed = typeof options.zoomSpeed === 'number' ? options.zoomSpeed : defaultZoomSpeed | ||
var bounds = options.bounds | ||
validateBounds(bounds) | ||
var maxZoom = typeof options.maxZoom === 'number' ? options.maxZoom : Number.POSITIVE_INFINITY | ||
var minZoom = typeof options.minZoom === 'number' ? options.minZoom : 0 | ||
var boundsPadding = typeof options.bounds === 'number' ? options.bounds : 0.05 | ||
var lastTouchEndTime = 0 | ||
@@ -90,2 +96,5 @@ | ||
transform.y += dy | ||
keepTransformInsideBounds() | ||
triggerEvent('pan') | ||
@@ -95,5 +104,85 @@ makeDirty() | ||
function keepTransformInsideBounds() { | ||
var boundingBox = getBoundingBox() | ||
if (!boundingBox) return | ||
var adjusted = false | ||
var clientRect = getClientRect() | ||
var diff = boundingBox.left - clientRect.right; | ||
if (diff > 0) { | ||
transform.x += diff | ||
adjusted = true | ||
} | ||
// check the other side: | ||
diff = boundingBox.right - clientRect.left | ||
if (diff < 0) { | ||
transform.x += diff | ||
adjusted = true | ||
} | ||
// y axis: | ||
diff = boundingBox.top - clientRect.bottom; | ||
if (diff > 0) { | ||
// we adjust transform, so that it matches exactly our boinding box: | ||
// transform.y = boundingBox.top - (boundingBox.height + boundingBox.y) * transform.scale => | ||
// transform.y = boundingBox.top - (clientRect.bottom - transform.y) => | ||
// transform.y = diff + transform.y => | ||
transform.y += diff | ||
adjusted = true | ||
} | ||
diff = boundingBox.bottom - clientRect.top; | ||
if (diff < 0) { | ||
transform.y += diff | ||
adjusted = true | ||
} | ||
return adjusted | ||
} | ||
/** | ||
* Returns bounding box that should be used to restrict svg scene movement. | ||
*/ | ||
function getBoundingBox() { | ||
if (!bounds) return // client does not want to restrict movement | ||
if (typeof bounds === 'boolean') { | ||
var sceneWidth = owner.clientWidth | ||
var sceneHeight = owner.clientHeight | ||
return { | ||
left: sceneWidth * boundsPadding, | ||
top: sceneHeight * boundsPadding, | ||
right: sceneWidth * (1 - boundsPadding), | ||
bottom: sceneHeight * (1 - boundsPadding), | ||
} | ||
} | ||
return bounds | ||
} | ||
function getClientRect() { | ||
var bbox = svgElement.getBBox() | ||
var leftTop = client(bbox.x, bbox.y) | ||
return { | ||
left: leftTop.x, | ||
top: leftTop.y, | ||
right: bbox.width * transform.scale + leftTop.x, | ||
bottom: bbox.height * transform.scale + leftTop.y | ||
} | ||
} | ||
function client(x, y) { | ||
return { | ||
x: (x * transform.scale) + transform.x, | ||
y: (y * transform.scale) + transform.y | ||
} | ||
} | ||
function moveTo(x, y) { | ||
transform.x = x | ||
transform.y = y | ||
keepTransformInsideBounds() | ||
makeDirty() | ||
@@ -108,2 +197,9 @@ } | ||
function zoomByRatio(clientX, clientY, ratio) { | ||
var newScale = transform.scale * ratio | ||
if (newScale > maxZoom || newScale < minZoom) { | ||
// outside of allowed bounds | ||
return | ||
} | ||
var parentCTM = owner.getScreenCTM() | ||
@@ -116,4 +212,6 @@ | ||
transform.y = y - ratio * (y - transform.y) | ||
transform.scale *= ratio | ||
var transformAdjusted = keepTransformInsideBounds() | ||
if (!transformAdjusted) transform.scale *= ratio | ||
makeDirty() | ||
@@ -123,13 +221,4 @@ } | ||
function zoomToAbsoluteValue(clientX, clientY, zoomLevel) { | ||
var parentCTM = owner.getScreenCTM() | ||
var x = clientX * parentCTM.a - parentCTM.e | ||
var y = clientY * parentCTM.a - parentCTM.f | ||
var ratio = zoomLevel / transform.scale | ||
transform.x = x - ratio * (x - transform.x) | ||
transform.y = y - ratio * (y - transform.y) | ||
transform.scale = zoomLevel | ||
makeDirty() | ||
zoomByRatio(clientX, clientY, ratio) | ||
} | ||
@@ -510,1 +599,16 @@ | ||
function noop() { } | ||
function validateBounds(bounds) { | ||
var boundsType = typeof bounds | ||
if (boundsType === 'undefined' || boundsType === 'boolean') return // this is okay | ||
// otherwise need to be more thorough: | ||
var validBounds = isNumber(bounds.left) && isNumber(bounds.top) && | ||
isNumber(bounds.top) && isNumber(bounds.right) | ||
if (!boundsValid) throw new Error('Bounds object is not valid. It can be: ' + | ||
'undefined, boolean (true|false) or an object {left, top, right, bottom}') | ||
} | ||
function isNumber(x) { | ||
return Number.isFinite(x) | ||
} |
{ | ||
"name": "panzoom", | ||
"version": "2.1.0", | ||
"version": "2.2.0", | ||
"description": "Pan and zoom SVG elements", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
127235
1363