2011-07-29 3 views
2

私は、ユーザーのマウスの位置を記録し、各時間ステップで速度と加速度を計算するJavaアプレットを作成しました。私はそれをJavascriptに変換したいと思います。これは可能ですか?Qualtrics Survey内でのマウスの追跡

EDIT 2:私はコードを公開し、実装方法の簡単なチュートリアルを作成しました。

http://math.bu.edu/people/jackwalt/qualtrics-mousetracking/

使用し、共有すること自由に感じます!

EDIT 1:ここではJavascriptのコードがあります:

<input type="hidden" id="xPos" name="ED~xPos" value="" /> 
<input type="hidden" id="yPos" name="ED~yPos" value="" /> 
<input type="hidden" id="time" name="ED~time" value="" /> 

<script type="text/javascript"> 

var initTime = new Date().getTime(); 

document.onmousemove = getMousePosition; 

function getMousePosition(mp) { 
    var divPos = getPosition(document.getElementById("mousearea")); 

var event = [mp.pageX - divPos[0], mp.pageY - divPos[1], new Date().getTime() - initTime]; 

document.getElementById("xPos").value += event[0] + ", "; 
document.getElementById("yPos").value += event[1] + ", "; 
document.getElementById("time").value += event[2] + ", "; 

return true; 
} 


function getPosition(obj){ 

var topValue= 0,leftValue= 0; 

while(obj){ 
    leftValue+= obj.offsetLeft; 
    topValue+= obj.offsetTop; 
    obj= obj.offsetParent; 
    } 

return [leftValue, topValue]; 
} 

</script> 

ここではJavaコードがあります:

メインクラス:

package com.jackson.allgood; 

import java.applet.Applet; 
import java.awt.Graphics; 
import java.awt.MouseInfo; 
import java.awt.Point; 
import java.io.BufferedWriter; 
import java.io.FileWriter; 
import java.text.DateFormat; 
import java.util.ArrayList; 
import java.util.Date; 
import java.util.List; 

/** 
* This is a simple applet to record the position, velocity, and acceleration of a 
* mouse pointer as it moves relative to names positioned in the window. Metadata is 
* written to a text file and raw data to a .csv file. 
* 
* @author Jackson Walters 
* 
*/ 
public class Main extends Applet { 

    private static final long serialVersionUID = 1L; 

    private List<Data> dataList; 
    private MouseListenerThread testThread; 
    private long startTime; 
    private long endTime; 
    private static long DT = 10L; 

    private static final String[] NAMES = {"Name 1","Name 2","Name 3","Name 4"}; 
    private static final String METADATA_FILENAME = "metadata"; 
    private static final String DATA_FILENAME = "data"; 

    /** 
    * Initializes the applet by creating an ArrayList to hold the data 
    * and starts a thread to begin collecting data. 
    */ 
    public void init() { 
     dataList = new ArrayList<Data>(); 

     testThread = new MouseListenerThread(); 
     testThread.start(); 
    } 

