web-dev-qa-db-ja.com

Webページ上でマウスを使用して振戦をシミュレートしますか(パーキンソン病など)?

私は、インターネットのアクセシビリティに対する意識を高めるための財団のために働いています。プレゼンテーションのために、さまざまな障害/障害をシミュレートする小さなワークショップを提供したいと考えています。これは、このプレゼンテーション専用に作成されたWebサイトを介して行われます。

実証された障害の1つは振戦です。これは、不安定で制御が難しい手の動きを経験することを意味します。この障害により、マウスカーソルを正確に移動し、マウスがリンク上にあるときにマウスボタンを押すのが非常に困難になります。一部の高齢者と病気のある人、例えばパーキンソン病、振戦に苦しむことができます。

さて、どういうわけか、マウスカーソルを予測できない方法で動かしたいので、小さなボタンをクリックするのは非常に困難です。 JavaScriptではマウスカーソルを直接移動できないため、これを実現する他の方法を探しています。次のアイデアを思いつきました。

  • マウスの揺れをシミュレートするマウスドライバー/ユーティリティを使用する。
  • CSSを介してマウスカーソルを非表示にし、元のカーソルの場所に(JavaScriptを使用して)揺れているマウスカーソルのGIFアニメーションを配置し、ターゲットリンクを数秒ごとに1秒程度クリックできるようにします。これは、少なくともあたかも間違った瞬間にクリックするかのような感覚を与えます。

最初のアイデアはかなりクールですが、MacでもWindowsでも、このようなツールは見つかりませんでした。そして、私は自分でそのようなことをプログラミングするスキルを持っていません。

2番目のアイデアは少しぎこちないように見えますが、望ましい効果が得られると思います。

誰か他のアイデアがありますか?

204
Joshua Muheim

Pointer Lock API を使用して、コードのベースにすることができるはずの何かの簡単なデモを作成しました。

this pointer-lock-demo repo を分岐し、ランダムな移動要素を追加するように変更しました。

GitHubページへのリンクは次のとおりです。 https://aristocrates.github.io/pointer-lock-demo
そして、ここに私のレポへのリンクがあります: https://github.com/aristocrates/pointer-lock-demo

重要なjavascriptコードは、canvasLoop(e)メソッドのapp.jsに含まれています。

元のデモから変更した唯一のことは、

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

ランダムな動きを表す2行を追加しました。

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

改善できることはまだたくさんありますが、うまくいけば、これが開始に役立つことを願っています。

148
Aristocrates

非javascriptの方法

実際、私はJavascriptに基づいたソリューションが好きです。なぜならそれらはウェブに関連している可能性が高いからです。しかし、私は考えていました-すべてのブラウザーの問題を解決する方法。この場合、javascriptソリューションはすべての可能なブラウザーに合わせて調整するのが難しいからです(まったく可能かどうかはわかりません)。

したがって、あなたが言及したように、別の方法があります-つまり、OSレベルで動作をエミュレートすることです。これには別の利点もあります。ブラウザの場合、人間のように100%に見えることは確かです(信号を送信しているのはドライバーだからです)。そのため、任意のブラウザで(またはjavascriptが無効になっている状況でも)ドライバ/デバイスベースのソリューションを使用できます。

Linux

残念ながら、ドライバー/デバイスを使用すると、すぐにOSの依存関係が発生します。そのため、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;
}
_

問題の私の完全なコードが見つかりました here 。プログラムは、「振戦」の振幅とその頻度を求めます(したがって、「振戦」の間隔はマイクロ秒単位です)。状況をエミュレートするには、マウスを_0..X_ポイントでランダムな方向(上下左下)にランダムに移動させ、次の「振戦」までランダムに_0..Y_マイクロ秒待機しますXは「振戦」の振幅であり、Yは「振戦」の頻度です。

もう1つは、システムに合わせてプログラムを調整することです。このプログラムは「ダミー」であり、マウス自体を検出できないため、_"/dev/input/event4"_はハードコードされています。システムの識別子となるものを理解するには、次を試してください。

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

そして、可能性は_"event3"_と_"event4"_です—しかし、あなたのシステムでは他の値を持っているかもしれません。したがって、現在Cコードで使用されているものと異なる場合は、対応する行を変更するだけです(そのため、int fd = open("/dev/input/event4", O_RDWR);を含む行を作成し、_event4_の代わりにデバイスを配置します)

