Reputation: 938
I am trying to create a function in javascript that creates new filters based off input parameters. So far my code is:
var svg=document.getElementById("canvas");
var fs=document.getElementById("filters");
var circles=0;
var svgns="http://www.w3.org/2000/svg";
var w=window.innerWidth;
function createfilter(posx,posy,sizex,sizey,type,data){
var filter=document.createElement("filter");
filter.setAttribute("id","f"+circles);
filter.setAttribute("x",posx);
filter.setAttribute("y",posy);
filter.setAttribute("width",sizex);
filter.setAttribute("height",sizey);
fs.appendChild(filter);
for(z=0;z<(data.length/2);z++){
var filter=document.createElementNS(svgns,type[z]);
filter.setAttributeNS("null","in","SourceGraphic");
filter.setAttributeNS("null",data[2*z],data[2*z+1]);
document.getElementById("f"+circles).appendChild(filter);
}
console.log(document.getElementById("f"+circles)); //to see if it has worked or not
}
for(i=0;i<10;i++){
circles+=1;
createfilter("-50%","-50%","200%","200%",["feGaussianBlur"],["stdDeviation","5"]);
createcircle((i*w/10),"50%","100","0","hsla("+(i*36)+",100%,50%,0.5)","url(#f"+circles+")"); //this works - the parameters are (posx,posy,radius,stroke,fill,filter) but currently I can only use a filter that I have created in the html svg element as my code doesn't work
}
As you can see, this is effectively creating 10 circles. I wish to be able to move the circles around in an animation at a future point, but for now I want to have each circle having its own filter which I will also animate.
Currently the console output shows the filter tag as
<filter id="f1" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
</filter>
which is not what I had hoped for, as the tag should be all as one (endinf in a />), not split into 2 (oddly this copy and paste has made the feGaussianBlur tag appear in capitals, but google chrome's console shows it all lowercase, but the SourceGraphic is correctly capitalised)
Does anyone know how to get this to work?
Side note: the createcircle function is
function createcircle(posx,posy,radius,stroke,fill,filter){
var circle=document.createElementNS(svgns,"circle");
circle.setAttributeNS(null,"id","c"+circles);
circle.setAttributeNS(null,"cx",posx);
circle.setAttributeNS(null,"cy",posy);
circle.setAttributeNS(null,"r",radius);
circle.setAttributeNS(null,"stroke-width",stroke);
circle.setAttributeNS(null,"fill",fill);
//circle.setAttributeNS(null,"filter",filter);
circle.setAttributeNS(null,"data-posx",posx);
svg.appendChild(circle);
console.log(circle);
}
if it matters
Upvotes: 1
Views: 963
Reputation: 123985
The filter needs to be created with createElementNS like the other SVG elements are. Also the null namespace is null, not the string "null" (alternatively you could use setAttribute and omit the first argument).
var svg=document.getElementById("canvas");
var fs=document.getElementById("filters");
var circles=0;
var svgns="http://www.w3.org/2000/svg";
var w=window.innerWidth;
function createfilter(posx,posy,sizex,sizey,type,data){
var filter=document.createElementNS(svgns,"filter");
filter.setAttribute("id","f"+circles);
//filter.setAttribute("x",posx);
//filter.setAttribute("y",posy);
//filter.setAttribute("width",sizex);
//filter.setAttribute("height",sizey);
fs.appendChild(filter);
for(z=0;z<(data.length/2);z++){
var filter=document.createElementNS(svgns,type[z]);
filter.setAttributeNS(null,"in","SourceGraphic");
filter.setAttributeNS(null,data[2*z],data[2*z+1]);
document.getElementById("f"+circles).appendChild(filter);
}
//console.log(document.getElementById("f"+circles)); //to see if it has worked or not
}
function createcircle(posx,posy,radius,stroke,fill,filter){
var circle=document.createElementNS(svgns,"circle");
circle.setAttributeNS(null,"id","c"+circles);
circle.setAttributeNS(null,"cx",posx);
circle.setAttributeNS(null,"cy",posy);
circle.setAttributeNS(null,"r",radius);
circle.setAttributeNS(null,"stroke-width",stroke);
circle.setAttributeNS(null,"fill",fill);
circle.setAttributeNS(null,"filter",filter);
circle.setAttributeNS(null,"data-posx",posx);
svg.appendChild(circle);
// console.log(circle);
}
for(i=0;i<10;i++){
circles+=1;
createcircle((i*w/10),"50%","100","0","hsla("+(i*36)+",100%,50%,0.5)","url(#f"+circles+")"); createfilter("-50%","-50%","200%","200%",["feGaussianBlur"],["stdDeviation","5"]);
//this works - the parameters are (posx,posy,radius,stroke,fill,filter) but currently I can only use a filter that I have created in the html svg element as my code doesn't work
}
html, body, svg {
width: 100%;
height: 100%;
}
<svg id="canvas" viewBox="0 0 1000 1000"><defs id="filters">
</defs></svg>
Upvotes: 2