Javascript 用JS绘制草图

Javascript 用JS绘制草图,javascript,canvas,Javascript,Canvas,我很难把这件事想清楚 假设您有一个用JS构建的草图应用程序。例如: 您希望在用户绘制某些内容后存储用户的图形。因此,每当有人访问该站点时,它都会加载所有以前的图形。这有点假实时多用户绘图,因为使其真正实时在目前还不是一个选项 服务器端我正在使用PHP和MySQL,我不知道这是否有什么好处 谢谢。应用“sketch.js”的画布(使用$(“#myCanvas”).sketch())有一个名为toDataURL()的函数(在HTML元素上,而不是在jQuery元素上)。您可以将此函数返回的数据上载到

我很难把这件事想清楚

假设您有一个用JS构建的草图应用程序。例如:

您希望在用户绘制某些内容后存储用户的图形。因此,每当有人访问该站点时,它都会加载所有以前的图形。这有点假实时多用户绘图,因为使其真正实时在目前还不是一个选项

服务器端我正在使用PHP和MySQL,我不知道这是否有什么好处


谢谢。

应用“sketch.js”的画布(使用
$(“#myCanvas”).sketch()
)有一个名为
toDataURL()
的函数(在HTML元素上,而不是在jQuery元素上)。您可以将此函数返回的数据上载到服务器

$('#upload').click(function () {
    $.post('/upload_image.php', { data: $('#myCanvas').get(0).toDataURL() }, function () {
         alert('uploaded');
    });
});

您可以通过加载发布到服务器的数据来恢复画布。请参见此处的示例:。

像这样的项目需要解决许多复杂的问题。实际上,我最近开发了一个基于画布的实时多用户绘图应用程序,使用PHP和MySQL作为后端。一些更重要的想法是:

JS无法以完美绘图应用程序真正需要的分辨率轮询鼠标坐标。为了轻松、有趣的素描,你可以不受惩罚。不过,模仿Photoshop的质量是不可能的。此问题主要导致绘制面绘制线。您可以在链接到的示例中稍微看到这一点,但如果您不使用本机线条绘制功能,而是使用自定义戳记形状,这一点就显得过于明显了

可以通过Jan Jongboom解释的方法上传用户的画布状态,但这并非没有问题。考虑这个场景:<代码> USER1和<代码> USE2同时连接到应用程序,并用空白的画布打招呼。code>user1绘制一个大的红色填充圆圈,然后
user2
绘制一个大的蓝色填充三角形。从外部观察者的角度来看,
user1
首先绘制了它们的形状,
user2
其次绘制了它们的形状。在一个非常可能的场景中,假设由于网络延迟,
user2
的绘图在
user1
之前已完成上传到服务器。您的服务器将错误地将
user1
的状态保存在
user2
上。这是问题的一个相当简化的版本,但这是一个巨大的问题,因为系统在扩展,多人同时绘图。人们最终会在彼此之间画图,而画布的状态对于每个本地用户都是不同的

另一个要考虑的问题是,在每次动作之后,上传画布数据都不会与画布的分辨率成比例。如果你设计的东西应该以全屏分辨率运行,那么在每次操作后上传(例如)1680x1050图像肯定是没有效率的。相反,您应该考虑传输重新创建用户操作所需的信息。这是一种更好的方法(即在[4,6]处绘制一个半径为9px的蓝色圆圈)。这也有利于数据库组织

我考虑了一段时间的一个选择是让PHP更新每个人都在绘制的画布的服务器端图像。当服务器接收到更新时,PHP将加载用户在本地使用的相同资源,并执行相同的绘图操作。然后,当新用户连接时,他们只需抓取最新的服务器端映像,并在本地处理任何其他更新,以赶上其他人。不幸的是,这并没有很好的扩展性,因为PHP的所有图像函数都是基于CPU的,当您处理画笔大小调整、旋转、透明度和间距等事情时,更新需要花费太长的时间,因此不值得处理

除了线路质量,您将面临的最大问题是保持每个人的同步。出于您的目的,这可能根本不是问题,但如果您打算在浏览器中实现多用户Photoshop,这将是一个非常昂贵的项目


如果您对此或特定的想法/方法有任何其他问题,请随时提问。

如果您以后仍希望能够编辑图形,则toDataURL方法将有问题

我最近使用不同的保存方法和撤消/重做功能实现了sketch.js

我在Github上回答了这个问题

这是,你可以,如果你喜欢这个,但它有点神秘

# this is what I save via AJAX
dataURL: -> JSON.stringify(@getSketch().actions)

load: (id) ->
  $.ajax "#{@getContainer().data("target-url")}/#{id}.json",
    success: (data, status, xhr) =>
      sketch = @getSketch()
      $.each data.json_data, -> sketch.actions.push(this)
      sketch.redraw()
    error: (xhr, status, msg) => alert("Failed to load sketch! #{xhr.status}: #{msg}")