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

Jos*_*eim 204 html javascript css simulation accessibility

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

其中一个显示的损伤是震颤,这意味着经历摇晃,难以控制的手部动作.由于这种损伤,当鼠标悬停在链接上时,很难准确地移动鼠标光标并按下鼠标按钮.一些老年人和患有疾病的人,例如帕金森氏症,都可能患有震颤.

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

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

虽然第一个想法很酷,但我无法找到像这样的工具,无论是Mac还是Windows.我自己编程这样的东西没有任何技巧.

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

有人有另一个想法吗?

Ari*_*tes 148

我使用指针锁API快速演示了一些你希望能够基于代码的东西.

我分叉了这个指针锁定演示仓库并修改它以添加随机运动元素.

这是我的GitHub页面的链接:https://aristocrates.github.io/pointer-lock-demo
这里是我的回购链接:https://github.com/aristocrates/pointer-lock-demo

重要的JavaScript代码包含在app.js,在canvasLoop(e)方法.

我从原始演示中改变的唯一一件事是在线后

x += movementX * 2;
y += movementY * 2;
Run Code Online (Sandbox Code Playgroud)

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

x += Math.floor(Math.random()*3 - 1);
y += Math.floor(Math.random()*3 - 1);
Run Code Online (Sandbox Code Playgroud)

还有很多东西你可以改进,但希望这可以帮助你开始.

  • 作为功​​能中的注释,随机移动与握手不同.随机移动,指针可以在屏幕上漂移.握手时,指针会围绕中心点振动. (36认同)
  • 更现实的实现将跟踪光标的"真实"位置并在其周围的圆圈内随机移动,但这可能过于复杂. (8认同)
  • 值得注意的是,浏览器对指针锁Api的支持并不是很好 - 这在Internet Explorer或Safari中不起作用. (5认同)
  • 我没有时间自己尝试一下,但也许你知道这一点:指针锁API是否也能在画布外工作?还是仅限于画布? (3认同)

Alm*_* Do 36

非JavaScript方式

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

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

Linux的

不幸的是,涉及驱动程序/设备会立即导致OS依赖 因此对于每个操作系统,您都需要自己的解决方案 在这篇文章中,我专注于基于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;
}
Run Code Online (Sandbox Code Playgroud)

我可以在此处找到该问题的完整代码.该程序将询问"震颤"的幅度及其频率(因此,在"震颤"之间以微秒为单位的时间).为了模拟情况,它将强制鼠标随机移动点随机方向(上下左下)并随机微秒等待直到下一个"震颤",有"震颤"的振幅并且是"震颤" 的频率"0..X0..YXY

另一件事可能是为您的系统调整程序.该程序是"虚拟的",无法自行检测鼠标,因此"/dev/input/event4"是硬编码的.要实现您的系统的标识符,您可以尝试:

user@host:/path$ cat /proc/bus/input/devices | grep mouse
H: Handlers=mouse0 event3 
H: Handlers=mouse1 event4
Run Code Online (Sandbox Code Playgroud)

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

对这一计划的一个GIF演示(低帧频,遗憾的是,保持图像不是太大)这里.

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

user@host:/path$ gcc -std=gnu99 file.c -o m
Run Code Online (Sandbox Code Playgroud)

file.c您的C源代码文件的名称在哪里,然后您将获得可执行文件,m在您的目录中调用.您很可能需要直接写入鼠标设备的权限,因此您可以使用sudo:

user@host:/path$ sudo ./m
Run Code Online (Sandbox Code Playgroud)

其他OS

逻辑将保持不变:

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

而已.例如,Mac OS有自己的方式使用鼠标(不像Linux,Mac也不procfs一样),这里有很好的描述.

作为结论

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

  • 你怎么会在触摸屏设备上展示摇摇欲坠的鼠标? (53认同)
  • @Davor老实说,我非常怀疑*实际上有震颤/颤抖手的人会使用*触控设备*,除非他们故意让自己疯狂. (6认同)
  • @ChrisCirefice:或者被迫,因为他们必须使用那里的大量设备之一,这些设备旨在让我们的生活更美好并使用触摸屏...记住这是为了提高人们对这些人遇到问题的认识那. (2认同)

tec*_*rus 23

我在Puppy Linux论坛上做了一次这样的笑话并得到了评论:

患有帕金森症的人不会认为这很有趣!

这里的治疗简直就是cntrl-C,幸运的是.

这是需要xdotool的shell脚本

#!/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
Run Code Online (Sandbox Code Playgroud)

命名为parkinson_sim并使用可选参数运行震颤之间的时间,可以是0.001到999.0.

parkinson_sim [time_between_tremors_in_seconds] #default为0.1

我自己错误地点击它而不是从命令行运行它,并很快发现它一定是多么令人沮丧.我花了好几次尝试让一个终端窗口打开来杀死它.


Ben*_*her 16

你的第二个想法(隐藏光标)是我觉得可能适合你的那个想法的一半:

  • 正如您的建议,通过CSS隐藏鼠标光标.(cursor:noneIIRC)
  • 而不是抖动光标GIF,使用一些图像+ CSS绝对定位+ JS来模拟鼠标指针; 即,在页面上按下鼠标并将光标图像植入鼠标光标本身所在的位置.

然后,在光标代码中添加一些震颤数学,以"摇动"光标.由您决定正确模拟震颤输入的正确曲线.

