2016-11-04 22 views
5

ben alıp İşte hereBirkaç tıklamadan sonra animasyon donuyor, neden?

dan değiştirmek aşağıdaki kod,

Şu anda merkezine çekilmek bu kabarcıklar, tam olarak 5 kabarcıklar gereken bir kullanıcı etkileşimini geliştiriyorum eylem benim jsfiddle olduğunu var ekran. Mesele şu ki, bir kullanıcının bu kabarcıkların her birine kaç kez tıklayacağını biliyorum. Fark ettiğim şey, bir noktada kabarcıkların büyümeye devam etmesi, ancak aralarındaki çarpışmanın çalışmayı durduracağıdır.

Burada değiştirmek kodunu görebilirsiniz:

var width = 500, 
    height = 500, 
    padding = 1.5, // separation between same-color circles 
    clusterPadding = 4, // separation between different-color circles 
    maxRadius = 40; 

var n = 5, // total number of circles 
    m = 1; // number of distinct clusters 

var color = d3.scale.category10() 
    .domain(d3.range(m)); 

// The largest node for each cluster. 
var clusters = new Array(m); 

var nodes = d3.range(n).map(function() { 
var i = Math.floor(Math.random() * m), 
    //r = Math.sqrt((i + 1)/m * -Math.log(Math.random())) * maxRadius, 
    r = maxRadius, 
    d = {cluster: i, radius: r}; 
    if (!clusters[i] || (r > clusters[i].radius)) clusters[i] = d; 
     return d; 
    }); 

// Use the pack layout to initialize node positions. 
d3.layout.pack() 
    .sort(null) 
    .size([width, height]) 
    .children(function(d) { return d.values; }) 
    .value(function(d) { return d.radius * d.radius; }) 
    .nodes({values: d3.nest() 
    .key(function(d) { return d.cluster; }) 
    .entries(nodes)}); 

var force = d3.layout.force() 
    .nodes(nodes) 
    .size([width, height]) 
    .gravity(.02) 
    .charge(0) 
    .on("tick", tick) 
    .start(); 

var svg = d3.select("body").append("svg") 
    .attr("width", width) 
    .attr("height", height); 

var node = svg.selectAll("circle") 
    .data(nodes) 
    .enter().append("circle") 
    .style("fill", function(d) { return color(d.cluster); }) 
    .on("click", function(d) { 
    d.radius *= 1.1; 
    d3.select(this).attr("r", d.radius); 
    }) 
    .call(force.drag); 

node.transition() 
    .duration(750) 
    .delay(function(d, i) { return i * 5; }) 
    .attrTween("r", function(d) { 
    var i = d3.interpolate(0, d.radius); 
     return function(t) { return d.radius = i(t); }; 
    }); 

function tick(e) { 
    node 
    .each(cluster(10 * e.alpha * e.alpha)) 
    .each(collide(.5)) 
    .attr("cx", function(d) { return d.x; }) 
    .attr("cy", function(d) { return d.y; }); 
} 

// Move d to be adjacent to the cluster node. 
function cluster(alpha) { 
    return function(d) { 
    var cluster = clusters[d.cluster]; 
    if (cluster === d) return; 
    var x = d.x - cluster.x, 
     y = d.y - cluster.y, 
     l = Math.sqrt(x * x + y * y), 
     r = d.radius + cluster.radius; 
    if (l != r) { 
     l = (l - r)/l * alpha; 
     d.x -= x *= l; 
     d.y -= y *= l; 
     cluster.x += x; 
     cluster.y += y; 
    } 
    }; 
} 

// Resolves collisions between d and all other circles. 
function collide(alpha) { 
    var quadtree = d3.geom.quadtree(nodes); 
    return function(d) { 
    var r = d.radius + maxRadius + Math.max(padding, clusterPadding), 
     nx1 = d.x - r, 
     nx2 = d.x + r, 
     ny1 = d.y - r, 
     ny2 = d.y + r; 
     quadtree.visit(function(quad, x1, y1, x2, y2) { 
     if (quad.point && (quad.point !== d)) { 
     var x = d.x - quad.point.x, 
      y = d.y - quad.point.y, 
      l = Math.sqrt(x * x + y * y), 
      r = d.radius + quad.point.radius + (d.cluster === quad.point.cluster ? padding : clusterPadding); 
     if (l < r) { 
      l = (l - r)/l * alpha; 
      d.x -= x *= l; 
      d.y -= y *= l; 
      quad.point.x += x; 
      quad.point.y += y; 
     } 
     } 
     return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1; 
    }); 
    }; 
} 

cevap

2

kuvvet simülasyon sona erdi çünkü açıklanan Bu davranış olur. Yani, en basit çözümdür her tıklamasıyla kuvvet yeniden ısıtma:

.on("click", function(d) { 
    d.radius *= 1.1; 
    d3.select(this).attr("r", d.radius); 
    force.resume(); 
}) 
İşte

, force.resume():

0.1 soğutma parametre alfa ayarlar. Bu yöntem dahili alfa parametresini 0,1 olarak ayarlar ve sonra zamanlayıcıyı yeniden başlatır. Genellikle, doğrudan bu yöntemi çağırmanız gerekmez; başlangıçta otomatik olarak çağrılır. Sürükleme hareketi sırasında otomatik olarak sürükleme olarak da adlandırılır. https://jsfiddle.net/usb7nhfm/

: Burada

güncellenmiş keman olduğunu
İlgili konular