6

Mike Bostock がどのようにして、マウス カーソルに追従する垂直線をこれほどスムーズに作成できたのか、興味があります。ここhttp://square.github.com/cubism/を見れば、私が話していることがわかります。

ここで作成した簡単な例を見てください: http://jsfiddle.net/zbfUq/

私の例の行が実際に消えることが何度もあります。記録されていない 2 点間のスムーズな移動を作成するために、何らかの位置補間を行っているのでしょうか? もしそうなら、誰かがそのようなことをする方法を知っていますか?

4

3 に答える 3

3

私はあなたに実用的な例を作りました: http://jsfiddle.net/zbfUq/37/

基本的に、onmousemoveイベント ハンドラーでマウスの位置を記録しますが、実際にそこに線をすぐに移動するわけではありません。

次に、頻繁に (私の例では 10 ミリ秒ごとに) チェックするタイマーを実行し、線をマウスの位置に近づけます。

イベントではonmouseover、行の位置をマウスの位置に設定し、タイマーを設定しました。

イベントではonmouseout、タイマーをクリアし、行の位置を 0 に戻します (行を非表示にすることもできます)。

このupdatepos関数は、最初に線がマウスの位置からどれだけ離れているかをチェックします。1px 未満の場合は、単に線をマウスの位置に移動します。1px 以上離れている場合は、距離に比例した速度で近づきます (線がマウスから離れている場合は、より速く近づきます)。

Javascript コード

(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';
    });
})();​
于 2012-10-11T17:28:08.353 に答える
2

彼は d3.js を使用していると思います。 https://github.com/mbostock/d3/wiki/Transitionstransitionを参照して、現在の行の位置から現在のマウスカーソルの位置まで行 (および値) を基本的にアニメーション化します。カーソルをすばやく動かすと、行が少し遅れていることがわかります。これは遷移のアニメーション時間です。

http://jsfiddle.net/2N2rt/4/の d3.js でこれを行う方法の簡単な例をまとめました。あまりいじっていなかったので、もっとスムーズにできると思いますが、これはかなり良さそうです。

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);

また、要素は要素svgよりもはるかにスムーズにアニメーション化される傾向があることに注意してDOMください。これが純粋な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();

繰り返しますが、これは簡単な例ですが、いくつかのアイデアを得ることができれば幸いです。

于 2012-10-11T17:12:58.773 に答える
0

この行は cubism.rule を使用して生成されていると思います。必要なものは次のとおりです。

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

これは、d3/cubism 関数である context.rule() を使用してそれを実現します。

ルールが現在の画面のみをカバーするという問題が 1 つだけあります。画面を上にスクロールすると、ルール (行) が消えます。

于 2013-03-08T17:01:08.973 に答える