最后:对于你正在编程的任何控件(链接等):

  • 捕获单击事件,根据震颤曲线的状态将它们移动到当前的"震颤"位置,然后检查元素以查看用户是否已从预期的元素中抖动,或者可能进入非预期的元素.

这种实现的一个主要好处是:你的"抖动光标"将显示在触摸设备上,而光标设备上没有光标.


编辑:

基于Michael Theriot(非常干净且乐于助人!)的基础JSFiddle来自评论,这里是一个不断颤抖的正常分布式扫描当前光标位置:http://jsfiddle.net/benmosher/0x4mc64v/4/

(该normal数组是rnorm(100)在我的R控制台中调用的结果.我可以在JS中想到最简单的方法来采样正态分布的随机整数.)


小智 14

只是让震颤"正确"的想法,您可以记录真实患者的鼠标移动,这使您在告诉人们数据来源时更加真实.

有一个让猫跟随你的鼠标光标的脚本,你可以调整一个让第二个光标跟随(跳转)你的光标.页面正在计算第二个光标的位置,因此它还可以确定点击事件是否成功.

如果可以,请以网络为基础,通过这种方式,您将获得更多人,而不是要求他们安装程序或激活闪存或其他任何东西.


chu*_*e x 10

您可以移动应用程序(网页),而不是尝试移动指针.我写了一个简单的html表单,里面有一些输入字段.将鼠标移动到表单上时,表单会移动.

您可以在jsfiddle上看到移动表单的演示.尝试单击其中一个输入字段以查看效果.

我使用jquery 摇动效果来实现这一目标.摇动效果的javascript看起来像这样,只要鼠标移过它就会使表单上下移动:

<script type="text/javascript">
    $(document).ready(function() {
        $("#toggle").hover(function () {
            $(this).effect("shake", { direction: "up", times: 1, distance: 40}, 1000);
        });
    });
</script>
Run Code Online (Sandbox Code Playgroud)

虽然表单只是上下移动,但我认为它具有预期的效果.您可以使用参数(方向,时间,距离以及上面未命名的"1000")来调整表单移动.

  • 我自己也考虑过这一点,但是虽然它更容易实现,但它并没有显示震颤的"真实"体验. (3认同)

Nza*_*all 10

为什么不使用硬件解决方案?有一些老鼠,你可以放入重量,如罗技G500.而不是增加重量,放入一个小型摆动马达,使鼠标轻微摇晃.这也更模拟了实际的障碍:它不仅仅是光标抖动,而是整个手和鼠标.它还意味着您可以显示除网站之外的其他软件.

而不是带有重量槽的鼠标,您也可以只是将某些东西粘贴到鼠标上,但这更加引人注目.


Pau*_*her 6

当您考虑使用自定义鼠标驱动程序时,我想在PC上运行的一个小程序可以做到吗?如果是这种情况,这里有一个C#的小片段,它可以无限地移动光标,当前光标位置周围的范围为正负5px.每次移位后,程序等待50 ms到100 ms(不准确!).可以通过调整位移和暂停的值来配置抖动.我在一个控制台应用程序中运行它 - 根据值 - 它让我很难停止程序.

Random rand = new Random();

while(true)
{
    Cursor.Position = new Point() { X = Cursor.Position.X + rand.Next(11)-5, Y = Cursor.Position.Y + rand.Next(11)-5 };
    Thread.Sleep(rand.Next(50) + 50);
}
Run Code Online (Sandbox Code Playgroud)


tec*_*rus 6

这是我的xdotool脚本的Windows版本,它使用AutoIt.这是我的第一个AutoIt脚本,编写只花了几分钟,所以我确信它可以改进.只需使用扩展名.au3保存并使用AutoIt(运行脚本x86)运行它.

HotKeySet("{HOME}", "GStart")
HotKeySet("{PAUSE}", "Gpause")
HotKeySet("{ESC}", "Gexit")

While 1
    Sleep(100)
WEnd

Func Gstart()
While 1
    sleep(100)
    $pos = MouseGetPos()
    $x = $pos[0] + 10 - Random(0, 20, 1)
    $y = $pos[1] + 10 - Random(0, 20, 1)
    MouseMove($x,$y)
Wend
Endfunc


Func Gpause()
While 1
   sleep(100)
Wend
Endfunc

Func Gexit()
    MsgBox(0, "exit box", "Script exited")
    Exit 0
EndFunc
Run Code Online (Sandbox Code Playgroud)

控制

  • 主页:开始模拟.
  • 暂停:暂停模拟.
  • Esc:退出模拟.

或者从这里使用我编译的版本.


jdp*_*nix 5

你不能指望任何人能够完全稳定地握住他们的手,所以你可以考虑的一件事是,

  1. 向用户解释你在做什么,
  2. 使演示页面上的可点击元素比正常情况小得多.
  3. 将示例系统上的鼠标灵敏度提高到最大值.

我的理由是(警告,我不是ux或医学方面的专家)通过使可点击元素更小,你为大多数人创造了类似的问题,患有帕金森病的人将面对日常网站.

  • 我担心大多数鼠标用户如果集中注意力可以将设备控制在1-2像素之间 - 例如,我使用的鼠标设置,手的抖动低于1像素.如果按钮大于1-2像素,那么可能不是通用的解决方案...... (2认同)