204 votes

Simuler des tremblements (dus, par exemple, à la maladie de Parkinson) avec la souris sur une page Web ?

Je travaille pour une fondation qui sensibilise à l'accessibilité de l'internet. Pour une présentation, nous voulons offrir un petit atelier qui simule différents handicaps/incapacités aux gens. Cela se fait via un site web créé spécialement pour cette présentation.

L'une des déficiences démontrées est le tremblement, qui se traduit par des mouvements de main tremblants et difficiles à contrôler. Avec cette déficience, il est très difficile de déplacer le curseur de la souris avec précision et d'appuyer sur le bouton de la souris lorsque celle-ci se trouve sur un lien. Tant certaines personnes âgées que les personnes atteintes d'une maladie, par exemple la maladie de Parkinson, peuvent souffrir de tremblements.

J'aimerais maintenant déplacer le curseur de la souris d'une manière imprévisible, de sorte qu'il soit très difficile pour les gens de cliquer sur un petit bouton. Comme JavaScript ne permet pas de déplacer directement le curseur de la souris, je cherche d'autres moyens d'y parvenir. J'ai trouvé les idées suivantes :

  • Utilisation d'un pilote de souris / utilitaire qui simule le tremblement de la souris.
  • Masquez le curseur de la souris via CSS, placez une animation GIF d'un curseur de souris tremblant à la place du curseur original (avec JavaScript), puis faites en sorte que le lien cible ne soit cliquable que toutes les quelques secondes pendant une seconde environ. Cela donnerait au moins l'impression que l'on clique toujours au mauvais moment.

Alors que la première idée serait plutôt cool, je n'ai pas trouvé d'outil de ce type, que ce soit pour Mac ou pour Windows. Et je n'ai aucune compétence pour programmer moi-même une telle chose.

La deuxième idée semble un peu maladroite, mais elle permettrait d'obtenir l'effet désiré, je pense.

Quelqu'un a-t-il une autre idée ?

148voto

Aristocrates Points 1487

J'ai réalisé une démonstration rapide de quelque chose sur lequel vous devriez pouvoir baser votre code, en utilisant la fonction API de verrouillage de pointeur .

J'ai bifurqué ce repo de pointer-lock-demo et l'a modifié pour ajouter un élément de mouvement aléatoire.

Voici le lien vers ma page GitHub : https://aristocrates.github.io/pointer-lock-demo
Et voici le lien vers mon repo : https://github.com/aristocrates/pointer-lock-demo

Le code javascript important est contenu dans app.js dans le canvasLoop(e) méthode.

La seule chose que j'ai changée par rapport à la démo originale était après les lignes

x += movementX * 2;
y += movementY * 2;

J'ai ajouté deux lignes pour représenter le mouvement aléatoire :

x += Math.floor(Math.random()*3 - 1);
y += Math.floor(Math.random()*3 - 1);

Il y a encore beaucoup de choses que vous pouvez améliorer, mais nous espérons que cela vous aidera à démarrer.

36voto

Alma Do Points 23653

Méthode sans javascript

En fait, je préfère les solutions qui peuvent être basées sur le javascript, car elles sont plus susceptibles d'être liées au web, et il y a de bonnes chances qu'elles soient indépendantes du système d'exploitation. Cependant, j'ai réfléchi à la manière de résoudre votre problème pour tous les navigateurs, puisque les solutions javascript, dans ce cas, seront difficiles à adapter à tous les navigateurs possibles (je ne suis pas sûr que ce soit possible du tout).

