在网页上使用鼠标模拟震颤(例如帕金森病)?

我正在为一个基金会工作,该基金会旨在提高人们对互联网可访问性的认识。对于演示,我们希望提供一个小型研讨会,模拟人们的不同残疾/障碍。这是通过专门为此演示文稿创建的网站完成的。

其中一个被证明的障碍是震颤,这意味着经历摇晃,难以控制的手部运动。有了这种损伤,很难精确地移动鼠标光标,并在鼠标悬停在链接上时按下鼠标按钮。一些老年人和患有疾病的人,例如帕金森氏症,都可能患有震颤。

现在我想以某种方式以一种不可预测的方式移动鼠标光标,这样人们就很难点击一个小按钮。因为JavaScript不允许直接移动鼠标光标,所以我正在寻找其他方法来实现这一目标。我想出了以下想法:

  • 使用模拟鼠标抖动的鼠标驱动程序/实用程序。
  • 通过CSS隐藏鼠标光标,将摇晃的鼠标光标的GIF动画放在原始光标的位置(使用JavaScript),然后使目标链接每隔几秒钟可单击一秒钟左右。这至少会让人感觉好像总是在错误的时刻点击。

虽然第一个想法会很酷,但我找不到这样的工具,无论是Mac还是Windows。我自己也没有任何编程这样的技能。

第二个想法似乎有点笨拙,但我认为它会达到预期的效果。

有人有其他想法吗?


答案 1

我使用指针锁定 API 快速演示了一些希望能够基于代码的内容。

我分叉了这个指针锁演示存储库,并对其进行了修改以添加随机移动元素。

这是我的GitHub页面的链接:https://aristocrates.github.io/pointer-lock-demo
这是我的存储库的链接:https://github.com/aristocrates/pointer-lock-demo

重要的 javascript 代码包含在 方法的 中。app.jscanvasLoop(e)

我与原始演示相比唯一更改的是行之后

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

我添加了两行来表示随机移动:

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

你还有很多东西可以改进,但希望这可以帮助你入门。


答案 2

非javascript方式

实际上,我喜欢可能基于javascript的解决方案,因为它们更有可能与Web相关,并且很有可能 - 独立于操作系统。但是,我正在考虑 - 如何解决所有浏览器的问题,因为在这种情况下,javascript解决方案将很难针对所有可能的浏览器进行调整(我不确定这是否可能)。

因此,正如您所提到的,还有另一种方法 - 即在操作系统级别上模拟行为。这还有另一个优点 - 你可以肯定,对于浏览器来说,它看起来100%就像人类一样(因为,好吧,它是发送信号的驱动程序)。因此,您可以将基于驱动程序/设备的解决方案与任何浏览器一起使用(甚至在禁用javascript的情况下)。

Linux

不幸的是,涉及驱动程序/设备会立即导致操作系统依赖性。因此,对于每个操作系统,您都需要自己的解决方案。在这篇文章中,我专注于基于Linux的解决方案(因此,将与Linux一起使用) - 以及Mac OS。使用Linux,可以将事件显式写入设备,因此下面是具有主循环的函数示例:

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;
}

的问题的完整代码可以在这里找到。该程序将要求“震颤”的振幅及其频率(因此,“震颤”之间有多少时间(以微秒为单位)。为了模拟情况,它会迫使鼠标随机移动随机方向(上-下-左-下-下)的点,并随机等待微秒,直到下一个“震颤”,有“震颤”的幅度和“震颤”的频率0..X0..YXY

另一件事可能是根据您的系统调整程序。该程序是“虚拟的”,本身无法检测到鼠标,因此是硬编码的。要了解您的系统标识符,您可以尝试:"/dev/input/event4"

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

因此,可能性是和 - 但对于您的系统来说,可能还有其他值。因此,如果这与C代码中当前使用的行不同,只需更改相应的行(因此,与设备一起行并放置设备,而不是"event3""event4"int fd = open("/dev/input/event4", O_RDWR);event4)

这个程序的gif演示(不幸的是,低帧率,所以保持图像不要太大)。

一个小小的旁注(如果你不知道如何处理C代码) - 要编译上面的程序,只需使用:

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

其中 是你的C源代码文件的名称,然后你会得到可执行文件,在你的目录中调用。最有可能的是,您需要权限才能直接写入鼠标设备,因此您可以使用:file.cmsudo

user@host:/path$ sudo ./m

其他操作系统

逻辑将保持不变:

  • 查找访问鼠标设备的方法
  • 移动鼠标的写入事件
  • 将随机化应用于您的活动

就是这样。例如,Mac OS有自己的鼠标工作方式(不像Linux,Mac也没有procfs),这里有很好的描述。

作为结论

更好的是什么 - javascript或面向设备的解决方案 - 取决于你,因为在这种情况下,某些条件(如跨浏览器或跨操作系统)可能会决定一切。因此,我提供了有关如何在操作系统级别实现该指南的某些工作示例。这里的好处是解决方案是跨浏览器的,但作为成本,我们有操作系统绑定的程序。