2014-03-06 50 views
1

我正在使用包含許多SVG藝術作品的界面,這些界面包含在Adobe Illustrator中創建的。這些SVG的顏色可由用戶自定義,並且所有的作品原來都使用相同的顏色。這個想法是,一旦用戶改變了每種顏色,它就會反映在所有的SVG藝術作品中。SVG用類聲明替換填充聲明以進行顏色自定義

現在,我有這個工作正常的功能。我首先使用LESS在我的CSS中生成所有顏色陰影,並將它們分配給類。

像這樣

@color3-base: #FF0000; 
@color3-shade1: mix(@color3-base, @color2-base, 90%); 
@color3-shade2: mix(@color3-base, @color2-base, 80%); 
@color3-shade3: mix(@color3-base, @color2-base, 70%); 
@color3-shade4: mix(@color3-base, @color2-base, 60%); 
@color3-shade5: mix(@color3-base, @color2-base, 50%); 
@color3-shade6: mix(@color3-base, @color2-base, 40%); 
@color3-shade7: mix(@color3-base, @color2-base, 30%); 
@color3-shade8: mix(@color3-base, @color2-base, 20%); 

.color3-base-fill {fill: @color3-base;} 
.color3-shade1-fill {fill: @color3-shade1;} 
.color3-shade2-fill {fill: @color3-shade2;} 
.color3-shade3-fill {fill: @color3-shade3;} 
.color3-shade4-fill {fill: @color3-shade4;} 
.color3-shade5-fill {fill: @color3-shade5;} 
.color3-shade6-fill {fill: @color3-shade6;} 
.color3-shade7-fill {fill: @color3-shade7;} 
.color3-shade8-fill {fill: @color3-shade8;} 

我使用less.js方法less.modifyVars來更新我的基色值,喜歡的顏色@color3-base。對每種顏色的任何更改都會導致整個SVG藝術品使用的所有顏色的不同陰影。所有的顏色生成完美,沒有問題。

我使用solution provided here將所有SVG內聯加載,以便它們成爲我的DOM的一部分,並且可以從我的LESS CSS中發生的所有顏色變化中生效。

現在,在這些加載的SVG中,我手動進去了,用類語句替換了填充語句。像fill="#FF0000"class="color3-base-fill"(或屬於我替換的特定填充色的類),以便它從類中檢索填充值,並且始終可以通過LESS發生的顏色變化產生影響。因爲我們所有的作品都使用相同的顏色,現在他們的填充語句被人工替換爲與這些顏色相對應的類,這很有用。使用less.modifyVars對每種顏色的更改反映了所有藝術品上的所有顏色。

問題是我們有大量的SVG圖形文件,我必須用相應的陰影類來手動替換SVG中的每一條填充語句。這爲很多人爲錯誤打開了餘量,這似乎是應該自動化的東西。

我最理想的是能夠在SVG加載時自動完成這些替換。這將使我們在Adobe Illustrator中製作的任何藝術作品在加載時立即可定製。我嘗試了不同的方式將我的SVG首先轉換爲字符串,以便我可以將填充聲明替換爲類聲明,但是我沒有成功。看起來SVG既不是XML也不是HTML,它很難序列化。我的知識在這一點上是有限的,所以在解決上述問題上的任何幫助都會很棒!

謝謝!

回答

1

我設法首先加載我所有的SVGs在我的DOM,並簡單地使用jQuery去除填充屬性和正確的對應的類屬性代替他們解決這個問題。

function applyClassesOverSVGColors(svg, classGroupName, colors){ 
     for (var i in colors) { 
      //Customize Fills 
      $("#" + svg.attr("id") + ' [fill="#'+ colors[i] +'"]').each(function(){$(this).removeAttr('fill').addClass($(this).attr("class")+" "+classGroupName+"-fill")}); 
      //Customize Strokes 
      $("#" + svg.attr("id") + ' [stroke="#'+ colors[i] +'"]').each(function(){$(this).removeAttr('stroke').addClass($(this).attr("class")+" "+classGroupName+"-stroke")}); 
     }; 
    } 

以上,colors包含使用類,而不是他們的在線填寫或中風的聲明表示所有需要的顏色。

applyClassesOverSVGColors(svg,"color1-base",["50B380","4FB280","4DB180"]); 
1

一個解決方案是使用XSLT樣式表。你可以運行它來在服務之前預處理你的文件,配置你的系統在服務器端自動運行它,或者甚至在客戶端運行它(取決於瀏覽器支持)。

SVG是100%的XML,因此您可以使用XSLT處理它。

假設你有這樣一個SVG:

<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"> 
    <circle cx="300" cy="300" r="200" fill="#FF0000"> 
     <desc>Text</desc> 
    </circle> 
    <rect rx="10" ry="10" height="150" width="200" x="10" y="10" fill="#0000FF" /> 
</svg> 

如果它與XSLT 1加載到一個XSL處理器。在下面的樣式表中,它會查找所有元素中的所有fill屬性,比較其內容(我假定#FF0000color3-base-fill#0000FFcolor4-base-fill),刪除fill屬性並將其替換爲相應的class

<xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node() | @*" /> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="*[@fill]"> 
    <xsl:choose> 
     <xsl:when test=".[@fill='#FF0000']"> 
      <xsl:copy> 
       <xsl:attribute name="class"> 
        <xsl:text>color3-base-fill</xsl:text> 
       </xsl:attribute> 
       <xsl:apply-templates select="node()|@*[not(name() = 'fill')]"/> 
      </xsl:copy> 
     </xsl:when> 
     <xsl:when test=".[@fill='#0000FF']"> 
      <xsl:copy> 
       <xsl:attribute name="class"> 
        <xsl:text>color4-base-fill</xsl:text> 
       </xsl:attribute> 
       <xsl:apply-templates select="node()|@*[not(name() = 'fill')]"/> 
      </xsl:copy> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:copy> 
       <xsl:apply-templates select="node()|@*" /> 
      </xsl:copy> 
     </xsl:otherwise> 
    </xsl:choose> 

</xsl:template> 

它可以改進的,當然。你可以將你的顏色/類關係表放在一個單獨的文件中,並加載它,這樣就不必像上面那樣硬連接結果。

如果您編譯樣式表並在服務器端進行服務或緩存之前進行轉換,效率會更高。這樣你也可以使用更強大的XSLT 2.0。但是如果你想將其加載到瀏覽器中,您可以包括在SVG此處理指令,而當你加載SVG將在運行中轉化:

<?xml-stylesheet type="text/xsl" href="the-stylesheet.xsl"?> 

這是樣式表改變了SVG以上:

<svg xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink" 
    width="100%" height="100%" version="1.1"> 
    <circle class="color3-base-fill" cx="300" cy="300" r="200"> 
     <desc>Text</desc> 
    </circle> 
    <rect class="color4-base-fill" rx="10" ry="10" height="150" width="200" x="10" y="10"/> 
</svg> 
+0

這似乎是正確的解決方案,但我無法使其正常工作。由於我正在使用的工具目前只是所有客戶端,所以XSLT轉換對我來說不起作用。我確信一旦涉及服務器,這可以很好地工作。 – alik