Donc, comme vous l'avez mentionné, il y a une autre solution - c'est-à-dire émuler le comportement au niveau du système d'exploitation. Cela présente également un autre avantage : vous pouvez être sûr que pour le navigateur, le comportement est 100% identique à celui de l'homme (car c'est le pilote qui envoie le signal). Vous pouvez donc utiliser des solutions basées sur le pilote ou le dispositif avec n'importe quel navigateur (ou même lorsque javascript est désactivé).

Linux

Malheureusement, l'implication d'un pilote/dispositif entraîne immédiatement une dépendance du système d'exploitation. Ainsi, pour chaque système d'exploitation, vous aurez besoin de votre propre solution. Dans ce billet, je me concentre sur une solution basée sur Linux (donc, qui fonctionnera avec Linux) - et un peu sur Mac OS. Avec Linux, il est possible d'écrire des événements sur le périphérique explicitement, donc ci-dessous un exemple de fonction avec une boucle principale :

int main()
{
    struct input_event event, event_end;

    int  fd = open("/dev/input/event4", O_RDWR);
    long ma = getInteger("Enter max amplitude [points, 0..50]: ", 0, 50);
    long ta = getInteger("Enter max wait time [usecs , 0..200000]: ", 0, 200000);
    if (fd < 0)
    {
        printf("Mouse access attempt failed:%s\n", strerror(errno));
        return -1;
    }
    memset(&event, 0, sizeof(event));
    memset(&event, 0, sizeof(event_end));
    gettimeofday(&event.time, NULL);
    event.type = EV_REL;
    gettimeofday(&event_end.time, NULL);
    event_end.type = EV_SYN;
    event_end.code = SYN_REPORT;
    event_end.value = 0;
    while(1)
    {
        event.code  = rand() % 2 ? REL_X : REL_Y;
        event.value = (rand() % 2 ? -1 : 1) * randomTill(ma);
        write(fd, &event, sizeof(event));
        write(fd, &event_end, sizeof(event_end));
        usleep(randomTill(ta));
    }
    close(fd);
    return 0;
}

Mi code complet pour que la question soit trouvée aquí . Le programme demandera l'amplitude du "tremblement" et sa fréquence (c'est-à-dire le nombre de microsecondes entre les "tremblements"). Pour simuler la situation, il va forcer la souris à se déplacer de façon aléatoire pour 0..X points dans une direction aléatoire (haut-bas-gauche-bas) et attendre de façon aléatoire. 0..Y micro-secondes jusqu'au prochain "tremblement", il y a X est l'amplitude du "tremblement" et Y est la fréquence du "tremblement"

Une autre chose peut être d'adapter le programme à votre système. Le programme est "factice" et ne peut pas détecter la souris par lui-même, donc il faut l'adapter à votre système. "/dev/input/event4" est codée en dur. Pour réaliser ce qui peut être un identifiant pour votre système, vous pouvez essayer :

user@host:/path$ cat /proc/bus/input/devices | grep mouse
H: Handlers=mouse0 event3 
H: Handlers=mouse1 event4

Et donc les possibilités sont "event3" y "event4" - mais pour votre système cela peut avoir d'autres valeurs. Donc, si cela est différent de ce qui est actuellement utilisé dans le code C, il suffit de changer la ligne correspondante (ainsi, la ligne avec int fd = open("/dev/input/event4", O_RDWR); et placez votre appareil à la place de event4 )

Une démo en gif pour ce programme (la fréquence d'images est faible, malheureusement, donc l'image ne doit pas être trop grande). aquí .

Une petite note complémentaire (si vous ne savez pas quoi faire avec du code C) - pour compiler le programme ci-dessus, il suffit d'utiliser :

user@host:/path$ gcc -std=gnu99 file.c -o m

file.c est le nom de votre fichier de code source C, alors vous obtiendrez un exécutable, appelé m dans votre répertoire. Le plus souvent, vous aurez besoin de permissions pour écrire directement dans le périphérique de la souris, donc vous pouvez utiliser sudo :

user@host:/path$ sudo ./m

Autres OS

La logique restera la même :

  • Trouvez un moyen d'accéder au périphérique de votre souris
  • Écriture de l'événement de déplacement de la souris
  • Appliquer la randomisation à votre événement

C'est tout. Par exemple, Mac OS a sa propre façon de travailler avec la souris (contrairement à Linux, Mac n'a pas d'interface avec la souris). procfs également), il est bien décrit aquí .

En guise de conclusion

