簡體   English   中英

點擊幾下動畫凍結了,為什么?

[英]After a few clicks the animation freezes, why?

我有以下代碼,我從這里開始修改

這是我的jsfiddle在行動

我目前正在開發一個需要這些氣泡的用戶交互,正好是5個氣泡,它們會被吸引到屏幕的中心。 問題是,我知道用戶點擊每個氣泡的次數。 我注意到的是,在某些時候氣泡不斷增長,但它們之間的碰撞將停止工作。

在這里,您可以看到修改的代碼:

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

您描述的那種行為發生是因為力模擬已經結束。 因此,最簡單的解決方案是在每次點擊時重新加熱力

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

這里, force.resume()

將冷卻參數alpha設置為0.1。 此方法將內部alpha參數設置為0.1,然后重新啟動計時器。 通常,您不需要直接調用此方法; 它是由start自動調用的。 在拖動手勢期間也會通過拖動自動調用它。

這是您更新的小提琴: https//jsfiddle.net/usb7nhfm/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM