我有一个 HTML5 画布应用程序绘制一些形状(目前使用 KineticJS)。每当用户将鼠标悬停在形状上时,我想显示一个弹出菜单。
该菜单应该看起来与普通的右键单击弹出菜单相当相似,但如果它具有一些富文本格式功能(例如,某些菜单项是另一种颜色或粗体),我更喜欢它,并且它不必位于右键单击(只在悬停时出现)。
每个形状在弹出菜单中可以有不同数量的元素(因此菜单具有灵活的高度),并且每个元素可以是不同的文本长度(因此具有不同的宽度)。可单独点击的元素是可选的附加功能。
虽然我确信我可以通过一些努力来手工制作这样的功能(计算所有文本的字体度量,绘制矩形和文本以呈现每个元素等),但这似乎是在重新发明轮子,我想使用一些现有的库来做到这一点(或至少有助于布局)。
目前,我看过:
一些适当的本机KineticJS方法来做到这一点(或至少有助于布局) - 到目前为止还没有找到,据我所知,我必须计算字体度量、布局大小,然后设置文本/格式的所有坐标手动矩形。
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 的布局,而且它似乎不是适合这项工作的工具
一个相关的(虽然更通用,因为它专注于抽象 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 对此并不满意。