2014-11-22 21 views
0

我正在創建一個小程序,它將根據我選擇的選項創建一個SVG文件。我遇到的問題是,JSVGCanvas(來自蠟染)似乎不會渲染漸變(使用DOM api)。奇怪的部分是,如果我導出文件並在Inkscape中打開它,或者使用測試類here,它(梯度)呈現!這是所有我認爲可能是重要的信息:蠟染Java - JSVGCanvas漸變不呈現?

蠟染版本:1.7

梯度構建代碼:

public Element parse(Document doc, String id) { //This is inside a gradient object. 
    Element defs = doc.createElementNS(Main.svgNS, "defs"); //Since multiple defs work in an SVG (or at least Inkscape), I add a defs tag per set of gradients. 
    defs.setAttribute("id", id); //Sets the id of the defs tag. 

    for (JsonElement je : json.getAsJsonArray("Linears")) { //I use GSON to store data, I am iterating through all objects in the Linears array. 
     if (je.isJsonObject()) { //Just a type check. 
      JsonObject jo = je.getAsJsonObject(); 
      Element lin = doc.createElementNS(Main.svgNS, "linearGradient"); //Creates the linearGradient element. 

      for (Entry<String, JsonElement> entry : jo.entrySet()) { //For all elements other than Stops (it is an array) we want to set the attribute. 
       if (!entry.getKey().equals("Stops")) { 
        lin.setAttribute(entry.getKey(), entry.getValue().getAsJsonPrimitive().getAsString()); 
       } 
      } 

      for (JsonElement stop : jo.getAsJsonArray("Stops")) { //For all objects in stops we want to add a stop. 
       Element el = doc.createElementNS(Main.svgNS, "stop"); //Creates a stop element. 
       for (Entry<String, JsonElement> entry : stop.getAsJsonObject().entrySet()) { 
        if (entry.getValue().isJsonObject()) { 
         el.setAttribute(entry.getKey(), parseObject(entry.getValue().getAsJsonObject())); //The parseObject method makes a string based on the JsonObject (this is used to get "variables" such as colors). 
        } else { 
         el.setAttribute(entry.getKey(), entry.getValue().getAsString()); 
        } 
       } 
       lin.appendChild(el); //Add stop to the linear gradient. 
      } 

      defs.appendChild(lin); //Add the linear gradient to defs. 
     } 
    } 

    for (JsonElement je : json.getAsJsonArray("Radials")) { //Loops through all the radial gradients. 
     if (je.isJsonObject()) { //Type check. 
      JsonObject jo = je.getAsJsonObject(); 
      Element rad = doc.createElementNS(Main.svgNS, "radialGradient"); //Creates the radialGradient element. 

      for (Entry<String, JsonElement> entry : jo.entrySet()) { 
       if (entry.getValue().isJsonPrimitive()) { 
         rad.setAttribute(entry.getKey(), entry.getValue().getAsJsonPrimitive().getAsString()); 
       } else { 
         rad.setAttribute(entry.getKey(), parseObject(entry.getValue().getAsJsonObject())); 
       } 
      } 

      defs.appendChild(rad); //Adds the radial gradient to defs. 
     } 
    } 

    cache = defs; 
    return cache; //We return the defs to be added in the main build code. 
} 

文檔創建: 構造:

impl = SVGDOMImplementation.getDOMImplementation(); 

生成方法:

doc = (SVGDocument) impl.createDocument(svgNS, "svg", null); 

JSVGCanvas創作:

preview = new JSVGCanvas(); 
preview.setEnableImageZoomInteractor(true); 
preview.setEnablePanInteractor(true); 

這裏是我的模板文件的梯度部分看起來像(JSON):

