HTML5 画布的弹出菜单

Popup menu for HTML5 canvas

本文关键字:菜单 HTML5      更新时间:2023-09-26

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

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

每个形状在弹出菜单中可以具有不同数量的元素(因此

菜单具有灵活的高度(,并且每个元素可以具有不同的文本长度(因此具有不同的宽度(。可单独点击的元素是可选的附加功能。

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

现在,我已经看了:

  • 一些适当的本机 KineticJS 方法来执行此操作(或至少有助于布局( - 到目前为止还没有找到,据我所知,我必须计算字体度量、布局大小,然后设置文本的所有坐标/手动格式化矩形。

  • ZebKit - 但我不确定ZebKit和KineticJS是否会在一个HTML5画布上很好地协同工作。

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

  • 其他HTML5框架,例如EaselJs,Paper.js - 似乎没有一个提供这样的功能

  • HTMLcanvas - 4年前被遗弃

  • 光栅化HTML - 看起来很有前途,但对我来说在Chrome下不起作用。

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

  • 生成动态 SVG,使用 canvg 渲染 - 仍然必须手动计算 SVG 的布局,而且它似乎不是适合这项工作的工具

  • GWT + LibGDX + TWL - 看起来非常复杂,而且有点矫枉过正

一个相关的(虽然更通用,因为它专注于抽象 HTML,但就我而言,任何最终看起来像弹出菜单的结构都可以(所以问题是这个:

  • 如何将 HTML 元素转换为画布元素?

我是否缺少一些相对简单的标准解决方案?

编辑 - 光栅化HTML似乎仍然有些有希望,但我得到:

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对此感到不满。

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