用JS绘制草图

时间:2011-09-07 08:15:21

标签: javascript canvas

我很难通过

来思考这个问题

假设你有一个用JS构建的草图应用程序。例如:http://intridea.github.com/sketch.js/

并且您希望在绘制内容后存储用户的绘图。因此,每当有人访问该网站时,它都会加载所有以前的图纸。实时多用户绘图有点伪造,因为目前实时制作并不是一种选择。

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

感谢。

3 个答案:

答案 0 :(得分:5)

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

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

您可以通过加载发布到服务器的数据来恢复画布。例如,请参见:http://www.html5canvastutorials.com/advanced/html5-canvas-load-image-data-url/

答案 1 :(得分:2)

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

JS无法以完美绘图应用程序所需的分辨率轮询鼠标坐标。对于轻松,有趣的素描,你可以逃脱它。但是,模拟Photoshop质量是不可能的。此问题主要导致切面草图线。您可以在链接的示例中略微看到这一点,但如果您没有使用原生线条绘制功能而是使用自定义图章形状,则会非常明显。

通过Jan Jongboom解释的方法可以上传用户的画布状态,但这并非没有问题。考虑这种情况:user1user2同时连接到应用程序,并用空白画布迎接。 user1绘制一个大的红色填充圆圈,然后user2绘制一个大的蓝色填充三角形。来自外部观察者,user1首先绘制了它们的形状,user2将它们绘制成第二个。在一个相当可能的情况下,让我们假设user2的绘图由于网络延迟而在user1之前完成上传到服务器。您的服务器会错误地将user1的状态保存在user2之上。这是问题的一个相当简化的版本,但它是一个巨大的问题,因为系统可以扩展,多个人同时绘制。人们最终会相互吸引,每个本地用户的画布状态会有所不同。

要考虑的另一个问题是,在每个操作之后上传画布数据根本不会根据画布的分辨率进行缩放。如果您正在设计应以全屏分辨率运行的内容,则在每次操作后上传(例如)1680x1050图像肯定效率不高。相反,您应该查看传输重新创建用户操作所需的信息。这是一种更好的方法(即在[4,6]处绘制半径为9px的蓝色圆圈)。这也有助于数据库组织。

我接受了一段时间的一个选择是让PHP更新每个人都在使用的画布的服务器端图像。当服务器收到更新时,PHP将加载用户在本地使用的相同资源,并执行相同的绘图操作。然后,当新用户连接时,他们只是抓取最新的服务器端图像并在本地处理任何其他更新以赶上其他人。遗憾的是,由于所有PHP的图像功能都是基于CPU的,并且当您处理诸如画笔调整大小,旋转,透明度和间距之类的事情时,它只需要很长时间才能将更新处理为值得。

除线路质量外,您将面临的最大问题是让每个人保持同步。为了您的目的,这可能不是一个问题,但如果你想在浏览器中实现多用户Photoshop,这是一个相当大的票据项目。

如果您对此或具体想法/方法有任何其他疑问,请随时提出。

答案 2 :(得分:0)

如果您仍然希望以后能够编辑图形,则会遇到toDataURL方法的问题。

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

我在Github的this issue回答了这个问题。

» My full implementation incl. undo/redo

# 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}")

这是CoffeeScript,你可以convert it to JS如果你喜欢这个,但它有点神秘。