【发布时间】:2012-05-17 23:30:36
【问题描述】:
我正在开发一个使用Raphael 绘制原始形状(矩形、椭圆、三角形等)和线条的应用程序,但也允许用户移动/调整这些对象的大小。主要要求之一是形状的表面可以有格式化的文本。实际文本是 Markdown 的子集(简单的东西,如粗体、斜体、列表)并呈现为 HTML。
FWIW - 我正在使用 Backbone.js 视图来模块化形状逻辑。
方法 1
我最初的想法是结合使用foreignObject for SVG 和直接HTML 与VML for IE。但是,IE9 doesn't support foreignObject,因此不得不放弃这种方法。
方法2
在画布对象旁边,添加包含实际 HTML 的 divs。然后,将它们放置在具有透明背景的实际形状上。我创建了一个形状视图,它引用了实际的 Raphael 形状和“覆盖”div。这种方法有几个问题:
使用不是 SVG/VML 容器子级的叠加层感觉是错误的。使用此叠加元素是否会导致其他渲染问题?
-
通常被 Raphael 捕获的事件(拖动、单击等)需要从叠加层转发到 Raphael 对象。对于支持
div.shape-text-overlay { 位置:绝对; 背景:无; 指针事件:无; }pointer-events的浏览器,这很容易做到:但是,其他浏览器(如 IE8 及以下)需要转发事件:
var forwardedEvents = 'mousemove mousedown mouseup click dblclick mouseover mouseout'; this.$elText.on(forwardedEvents, function(e) { var original = e.originalEvent; 变种事件; 如果(document.createEvent){ 事件 = document.createEvent('HTMLEvents'); event.initEvent(e.type, true, true); } 别的 { 事件 = document.createEventObject(); event.eventType = e.type; } // 仅供参考 - 这是最简单的事件转发方法。 // 我真正的实现要大得多,并且分别使用 MouseEvents 和 UIEvents。 event.eventName = e.type; _.extend(事件,原始); 如果(document.createEvent){ that.el.node.dispatchEvent(event); } 别的 { that.el.node.fireEvent('on' + event.eventType, event); } }); -
重叠的形状会导致文本重叠,因为文本/形状位于不同的图层上。虽然重叠的形状并不常见,但这看起来很糟糕:
我目前正在使用这种方法,但它感觉就像一个巨大的黑客攻击。
方法 3
几乎类似于方法 1,但这将涉及直接编写文本节点/VML 节点。最大的问题是所需的手动转换量。突破 Raphael 的 API 似乎可能会导致其他 Raphael 对象出现稳定性问题。
问题
有没有其他人不得不做类似的事情(在 SVG/VML 中渲染 HTML)?如果是这样,你是如何解决这个问题的?是否考虑了事件?
【问题讨论】:
标签: javascript raphael