2011-07-12 85 views
2

我有一個小應用程序,我需要爲arcs生成textPath標籤。我正在通過拉斐爾繪製弧線,這非常棒。然而Raphael不支持textPaths。我們可以通過jQuery將它們添加到svg元素中,但由於某種原因它們不會渲染。當我靜態地複製動態生成的代碼時,它呈現正常。使用jQuery修改Raphael SVG圖像

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="600" height="600"> 
    <desc>Created with Raphaël</desc><defs></defs> 
    <a title="This is a test entry"> 
    <path fill="none" stroke="#1e79a0" d="M395.2627944162883,355A110,110,0,0,1,199.5099996593139,344.74103073833805" style="stroke-width: 20px; " stroke-width="20" id="This_is_a_test_entry"></path> 
    </a> 
    <text> 
    <textpath xlink:href="#This_is_a_test_entry">This is a test entry</textpath> 
    </text> 
</svg> 

使用上面的代碼,您永遠不會看到弧的標籤。然而,當下面是硬編碼它呈現爲預期:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="600" height="600"> 
    <a title="Bacon"> 
    <path id="Arc" fill="none" stroke="#1e79a0" d="M395.2627944162883,355A110,110,0,0,1,201.13265490709162,348.2208261467985" style="stroke-width: 20;" stroke-width="20"> 
    </path> 
    </a> 
    <text> 
    <textPath xlink:href="#Arc">This is an Arc</textPath> 
    </text> 
</svg> 

任何有識之士,爲什麼我沒有看到我的整個SVG將不勝感激。

編輯:

我已經修改了自己的JavaScript,我認爲這是幾乎沒有,但textPath仍然不會呈現。下面是當前的代碼,主要是由於費米:

function drawRange(start, end, R, range, id, title) { 
        var color = "hsb(".concat(Math.round(R)/200, ",", end/360, ", .75)"); 
        var key_position = key[id]; 
        var svg_bits = document.getElementsByTagName('svg')[0].childNodes; 
        var svgns = document.createElementNS('http://www.w3.org/2000/svg', "path"); 
        var path; 
        range.attr({title: title}); 
        range.animate({arc: [start, end, R]}, 900, ">"); 
        //Add an id to the path element that was just drawn. This doesn't seem to help though. 
        for(var i = 0; i < svg_bits.length; i++) { 
         if (svg_bits[i].tagName == "a" && svg_bits[i].getAttribute('title') == title){ 
          path = svg_bits[i].childNodes[0]; 
         } 
        } 
        path.setAttribute('id', title); 
        //Add the name to the key, set the color and unhide the element. 
        $(key_position).html(range.attr("title")); 
        $(key_position).css('color', Raphael.getRGB(color).hex); 
        $(key_position).show(); 
       }; 



function makeSVG(tag, attrs) { 
        var el = document.createElementNS('http://www.w3.org/2000/svg', tag); 
        for (var k in attrs) 
         el.setAttribute(k, attrs[k]); 
        return el; 
       }; 

function addLabel(label) { 
        var text = makeSVG("text", {}); 
        var title = makeSVG("textPath", {"xlink:href":'#' + label.replace(/\s/g, '_')}); 
        title.appendChild(document.createTextNode(label)); 
        text.appendChild(title); 
        r.canvas.appendChild(text); 
       }; 

我得到爲0x0的邊框爲textPath但沒有textPath。

回答

0

所以,找到一個補丁拉斐爾here,使一個小的調整,它是工作後的補丁。我仍然不確定我錯過了什麼,但現在呈現的textPaths和大家都很開心。感謝大家的幫助。

3

您可能需要刪除出現在第一個示例中的xlink,或添加適當的XML名稱空間定義。

編輯:當您添加textPath元素時,您可能需要使用正確的元素名稱(textPath,而不是textpath)。