    /** 
    * Stops the applet. Asks the thread to stop and waits until it does, then prints 
    * the metadata and data. 
    */ 
    public void stop(){ 
     testThread.requestStop(); 
     try { 
      testThread.join(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     printData(); 
     printMetaData(); 
    } 

    public void paint(Graphics g) 
    { 
     g.drawString(NAMES[0],getSize().width/2,20); 
     g.drawString(NAMES[1],getSize().width/2,getSize().height-20); 
     g.drawString(NAMES[2],10,getSize().height/2); 
     g.drawString(NAMES[3],getSize().width-100,getSize().height/2); 
    } 

    /** 
    * Thread that records the time and position of the mouse, calculates velocity and acceleration, 
    * then stores the data into the data list. Sleeps for the time interval specified by DT. Able to 
    * be stopped by setting a flag then waiting one time interval for the loop to exit. 
    * 
    */ 
    private class MouseListenerThread extends Thread{ 

     private boolean running = true; 

     @Override 
     public void run(){ 

      //initialize time and first data point 
      startTime = System.currentTimeMillis(); 
      dataList.add(new Data(
        0L, 
        MouseInfo.getPointerInfo().getLocation().getX(), 
        MouseInfo.getPointerInfo().getLocation().getY(), 
        0.,0.,0.,0.) 
        ); 

      while(running){ 

       long currentTime = System.currentTimeMillis()-startTime; 

       Point mousePos = MouseInfo.getPointerInfo().getLocation(); 

       double xPos = mousePos.getX(); 
       double yPos = mousePos.getY(); 

       double xVel = (xPos-dataList.get(dataList.size()-1).getXPos())/DT; 
       double yVel = (yPos-dataList.get(dataList.size()-1).getYPos())/DT; 

       double xAcc = (xVel-dataList.get(dataList.size()-1).getXVel())/DT; 
       double yAcc = (yVel-dataList.get(dataList.size()-1).getYVel())/DT; 

       dataList.add(new Data(currentTime, xPos, yPos, xVel, yVel, xAcc, yAcc)); 

       try { 
        sleep(DT); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 

      endTime = System.currentTimeMillis(); 
     } 

     public void requestStop(){ 
      running = false; 
     } 
    } 

    /** 
    * Prints the raw data generated by the program to a .csv file. 
    */ 
    private void printData(){ 

     try { 
      BufferedWriter out = new BufferedWriter(new FileWriter(DATA_FILENAME + ".csv")); 
      out.write(Data.DATA_HEADER_STRING); 
      for(Data data : dataList){ 
       out.write(data.toString()); 
      } 
      out.close(); 
     } catch (Exception e){ 
      System.err.println("Error: " + e.getMessage()); 
     } 
    } 

    /** 
    * Prints general information about what the program did to a text file. 
    */ 
    private void printMetaData(){ 

     try { 
      BufferedWriter out = new BufferedWriter(new FileWriter(METADATA_FILENAME + ".txt")); 

      out.write("Start time: " + DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG).format(new Date(startTime))); out.newLine(); 
      out.write("End time: " + DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG).format(new Date(endTime))); out.newLine(); 
      out.write("Elapsed time: " + formatElapsedTime(endTime-startTime)); out.newLine(); 
      out.write("Number of measurments: " + dataList.size()); out.newLine(); 
      out.write("Measurement interval: " + DT + "ms"); out.newLine(); out.newLine(); 
      out.write("Names:"); out.newLine(); 
      for(String name : NAMES){ 
       out.write(name); out.newLine(); 
      } out.newLine(); out.newLine(); 

      out.close(); 
     } catch (Exception e){ 
      System.err.println("Error: " + e.getMessage()); 
     } 
    } 

    /** 
    * Converts milliseconds in the format min:sec. 
    * @param ms 
    * @return Time as min:sec. 
    */ 
    private static String formatElapsedTime(long ms){ 

     int seconds = (int) (ms/1000.); 
     int minutes = seconds/60; 
     seconds %= 60; 

     if(seconds < 10) return minutes + ":0" + seconds; 
     else return minutes + ":" + seconds; 
    } 
} 

ユーティリティクラス:

package com.jackson.allgood; 

/** 
* Simple class to store data such as time, position, velocity, and acceleration. 
* @author Jackson Walters 
* 
*/ 
public class Data { 

    protected static final String DATA_HEADER_STRING = "Time, " + 
                 "x position, " + 
                 "y position, " + 
                 "x velocity, " + 
                 "y velocity, " + 
                 "x acceleration, " + 
                 "y acceleration" + 
                 "\n"; 

    private long time; 

    private double xPos; 
    private double yPos; 

    private double xVel; 
    private double yVel; 

    private double xAcc; 
    private double yAcc; 

    public Data(){} 

    public Data(long time, double xPos, double yPos, double xVel, double yVel, double xAcc, double yAcc){ 
     this.time = time; 

     this.xPos = xPos; 
     this.yPos = yPos; 

     this.xVel = xVel; 
     this.yVel = yVel; 

     this.xAcc = xAcc; 
     this.yAcc = yAcc; 
    } 

    //getters and setters for time, pos, vel, and acc 

    public long getTime(){return time;} 
    public void setTime(long time){this.time = time;} 

    public double getXPos(){return xPos;} 
    public void setXPos(double xPos){this.xPos = xPos;} 
    public double getYPos(){return yPos;} 
    public void setYPos(double yPos){this.yPos = yPos;} 

    public double getXVel(){return xVel;} 
    public void setXVel(double xVel){this.xVel = xVel;} 
    public double getYVel(){return yVel;} 
    public void setYVel(double yVel){this.yVel = yVel;} 

    public double getXAcc(){return xAcc;} 
    public void setXAcc(double xAcc){this.xAcc = xAcc;} 
    public double getYAcc(){return yAcc;} 
    public void setYAcc(double yAcc){this.yAcc = yAcc;} 

    /** 
    * Formats the data as a string of comma separated values. 
    */ 
    @Override 
    public String toString(){ 
     String toReturn = ""; 

     toReturn += time + ", "; 

     toReturn += xPos + ", "; 
     toReturn += yPos + ", "; 

     toReturn += xVel + ", "; 
     toReturn += yVel + ", "; 

     toReturn += xAcc + ", "; 
     toReturn += yAcc + ", "; 

     toReturn += "\n"; 

     return toReturn; 
    } 
} 

答えて

1

これはもう少し遅いかもしれませんが、私はと多くのマウス&アイトラッキングシステムを使用しています。主な問題は、Qualtricsドメインで小さなセッションファイルをホストするためのアクセス権を得ることです。 MouseFlowのような良い仕事をし、ヒートマップ、フルビデオなどのパラメータを含む棚のプログラムからいくつかがあります。私の研究のほとんどは、プロセス全体を制御しているラボで行われていましたが、JavaScriptのアイデアは本当に素晴らしいと思います。私はあなたがどのように乗っているか聞くことにとても興味があります。

+0

少し遅れましたが、私はJavascriptに変換して終了し、コードはかなりシンプルでした。 – Jackson

+0

こんにちは@JacksonWalters、私は今Qualtricsで別の研究プロジェクトをやっているようですが、あなたが書いたスクリプトのようなものが必要です。あなたがあなたがそれをどうやって分かち合って説明する機会はありますか?スクリプトの作者としてのあなたへの帰属は、言うまでもなく、収集されたデータの出版物があれば、これを言いたいと思っています。よろしく、ありがとうございます。 – Will

+0

確かに問題ありません。私はあなたにJavascriptと私がしばらく前に書いたpseduocodeの説明をメールします。 – Jackson

関連する問題