0

So tried to make a small script to track mouse movements. I wanted to calculate the average speed and average duration in which the mouse does not move.

However, my variables show up as NaN in console when I print them out.

var avgSize = 0;
var avgSpeed = 0;
var measures = 0;
var lastX;
var lastY;
var lastMillis;

var eventDoc, doc, body, pageX, pageY;
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");

// Mouse moved
document.onmousemove = function(event) {
    event = event || window.event; // IE-ism

    // If pageX/Y aren't available but clientX/Y are, calculate pageX/Y - logic taken from jQuery
    if (event.pageX == null && event.clientX != null) {
        eventDoc = (event.target && event.target.ownerDocument) || document;
        doc = eventDoc.documentElement;
        body = eventDoc.body;

        event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
        event.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);
    }

    // Calculate dot size
    dotSize = (Date.now() - lastMillis) / 50;
    if (dotSize > window.innerHeight / 10) {
        dotSize = window.innerHeight / 10;
    }

    // Draw dots
    if (dotSize > 2) {
        ctx.beginPath();
        ctx.arc(lastX, lastY, dotSize, 0, 2 * Math.PI);
        ctx.stroke(); 
        ctx.fill();
    }

    measure(Math.abs(event.pageX - lastX) + Math.abs(event.pageY - lastY), dotSize);

    // Variables for comparison
    lastX = event.pageX;
    lastY = event.pageY;
    lastMillis = Date.now();
}

// Calculate averages
function measure(speed, size) {
    measures++;
    avgSpeed = avgSpeed - (avgSpeed / measures) + speed / measures;
    avgSize = avgSize - (avgSize / measures) + size / measures;

    console.log("average speed: " + avgSpeed + " average size: " + avgSize);
}
<canvas id="canvas"></canvas>

EDIT: Added missing declarations i accidentally deleted.

ibrahim mahrir
  • 31,174
  • 5
  • 48
  • 73
Hans Gagel
  • 11
  • 3
  • 2
    Have you tried stepping thru with debugger? It should point out where things go wrong – Huangism Jun 12 '17 at 14:10
  • 1
    Initialize `lastMillis` at the begining as you're using it as `undefined`. (Its `undefined` value is affecting other variables). – ibrahim mahrir Jun 12 '17 at 14:10
  • I updated the question, I had accidentally deleted this line (thanks for pointing out). It still doesn't work though. – Hans Gagel Jun 12 '17 at 14:13
  • Possible duplicate of [How can I debug my JavaScript code?](https://stackoverflow.com/questions/988363/how-can-i-debug-my-javascript-code) – Liam Jun 12 '17 at 14:18
  • @HansChnuspi You should initialize them not just declare them (`var lastMillis = something; ....`). – ibrahim mahrir Jun 12 '17 at 14:20
  • @Huangism both variables just jump to NaN in the measure() function. – Hans Gagel Jun 12 '17 at 14:20
  • 1
    @Liam - Well, to some degree, isn't *every* JS question on SO a duplicate of that over-broad question? – JDB Jun 12 '17 at 14:20
  • `var lastMillis = Date.now(); lastX = 0, lastY = 0;` I just tried and it's working. – ibrahim mahrir Jun 12 '17 at 14:20
  • @JDB I just don't see how this will help anyone in the future. The OPs question has been addressed, does this help solve anyone else having this issue, no. Also, debugging this should of made this issue obvious. – Liam Jun 12 '17 at 14:56
  • @liam Then maybe choose a different close reason in the future, but closing as duplicate of a question (rightfully) close as "too broad" doesn't seem to be helpful. – JDB Jun 12 '17 at 15:03

1 Answers1

2

The following variables are not defined in your mousemove handler when used for the first time. You should define these before/during the first move.

lastX = event.pageX;
lastY = event.pageY;
lastMillis = Date.now();

EDIT: The original code has been updated with missing code so here's a new answer

Your variables are still undefined, so I'd suggest defining them on the first move:

// Mouse moved
document.onmousemove = function(event) {
    event = event || window.event; // IE-ism

    if (typeof lastX == "undefined") {
        lastX = event.pageX;
    }

    if (typeof lastY == "undefined") {
        lastY = event.pageY;
    }

    if (typeof lastMillis == "undefined") {
        lastMillis = Date.now();
    }

    ...
Dennis Rasmussen
  • 520
  • 3
  • 12