編輯:適度有趣,因爲它是瀏覽器和jQuery更改路徑的組合。爲了得到正確的事情,使用此功能(從答案解放到jquery's append not working with svg element?):

function makeSVG(tag, attrs){ 
    var el= document.createElementNS('http://www.w3.org/2000/svg', tag); 
    for (var k in attrs) 
    el.setAttribute(k, attrs[k]); 
    return el; 
} 

然後做到這一點:

var paper = Raphael("notepad", 320, 200); 

// do all your other stuff here 
... 

var text = makeSVG("text", {}); 
     var c = makeSVG("textPath", {"xlink:href":"#Arc"}); 
     c.appendChild(document.createTextNode("This is an Arc")); 
     text.appendChild(c); 
paper.canvas.appendChild(text); 

,將讓你在正確的SVG:但是,仍然不會畫出正確的,這很奇怪。

+1

啊。不知怎的,沒有注意到。在這個例子中,你有'這是一個Arc ',在這個例子中你沒有'這個是一個測試條目' '。第二個元素名稱不同(全部小寫,而不是駱駝大小寫)。我假設SVG在這裏區分大小寫。 – Femi

+0

你最初是對的。我修復了我的帖子以反映實際的代碼,不確定錯誤來自哪裏。 我試過用單個單詞ID,它仍然不會呈現出於某種原因。唯一能夠真正識別爲不同的是Raphael被附加到了不完全渲染而不是另一個渲染的svg。 – LeakyBucket

+1

@LeakyBucket,你有沒有想念費米的編輯?正如他所說,它應該是'textPath'(注意大寫字母P)。 – mercator

2

如果你不擔心你的工作在IE8不工作或更早爲什麼不使用kieth支持木材的jQuery的SVG插件textpath 該插件的路徑語法是不同的,但很容易從拉斐爾 轉換的SVG插件出漂亮的徑向漸變,但這就是我現在參與其中的原因。

如果你想在一個路徑上的文本沒有與每個字母曲線高音,那麼你可以留在說唱和使用此... http://irunmywebsite.com/raphael/additionalhelp.php?v = 1 & q = anglebannersoncurves

藉口拼寫的iPod新手

+0

不知道瀏覽器的要求是在該點什麼。我們的營銷部門已經要求這樣做,所以我們可能需要就這一細節進行「談判」。 我不確定jQuery SVG插件是否仍然存在或最新。我找不到比2008年更新的任何內容,並且它的Google代碼網站沒有任何文件。 – LeakyBucket

+0

是的,不幸的是,這不適用於這個應用程序。 它看起來像還有其他事情正在進行。無論我是否使用Raphael,我都無法獲得svg更改。 – LeakyBucket

1

Femi的回答很不錯,唯一缺少的就是重新繪製並設置xlink命名空間。

我找不出其中的原因,但它必須是Raphael的核心內容,它可以防止SVG畫布更新,因爲您需要做的所有修復繪圖的操作都是通過快速刪除然後再強制重繪從DOM readding svg元素:

$('#myRaphaelDiv').html($('#myRaphaelDiv').html()); 

應當指出的是,SVG的任何直接的黑客攻擊屬性會破壞與瀏覽器的兼容性(嘆息,IE)使用VML來代替。我還沒有研究在VML中使用文本路徑的方式。下面的代碼是爲了完整。

// add the new namespace attribute to the SVG canvas. 'raphael' is the Raphael instance. 
// note that this only needs to be done once. 
$(raphael.canvas).attr('xmlns:xlink', "http://www.w3.org/1999/xlink"); 

// draw the curved text 
var lblId = 'some_unique_dom_id'; 
var path = raphael.path().attr({ 
    stroke : 'none' // defaults to black 
    // ...other path attributes used in generating it... 
}); 
var label = raphael.text().attr({ 'text-anchor' : 'start' }); 

// create and inject raw SVG textPath element 
var link; 
try { 
    link = document.createElementNS('http://www.w3.org/2000/svg', 'textPath'); 
} catch (e) { 
    // no createElementNS() method is pretty much synonymous with using IE, so 
    // this is where you would do your VML version of a text path 
    alert("Your browser does not support SVG, please use Firefox, Chrome etc"); 
} 
link.setAttribute('xlink:href', '#' + lblId); 
link.appendChild(document.createTextNode("path-oriented text")); 

// finally, force a redraw of the SVG document. 
// Obviously, you would defer this until all elements had been added. 
$('#myRaphaelDiv').html($('#myRaphaelDiv').html()); 
+0

VML實際上與我找到的補丁一起工作。 – LeakyBucket

+0

是的,那個補丁很有魅力!請注意,爲文本路徑設置動畫將需要爲路徑元素設置動畫效果,而不是Raphael.textPath()返回的文本元素。您可以通過返回的元素的'.path'屬性來訪問它。 我會upvote,但我的聲望不會讓我:p – pospi

+0

是的,最後我剛剛結束了爲每個標籤動畫另一個路徑,並將標籤綁定到defs部分中生成的路徑,但不是渲染。 – LeakyBucket