【发布时间】:2014-11-22 03:10:14
【问题描述】:
我正在创建一个小程序,它将根据我选择的选项制作 SVG 文件。我遇到的问题是 JSVGCanvas(来自 Batik)似乎不会渲染(使用 DOM api)制作的渐变。奇怪的是,如果我导出文件并在 Inkscape 或使用测试类here 打开它,它(渐变)会呈现!以下是我认为可能很重要的所有信息:
蜡染版本: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"/>
我认为这是一个命名空间的东西(我不太了解 XML/SVG)。我假设这是因为我之前遇到过这样的错误,它在预览中不起作用,但在导出(并加载 svg 文件)后会起作用。请注意,这是一个快速的家庭应用程序,因此代码不是最好的(也不是设计),但它适用于我正在做的事情。另请注意,我不是手动输入这些配置文件(那太疯狂了),我有一个转换器可以将 svg 文件转换为这些配置(是的,这听起来像是来回切换,但我正在组合这些配置中的多个一个图像)。
【问题讨论】: