aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/Touchable.tsx
diff options
context:
space:
mode:
authorStanley Yip <stanley_yip@brown.edu>2020-01-14 18:35:28 -0500
committerStanley Yip <stanley_yip@brown.edu>2020-01-14 18:35:28 -0500
commitde0c00ff0bb1f58a0736da24acc984f5a090d009 (patch)
tree5ebcb516b6197a44f2bf6b64325583d24c86bd59 /src/client/views/Touchable.tsx
parent75d5b58ef99a80ca2b2823a7836b96a2b574f9f5 (diff)
ok we now use custom events for touch. im struggling with figuring out how to ignore a hand lol
Diffstat (limited to 'src/client/views/Touchable.tsx')
-rw-r--r--src/client/views/Touchable.tsx114
1 files changed, 78 insertions, 36 deletions
diff --git a/src/client/views/Touchable.tsx b/src/client/views/Touchable.tsx
index 2a7599fbf..a71015b05 100644
--- a/src/client/views/Touchable.tsx
+++ b/src/client/views/Touchable.tsx
@@ -8,8 +8,11 @@ const HOLD_DURATION = 1000;
export abstract class Touchable<T = {}> extends React.Component<T> {
//private holdTimer: NodeJS.Timeout | undefined;
- holdTimer: NodeJS.Timeout | undefined;
+ private holdTimer: NodeJS.Timeout | undefined;
+ private moveDisposer?: InteractionUtils.MultiTouchEventDisposer;
+ private endDisposer?: InteractionUtils.MultiTouchEventDisposer;
+ protected abstract multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer;
protected _touchDrag: boolean = false;
protected prevPoints: Map<number, React.Touch> = new Map<number, React.Touch>();
@@ -22,16 +25,27 @@ export abstract class Touchable<T = {}> extends React.Component<T> {
* When a touch even starts, we keep track of each touch that is associated with that event
*/
@action
- protected onTouchStart = (e: React.TouchEvent): void => {
+ protected onTouchStart = (e: Event, me: InteractionUtils.MultiTouchEvent<React.TouchEvent>): void => {
const actualPts: React.Touch[] = [];
- for (let i = 0; i < e.targetTouches.length; i++) {
- const pt: any = e.targetTouches.item(i);
+ const te = me.touchEvent;
+ // loop through all touches on screen
+ for (let i = 0; i < te.touches.length; i++) {
+ const pt: any = te.touches.item(i);
actualPts.push(pt);
- // pen is also a touch, but with a radius of 0.5 (at least with the surface pens)
- // and this seems to be the only way of differentiating pen and touch on touch events
- if (pt.radiusX > 1 && pt.radiusY > 1) {
+ if (this.prevPoints.has(pt.identifier)) {
this.prevPoints.set(pt.identifier, pt);
}
+ // only add the ones that are targeted on "this" element, but with the identifier that the screen touch gives
+ for (let j = 0; j < te.changedTouches.length; j++) {
+ const tPt = te.changedTouches.item(j);
+ if (pt.clientX === tPt.clientX && pt.clientY === tPt.clientY) {
+ // pen is also a touch, but with a radius of 0.5 (at least with the surface pens)
+ // and this seems to be the only way of differentiating pen and touch on touch events
+ if (pt.radiusX > 1 && pt.radiusY > 1) {
+ this.prevPoints.set(pt.identifier, pt);
+ }
+ }
+ }
}
const ptsToDelete: number[] = [];
@@ -41,26 +55,30 @@ export abstract class Touchable<T = {}> extends React.Component<T> {
}
});
+ // console.log(ptsToDelete.length);
ptsToDelete.forEach(pt => this.prevPoints.delete(pt));
+ // console.log(this.prevPoints.size);
if (this.prevPoints.size) {
switch (this.prevPoints.size) {
case 1:
- this.handle1PointerDown(e);
- e.persist();
+ this.handle1PointerDown(te);
+ te.persist();
// if (this.holdTimer) {
// clearTimeout(this.holdTimer)
// this.holdTimer = undefined;
// }
- this.holdTimer = setTimeout(() => this.handle1PointerHoldStart(e), HOLD_DURATION);
+ this.holdTimer = setTimeout(() => this.handle1PointerHoldStart(te), HOLD_DURATION);
+ // e.stopPropagation();
// console.log(this.holdTimer);
break;
case 2:
- this.handle2PointersDown(e);
- break;
- case 5:
- this.handleHandDown(e);
+ this.handle2PointersDown(te);
+ // e.stopPropagation();
break;
+ // case 5:
+ // this.handleHandDown(te);
+ // break;
}
}
}
@@ -69,28 +87,30 @@ export abstract class Touchable<T = {}> extends React.Component<T> {
* Handle touch move event
*/
@action
- protected onTouch = (e: TouchEvent): void => {
- const myTouches = InteractionUtils.GetMyTargetTouches(e, this.prevPoints, true);
+ protected onTouch = (e: Event, me: InteractionUtils.MultiTouchEvent<TouchEvent>): void => {
+ const te = me.touchEvent;
+ const myTouches = InteractionUtils.GetMyTargetTouches(te, this.prevPoints, true);
// if we're not actually moving a lot, don't consider it as dragging yet
if (!InteractionUtils.IsDragging(this.prevPoints, myTouches, 5) && !this._touchDrag) return;
this._touchDrag = true;
if (this.holdTimer) {
- console.log("CLEAR")
+ console.log("CLEAR");
clearTimeout(this.holdTimer);
// this.holdTimer = undefined;
}
+ // console.log(myTouches.length);
switch (myTouches.length) {
case 1:
- this.handle1PointerMove(e);
+ this.handle1PointerMove(te);
break;
case 2:
- this.handle2PointersMove(e);
+ this.handle2PointersMove(te);
break;
}
- for (let i = 0; i < e.targetTouches.length; i++) {
- const pt = e.targetTouches.item(i);
+ for (let i = 0; i < te.touches.length; i++) {
+ const pt = te.touches.item(i);
if (pt) {
if (this.prevPoints.has(pt.identifier)) {
this.prevPoints.set(pt.identifier, pt);
@@ -100,11 +120,12 @@ export abstract class Touchable<T = {}> extends React.Component<T> {
}
@action
- protected onTouchEnd = (e: TouchEvent): void => {
+ protected onTouchEnd = (e: Event, me: InteractionUtils.MultiTouchEvent<TouchEvent>): void => {
// console.log(InteractionUtils.GetMyTargetTouches(e, this.prevPoints).length + " up");
// remove all the touches associated with the event
- for (let i = 0; i < e.changedTouches.length; i++) {
- const pt = e.changedTouches.item(i);
+ const te = me.touchEvent;
+ for (let i = 0; i < te.changedTouches.length; i++) {
+ const pt = te.changedTouches.item(i);
if (pt) {
if (this.prevPoints.has(pt.identifier)) {
this.prevPoints.delete(pt.identifier);
@@ -116,7 +137,7 @@ export abstract class Touchable<T = {}> extends React.Component<T> {
console.log("clear");
}
this._touchDrag = false;
- e.stopPropagation();
+ te.stopPropagation();
// if (e.targetTouches.length === 0) {
@@ -126,11 +147,12 @@ export abstract class Touchable<T = {}> extends React.Component<T> {
if (this.prevPoints.size === 0) {
this.cleanUpInteractions();
}
+ e.stopPropagation();
}
cleanUpInteractions = (): void => {
- document.removeEventListener("touchmove", this.onTouch);
- document.removeEventListener("touchend", this.onTouchEnd);
+ this.removeMoveListeners();
+ this.removeEndListeners();
}
handle1PointerMove = (e: TouchEvent): any => {
@@ -144,23 +166,43 @@ export abstract class Touchable<T = {}> extends React.Component<T> {
}
handle1PointerDown = (e: React.TouchEvent): any => {
- document.removeEventListener("touchmove", this.onTouch);
- document.addEventListener("touchmove", this.onTouch);
- document.removeEventListener("touchend", this.onTouchEnd);
- document.addEventListener("touchend", this.onTouchEnd);
+ this.removeMoveListeners();
+ this.addMoveListeners();
+ this.removeEndListeners();
+ this.addEndListeners();
}
handle2PointersDown = (e: React.TouchEvent): any => {
- document.removeEventListener("touchmove", this.onTouch);
- document.addEventListener("touchmove", this.onTouch);
- document.removeEventListener("touchend", this.onTouchEnd);
- document.addEventListener("touchend", this.onTouchEnd);
+ this.removeMoveListeners();
+ this.addMoveListeners();
+ this.removeEndListeners();
+ this.addEndListeners();
}
handle1PointerHoldStart = (e: React.TouchEvent): any => {
e.stopPropagation();
e.preventDefault();
- document.removeEventListener("touchmove", this.onTouch);
+ this.removeMoveListeners();
+ }
+
+ addMoveListeners = () => {
+ const handler = (e: Event) => this.onTouch(e, (e as CustomEvent<InteractionUtils.MultiTouchEvent<TouchEvent>>).detail);
+ document.addEventListener("dashOnTouchMove", handler);
+ this.moveDisposer = () => document.removeEventListener("dashOnTouchMove", handler);
+ }
+
+ removeMoveListeners = () => {
+ this.moveDisposer && this.moveDisposer();
+ }
+
+ addEndListeners = () => {
+ const handler = (e: Event) => this.onTouchEnd(e, (e as CustomEvent<InteractionUtils.MultiTouchEvent<TouchEvent>>).detail);
+ document.addEventListener("dashOnTouchEnd", handler);
+ this.endDisposer = () => document.removeEventListener("dashOnTouchEnd", handler);
+ }
+
+ removeEndListeners = () => {
+ this.endDisposer && this.endDisposer();
}
handleHandDown = (e: React.TouchEvent) => {