|
11 | 11 | *
|
12 | 12 | * @license EUPL-1.2
|
13 | 13 | * @licstart
|
14 |
| - * (c) 2000-2020 Educational Telematic Network of Catalonia (XTEC) |
| 14 | + * (c) 2000-2022 Educational Telematic Network of Catalonia (XTEC) |
15 | 15 | *
|
16 | 16 | * Licensed under the EUPL, Version 1.1 or -as soon they will be approved by
|
17 | 17 | * the European Commission- subsequent versions of the EUPL (the "Licence");
|
|
29 | 29 | * @module
|
30 | 30 | */
|
31 | 31 |
|
32 |
| -/* global JSON, Promise, location, window */ |
| 32 | +/* global JSON, Promise, location, window, document */ |
33 | 33 |
|
34 | 34 | import $ from 'jquery';
|
35 | 35 | import JSZip from 'jszip';
|
@@ -110,61 +110,82 @@ export class JClicPlayer extends Container {
|
110 | 110 | }
|
111 | 111 |
|
112 | 112 | /**
|
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 |
115 | 116 | */
|
116 | 117 | listenTouchEvents() {
|
117 | 118 |
|
118 | 119 | // 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 { |
132 | 152 | 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); |
148 | 166 | }
|
149 | 167 | startTouch = null;
|
150 |
| - break; |
151 |
| - |
152 |
| - default: |
| 168 | + } |
| 169 | + // Cancel double touch detection when long gestures detected |
| 170 | + else if (dist > minSwipeX) |
153 | 171 | startTouch = null;
|
154 |
| - break; |
155 |
| - } |
156 |
| - event.preventDefault(); |
| 172 | + break; |
| 173 | + |
| 174 | + case 'touchcancel': |
| 175 | + startTouch = null; |
| 176 | + break; |
157 | 177 | }
|
158 |
| - else |
159 |
| - // Cancel any started gesture |
160 |
| - startTouch = null; |
161 |
| - }; |
| 178 | + } |
| 179 | + else |
| 180 | + // Cancel any started gesture |
| 181 | + startTouch = null; |
| 182 | + }; |
162 | 183 |
|
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 | + //} |
168 | 189 | }
|
169 | 190 |
|
170 | 191 | /**
|
@@ -273,7 +294,6 @@ export class JClicPlayer extends Container {
|
273 | 294 | }
|
274 | 295 |
|
275 | 296 | /**
|
276 |
| - * |
277 | 297 | * Creates and initializes objects of type {@link module:AWT.Timer}
|
278 | 298 | */
|
279 | 299 | initTimers() {
|
@@ -1138,7 +1158,7 @@ Object.assign(JClicPlayer.prototype, {
|
1138 | 1158 | minSwipeX: 40,
|
1139 | 1159 | // Maximum vertical swipe length to be considered an activity change gesture
|
1140 | 1160 | 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) |
1142 | 1162 | rightToLeft: false,
|
1143 | 1163 | },
|
1144 | 1164 | /**
|
|
0 commit comments