このプログラムのgifデモ(低フレームレート、残念ながら、画像が大きすぎないようにしてください) here

ちょっとした補足事項(Cコードの処理方法がわからない場合)—上記のプログラムをコンパイルするには、次を使用します。

_user@Host:/path$ gcc -std=gnu99 file.c -o m
_

ここで、_file.c_はCソースコードファイルの名前であり、ディレクトリ内でmと呼ばれる実行可能ファイルを取得します。ほとんどの場合、マウスデバイスに直接書き込むためのアクセス許可が必要になるため、Sudoを使用できます。

_user@Host:/path$ Sudo ./m
_

その他のOS

ロジックは同じままです。

  • マウスデバイスにアクセスする方法を見つける
  • 動くマウスのイベントを書く
  • イベントにランダム化を適用する

それでおしまい。たとえば、Mac OSにはマウスを操作する独自の方法があります(Linuxとは異なり、Macにはprocfsもありません)、よく説明されています- ここ

結論として

この場合、特定の条件(ブラウザー間またはOS間など)がすべてを決定する可能性があるため、JavaScriptまたはデバイス指向のソリューションの方が優れています。したがって、OSレベルでそれを実装する方法の特定の実例とともにガイドラインを提供しました。ここでの利点は、ソリューションがクロスブラウザであるということですが、コストとしてOSにバインドされたプログラムがあります。

36
Alma Do

Puppy Linux Forum で一度冗談としてこれを行い、次のようなコメントを得ました:

パーキンソン病の人は面白いとは思わないでしょう!!!

ここでの治療法は、単にcntrl-Cです。

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

Parkinson_simという名前を付け、0.001から999.0の振戦間の時間のオプションの引数を指定して実行します。

parkinson_sim [time_between_tremors_in_seconds] #defaultは0.1

コマンドラインから実行するのではなく、自分でクリックするというミスを犯し、すぐにそれがいかにイライラするかを発見しました。ターミナルウィンドウを開いて強制終了するのに数回試行しました。

23
technosaurus

2番目のアイデア(カーソルを非表示にする)は、あなたにとってうまくいくと思うアイデアの半分です。

  • 提案どおり、CSSを介してマウスカーソルを非表示にします。 (_cursor:none_ IIRC)
  • 不安定なカーソルGIFの代わりに、画像+ CSS絶対配置+ JSを使用してマウスポインターをエミュレートします。つまり、ページの周りでマウスを追跡し、マウスカーソルが本来存在する場所にカーソル画像を配置します。

次に、微動の計算をカーソルコードに追加して、カーソルを「振る」。振戦入力を適切にシミュレートするために適切な曲線を決定するのはあなた次第です。

最後に:プログラミングしているコントロール(リンクなど)について:

  • クリックイベントをキャプチャし、振戦曲線の状態に基づいて現在の「振戦」位置にナッジし、要素を境界チェックして、ユーザーが意図した要素から、または場合によっては意図していない要素に動いたかどうかを確認します。

この実装による1つの大きなボーナス:「揺れるカーソル」はタッチデバイスに表示されますが、最初はカーソルがありません。


編集:

Michael Theriotの(非常にクリーンで役立つ!)ベースのJSFiddleのコメントに基づいて、現在のカーソル位置の周囲に通常分布するスイープで絶え間なく揺れ動くものを以下に示します。 http://jsfiddle.net/benmosher/0x4mc64v/ 4 /

normal配列は、Rコンソールでrnorm(100)を呼び出した結果です。JSで考えられる最も簡単な方法は、正規分布のランダムな整数をサンプリングすることです。)

16
Ben Mosher

振戦を「正しく」行うためのアイデアであり、実際の患者のマウスの動きを記録することができます。これにより、データの出所を人々に伝えるときに、より確実になります。

猫をマウスカーソルに追従させるためのスクリプトがあります。2つ目のカーソルがカーソルに追従(ジャンプ)するように調整できます。ページは2番目のカーソルの位置を計算しているため、クリックイベントが成功したかどうかを判断することもできます。

可能であれば、ウェブベースにしてください。この方法で、プログラムをインストールしたり、フラッシュなどを有効にするように依頼するよりも多くの人にアプローチできます。

14
user3934260

