概要 实例 介绍 源码

行星齿轮传动

源文件:index.html

  1. <!DOCTYPE html>
  2. <meta charset="utf-8">
  3. <style>
  4. body {
  5. font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  6. width: 960px;
  7. height: 500px;
  8. position: relative;
  9. }
  10. form {
  11. position: absolute;
  12. top: 1em;
  13. left: 1em;
  14. }
  15. path {
  16. fill-rule: evenodd;
  17. stroke: #333;
  18. stroke-width: 2px;
  19. }
  20. .sun path {
  21. fill: #6baed6;
  22. }
  23. .planet path {
  24. fill: #9ecae1;
  25. }
  26. .annulus path {
  27. fill: #c6dbef;
  28. }
  29. </style>
  30. <form>
  31. <input type="radio" name="reference" id="ref-annulus">
  32. <label for="ref-annulus">Annulus</label><br>
  33. <input type="radio" name="reference" id="ref-planet" checked>
  34. <label for="ref-planet">Planets</label><br>
  35. <input type="radio" name="reference" id="ref-sun">
  36. <label for="ref-sun">Sun</label>
  37. </form>
  38. <script src="https://d3js.org/d3.v4.min.js"></script>
  39. <script>
  40. var width = 960,
  41. height = 500,
  42. radius = 80,
  43. x = Math.sin(2 * Math.PI / 3),
  44. y = Math.cos(2 * Math.PI / 3);
  45. var offset = 0,
  46. speed = 4,
  47. start = Date.now();
  48. var svg = d3.select("body").append("svg")
  49. .attr("width", width)
  50. .attr("height", height)
  51. .append("g")
  52. .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(.55)")
  53. .append("g");
  54. var frame = svg.append("g")
  55. .datum({radius: Infinity});
  56. frame.append("g")
  57. .attr("class", "annulus")
  58. .datum({teeth: 80, radius: -radius * 5, annulus: true})
  59. .append("path")
  60. .attr("d", gear);
  61. frame.append("g")
  62. .attr("class", "sun")
  63. .datum({teeth: 16, radius: radius})
  64. .append("path")
  65. .attr("d", gear);
  66. frame.append("g")
  67. .attr("class", "planet")
  68. .attr("transform", "translate(0,-" + radius * 3 + ")")
  69. .datum({teeth: 32, radius: -radius * 2})
  70. .append("path")
  71. .attr("d", gear);
  72. frame.append("g")
  73. .attr("class", "planet")
  74. .attr("transform", "translate(" + -radius * 3 * x + "," + -radius * 3 * y + ")")
  75. .datum({teeth: 32, radius: -radius * 2})
  76. .append("path")
  77. .attr("d", gear);
  78. frame.append("g")
  79. .attr("class", "planet")
  80. .attr("transform", "translate(" + radius * 3 * x + "," + -radius * 3 * y + ")")
  81. .datum({teeth: 32, radius: -radius * 2})
  82. .append("path")
  83. .attr("d", gear);
  84. d3.selectAll("input[name=reference]")
  85. .data([radius * 5, Infinity, -radius])
  86. .on("change", function(radius1) {
  87. var radius0 = frame.datum().radius, angle = (Date.now() - start) * speed;
  88. frame.datum({radius: radius1});
  89. svg.attr("transform", "rotate(" + (offset += angle / radius0 - angle / radius1) + ")");
  90. });
  91. d3.selectAll("input[name=speed]")
  92. .on("change", function() { speed = +this.value; });
  93. function gear(d) {
  94. var n = d.teeth,
  95. r2 = Math.abs(d.radius),
  96. r0 = r2 - 8,
  97. r1 = r2 + 8,
  98. r3 = d.annulus ? (r3 = r0, r0 = r1, r1 = r3, r2 + 20) : 20,
  99. da = Math.PI / n,
  100. a0 = -Math.PI / 2 + (d.annulus ? Math.PI / n : 0),
  101. i = -1,
  102. path = ["M", r0 * Math.cos(a0), ",", r0 * Math.sin(a0)];
  103. while (++i < n) path.push(
  104. "A", r0, ",", r0, " 0 0,1 ", r0 * Math.cos(a0 += da), ",", r0 * Math.sin(a0),
  105. "L", r2 * Math.cos(a0), ",", r2 * Math.sin(a0),
  106. "L", r1 * Math.cos(a0 += da / 3), ",", r1 * Math.sin(a0),
  107. "A", r1, ",", r1, " 0 0,1 ", r1 * Math.cos(a0 += da / 3), ",", r1 * Math.sin(a0),
  108. "L", r2 * Math.cos(a0 += da / 3), ",", r2 * Math.sin(a0),
  109. "L", r0 * Math.cos(a0), ",", r0 * Math.sin(a0));
  110. path.push("M0,", -r3, "A", r3, ",", r3, " 0 0,0 0,", r3, "A", r3, ",", r3, " 0 0,0 0,", -r3, "Z");
  111. return path.join("");
  112. }
  113. d3.timer(function() {
  114. var angle = (Date.now() - start) * speed,
  115. transform = function(d) { return "rotate(" + angle / d.radius + ")"; };
  116. frame.selectAll("path").attr("transform", transform);
  117. frame.attr("transform", transform); // frame of reference
  118. });
  119. </script>