Tracking de l'application VApp (IHM du jeu)
This commit is contained in:
104
VApp/node_modules/vuetify/lib/composables/touch.mjs
generated
vendored
Normal file
104
VApp/node_modules/vuetify/lib/composables/touch.mjs
generated
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
// Utilities
|
||||
import { CircularBuffer } from "../util/index.mjs";
|
||||
const HORIZON = 100; // ms
|
||||
const HISTORY = 20; // number of samples to keep
|
||||
|
||||
/** @see https://android.googlesource.com/platform/frameworks/native/+/master/libs/input/VelocityTracker.cpp */
|
||||
function kineticEnergyToVelocity(work) {
|
||||
const sqrt2 = 1.41421356237;
|
||||
return (work < 0 ? -1.0 : 1.0) * Math.sqrt(Math.abs(work)) * sqrt2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns pointer velocity in px/s
|
||||
*/
|
||||
export function calculateImpulseVelocity(samples) {
|
||||
// The input should be in reversed time order (most recent sample at index i=0)
|
||||
if (samples.length < 2) {
|
||||
// if 0 or 1 points, velocity is zero
|
||||
return 0;
|
||||
}
|
||||
// if (samples[1].t > samples[0].t) {
|
||||
// // Algorithm will still work, but not perfectly
|
||||
// consoleWarn('Samples provided to calculateImpulseVelocity in the wrong order')
|
||||
// }
|
||||
if (samples.length === 2) {
|
||||
// if 2 points, basic linear calculation
|
||||
if (samples[1].t === samples[0].t) {
|
||||
// consoleWarn(`Events have identical time stamps t=${samples[0].t}, setting velocity = 0`)
|
||||
return 0;
|
||||
}
|
||||
return (samples[1].d - samples[0].d) / (samples[1].t - samples[0].t);
|
||||
}
|
||||
// Guaranteed to have at least 3 points here
|
||||
// start with the oldest sample and go forward in time
|
||||
let work = 0;
|
||||
for (let i = samples.length - 1; i > 0; i--) {
|
||||
if (samples[i].t === samples[i - 1].t) {
|
||||
// consoleWarn(`Events have identical time stamps t=${samples[i].t}, skipping sample`)
|
||||
continue;
|
||||
}
|
||||
const vprev = kineticEnergyToVelocity(work); // v[i-1]
|
||||
const vcurr = (samples[i].d - samples[i - 1].d) / (samples[i].t - samples[i - 1].t); // v[i]
|
||||
work += (vcurr - vprev) * Math.abs(vcurr);
|
||||
if (i === samples.length - 1) {
|
||||
work *= 0.5;
|
||||
}
|
||||
}
|
||||
return kineticEnergyToVelocity(work) * 1000;
|
||||
}
|
||||
export function useVelocity() {
|
||||
const touches = {};
|
||||
function addMovement(e) {
|
||||
Array.from(e.changedTouches).forEach(touch => {
|
||||
const samples = touches[touch.identifier] ?? (touches[touch.identifier] = new CircularBuffer(HISTORY));
|
||||
samples.push([e.timeStamp, touch]);
|
||||
});
|
||||
}
|
||||
function endTouch(e) {
|
||||
Array.from(e.changedTouches).forEach(touch => {
|
||||
delete touches[touch.identifier];
|
||||
});
|
||||
}
|
||||
function getVelocity(id) {
|
||||
const samples = touches[id]?.values().reverse();
|
||||
if (!samples) {
|
||||
throw new Error(`No samples for touch id ${id}`);
|
||||
}
|
||||
const newest = samples[0];
|
||||
const x = [];
|
||||
const y = [];
|
||||
for (const val of samples) {
|
||||
if (newest[0] - val[0] > HORIZON) break;
|
||||
x.push({
|
||||
t: val[0],
|
||||
d: val[1].clientX
|
||||
});
|
||||
y.push({
|
||||
t: val[0],
|
||||
d: val[1].clientY
|
||||
});
|
||||
}
|
||||
return {
|
||||
x: calculateImpulseVelocity(x),
|
||||
y: calculateImpulseVelocity(y),
|
||||
get direction() {
|
||||
const {
|
||||
x,
|
||||
y
|
||||
} = this;
|
||||
const [absX, absY] = [Math.abs(x), Math.abs(y)];
|
||||
return absX > absY && x >= 0 ? 'right' : absX > absY && x <= 0 ? 'left' : absY > absX && y >= 0 ? 'down' : absY > absX && y <= 0 ? 'up' : oops();
|
||||
}
|
||||
};
|
||||
}
|
||||
return {
|
||||
addMovement,
|
||||
endTouch,
|
||||
getVelocity
|
||||
};
|
||||
}
|
||||
function oops() {
|
||||
throw new Error();
|
||||
}
|
||||
//# sourceMappingURL=touch.mjs.map
|
Reference in New Issue
Block a user