Skip to content

Commit 3505f9c

Browse files
committed
✨ Detect double touch gesture
1 parent c2dbaf9 commit 3505f9c

File tree

3 files changed

+73
-52
lines changed

3 files changed

+73
-52
lines changed

CHANGELOG.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
### v2.1.11 (2022-08-03)
1+
### v2.1.11 (2022-08-04)
22
#### Improvements
33
- Upgraded dependencies
4-
- Detect swipe gestures on touch devices to go back or forward in the sequence of activities.
4+
- Detect swipe gestures on touch devices to go back or forward in the sequence of activities.
5+
- Toggle full screen with "double touch" gesture.
56

67
### v2.1.10 (2022-03-15)
78
#### Bug fixes

src/JClicPlayer.js

Lines changed: 69 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
* @license EUPL-1.2
1313
* @licstart
14-
* (c) 2000-2020 Educational Telematic Network of Catalonia (XTEC)
14+
* (c) 2000-2022 Educational Telematic Network of Catalonia (XTEC)
1515
*
1616
* Licensed under the EUPL, Version 1.1 or -as soon they will be approved by
1717
* the European Commission- subsequent versions of the EUPL (the "Licence");
@@ -29,7 +29,7 @@
2929
* @module
3030
*/
3131

32-
/* global JSON, Promise, location, window */
32+
/* global JSON, Promise, location, window, document */
3333

3434
import $ from 'jquery';
3535
import JSZip from 'jszip';
@@ -110,61 +110,82 @@ export class JClicPlayer extends Container {
110110
}
111111

112112
/**
113-
* Detects swipe-right and swipe-left gestures on touch devices,
114-
* and associates them with 'next activity' and 'prev activity' actions
113+
*
114+
* Detects swipe-right, swipe-left and double touch gestures on touch devices,
115+
* associating them with 'next activity', 'previous activity' and 'toggle full screen' actions
115116
*/
116117
listenTouchEvents() {
117118

118119
// Enable listeners only in touch devices
119-
if ('ontouchstart' in window) {
120-
121-
let startTouch = null;
122-
let thisDiv = this.$div[0];
123-
const { minSwipeX, maxSwipeY, rightToLeft } = this.options;
124-
125-
// Generic handler for touch events
126-
const touchEventHandler = event => {
127-
// Process only single-finger events targeted to our main 'div'
128-
if (event.target === thisDiv && event.changedTouches && event.changedTouches.length === 1) {
129-
const touch = event.changedTouches[0];
130-
switch (event.type) {
131-
case 'touchstart':
120+
//if ('ontouchstart' in window) {
121+
122+
let startTouch = null;
123+
let startTouchTime = 0;
124+
let thisDiv = this.$div[0];
125+
const { minSwipeX, maxSwipeY, rightToLeft } = this.options;
126+
127+
// Generic handler for touch events
128+
const touchEventHandler = event => {
129+
// Process only single-finger events targeted to our main 'div'
130+
if (event.target === thisDiv && event.changedTouches && event.changedTouches.length === 1) {
131+
const touch = event.changedTouches[0];
132+
const dx = startTouch ? touch.clientX - startTouch.clientX : 0;
133+
const dy = startTouch ? touch.clientY - startTouch.clientY : 0;
134+
const dist = Math.sqrt(dx * dx + dy * dy);
135+
136+
switch (event.type) {
137+
case 'touchstart':
138+
const currentTime = new Date();
139+
// Detect double taps, done in less than 800 ms and at short distance
140+
if (
141+
document && document.fullscreenEnabled
142+
&& startTouch && startTouchTime
143+
&& currentTime - startTouchTime < 800
144+
&& dist < minSwipeX
145+
) {
146+
event.preventDefault();
147+
log('info', 'Toggle full screen mode from double touch');
148+
this.skin.setScreenFull();
149+
startTouch = null;
150+
}
151+
else {
132152
startTouch = touch;
133-
break;
134-
135-
case 'touchend':
136-
if (touch && startTouch) {
137-
// Get touch distances, and discard non true and significant horizontal gestures
138-
const dx = touch.clientX - startTouch.clientX;
139-
const dy = touch.clientY - startTouch.clientY;
140-
if (Math.abs(dx) > minSwipeX && Math.abs(dy) < maxSwipeY) {
141-
const actionName = dx < 0 && !rightToLeft ? 'next' : 'prev';
142-
const action = this.actions[actionName];
143-
if (action && action.enabled) {
144-
log('info', `Performing action "${actionName}" from touch gesture`);
145-
action.actionPerformed(event);
146-
}
147-
}
153+
startTouchTime = currentTime;
154+
}
155+
break;
156+
157+
case 'touchend':
158+
// Discard non-horizontal gestures and those that do not have sufficient length
159+
if (startTouch && Math.abs(dx) > minSwipeX && Math.abs(dy) < maxSwipeY) {
160+
const actionName = dx < 0 && !rightToLeft ? 'next' : 'prev';
161+
const action = this.actions[actionName];
162+
if (action && action.enabled) {
163+
event.preventDefault();
164+
log('info', `Performing action "${actionName}" from touch gesture`);
165+
action.actionPerformed(event);
148166
}
149167
startTouch = null;
150-
break;
151-
152-
default:
168+
}
169+
// Cancel double touch detection when long gestures detected
170+
else if (dist > minSwipeX)
153171
startTouch = null;
154-
break;
155-
}
156-
event.preventDefault();
172+
break;
173+
174+
case 'touchcancel':
175+
startTouch = null;
176+
break;
157177
}
158-
else
159-
// Cancel any started gesture
160-
startTouch = null;
161-
};
178+
}
179+
else
180+
// Cancel any started gesture
181+
startTouch = null;
182+
};
162183

163-
// Handle touch events
164-
thisDiv.addEventListener('touchstart', touchEventHandler);
165-
thisDiv.addEventListener('touchend', touchEventHandler);
166-
thisDiv.addEventListener('touchcancel', touchEventHandler);
167-
}
184+
// Handle touch events
185+
thisDiv.addEventListener('touchstart', touchEventHandler);
186+
thisDiv.addEventListener('touchend', touchEventHandler);
187+
thisDiv.addEventListener('touchcancel', touchEventHandler);
188+
//}
168189
}
169190

170191
/**
@@ -273,7 +294,6 @@ export class JClicPlayer extends Container {
273294
}
274295

275296
/**
276-
*
277297
* Creates and initializes objects of type {@link module:AWT.Timer}
278298
*/
279299
initTimers() {
@@ -1138,7 +1158,7 @@ Object.assign(JClicPlayer.prototype, {
11381158
minSwipeX: 40,
11391159
// Maximum vertical swipe length to be considered an activity change gesture
11401160
maxSwipeY: 100,
1141-
// Read swipe gestures as in right-to-left languages (default is left-to-right)
1161+
// Read swipe gestures as in right-to-left languages (default is left-to-right)
11421162
rightToLeft: false,
11431163
},
11441164
/**

src/skins/Skin.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,7 @@ export class Skin extends Container {
699699
* @returns {boolean} `true` if the request was successful, `false` otherwise.
700700
*/
701701
setScreenFull(status) {
702-
if (document && document && document.fullscreenEnabled && (
702+
if (document && document.fullscreenEnabled && (
703703
status === true && !document.fullscreenElement ||
704704
status === false && !document.fullscreenElement ||
705705
status !== true && status !== false)) {

0 commit comments

Comments
 (0)