Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Smooth Javascript mousemove similar to Cubism.js

I'm curious how Mike Bostock was able to create a vertical line that follows your mouse cursor in such a smooth way. If you look here http://square.github.com/cubism/ , you can see what I'm talking about.

Take a look at a quick example I just made here: http://jsfiddle.net/zbfUq/

There are many times where the line in my example actually disappears. Is there some sort of position interpolation he is doing to create a smooth translation between two points that are not being recorded? If so, anyone know how to do something like that?

like image 262
frshca Avatar asked Oct 11 '12 16:10

frshca


1 Answers

I've made you a working example: http://jsfiddle.net/zbfUq/37/

Essentially you have record the mouse position in the onmousemove event handler, but not actually move the line there straight away.

You then run a timer which checks every so often (every 10 milliseconds in my example), and moves the line closer to the mouse position.

In the onmouseover event, I set the line position to the mouse position, and set the timer going.

In the onmouseout event I clear the timer, and set the line position back to 0 (you could also hide the line).

The updatepos function first checks how far away the line is from the mouse position. If it is less than 1px away, it simply moves the line to the mouse position. If it is more than 1px away, it moves is closer at a speed proportional to the distance away it is (if the line is further from the mouse, it moves towards it quicker).

Javascript code

(function() {
    var selectline = document.getElementById('selection_line');
    var container = document.getElementById('page_content');
    var mouseX = 0;
    var lineX = 0;

    var linetimer;

    var updatepos = function () {
        var speed, distance;
        distance = Math.abs(mouseX - lineX);
        if (distance < 1) {
            lineX = mouseX;
        }
        else {
            speed = Math.round( distance / 10, 0 );
            speed = speed >= 1 ? speed : 1;
            lineX = (lineX < mouseX) ? lineX + speed : lineX - speed;
        }

        selectline.style.left = lineX + 'px';

    }

    $(container).on("mouseover", function(e) {
        lineX = mouseX;
        selectline.style.left = lineX + 'px';
        linetimer = setInterval(updatepos, 10);
    });

    $(container).on('mousemove', function(e) {
        mouseX = e.pageX;
        console.log(mouseX);
    });

    $(container).on("mouseout", function(e) {
        clearTimeout(linetimer);
        lineX = 0;
        selectline.style.left = LineX + 'px';
    });
})();​
like image 108
Nico Burns Avatar answered Sep 28 '22 12:09

Nico Burns