svg操作应用程序 - 记录和播放svg操作

时间:2016-10-04 02:29:33

标签: d3.js svg snap.svg

我正在构建一个moble应用程序,用户可以在其中拍摄SVG图像,在"录制"下操作它,然后将录制内容发送给他们的朋友#34 ;重放"

我对D3.js有一些经验,并且还查看了Snap.svg库以进行SVG操作,但我还没有完全理解如何实现它。

特别是,能够保存用户正在进行的操作然后重放"的好方法是什么?他们?例如,我可以使用D3.js来操纵SVG,但由于这是基于代码的,我不能完全"序列化"动画,以便发送给其他人,并让他们能够重播"它。我不想沿着代码生成的路线走下去。

任何想法如何做到这一点?

1 个答案:

答案 0 :(得分:1)

我不确定您的应用目标有多复杂。但是,很容易将SVG中的更新序列化为JSON数组并使用d3重放它们。这是一个小例子。

步骤

  1. 使用更新按钮更新SVG。
  2. 点击清除按钮恢复图表。
  3. 现在点击播放按钮重播上次更新。
  4. 
    
    var defaults = [{
      key: "r",
      val: 15,
      type: "attr"
    }, {
      key: "fill",
      val: "blue",
      type: "style"
    }];
    var updates = [];
    var c20 = d3.scale.category20();
    var circles = d3.selectAll("circle");
    
    d3.select("#increase_rad")
      .on("click", function() {
        var val = parseInt(d3.select("circle").attr("r")) + 1;
        circles.attr("r", val);
        updates.push({
          "key": "r",
          "val": val,
          "type": "attr"
        });
        enableButton();
      });
    
    d3.select("#decrease_rad")
      .on("click", function() {
        var val = parseInt(d3.select("circle").attr("r")) - 1;
        circles.attr("r", val);
        updates.push({
          "key": "r",
          "val": val,
          "type": "attr"
        });
        enableButton();
      });
    
    d3.select("#change_color")
      .on("click", function() {
        var val = c20(Math.floor(Math.random() * (18) + 1));
        circles.style("fill", val);
        updates.push({
          "key": "fill",
          "val": val,
          "type": "style"
        });
        enableButton();
      });
    
    d3.select("#clear")
      .on("click", function() {
        applyEffects(defaults);
      });
    d3.select("#play")
      .on("click", function() {
        applyEffects(updates);
      });
    
    function applyEffects(effects, delay) {
      var trans = circles.transition()
      effects.forEach(function(update) {
        if (update.type == "attr") {
          trans = trans.attr(update.key, update.val).transition();
        } else {
          trans = trans.style(update.key, update.val).transition();
        }
      });
    }
    
    function enableButton() {
      d3.select("#clear").attr("disabled", null);
      d3.select("#play").attr("disabled", null);
    }
    
    svg {
      background: white;
    }
    .link {
      stroke: black;
    }
    .node {
      fill: blue;
    }
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
    <div>
      <input type="button" value="Clear" id="clear" disabled />
      <input type="button" value="Play" id="play" disabled />
      <br/>
      <br/>
      <input type="button" value="Increase Radius" id="increase_rad" />
      <input type="button" value="Decrease Radius" id="decrease_rad" />
      <input type="button" value="Change Color" id="change_color" />
    </div>
    <svg width="250" height="250">
      <g id="links">
        <line class="link" x1="138.0538594815113" y1="55.927846328346924" x2="58.77306466322782" y2="110.43892621419347"></line>
        <line class="link" x1="138.0538594815113" y1="55.927846328346924" x2="195.04044384802015" y2="133.44259356292176"></line>
      </g>
      <g id="nodes">
        <g class="node" transform="translate(138.0538594815113,55.927846328346924)">
          <circle r=15></circle>
        </g>
        <g class="node" transform="translate(58.77306466322782,110.43892621419347)">
          <circle r=15></circle>
        </g>
        <g class="node" transform="translate(195.04044384802015,133.44259356292176)">
          <circle r=15></circle>
        </g>
      </g>
    </svg>
    &#13;
    &#13;
    &#13;