用JS绘制草图

Sketching with JS

本文关键字:绘制 JS      更新时间:2023-09-26

我很难把这件事想清楚

假设你有一个用JS构建的草图应用程序。例如:http://intridea.github.com/sketch.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');
    });
});

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

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

JS没有能力在一个完美的绘图应用程序真正需要的分辨率下轮询鼠标坐标。对于轻松,有趣的素描,你可以摆脱它。但是,模仿Photoshop的质量是不可能的。这个问题主要导致多面素描线条。您可以在链接的示例中稍微看到这一点,但是如果您不使用本地的线条绘制函数,而是使用自定义的邮票形状,那么它就过于明显了。

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

另一个需要考虑的问题是,在每个动作之后上传画布数据根本不随画布的分辨率而缩放。如果你正在设计一些应该在全屏分辨率下运行的内容,那么在每个动作之后上传(例如)一个1680x1050的图像肯定是没有效率的。相反,您应该考虑传输重新创建用户操作所需的信息。这是一个好得多的方法。在[4,6]处画一个半径为9px的蓝色圆。这也有助于更好地组织数据库。

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

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

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

如果您仍然希望能够编辑绘图之后,您将有一个问题与toDataURL方法。

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

我在Github上回答了这个问题。

»我的完整实现包括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,如果你喜欢的话你可以把它转换成JS但是它有点神秘