"Gradients": { 
"Radials": [ 
    { 
    "gradientTransform": "matrix(0.96774313,-1.5022501e-7,3.5488612e-7,1.483871,-201.69415,-217.84922)", 
    "inkscape:collect": "always", 
    "xmlns:xlink": "http://www.w3.org/1999/xlink", 
    "id": "radialGradient5607", 
    "gradientUnits": "userSpaceOnUse", 
    "xlink:show": "other", 
    "xlink:type": "simple", 
    "r": "15.5", 
    "cx":{ 
     pre:"", 
     var:"X", 
     add:327, 
     post:"" 
    }, 
    "fx":{ 
     pre:"", 
     var:"Y", 
     add:327, 
     post:"" 
    }, 
    "cy": { 
     pre:"", 
     var:"X", 
     add:209, 
     post:"" 
    }, 
    "fy": { 
     pre:"", 
     var:"Y", 
     add:209, 
     post:"" 
    }, 
    "xlink:href": "#linearGradient4114", 
    "xlink:actuate": "onLoad" 
    } 
], 
"Linears": [ 
    { 
    "xlink:actuate": "onLoad", 
    "xlink:type": "simple", 
    "id": "linearGradient4114", 
    "xlink:show": "other", 
    "xmlns:xlink": "http://www.w3.org/1999/xlink", 
    "Stops": [ 
     { 
     "offset": "0", 
     "style": { 
      "pre": "stop-color:", 
      "var": "Eye", 
      "post": ";stop-opacity:1;" 
     }, 
     "id": "stop4116" 
     }, 
     { 
     "style": { 
      "pre": "stop-color:", 
      "var": "Eye2", 
      "post": ";stop-opacity:1;" 
     }, 
     "offset": "0.5", 
     "id": "stop4122" 
     }, 
     { 
     "offset": "1", 
     "style": { 
      "pre": "stop-color:", 
      "var": "Eye3", 
      "post": ";stop-opacity:1;" 
     }, 
     "id": "stop4118" 
     } 
    ] 
    } 
] 
} 

配置文件的那部分,然後被變成:

<defs id="defs0"> 
<linearGradient 
    xmlns:xlink="http://www.w3.org/1999/xlink" 
    xlink:type="simple" 
    xlink:actuate="onLoad" 
    id="linearGradient4114" 
    xlink:show="other"> 
    <stop 
     style="stop-color:#d80a00;stop-opacity:1;" 
     offset="0" 
     id="stop4116"/> 
    <stop 
     style="stop-color:#ffffff;stop-opacity:1;" 
     offset="0.5" 
     id="stop4122"/> 
    <stop 
     style="stop-color:#ffffff;stop-opacity:1;" 
     offset="1" 
     id="stop4118"/> 
</linearGradient> 
<radialGradient 
    gradientTransform="matrix(0.96774313,-1.5022501e-7,3.5488612e-7,1.483871,-201.69415,-217.84922)" 
    xmlns:xlink="http://www.w3.org/1999/xlink" 
    xlink:type="simple" 
    xlink:href="#linearGradient4114" 
    id="radialGradient5607" 
    xlink:show="other" 
    gradientUnits="userSpaceOnUse" 
    r="15.5" 
    xlink:actuate="onLoad" 
    cx="392.0" 
    fx="427.0" 
    cy="274.0" 
    fy="309.0" 
    inkscape:collect="always"/> 

我想這是一個namespa ce的東西(我不完全得到XML/SVG)。我假設這是因爲我以前有過這樣的錯誤,在預覽中它不起作用,但在導出(並加載svg文件)後它會起作用。請注意,這是一個快速的家庭應用程序,所以代碼不是最好的(也不是設計),但它適用於我正在做的事情。另外請注意,我沒有手動輸入這些配置文件(這將是瘋了),我有一個轉換器,將svg文件轉換爲這些配置(是的,它聽起來像來回,但我結合多個這些配置使一個圖像)。

回答

0

昨天和今天搞砸了之後,我想出了它。 xlink:href屬性要求您將其名稱空間設置爲xlink。對於我的項目,這意味着只是這樣做:

if (entry.getKey().equals("xlink:href")) { 
     rad.setAttributeNS(XMLConstants.XLINK_NAMESPACE_URI, "xlink:href", entry.getValue().getAsJsonPrimitive().getAsString()); 
} 

添加後,我的梯度工作成功。