概要 实例 介绍 源码

蝌蚪

源文件:index.html

  1. <!DOCTYPE html>
  2. <meta charset="utf-8">
  3. <style>
  4. body {
  5. background: #000;
  6. }
  7. ellipse {
  8. fill: #fff;
  9. }
  10. path {
  11. fill: none;
  12. stroke: #fff;
  13. stroke-linecap: round;
  14. }
  15. .mid {
  16. stroke-width: 4px;
  17. }
  18. .tail {
  19. stroke-width: 2px;
  20. }
  21. </style>
  22. <body>
  23. <script src="//d3js.org/d3.v3.min.js"></script>
  24. <script>
  25. var width = 960,
  26. height = 500;
  27. var n = 100,
  28. m = 12,
  29. degrees = 180 / Math.PI;
  30. var spermatozoa = d3.range(n).map(function() {
  31. var x = Math.random() * width,
  32. y = Math.random() * height;
  33. return {
  34. vx: Math.random() * 2 - 1,
  35. vy: Math.random() * 2 - 1,
  36. path: d3.range(m).map(function() { return [x, y]; }),
  37. count: 0
  38. };
  39. });
  40. var svg = d3.select("body").append("svg")
  41. .attr("width", width)
  42. .attr("height", height);
  43. var g = svg.selectAll("g")
  44. .data(spermatozoa)
  45. .enter().append("g");
  46. var head = g.append("ellipse")
  47. .attr("rx", 6.5)
  48. .attr("ry", 4);
  49. g.append("path")
  50. .datum(function(d) { return d.path.slice(0, 3); })
  51. .attr("class", "mid");
  52. g.append("path")
  53. .datum(function(d) { return d.path; })
  54. .attr("class", "tail");
  55. var tail = g.selectAll("path");
  56. d3.timer(function() {
  57. for (var i = -1; ++i < n;) {
  58. var spermatozoon = spermatozoa[i],
  59. path = spermatozoon.path,
  60. dx = spermatozoon.vx,
  61. dy = spermatozoon.vy,
  62. x = path[0][0] += dx,
  63. y = path[0][1] += dy,
  64. speed = Math.sqrt(dx * dx + dy * dy),
  65. count = speed * 10,
  66. k1 = -5 - speed / 3;
  67. // Bounce off the walls.
  68. if (x < 0 || x > width) spermatozoon.vx *= -1;
  69. if (y < 0 || y > height) spermatozoon.vy *= -1;
  70. // Swim!
  71. for (var j = 0; ++j < m;) {
  72. var vx = x - path[j][0],
  73. vy = y - path[j][1],
  74. k2 = Math.sin(((spermatozoon.count += count) + j * 3) / 300) / speed;
  75. path[j][0] = (x += dx / speed * k1) - dy * k2;
  76. path[j][1] = (y += dy / speed * k1) + dx * k2;
  77. speed = Math.sqrt((dx = vx) * dx + (dy = vy) * dy);
  78. }
  79. }
  80. head.attr("transform", headTransform);
  81. tail.attr("d", tailPath);
  82. });
  83. function headTransform(d) {
  84. return "translate(" + d.path[0] + ")rotate(" + Math.atan2(d.vy, d.vx) * degrees + ")";
  85. }
  86. function tailPath(d) {
  87. return "M" + d.join("L");
  88. }
  89. </script>