私は、Raphaelを使用してプリミティブな形状(長方形、楕円、三角形など)と線を描画するが、ユーザーがこれらのオブジェクトを移動/サイズ変更できるようにするアプリケーションに取り組んでいます。主な要件の1つは、図形の面にフォーマットされたテキストを含めることができることです。実際のテキストはMarkdownのサブセット(太字、斜体、リストなどの単純なもの)であり、HTMLとしてレンダリングされます。
FWIW-形状ロジックをモジュール化するためにBackbone.jsビューを使用しています。
アプローチ1
私の最初の考えは、foreignObject
forSVGとダイレクトHTMLとVMLforIEの組み合わせを使用することでした。ただし、IE9はをサポートしていないためforeignObject
、このアプローチは中止する必要がありました。
アプローチ2
キャンバスオブジェクトの横にdiv
、実際のHTMLを含むを追加します。次に、背景を透明にして実際の形状の上に配置します。実際のラファエル形状と「オーバーレイ」の両方を参照する形状ビューを作成しましたdiv
。このアプローチにはいくつかの問題があります。
SVG/VMLコンテナの子ではないオーバーレイを使用するのは間違っていると感じます。このオーバーレイ要素があると、将来のレンダリングで他の問題が発生しますか?
通常Raphaelによってトラップされるイベント(ドラッグ、クリックなど)は、オーバーレイからRaphaelオブジェクトに転送する必要があります。をサポートするブラウザの場合
pointer-events
、これは簡単に実行できます。div.shape-text-overlay { 位置:絶対; 背景:なし; ポインタイベント:なし; }
ただし、他のブラウザー(IE8以下など)では、イベントを転送する必要があります。
var forwardedEvents ='mousemove mousedown mouseup click dblclick mouseover mouseout'; this。$elText.on(forwardedEvents、function(e){ var original = e.originalEvent; varイベント; if(document.createEvent){ event = document.createEvent('HTMLEvents'); event.initEvent(e.type、true、true); } そうしないと { イベント=document.createEventObject(); event.eventType = e.type; } //参考までに-これは、イベント転送の最も単純なアプローチです。 //私の実際の実装ははるかに大きく、MouseEventsとUIEventsを別々に使用します。 event.eventName = e.type; _.extend(event、original); if(document.createEvent){ that.el.node.dispatchEvent(event); } そうしないと { that.el.node.fireEvent('on' + event.eventType、event); } });
図形が重なると、テキスト/図形が異なるレイヤー上にあるため、テキストが重なります。重なり合う形状は一般的ではありませんが、これは見栄えが悪いです。
このアプローチは私が現在使用しているものですが、それは巨大なハックのように感じます。
アプローチ3
アプローチ1とほぼ同じですが、これにはテキストノード/VMLノードを直接書き込む必要があります。これに関する最大の問題は、必要な手動変換の量です。RaphaelのAPIの外部に侵入すると、他のRaphaelオブジェクトで安定性の問題が発生する可能性があるようです。
質問
他の誰かが同様のことをしなければなりませんでしたか(SVG / VML内でHTMLをレンダリングする)?もしそうなら、どのようにしてこの問題を解決しましたか?イベントは考慮されましたか?