15

私は、Raphaelを使用してプリミティブな形状(長方形、楕円、三角形など)と線を描画するが、ユーザーがこれらのオブジェクトを移動/サイズ変更できるようにするアプリケーションに取り組んでいます。主な要件の1つは、図形の面にフォーマットされたテキストを含めることができることです。実際のテキストはMarkdownのサブセット(太字、斜体、リストなどの単純なもの)であり、HTMLとしてレンダリングされます。

FWIW-形状ロジックをモジュール化するためにBackbone.jsビューを使用しています。

アプローチ1

私の最初の考えは、foreignObjectforSVGとダイレクトHTMLとVMLforIEの組み合わせを使用することでした。ただし、IE9はをサポートしていないためforeignObject、このアプローチは中止する必要がありました。

アプローチ2

キャンバスオブジェクトの横にdiv、実際のHTMLを含むを追加します。次に、背景を透明にして実際の形状の上に配置します。実際のラファエル形状と「オーバーレイ」の両方を参照する形状ビューを作成しましたdiv。このアプローチにはいくつかの問題があります。

  1. SVG/VMLコンテナの子ではないオーバーレイを使用するのは間違っていると感じます。このオーバーレイ要素があると、将来のレンダリングで他の問題が発生しますか?

  2. 通常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. 図形が重なると、テキスト/図形が異なるレイヤー上にあるため、テキストが重なります。重なり合う形状は一般的ではありませんが、これは見栄えが悪いです。

    オーバーラップ

このアプローチは私が現在使用しているものですが、それは巨大なハックのように感じます。

アプローチ3

アプローチ1とほぼ同じですが、これにはテキストノード/VMLノードを直接書き込む必要があります。これに関する最大の問題は、必要な手動変換の量です。RaphaelのAPIの外部に侵入すると、他のRaphaelオブジェクトで安定性の問題が発生する可能性があるようです。

質問

他の誰かが同様のことをしなければなりませんでしたか(SVG / VML内でHTMLをレンダリングする)?もしそうなら、どのようにしてこの問題を解決しましたか?イベントは考慮されましたか?

4

2 に答える 2

4

私はRaphael を使用してこのプロジェクト を構築しました(ライブではなくなりました) 。私が実際にしたことは、SVG 内で HTML を使用するという考えを放棄しました。代わりに、HTML レイヤーを SVG レイヤーの上に完全に配置し、それらを一緒に移動しました。HTML を表示したいときは、HTML をフェード インし、対応する SVG オブジェクトをフェード アウトするだけでした。タイミングが合って正しく並べられていれば、訓練されていない目にはあまり目立ちません。

これは必ずしもあなたが探しているものではないかもしれませんが、あなたの問題にアプローチするための新しい方法を考えるきっかけになるかもしれません! そのページの JS は縮小されていないので、気軽に見てください ;)

PS、プロジェクトはリード収集アプリケーションです。それがどのように機能するかを確認したいだけの場合は、最初のドロップダウンで「友達」を選択してください。情報を提供する必要はありません.

于 2012-05-09T23:16:26.130 に答える
0

別の回答が提供され、私の解決策よりも優先されない限り、追加の div レイヤーを続行しました。イベントの転送が最も困難な部分でした (転送イベントのコードが必要な場合は、ここに投稿できます)。繰り返しになりますが、このソリューションの最大の欠点は、図形が重なると、テキストが実際に描画された図形の上に重なってしまうことです。

于 2012-05-17T22:03:13.023 に答える