2016-11-04 1 views
5

나는 내가 데리고 여기 here몇 번의 클릭만으로 애니메이션이 정지 된 이유는 무엇입니까?

에서 수정 다음 코드는,

나는 현재의 중앙으로 몰리는 이러한 거품, 정확히 5 거품을 필요로하는 사용자 상호 작용을 개발하고 행동 내 jsfiddle있다가 화면. 것은 사용자가이 거품 각각을 얼마나 많이 클릭 하는지를 아는 것입니다. 내가 알아챈 점은 거품이 계속 자라나지만 충돌이 멈추게된다는 것입니다.

여기를 수정 코드를 볼 수 있습니다

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

답변

2

힘 시뮬레이션이 종료 때문에 기술 그 동작이 발생합니다. 따라서, 간단한 솔루션이 모든 클릭에 힘 재가열 :

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

, force.resume()을 :

0.1로 냉각 매개 변수 (α)를 설정한다. 이 메서드는 내부 알파 매개 변수를 0.1로 설정 한 다음 타이머를 다시 시작합니다. 통상,이 Methods를 직접 호출 할 필요는 없습니다. 시작에 의해 자동으로 호출됩니다. 또한 드래그 동작 중에 드래그하여 자동으로 호출됩니다. https://jsfiddle.net/usb7nhfm/

: 여기

는 업데이트 된 바이올린입니다
관련 문제