ポインターを移動しようとする代わりに、代わりにアプリケーション(Webページ)を移動できます。いくつかの入力フィールドがある単純なhtmlフォームを作成しました。マウスをフォームに移動すると、フォームが移動します。

jsfiddleでの移動フォームのデモ を見ることができます。入力フィールドのいずれかをクリックして、効果を確認してください。

これを実現するためにjquery shake エフェクトを使用しました。シェイク効果のjavascriptは次のようになり、マウスが上に移動するたびにフォームを上下に移動します。

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

フォームは上下にしか移動しませんが、望ましい効果があると思います。パラメーター(方向、時間、距離、および上記の名前のない「1000」)を使用して、フォームの動きを微調整できます。

10
chue x

ハードウェアソリューションを使用しないのはなぜですか? Logitech G500のように、体重を入れることができる特定のマウスがあります。重りを入れる代わりに、マウスをわずかに振る小さな振動モーターを入れます。また、これは実際の障害をよりシミュレートしました。震えるのはカーソルだけではなく、手とマウス全体です。また、ウェブサイト以外のソフトウェアを表示できることも意味します。

重量スロットのあるマウスの代わりに、マウスに何かをテープで留めることもできますが、それはより顕著です。

10
Nzall

カスタムマウスドライバーを使用してそれを行うことを考えていたとき、PCで実行されている小さなプログラムでもどちらでもできると思いますか?この場合、C#の小さなスニペットがあります。これは、現在のカーソル位置を中心にプラスマイナス5pxの範囲でカーソルをランダムに無限に移動します。各変位の後、プログラムは50ミリ秒から100ミリ秒待機します(正確ではありません!)。揺れは、変位と休止の値を調整することで構成できます。これをコンソールアプリケーションで実行しました。値によっては、プログラムを停止するのにかなり苦労しました。

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);
}
6
Paul Kertscher

AutoIt を使用するxdotoolスクリプトのWindowsバージョンです。これは私の初めてのAutoItスクリプトであり、書くのに数分しかかからなかったので、改善できると確信しています。拡張子.au3で保存し、AutoIt(Run Script 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

コントロール

  • ホーム:シミュレーションを開始します。
  • pause:シミュレーションを一時停止します。
  • Esc:シミュレーションを終了します。

または、 here のコンパイル済みバージョンを使用します。

6
technosaurus

誰もが手を完全に安定させることができるとは期待できないので、考慮できることの1つは、

  1. 何をしているかをユーザーに説明し、
  2. デモページのクリック可能な要素を通常よりも小さくします。
  3. サンプルシステムでのマウスの感度を最大にします。

私の推論は(注意、私はUXや医学の専門家ではありません)クリック可能な要素を小さくすることで、パーキンソン病に苦しんでいる人が日常のウェブサイトに直面するほとんどの人に同様の問題を作成します。

5
jdphenix
  • DIVで、cursor:none;を使用してCSSでカーソルを非表示にします
  • .pngカーソル画像を作成し、leftでjQを使用して移動(topmousemove
  • setTimeoutを使用して.png margin-leftおよびmargin-topをランダム化します(CSS3 transitionをスムーズに再配置するため、またはjQ .animate()で実行します) )。

注:スクリプトは、手がまだマウス上にあるかどうかを知ることができません;)

function Rand(min, max) {return Math.random() * (max - min) + min;}

var $cursor = $('div img');

$('div').mousemove(function(e) {  // Make .png follow the mouse coordinates
  $cursor.css({
    left: e.pageX,
    top:e.pageY
  });
}).hover(function(e){
  $cursor.toggle(); // Show .png cursor as we enter the DIV
});

(function tremor(){ // Add tremor to .png image
  $cursor.css({
      marginLeft: Rand(-15,15), // arm tremor
      marginTop:  Rand(-30,30)  // hand contractions
  });
  setTimeout(tremor, Rand(50,100));
}());
div{
  position:absolute;
  background:#eee;
  height:100%;
  width:100%;
  cursor:none;
}

div img{
  display:none;
  position:absolute;
  transition: margin 0.2s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div><img src="http://i.stack.imgur.com/KwMGA.png"></div>
4
Roko C. Buljan

this article ...に記載されているような古い時代のシミュレーションスーツを使用できます。手を全体的に不器用にします。

4
user3067860