0

この問題に対する最善のアプローチについてアドバイスが必要です:

私は RaphaëlJS に狂ったように恋に落ちました.SVGは私と私のコーディングにとって SVG を実現可能にしてくれました。

.jsただし、ページにレンダリングするすべての SVG グラフィックのファイルを含める必要はありません。

それで、もっと「動的」なものを見つけることができるかどうかを確認するためにインターネットを探し回ったところ、これを見つけました: (以下は、ここで見つけたコードの編集バージョンです: http://groups.google.com/グループ/raphaeljs/msg/ce59df3d01736a6f )

function parseXML(xml) { 
  if (window.ActiveXObject && window.GetObject) { 
    var dom = new ActiveXObject('Microsoft.XMLDOM'); 
    dom.loadXML(xml); 
    return dom; 
  } 
  if (window.DOMParser) {
    return new DOMParser().parseFromString(xml, 'text/xml');
    throw new Error('No XML parser available');
  }
}

(function($) {

  $.fn.render_raphaels = function(options) {
    var defaults, options, counter, img_path, doc, root, vb, dims, img, node, path, atts, container, new_svg, inline;
    defaults = {};
    options = $.extend(defaults, options);

    counter = 0;
    inline = false;
    // find all the img's that point to SVGs
    $('img[src*="\.svg"]').each(function() {
      $(this).fadeOut(1000);
      img_path = $(this).attr('src');
      if (!$(this).attr('id')) new_svg = true;
      if ($(this).hasClass('inline')) inline = true;
      container = jQuery('<div/>', {
        id: $(this).attr('id') ? $(this).attr('id') : 'svg-' + (counter + 1),
        'class': $(this).attr('class') ? $(this).attr('class') : 'svg'
      }).hide().insertBefore($(this));

      $.get(img_path, null, function(doc) { 

        doc = parseXML(doc);
        root = $(doc).find('svg')[0];
        dims = [root.getAttribute('width'), root.getAttribute('height')];

        if(new_svg) container.css({ width: dims[0], height: dims[1] });
        if(inline) container.css('display', 'inline-block');

        img = Raphael(container.attr('id'), parseInt(dims[0]), parseInt(dims[1]));

        $(root).find('path').each(function() {
          node = this;
          path = img.path($(this).attr('d'));


          $(['stroke-linejoin','stroke','stroke-miterlimit','stroke-width','fill','stroke-linecap']).each(function() { 
            if($(node).attr(this.toString())) {
              path.attr(this, $(node).attr(this.toString()));
            } else {
              path.attr(this, 0);
            }
          });


          if($(node).attr('style')) {
            atts = $(node).attr('style').split(';');
            for(var i=0; i < atts.length; i++) { 
              bits = atts[i].split(':');
              path.attr(bits[0],bits[1]);
            }
          }

        });

      }, 'text');

      $(this).remove(); // removes the original image after the new one has been redrawn
      container.fadeIn(2000);
    });

  };

})(jQuery);

要するに、これにより、通常のイメージ タグを.svgグラフィックと共に記述するだけで済み、jQuery プラグインがそれを Raphaël でレンダリングされたバージョンに自動的に置き換えます。

これは、IE などの非 SVG 準拠のブラウザーではうまく機能しますが、実際に既に SVG グラフィックスをサポートしている最新のブラウザーでは、イメージ タグはそのまま (Raphaël なしで) 機能するため、Raphaël がロードされると、既存のイメージがアンロードされ、フェードインします。 Raphaëlバージョン...本質的にちらつきを作成します。新しいバージョンをフェードインしてこれを軽視しようとしましたが、古いバージョンが表示され、隠され、再び表示されるという問題にまだ直面しています。

IE などの問題のあるブラウザーでの望ましい動作と、Safari 4 や Firefox 3 などの最新の標準準拠ブラウザーでの望ましくない動作を調整する方法が必要です。しかし、私が持っていない方法でこれを行いたいです。コーディング方法を大幅に変更する (そもそもプラグインを使用する理由)。

SVG がまだ少し最先端であることは知っていますが、これを回避する方法について何か考えがある人はいますか?

免責事項: 可能な限り、ブラウザーのターゲティングは避けたいと思います... 私は、ブラウザーのハッキングではなく、管理しやすく機能的なワークフロー ソリューションを探しています。

免責事項 2: Flash に基づくソリューションは必要ありません。私はできるだけ「ネイティブ」になりたいと思っており、JavaScript は Flash よりもはるかにネイティブであると考えています。(これが、私がラファエルにとても興奮している理由です。フラッシュから離れることができるからです)。

4

2 に答える 2

0

そうです、私はこれを思いつきました...(Ruby on Railsを使用して、ところで)

  1. SVG グラフィックスをエクスポートpublic/images/svg/
  2. 実行rake svg:parse:to_json(以下の私の rake タスク ソース)
  3. JSON パス データを使用して Raphaël グラフィックを再描画します。
  4. のみを使用して SVG グラフィックを呼び出します<span class="svg">name_of_svg_file</span>(CSS を使用してデフォルトでスパンを非表示にし、以下の変更された jQuery プラグインを使用して再描画します)。

これは、Illustrator から HTML への私のワークフローが非常にクリーンであることを意味します (Capistrano のデプロイ中に rake タスクを開始しました)。これは、これまでにテストした (Raphaël がサポートする) ほぼすべてのブラウザーで高速かつちらつきのないレンダリングを行い、Flash を必要とせず、SVG ごとに 1 行のコードしか記述しないという点で、質問で概説した私のニーズを満たします。グラフィック (グラフィック<span>の名前を持つタグ)。

リファクタリング歓迎。

ToDo: 現時点では、ユーザーが JavaScript をオフにしている場合、代替手段はありません。単純な<noscript>ブロックが私を助けるかもしれないと思います...


parse_svg.rake

require 'hpricot' # >= 0.8.2
require 'json/pure'

namespace :svg do
  namespace :parse do
    desc "Parse all SVG graphics in '/public/images/svg' into JSON libraries in '/public/javascripts/raphael/svg-js/' usable by Raphaël"
    task :to_json do
      FileList['public/images/svg/*.svg'].each do |svg|
        name = File.basename(svg).split('.')[0]
        doc = open(svg) { |f| Hpricot.XML(f) } # parse the SVG
        js = {} # container
        js[:name] = name
        js[:width] = doc.at('svg')['width'].to_i
        js[:height] = doc.at('svg')['height'].to_i
        js[:paths] = [] # all paths
        doc.search("/svg/g//path").each do |p|
          path = {} # our path hash
          path[:path] = p['d'].gsub(/(?:[\r\n\t])+/, ',')
          path[:stroke_width] = p['stroke-width'] || 0
          path[:stroke] = p['stroke'] || 0
          path[:fill] = p['fill'] || 0
          js[:paths] << path
        end
        File.open("public/javascripts/raphael/svg-js/#{name}.js", 'w') { |f| f.write(js.to_json) }
      end
      puts "Done!"
    end
  end
end

render_raphaels.jquery.js

(function($) {
  $.fn.render_raphaels = function(options) {
    var defaults, options, name, container, raphael;
    defaults = {
      span_id: 'svg-ref'
    };
    options = $.extend(defaults, options);
    // find all the spans that point to SVGs, based on default or passed-in identifier
    $('span.'+options.span_id).each(function() {
      name = $(this).text();
      $.getJSON('/javascripts/raphael/svg-js/' + name + '.js', function(data) {
        paper = Raphael(document.getElementById(data.name), data.width, data.height);
        for (var p in data.paths) {
          paper.path(data.paths[p].path).attr({
            fill: data.paths[p].fill,
            stroke: data.paths[p].stroke,
            'stroke-width': data.paths[p].stroke_width
          });
        }
      });
      // remove the span
      $(this).remove();
    });
  };
})(jQuery);

SVG を含むすべてのページで呼び出す

$.fn.render_raphaels({ span_id: 'svg' });
于 2010-01-28T18:39:30.810 に答える
0

svgwebを試しましたか?

ネイティブ サポートがない場合、Flash プラグインがトリガーされて SVG がレンダリングされます。

于 2010-01-26T08:06:58.067 に答える