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

svg manipulation app - record and play svg manipulations

我正在寻找一个移动应用程序,用户可以在其中拍摄 SVG 图像,在 "recording" 下对其进行操作,然后将录制的内容发送给朋友,让他们发送给 "replay"。

我有一些使用 D3.js 的经验,也看过 Snap.svg 用于 SVG 操作的库,但我并没有完全了解如何实现它。

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

知道怎么做吗?

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

步骤

  1. 使用更新按钮更新 SVG。
  2. 点击清除按钮还原图表。
  3. 现在点击播放按钮重播最近的更新。

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>