HTML5画布的弹出菜单

时间:2013-10-10 10:33:13

标签: javascript html5-canvas kineticjs

我有一个HTML5画布应用程序绘制一些形状(目前使用KineticJS)。我想在用户将鼠标悬停在形状上时显示一个弹出菜单。

菜单看起来应该与普通的右键单击弹出菜单相似,但我更喜欢它是否具有一些富文本格式化功能(例如,某些菜单项是另一种颜色或粗体),并且它不必右键单击(只在悬停时显示)。

每个形状在弹出菜单中可以具有不同数量的元素(因此菜单具有灵活的高度),并且每个元素可以是不同的文本长度(因此具有不同的宽度)。可单独点击的元素是可选的额外元素。

虽然我确信我可以通过一些努力手工制作这样的功能(计算所有文本的字体度量,绘制矩形和文本以呈现每个元素等),这似乎重新发明了轮子,我我想使用一些现有的库来做这件事(或者至少帮助布局)。

现在,我看过:

  • 一些适当的原生KineticJS方式(或者至少有布局帮助) - 到目前为止还没有找到一个,据我所知,我必须计算fontmetrics,布局大小,然后手动设置文本/格式化矩形的所有坐标。

  • ZebKit - 但我不确定ZebKit和KineticJS是否能在一张HTML5画布上很好地配合。

  • html2canvas - 为了将菜单作为HTML片段呈现给图像,然后将其渲染回画布上;但它似乎不适用于隐藏/屏幕外的HTML片段。

  • 其他HTML5框架,例如EaselJs,Paper.js - 似乎没有提供此类功能

  • htmlcanvas - 4年前放弃

  • rasterizeHTML - 看起来很有前途,但在我的Chrome下无效。

  • 远离HTML5 Canvas,只是使用类似JsGraphics之类的东西做非常精美的CSS绘图,然后使用类似jQuery UI或任何适当的HTML框架来代替。这将严重限制我的应用程序的其他功能,只是为了使菜单更容易。

  • 生成动态SVG,使用canvg渲染 - 仍然需要手动为SVG计算布局,它似乎不是正确的工具

  • GWT + LibGDX + TWL - 看起来非常复杂且相当矫枉过正

一个相关的(虽然更通用,因为它侧重于抽象HTML,但在我的情况下,任何结构化的东西最终看起来像一个弹出菜单)这样的问题就是这个:

我错过了一些相对简单的标准解决方案吗?

编辑 - rasterizeHTML似乎仍然有些看好,但我得到了:

Uncaught SecurityError: An attempt was made to break through the security policy of the user agent. [VM] kinetic-v4.7.2.js (521):7621
  Kinetic.Util.addMethods.getIntersection [VM] kinetic-v4.7.2.js (521):7621
  Kinetic.Util.addMethods.getIntersection [VM] kinetic-v4.7.2.js (521):7196
  Kinetic.Util.addMethods._mousemove [VM] kinetic-v4.7.2.js (521):7294
  (anonymous function)
Unable to get image data from canvas because the canvas has been tainted by cross-origin data. [VM] kinetic-v4.7.2.js (521):7
  Kinetic.Util.addMethods.getIntersection [VM] kinetic-v4.7.2.js (521):7621
  Kinetic.Util.addMethods.getIntersection [VM] kinetic-v4.7.2.js (521):7196
  Kinetic.Util.addMethods._mousemove [VM] kinetic-v4.7.2.js (521):7294
  (anonymous function)

......做类似......的事情。

result.popupMenu = new Kinetic.Shape({
    drawFunc: function(context) {
        var subCanvas = renderToCanvas(578, 200, function(canvas) {
            rasterizeHTML.drawHTML(result.popupMenuHtml, canvas, {}, function(image) {
                context.drawImage(image, 0, 0);
            });
        });
    });

基本上看起来渲染的图像被认为是不安全的,因此破坏了整个上下文,而KineticJS对此并不满意。

1 个答案:

答案 0 :(得分:0)

我正在做一个Jasper报告,将弹出菜单生成为服务器上的图像,然后将其加载到Kinetic.Image中以实际显示。可能不是最好的解决方案,但现在可以使用。