C'est à vous de décider ce qui est le mieux - javascript ou des solutions orientées vers les dispositifs - car certaines conditions (comme le croisement des navigateurs ou des systèmes d'exploitation) peuvent tout décider dans ce cas. Par conséquent, j'ai fourni des lignes directrices ainsi que certains exemples de travail sur la façon de mettre en œuvre cette solution au niveau du système d'exploitation. L'avantage ici est que la solution est multi-navigateurs, mais le prix à payer est un programme lié au système d'exploitation.

23voto

technosaurus Points 1980

J'ai fait ça comme une blague une fois, sur le Forum Puppy Linux et j'ai reçu le commentaire suivant :

Les personnes atteintes de la maladie de Parkinson ne trouveront pas ça drôle ! !!

Le remède ici est simplement cntrl-C, heureusement.

Voici le shell script qui requiert xdotool

#!/bin/sh
while :; do
   xdotool mousemove_relative -- -$(($RANDOM % 10)) $(($RANDOM % 10))
   xdotool mousemove_relative -- $(($RANDOM % 10)) -$(($RANDOM % 10))
   sleep ${1:-.1} #adjust this as necessary for effect
done

Nommé parkinson_sim et exécuté avec un argument facultatif pour le temps entre les tremblements qui peut être de 0,001 à 999,0.

parkinson_sim [time_between_tremors_in_seconds] #par défaut 0.1

J'ai fait l'erreur de cliquer moi-même dessus au lieu de l'exécuter depuis la ligne de commande et j'ai rapidement découvert à quel point cela devait être frustrant. Il m'a fallu plusieurs tentatives pour ouvrir une fenêtre de terminal et l'arrêter.

16voto

Ben Mosher Points 5005

Votre deuxième idée (masquer le curseur) est à mi-chemin d'une idée qui, à mon avis, pourrait bien fonctionner pour vous :

  • Masquez le curseur de la souris via CSS, comme vous le suggérez. ( cursor:none IIRC)
  • Au lieu d'un GIF au curseur instable, utilisez une image + un positionnement absolu CSS + un JS pour émuler le pointeur de la souris ; autrement dit, suivez la souris sur la page et placez l'image du curseur à l'endroit où le curseur de la souris se trouverait nativement.

Ensuite, vous ajoutez des mathématiques de tremblement à votre code de curseur, pour "secouer" le curseur. C'est à vous de déterminer quelles sont les bonnes courbes pour simuler correctement les tremblements.

Enfin, pour les contrôles que vous programmez (liens, etc.) :

  • capturent les événements de clic, les déplacent vers l'emplacement actuel du "tremblement" en fonction de l'état de vos courbes de tremblement, et vérifient les limites de vos éléments pour voir si l'utilisateur est sorti de l'élément prévu, ou éventuellement dans un élément qui n'était pas prévu.

Un atout majeur avec cette mise en œuvre : votre "curseur tremblant" sera affiché sur des appareils tactiles qui n'auraient pas de curseur au départ.


Editar:

En se basant sur le JSFiddle de base de Michael Theriot (très propre et très utile !) dans les commentaires, en voici un qui tremble constamment avec un balayage normalement distribué autour de l'emplacement actuel du curseur : http://jsfiddle.net/benmosher/0x4mc64v/4/

(Le normal est le résultat de l'appel à rnorm(100) dans ma console R. La manière la plus simple à laquelle j'ai pensé en JS pour échantillonner un entier aléatoire normalement distribué).

14voto

user3934260 Points 141

Juste une idée pour obtenir le tremblement "correct", vous pouvez enregistrer le mouvement de la souris d'un vrai patient, ce qui le rend plus authentique lorsque vous dites aux gens d'où proviennent les données.

Il existe des scripts pour qu'un chat suive le curseur de votre souris, vous pourriez en ajuster un pour qu'un second curseur suive (saute autour) de votre curseur. La page calcule la position du second curseur, de sorte qu'elle peut également déterminer si un événement de clic est réussi ou non.

Si vous le pouvez, faites en sorte qu'il soit basé sur le web, vous toucherez beaucoup plus de personnes de cette manière que si vous leur demandez d'installer un programme ou d'activer Flash ou quoi que ce soit d'autre.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X