与paper.js同时绘图

时间:2015-04-21 13:13:03

标签: javascript html5 paperjs

我有一个应用程序来处理基于paper.js的绘制小部件。几个用户可以同时绘制,并且实时更改相互广播。问题是我需要存储更改并在加载文档时显示绘制的图像。

自然的解决方案是存储客户端在DB中发送的命令。但绘制的图像可以包含数千个命令,我可以拥有数十个图像。因此,当我打开文档从服务器获取命令列表时,绘图可能会花费太多时间。

有没有更好的方法来存储客户端之间的图像和交互?

请注意,我有缩放功能,因此无法存储光栅。

更新:如果我正在存储图片(例如在BLOB中),则不清楚如何应用实时更改。每次传递图像都不是我想要的解决方案。

4 个答案:

答案 0 :(得分:2)

如果您要将图形保存为图像,则可以使用一些可能的解决方案。

  1. 将项目保存在文件夹中的某个位置,并将目录路径+文件名保存在数据库中
  2. 将图像作为blob保存在数据库中。然而,Blob确实是数据库密集型的。
  3. 有一些关于blob的有趣的艺术品。与微软的this one一样。

      

    众所周知,小于256K的对象最好存储在数据库中,而大于1M的对象最好存储在文件系统中。

    因此,将图像保存到目录中是一种更好的解决方案。

    也可以导出绘制图像的svg文件。 (info)我不知道这对你有什么帮助,但这是我个人的经历。我同意你的看法,将数千个命令存储到数据库中并不是最佳解决方案。所以你可能想看一下在某个地方保存图像,但是如果你已经实现了那么你将失去编辑图像的能力。

    <强>更新

    如果您不想保存blob,最佳解决方案是每次编辑时“渲染”图像。因此,当某人打开图形时,您可以执行所有命令。并且仅在编辑被触发时应用最新的命令。

    有几种方法可以实现这一目标。就像 Jimmy Chandra 所说,firebase将是一个很好的解决方案。他们还提供tutorial几乎所有你想要实现的东西。 (使用xy坐标实时绘制图像)也许您需要查看它。

    有关Firebase的更多信息。

      

    Firebase是一个功能强大的API,可以实时存储和同步数据

    这正是你想要实现的目标。您可以尝试完整的教程here

    您可能会考虑的其他选项是nodejs。我见过有人使用nodejs聊天系统将数据发送给所有其他用户。如果你可以发送数据,我相信你可以用它来绘制图像。

    最后,您可以选择要使用的技术。所以我认为你可以调查像我建议的一些解决方案,如果你在整合这项技术时遇到麻烦,可以提出一个不同的问题。

答案 1 :(得分:1)

将客户端的数据保存为二级存储是否可以接受?

使用html5文件api,应该可以保留客户端在DB中发送的所有保存命令的副本。因此,下次打开文档时,应用程序将从辅助存储器渲染绘图,同时在服务器上查询最新更新,这些更新将在辅助存储完成渲染后附加。

使用websockets,您可以保存命令,它会将更改广播到其他客户端,从而实时更新其绘图。

答案 2 :(得分:1)

2年前,我开发了类似的东西(团队中,封闭的代码)。

首先要注意的是谷歌文档已经解决了这样的问题。我们阅读了每篇博文和关于他们如何做到的文章,并将其应用于多用户SVG,如简单的编辑器。所以这就是我记得的:

简单命令的细分是正确的方法。 正如您所写,通过它们,您可以非常详细地重新创建图像。您甚至可以准确回答每个请求时间戳的图像。

示例命令可能是

- change color
- change color again
- draw a line from .. to ..
- draw a line from .. to ..
- draw a line from .. to ..
- draw a line from .. to ..
- smooth that line
- change color
- change Stroke
- delete those lines and draw them again ;-)

回到goolge docs示例,他们保存并广播每个字符的更改(以及更多)。

是的,这是一种非常明确且可测试的方法,但要求性能需要另一个逻辑层。 有必要添加一个例程,将这些命令简化为压缩版本(见下文)

当用户请求图像时,系统会查找最新的压缩图像并添加压缩例程中未包含的单个命令。

压缩程序:

在您喜欢的矢量编辑器中录制虚拟图像的创建视频(类似于您对用户的期望),您会注意到大约60%到80%的命令对最终结果毫无用处

目标压缩程序可能包含以下三个步骤:

  1. 大多数情况下,您会看到自己在录制重新定位点,处理或移动对象,再次更改颜色设置和撤消其他参数,如笔触粗细。甚至删除元素的重做。例程需要优化这些命令以直接绘制最终结果。我确定,这会将您的命令列表缩小到10%-50%,具体取决于您要查找的图像类型。

  2. 压缩命令。上面示例中的路径是以线段绘制的,它需要。您通常不会在第一个onMouseDown上知道它将以100个段和200个句柄的路径结束。但仍然像其他用户一样展示创作过程。在程序中添加一个能够绘制路径等复杂事物的命令。您在用户绘图过程中不需要它。此命令可用于更快地重新创建完整形状。现在可以在一个命令中绘制具有100个点和200个手柄的路径。在此之前,您有一个至少300个命令的列表。

  3. 重新排序命令。两个用户同时绘制的两个路径元素不易压缩。一个简单的解决方案是按元素排序命令。创建每个形状可能需要3分钟。动画需要真正的命令顺序才能看到每个shpae同时发展,但最终结果并不关心。如果按元素排序,每个形状都可以更容易压缩。

  4. 抱歉这篇长篇文章,希望有所帮助

答案 3 :(得分:0)

我会对建筑推荐给出更广泛的答案,所以请提前向完美主义者道歉。

我将 nginx nodejs 与websockets一起用作我的应用层,并通过 npm {在我的服务器端使用paperjs {3}}

对于我的持久性级别,我不仅使用数据库集群( mysql / mongodb 等),还使用 redis 作为命令缓存。

每当在画布上执行命令时,我都会将其保存在redis中并通过 socket.io 广播给所有客户端,最后是由任何用户I&引起的终止/保存/退出等事件#39; d将其保留为 db 中的图像,或 fs ,并在我的数据库中添加路径引用。

希望这有帮助。