【问题标题】:svg manipulation app - record and play svg manipulations [closed]svg 操作应用程序 - 记录和播放 svg 操作 [关闭]
【发布时间】:2023-03-05 23:38:02
【问题描述】:

我正在寻找构建一个移动应用程序,用户可以在其中拍摄 SVG 图像,在“记录”下对其进行操作,然后将记录发送给朋友让他们“重播”。

我有一些使用 D3.js 的经验,并且还研究了 Snap.svg 库以进行 SVG 操作,但我并没有完全了解如何实现它。

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

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

【问题讨论】:

    标签: d3.js svg snap.svg


    【解决方案1】:

    我不确定您的应用程序目标有多复杂。但是,很容易将 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>

    【讨论】:

    • 这太完美了,非常感谢!对试图将其作为非法问题关闭的 3 人感到羞耻 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-07
    • 1970-01-01
    • 2014-03-10
    • 2019-01-29
    • 2011-01-04
    相关资源
    最近更新 更多