Smooth Javascript mousemove is similar to Cubism.js

I'm curious how Mike Bostock was able to create a vertical line that follows the 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 the quick example I just made here: http://jsfiddle.net/zbfUq/

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

+6
source share
3 answers

I assume it uses d3.js transition , see https://github.com/mbostock/d3/wiki/Transitions to basically animate the line (and values) from the current line position to where the mouse cursor is. You can say that he is not trying to just follow the mouse whip, because if you quickly move the cursor, you can see the lag behind the line behind, this is the transition animation time.

I put together a quick example of how this is done in d3.js at http://jsfiddle.net/2N2rt/4/ . I have not played with him much, so I am sure you can make it even smoother, but it seemed very good to us.

 var line = d3.select('#selection_line'), page = d3.select('#page_content'), x = 0; page.on('mousemove', function() { x = d3.mouse(this)[0]; }); var update = function() { line.transition() .duration(5) .ease('cubic-in-out') .style('left', x + 'px'); }; setInterval(update, 35); 

Also keep in mind that svg elements tend to come to life much more smoothly than DOM elements. Here is an example of svg ( http://jsfiddle.net/2N2rt/10/ ).

 var graph = d3.select('#graph') .append('svg') .attr('width', '100%') .attr('height', 600); var box = graph.append('rect') .attr('transform', 'translate(0, 100)') .attr('width', '100%') .attr('height', 200) .attr('class', 'page_content'); var line = graph.append('line') .attr('transform', 'translate(0, 50)') .attr({'x1': 0, 'y1' : 0, 'x2': 0, 'y2': 300}) .attr('class', 'selection_line'); var x = 0; graph.on('mousemove', function () { x = d3.mouse(this)[0]; }); var draw = function () { line .transition() .duration(18) .attrTween('transform', d3.tween('translate(' + x + ', 50)', d3.interpolateString)) .each('end', draw); }; draw(); 

Again, this is just a quick example, but hopefully it gives you some ideas.

+2
source

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

Essentially, you record the mouse position in the onmousemove event onmousemove , but you are not actually moving the line right now.

Then you start a timer that checks each so often (every 10 milliseconds in my example) and moves the line closer to the mouse position.

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

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

The updatepos function first checks how far the line is from the mouse position. If it is less than 1px, it simply moves the line to the mouse position. If it is larger than 1px, it moves closer with a speed proportional to the distance from it (if the line is farther from the mouse, it moves toward it faster).

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'; }); })();​ 
+3
source

I believe this line is generated using cubism.rule, Check out view-source: http://bost.ocks.org/mike/cubism/intro/demo-stocks.html . You need the following:

d3.select ("body"). append ("div") .attr ("class", "rule") .call (context.rule ());

To do this, use context.rule (), the d3 / cubism function.

There is only one problem that the rule applies only to the current screen. After scrolling the screen, the rule (line) disappears.

0
source

Source: https://habr.com/ru/post/927482/


All Articles