Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unify the Event API #322

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 54 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -347,8 +347,43 @@ panzoom(element, {
The library will handle `ontouch` events very aggressively, it will `preventDefault`, and
`stopPropagation` for the touch events inside container. [Sometimes](https://github.com/anvaka/panzoom/issues/12) this is not a desirable behavior.

If you want to take care about this yourself, you can pass `onTouch` callback to the options object:
If you want to take care about this yourself, you can pass `beforeTouchStart` callback to the options object.

Note: if you don't `preventDefault` yourself - make sure you test the page behavior on iOS devices.
Sometimes this may cause page to [bounce undesirably](https://stackoverflow.com/questions/23862204/disable-ios-safari-elastic-scrolling).

### beforeTouchStart

``` js
panzoom(element, {
beforeTouchStart: function(e) {
// `e` - is current touch event.
// below is the default behavior modify as needed
e.stopPropagation();
e.preventDefault();

// You can return true to prevent library from handling this touch event.
// return true;
}
});
```

E.g. Sometimes single finger touch interferes with scrolling. If you want to alleviate it you can provide a custom filter to ignore those.
``` js
panzoom(element, {
// disable when only 1 touch.
beforeTouchStart: (e) => {
// `e` - is current touch event.
e.stopPropagation();
if (e.touches.length === 1) {
return true; // this return prevents library from handle this touch.
}
e.preventDefault();
},
});
```

### ~~onTouch~~ (depreciated)
``` js
panzoom(element, {
onTouch: function(e) {
Expand All @@ -359,17 +394,31 @@ panzoom(element, {
});
```

Note: if you don't `preventDefault` yourself - make sure you test the page behavior on iOS devices.
Sometimes this may cause page to [bounce undesirably](https://stackoverflow.com/questions/23862204/disable-ios-safari-elastic-scrolling).


## Handling double click events

By default panzoom will prevent default action on double click events - this is done to avoid
accidental text selection (which is default browser action on double click). If you prefer to
allow default action, you can pass `onDoubleClick()` callback to options. If this callback
returns false, then the library will not prevent default action:

### beforeDoubleClick

``` js
panzoom(element, {
beforeDoubleClick: function(e) {
// `e` - is current touch event.
// below is the default behavior modify as needed
e.stopPropagation();
e.preventDefault();

// You can return true to prevent library from handling this touch event.
// return true;
}
});
```

### ~~onDoubleClick~~ (depreciated)

``` js
panzoom(element, {
onDoubleClick: function(e) {
Expand Down
67 changes: 67 additions & 0 deletions demo/test/prevent_double_click.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='content-type' content='text/html; charset=utf-8' />
<meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no'>
<meta http-equiv='X-UA-Compatible' content='IE=edge' >
<META NAME='Description' content='Pan and zoom DOM elements demo '>
<meta name='keywords' content='dom, pan, zoom' />
<meta name='author' content='Andrei Kashcha'>
<meta name='title' content='DOM panzoom demo' />
<title>DOM panzoom demo</title>
<style type="text/css" media="screen">
body, html {
padding: 0;
margin: 0;
}
.header, .footer{
position: absolute;
padding: 10px;
margin: 0;
background: rgba(255, 255, 255, 0.4);
}
.header {
color: rgba(0, 0, 0, 0.82);
}
a {
color: #FF4081;
text-decoration: none;
}
.footer {
bottom: 10px;
color: rgba(0, 0, 0, 0.52);
}
</style>
</head>
<body>
<div id="top-part">I occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, ove zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable area</div>
<div>
<div id="lipsum" class='zoomable'>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam enim lectus, euismod ac metus eget, consequat aliquam augue. Fusce vestibulum sagittis massa, eget iaculis lorem malesuada ut. Curabitur fringilla a lectus sed suscipit. Sed mollis ligula blandit ipsum posuere, et luctus sem iaculis. Suspendisse scelerisque mollis dapibus. Sed elementum placerat lacus, ac rutrum mauris varius in. Sed malesuada, ipsum in facilisis facilisis, eros massa euismod odio, id pretium augue purus sed risus. Nulla vitae purus enim. Suspendisse placerat ac turpis sed tempor. Cras et vulputate eros. Aenean volutpat tincidunt erat eu aliquam. Sed vel ex pulvinar, rutrum velit at, ullamcorper nibh. Ut ac rhoncus nulla. Pellentesque eu orci eu libero semper commodo ac sit amet massa.
</p>
<p>
Donec condimentum odio ut lorem rhoncus pharetra. Maecenas nisl mi, faucibus ut tincidunt eu, lobortis at nunc. Suspendisse ut ipsum nec libero pharetra porta. Mauris porttitor neque nec mi rhoncus, a luctus massa consectetur. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed varius mauris et volutpat dignissim. Maecenas consectetur porta mollis. Morbi quis hendrerit massa. Cras vel eros vitae nisi mollis volutpat blandit id est. Vivamus fringilla iaculis lacus eu aliquet. Ut a varius augue, et accumsan nulla. Integer eu sem non erat porttitor posuere. Sed dui tortor, aliquam sed volutpat vitae, sodales non enim. Vestibulum libero nulla, tempus blandit pretium ac, ullamcorper eu nisl.
</p>
<p>
Aenean quis rhoncus ante. Maecenas euismod non lacus nec accumsan. Integer vitae sollicitudin lacus. Aliquam in justo augue. Pellentesque nisl nisi, sollicitudin sed commodo vitae, vestibulum eget est. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis auctor laoreet lectus sit amet eleifend. Curabitur tempus est nunc, vel molestie mauris congue vel. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent tincidunt aliquam massa, at ornare lacus tincidunt et.
</p>
<p>
Nam posuere et ante in finibus. Proin sagittis iaculis lacus, scelerisque convallis nulla porttitor ac. Nunc sagittis velit vitae pharetra dapibus. Etiam tortor ante, facilisis a odio sed, pretium vehicula dui. Proin et pellentesque lacus, ac tristique nibh. Pellentesque vitae ex a justo fringilla pharetra. Aenean accumsan tempor sollicitudin. Integer elementum, quam at commodo vestibulum, odio massa egestas nibh, nec hendrerit lacus diam eget nisi. Integer pretium pretium purus, eu ornare ipsum posuere id. Nullam eget varius magna, ac blandit tellus. In hac habitasse platea dictumst. Praesent volutpat, purus quis rhoncus faucibus, orci lacus dictum purus, sed sagittis ligula ante ut augue. Curabitur eget est quis erat volutpat mattis. Aliquam eleifend ut tortor eu ultrices.
</p>
<p>
Integer pretium erat et elit bibendum, ut laoreet tortor rutrum. Donec pulvinar faucibus enim vel molestie. Donec et euismod urna. Vestibulum nec feugiat magna. Nam at nunc lorem. Fusce sed ante eu purus posuere vulputate. In hac habitasse platea dictumst. Fusce consectetur elit a magna faucibus euismod. Ut congue efficitur ex. In dictum velit ac arcu condimentum, hendrerit venenatis dui tincidunt. Vestibulum pulvinar purus elementum felis tempus tincidunt. Aenean convallis, leo eu interdum varius, ante dui volutpat urna, a pharetra risus felis mattis mauris. Cras tincidunt justo enim, faucibus commodo nisl fringilla sed. Nullam facilisis, nisl a tincidunt euismod, purus odio sollicitudin sem, at ornare lorem sem ac nisi. Etiam a tincidunt tortor, consectetur porta nisl. Phasellus diam arcu, dapibus finibus nisi facilisis, dictum rutrum leo.
</p></div>
</div>
<p class='header'>
Drag it or zoom it...
</p>
<script src='../../dist/panzoom.js'></script>

<script>
var area = document.querySelector('.zoomable')
panzoom(area, { beforeDoubleClick: () => true });
</script>
<a href="https://github.com/anvaka/panzoom"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/365986a132ccd6a44c23a9169022c0b5c890c387/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f7265645f6161303030302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png"></a>
</body>
</html>
67 changes: 67 additions & 0 deletions demo/test/prevent_touch.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='content-type' content='text/html; charset=utf-8' />
<meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no'>
<meta http-equiv='X-UA-Compatible' content='IE=edge' >
<META NAME='Description' content='Pan and zoom DOM elements demo '>
<meta name='keywords' content='dom, pan, zoom' />
<meta name='author' content='Andrei Kashcha'>
<meta name='title' content='DOM panzoom demo' />
<title>DOM panzoom demo</title>
<style type="text/css" media="screen">
body, html {
padding: 0;
margin: 0;
}
.header, .footer{
position: absolute;
padding: 10px;
margin: 0;
background: rgba(255, 255, 255, 0.4);
}
.header {
color: rgba(0, 0, 0, 0.82);
}
a {
color: #FF4081;
text-decoration: none;
}
.footer {
bottom: 10px;
color: rgba(0, 0, 0, 0.52);
}
</style>
</head>
<body>
<div id="top-part">I occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, ove zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable areaI occupy space, above zoomable area</div>
<div>
<div id="lipsum" class='zoomable'>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam enim lectus, euismod ac metus eget, consequat aliquam augue. Fusce vestibulum sagittis massa, eget iaculis lorem malesuada ut. Curabitur fringilla a lectus sed suscipit. Sed mollis ligula blandit ipsum posuere, et luctus sem iaculis. Suspendisse scelerisque mollis dapibus. Sed elementum placerat lacus, ac rutrum mauris varius in. Sed malesuada, ipsum in facilisis facilisis, eros massa euismod odio, id pretium augue purus sed risus. Nulla vitae purus enim. Suspendisse placerat ac turpis sed tempor. Cras et vulputate eros. Aenean volutpat tincidunt erat eu aliquam. Sed vel ex pulvinar, rutrum velit at, ullamcorper nibh. Ut ac rhoncus nulla. Pellentesque eu orci eu libero semper commodo ac sit amet massa.
</p>
<p>
Donec condimentum odio ut lorem rhoncus pharetra. Maecenas nisl mi, faucibus ut tincidunt eu, lobortis at nunc. Suspendisse ut ipsum nec libero pharetra porta. Mauris porttitor neque nec mi rhoncus, a luctus massa consectetur. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed varius mauris et volutpat dignissim. Maecenas consectetur porta mollis. Morbi quis hendrerit massa. Cras vel eros vitae nisi mollis volutpat blandit id est. Vivamus fringilla iaculis lacus eu aliquet. Ut a varius augue, et accumsan nulla. Integer eu sem non erat porttitor posuere. Sed dui tortor, aliquam sed volutpat vitae, sodales non enim. Vestibulum libero nulla, tempus blandit pretium ac, ullamcorper eu nisl.
</p>
<p>
Aenean quis rhoncus ante. Maecenas euismod non lacus nec accumsan. Integer vitae sollicitudin lacus. Aliquam in justo augue. Pellentesque nisl nisi, sollicitudin sed commodo vitae, vestibulum eget est. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis auctor laoreet lectus sit amet eleifend. Curabitur tempus est nunc, vel molestie mauris congue vel. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent tincidunt aliquam massa, at ornare lacus tincidunt et.
</p>
<p>
Nam posuere et ante in finibus. Proin sagittis iaculis lacus, scelerisque convallis nulla porttitor ac. Nunc sagittis velit vitae pharetra dapibus. Etiam tortor ante, facilisis a odio sed, pretium vehicula dui. Proin et pellentesque lacus, ac tristique nibh. Pellentesque vitae ex a justo fringilla pharetra. Aenean accumsan tempor sollicitudin. Integer elementum, quam at commodo vestibulum, odio massa egestas nibh, nec hendrerit lacus diam eget nisi. Integer pretium pretium purus, eu ornare ipsum posuere id. Nullam eget varius magna, ac blandit tellus. In hac habitasse platea dictumst. Praesent volutpat, purus quis rhoncus faucibus, orci lacus dictum purus, sed sagittis ligula ante ut augue. Curabitur eget est quis erat volutpat mattis. Aliquam eleifend ut tortor eu ultrices.
</p>
<p>
Integer pretium erat et elit bibendum, ut laoreet tortor rutrum. Donec pulvinar faucibus enim vel molestie. Donec et euismod urna. Vestibulum nec feugiat magna. Nam at nunc lorem. Fusce sed ante eu purus posuere vulputate. In hac habitasse platea dictumst. Fusce consectetur elit a magna faucibus euismod. Ut congue efficitur ex. In dictum velit ac arcu condimentum, hendrerit venenatis dui tincidunt. Vestibulum pulvinar purus elementum felis tempus tincidunt. Aenean convallis, leo eu interdum varius, ante dui volutpat urna, a pharetra risus felis mattis mauris. Cras tincidunt justo enim, faucibus commodo nisl fringilla sed. Nullam facilisis, nisl a tincidunt euismod, purus odio sollicitudin sem, at ornare lorem sem ac nisi. Etiam a tincidunt tortor, consectetur porta nisl. Phasellus diam arcu, dapibus finibus nisi facilisis, dictum rutrum leo.
</p></div>
</div>
<p class='header'>
Drag it or zoom it...
</p>
<script src='../../dist/panzoom.js'></script>

<script>
var area = document.querySelector('.zoomable')
panzoom(area, { beforeTouchStart: () => true });
</script>
<a href="https://github.com/anvaka/panzoom"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/365986a132ccd6a44c23a9169022c0b5c890c387/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f7265645f6161303030302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png"></a>
</body>
</html>
53 changes: 28 additions & 25 deletions dist/panzoom.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ function createPanZoom(domElement, options) {
var zoomDoubleClickSpeed = typeof options.zoomDoubleClickSpeed === 'number' ? options.zoomDoubleClickSpeed : defaultDoubleTapZoomSpeed;
var beforeWheel = options.beforeWheel || noop;
var beforeMouseDown = options.beforeMouseDown || noop;
var beforeTouchStart = options.beforeTouchStart || options.onTouch || beforeTouchStartDefault;
var beforeDoubleClick = options.beforeDoubleClick || options.onDoubleClick || beforeDoubleClickDefault;
var speed = typeof options.zoomSpeed === 'number' ? options.zoomSpeed : defaultZoomSpeed;
var transformOrigin = parseTransformOrigin(options.transformOrigin);
var textSelection = options.enableTextSelection ? fakeTextSelectorInterceptor : domTextSelectionInterceptor;
Expand Down Expand Up @@ -591,7 +593,15 @@ function createPanZoom(domElement, options) {

function onTouch(e) {
// let them override the touch behavior
beforeTouch(e);
// support onTouch backwards compatibility.
if (beforeTouchStart(e)) {
if (options.onTouch) {
beforeTouchStartDefault(e);
} else {
return;
}
}

clearPendingClickEventTimeout();

if (e.touches.length === 1) {
Expand All @@ -604,28 +614,12 @@ function createPanZoom(domElement, options) {
}
}

function beforeTouch(e) {
// TODO: Need to unify this filtering names. E.g. use `beforeTouch`
if (options.onTouch && !options.onTouch(e)) {
// if they return `false` from onTouch, we don't want to stop
// events propagation. Fixes https://github.com/anvaka/panzoom/issues/12
return;
}

function beforeTouchStartDefault(e) {
e.stopPropagation();
e.preventDefault();
}

function beforeDoubleClick(e) {
clearPendingClickEventTimeout();

// TODO: Need to unify this filtering names. E.g. use `beforeDoubleClick``
if (options.onDoubleClick && !options.onDoubleClick(e)) {
// if they return `false` from onTouch, we don't want to stop
// events propagation. Fixes https://github.com/anvaka/panzoom/issues/46
return;
}

function beforeDoubleClickDefault(e) {
e.preventDefault();
e.stopPropagation();
}
Expand Down Expand Up @@ -763,7 +757,16 @@ function createPanZoom(domElement, options) {
}

function onDoubleClick(e) {
beforeDoubleClick(e);
// support onDoubleClick backwards compatibility
if (beforeDoubleClick(e)) {
if (options.onDoubleClick) {
beforeDoubleClickDefault(e);
} else {
return;
}
}
clearPendingClickEventTimeout();

var offset = getOffsetXY(e);
if (transformOrigin) {
// TODO: looks like this is duplicated in the file.
Expand Down Expand Up @@ -1327,12 +1330,12 @@ function makeSvgController(svgElement, options) {
}

function getBBox() {
var bbox = svgElement.getBBox();
var boundingBox = svgElement.getBBox();
return {
left: bbox.x,
top: bbox.y,
width: bbox.width,
height: bbox.height,
left: boundingBox.x,
top: boundingBox.y,
width: boundingBox.width,
height: boundingBox.height,
};
}

Expand Down
2 changes: 1 addition & 1 deletion dist/panzoom.min.js

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,15 @@ declare module "panzoom" {
beforeWheel?: (e: WheelEvent) => void;
beforeMouseDown?: (e: MouseEvent) => void;
autocenter?: boolean;
beforeTouchStart?: (e: TouchEvent) => void;
/**
* @deprecated Use beforeTouchStart instead. Warning: this involves more than just a name change. Please read the documentation for details.
*/
onTouch?: (e: TouchEvent) => void;
beforeDoubleClick?: (e: Event) => void;
/**
* @deprecated Use beforeDoubleClick instead. Warning: this involves more than just a name change. Please read the documentation for details.
*/
onDoubleClick?: (e: Event) => void;

/**
Expand Down
Loading