9

このSVGコンテナにパスがあります。編集したいので、パスの塗りつぶしがパターンになります。これは私の失敗した試みです:

グラデーションを追加します:

$('svg defs').prepend('<linearGradient id="MyGradient"><stop offset="5%" stop-color="#F60" /><stop offset="95%" stop-color="#FF6" /></linearGradient>');

次に、パスの塗りつぶしを変更します。

$(base + ' svg path').each(function() {
    this.setAttribute('fill','url(#MyGradient)')
}

これは機能しません。私は何が欠けていますか?

4

4 に答える 4

24

あなたの問題(「欠けている」もの)は、jQueryがXHTML名前空間に新しい要素を作成するのに対し、SVG要素はSVG名前空間に作成する必要があることです。SVG 要素の文字列で raw コードを使用することはできません。

最も単純な (プラグインを使用しない) メソッドは、jQuery に頼るのをやめて、単純な DOM メソッドを使用して要素を作成することです。はい、jQuery を使用して要素を魔法のように構築するよりも冗長ですが、この場合 jQuery は機能しません。

デモ: http://jsfiddle.net/nra29/2/

createGradient($('svg')[0],'MyGradient',[
  {offset:'5%', 'stop-color':'#f60'},
  {offset:'95%','stop-color':'#ff6'}
]);
$('svg path').attr('fill','url(#MyGradient)');

// svg:   the owning <svg> element
// id:    an id="..." attribute for the gradient
// stops: an array of objects with <stop> attributes
function createGradient(svg,id,stops){
  var svgNS = svg.namespaceURI;
  var grad  = document.createElementNS(svgNS,'linearGradient');
  grad.setAttribute('id',id);
  for (var i=0;i<stops.length;i++){
    var attrs = stops[i];
    var stop = document.createElementNS(svgNS,'stop');
    for (var attr in attrs){
      if (attrs.hasOwnProperty(attr)) stop.setAttribute(attr,attrs[attr]);
    }
    grad.appendChild(stop);
  }

  var defs = svg.querySelector('defs') ||
      svg.insertBefore( document.createElementNS(svgNS,'defs'), svg.firstChild);
  return defs.appendChild(grad);
}

ライブラリの使用

または、 Keith Woods の「jQuery SVG」プラグインを含めることもできます。このプラグインには、線形グラデーションを作成する機能など、一般的な SVG 操作のための便利なメソッドが多数含まれています。

于 2012-06-05T13:32:40.640 に答える
3

解決策を見つけました。少し醜いですが、追加のプラグインを使用する必要はありません。

どうやら、SVGが最初に作成されたときにパターンをタグに含める必要があります(おそらくその後にのみ読み取られます)。

したがって、SVGタグのラッパーの内容をそれ自体で置き換えることは機能します(baseそのラッパーである):

$(base).html($(base).html())
于 2012-06-05T09:25:20.917 に答える
3

jQuery 用の SVG プラグインを使用する必要があると思います (ここにあります)。「通常の」jQuery ライブラリを使用して SVG 要素を追加すると、名前空間が混同される可能性があります。

次のことを試してください。

svg.linearGradient( $('svg defs'), 
                    'MyGradient', 
                    [ ['5%', '#F60'], ['95%', '#FF6']] );

(ただし、正確にはわかりません。そのコードを少しいじる必要があるかもしれません。)

編集

論文をテストするために、このフィドルを作成しました(@Phrogzの提案による)。実際http://www.w3.org/1999/xhtml、挿入された の名前空間として返されますが<linearGradient>、これは間違った名前空間であるため、上記の推測を検証します。

于 2012-06-05T09:11:47.477 に答える
3

ちょっと立ち寄って、jQuery SVG ライブラリ (更新されなくなり、jQuery 1.8 以降でいくつかの問題があります) なしで、SVG 要素で jQuery を使い続けることができる、より洗練されたソリューションを見つけたと言いたいだけです。次のような関数を使用するだけです。

createSVGElement= function(element) {
    return $(document.createElementNS('http://www.w3.org/2000/svg', element));
}

SVG 名前空間で SVG 要素を作成し、jQuery でカプセル化します。要素が適切な名前空間で作成されると、jQuery で自由に使用できます。

次に、この方法で関数を使用できます。

var $myGradient= createSVGElement('linearGradient')
    .attr( {
        id:"MyGradient"
    });

//if you dont need `defs`, skip this next line
var $myDefs = createSVGElement('defs');

createSVGElement('stop')
    .attr({
        offset: "5%",
        "stop-color": "#F60"
    })
    .appendTo($myGradient);


createSVGElement('stop')
    .attr({
        offset:"95%",
        "stop-color":"#FF6"
    })
    .appendTo($myGradient);

//Use this if you already have `defs`
$('svg defs').prepend($myGradient);

//Use this if you dont have `defs`
$('svg').prepend($myDefs);
$('svg defs').prepend($myGradient);

各要素を手動で作成する必要があるため、必要なほどコンパクトではありませんが、DOM メソッドですべてを操作するよりははるかに優れています。

jQuery .attr() 関数は、すべての属性が小文字であると想定していますが、これは SVG 要素 (タグviewBox内の属性など) には当てはまりません。<svg>これを回避するには、大文字で属性を設定するときに次のようなものを使用します。

$("svg")[0].setAttribute("viewBox", "0 0 1000 1000");
于 2013-02-06T13:48:37.267 に答える