2016-02-10 24 views
1

我有一個defs組件的SVG,就像這樣:是對SVG def組件編輯

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 250 330" onclick="tweenGloss()"> 
    <defs> 
    <linearGradient id="grad" x1="174.62" y1="-20.2" x2="75.38" y2="350.2" gradientUnits="userSpaceOnUse"> 
     <stop offset="0" stop-color="#d4af37"/> 
     <stop offset="0.14" stop-color="#fefdfb"/> 
     <stop offset="0.27" stop-color="#d6b23f"/> 
     <stop offset="0.45" stop-color="#816e26"/> 
     <stop offset="0.59" stop-color="#d6b23f"/> 
     <stop offset="0.82" stop-color="#d6b23f"/> 
     <stop offset="0.91" stop-color="#fff"/> 
     <stop offset="1" stop-color="#d6b23f"/> 
    </linearGradient> 
    </defs> 
    <title>StickerBorder</title> 
    <rect x="5" y="292.04" width="240" height="30.58" style="fill: #aa4c4e;stroke: #4f2426;stroke-miterlimit: 10;stroke-width: 4px"/> 
    <polygon points="6.71 4 6.71 53.09 47.54 53.09 68.22 32.41 245 32.41 246.28 4 6.71 4" style="fill: #2680b8"/> 
    <polyline points="5 54.09 47.06 54.09 67.51 33.41 242.31 33.41" style="fill: none;stroke: #184c66;stroke-miterlimit: 10;stroke-width: 4px"/> 
    <rect x="5" y="5" width="240" height="320" style="fill: none;stroke-miterlimit: 10;stroke-width: 10px;stroke: url(#grad)"/> 
    <circle cx="196.64" cy="292.04" r="21.94" style="fill: #fff;stroke: #4f2426;stroke-miterlimit: 10;stroke-width: 4px"/> 
    <text transform="translate(188.7 304.34)" style="font-size: 28.58350944519043px;fill: #1d1d1b;font-family: KG Second Chances Sketch">7</text> 
</svg> 

我通過JavaScript附加幾個孩子來此像這樣:

<lineargradient id="glossgrad" x1="22.3" y1="342.88" x2="227.7" y2="-12.88" gradientunits="userSpaceOnUse"> 
    <stop offset="0" stop-color="#ff0000"></stop> 
    <stop offset="0.2" stop-color="#ff0000"></stop> 
    <stop offset="0.4" stop-color="#ff0000"></stop> 
</lineargradient> 

<rect x="5" y="5" width="240" height="320" style="fill: none;stroke-miterlimit: 10;stroke-width: 10px;stroke: url(#glossgrad)"></rect> 

因此「glossgrad」被添加到defs元素,並且rect被添加到svg元素。我的問題是,新附加的rect根本沒有出現。但是,如果我將rect的網址更改爲原始lineargradient網址,則會顯示該網址。

所以我的問題是,'defs'元素一旦有初始加載後不會更新?這是緩存還是某種東西?

+2

我們需要看到你寫的添加元素的代碼。很可能你已經將它們添加到了錯誤的名稱空間中。 –

+0

另外SVG區分大小寫,所以lineargradient不正確。 –

+0

提示:擺脫xmlns =「http://www.w3.org/2000/svg」xmlns:xlink =「http://www.w3.org/1999/xlink」,看看它是否有效(羅伯特的第1次如上所示) –

回答

3

我不知道如何追加新的線性漸變定義和rect元素。但要回答你的問題,動態附加新元素到svg defs並使用它們是沒有問題的。

這裏是一個工作示例:

var svg = document.getElementsByTagName("svg")[0]; 
 
var svgNS = svg.namespaceURI; 
 

 
createGradient(svg,'glossgrad',[ 
 
    {offset:'5%', 'stop-color':'#f60'}, 
 
    {offset:'95%','stop-color':'#ff6'} 
 
]); 
 

 
var rect = document.createElementNS(svgNS,'rect'); 
 
    rect.setAttribute('x',60); 
 
    rect.setAttribute('y',80); 
 
    rect.setAttribute('width',50); 
 
    rect.setAttribute('height',50); 
 
    rect.setAttribute('fill','url(#glossgrad)'); 
 
    svg.appendChild(rect); 
 

 
function createGradient(svg,id,stops){ 
 
    
 
    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); 
 
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 250 330" onclick="tweenGloss()"> 
 
    <defs> 
 
    <linearGradient id="grad" x1="174.62" y1="-20.2" x2="75.38" y2="350.2" gradientUnits="userSpaceOnUse"> 
 
     <stop offset="0" stop-color="#d4af37"/> 
 
     <stop offset="0.14" stop-color="#fefdfb"/> 
 
     <stop offset="0.27" stop-color="#d6b23f"/> 
 
     <stop offset="0.45" stop-color="#816e26"/> 
 
     <stop offset="0.59" stop-color="#d6b23f"/> 
 
     <stop offset="0.82" stop-color="#d6b23f"/> 
 
     <stop offset="0.91" stop-color="#fff"/> 
 
     <stop offset="1" stop-color="#d6b23f"/> 
 
    </linearGradient> 
 
    </defs> 
 
    <title>StickerBorder</title> 
 
    <rect x="5" y="292.04" width="240" height="30.58" style="fill: #aa4c4e;stroke: #4f2426;stroke-miterlimit: 10;stroke-width: 4px"/> 
 
    <polygon points="6.71 4 6.71 53.09 47.54 53.09 68.22 32.41 245 32.41 246.28 4 6.71 4" style="fill: #2680b8"/> 
 
    <polyline points="5 54.09 47.06 54.09 67.51 33.41 242.31 33.41" style="fill: none;stroke: #184c66;stroke-miterlimit: 10;stroke-width: 4px"/> 
 
    <rect x="5" y="5" width="240" height="320" style="fill: none;stroke-miterlimit: 10;stroke-width: 10px;stroke: url(#grad)"/> 
 
    <circle cx="196.64" cy="292.04" r="21.94" style="fill: #fff;stroke: #4f2426;stroke-miterlimit: 10;stroke-width: 4px"/> 
 
    <text transform="translate(188.7 304.34)" style="font-size: 28.58350944519043px;fill: #1d1d1b;font-family: KG Second Chances Sketch">7</text> 
 
</svg>

+0

正如@RobertLongson所指出的那樣,命名空間是問題所在,我使用的代碼與此非常相似,除了我只使用了'document.createElement'。切換到'document.createElementNS'並使用svg namespaceURI對它進行排序。 –

+0

我的代碼的另一個可能的問題是,我正在使用'cloneNode'來創建矩形,將其更改爲'createElementNS'似乎也是必要的 –