SVG with JS

Discuss SVG code, accessible via the XML Editor.
JimJoyce
Posts: 37
Joined: Fri Jun 19, 2009 7:06 pm

SVG with JS

Postby JimJoyce » Wed Jan 18, 2012 2:49 am

I've embedded some SVG in HTML, using only JS to get initialise it.
It works ONLY in Opera.

I have two problems:
(1) Why only in Opera?
(2) How to dispense with the HTML, keeping only the JS which generates the SVG.

Here's the HTML:

Code: Select all

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Test Boxes</title>
<script type="text/javascript" src="svg.js"></script>
</head>
<body onload="init()">
</body>
</html>


Here's the external JS :

Code: Select all

var svgns = "http://www.w3.org/2000/svg";
var svg;            <!-- svg    <svg>    -->
var g1, g2, g3; <!-- Groups <g>         -->
var r1, r2, r3;   <!-- Rects   <rect>   -->
var a1, a2, a3;   <!-- Buttons            -->
var b1, b2, b3;
var c1, c2, c3;

function initSVG()
   {
   svg = document.createElementNS(svgns, 'svg');
   svg.setAttributeNS(svgns, 'width', '250');
   svg.setAttributeNS(svgns, 'height', '250');
   svg.setAttributeNS(svgns, 'version', '1.1');
   document.body.appendChild(svg);
   }
 
function rct(i, x,y, w,h, s,f)
   {
   var rc;
   rc = document.createElementNS(svgns, 'rect');
   rc.setAttributeNS(svgns, "id", i);
   rc.setAttributeNS(svgns, "x", x);
   rc.setAttributeNS(svgns, "y", y);
   rc.setAttributeNS(svgns, "width", w);
   rc.setAttributeNS(svgns, "height", h);
   rc.setAttributeNS(svgns, "stroke", s);
   rc.setAttributeNS(svgns, "fill", f);
   return rc;
   }

function txt(i, x,y, w)
   {
   var cc = document.createTextNode(w);
   var tx = document.createElementNS(svgns, "text");
   tx.setAttributeNS(svgns, "id", i);
   tx.setAttributeNS(svgns, "x", x);
   tx.setAttributeNS(svgns, "y", y);
   tx.appendChild(cc);
   return tx;
   }

function doBox(i, g,r, x,y,w,h, s,f)
   {
   var tx, xt, yt;
   g = document.createElementNS(svgns,  "g");
   svg.appendChild(g);
   g.setAttribute("id", i);
   r = rct(i,x,y,w,h,s,f);
   g.appendChild(r);
   xt=parseInt(x)+6; yt=parseInt(y)+16;
   tx = txt(null, xt+'', yt+'', i);
   g.appendChild(tx);
   }

function init()
  {
  initSVG();
  g1=doBox("wrap",g1,r1,"10","10","230","230","#000","#999");
  g2=doBox("main",g2,r2,"30","40","190","180","#000","#bbb");
  g3=doBox("cont",g3,r3,"50","70","150","130","#000","#ddd");

  a1=doBox("A1",a1,null,"70","100","30","20","#000","#fff");
  b1=doBox("B1",b1,null,"110","100","30","20","#000","#fff");
  c1=doBox("C1",c1,null,"150","100","30","20","#000","#fff");

  a2=doBox("A2",a2,null,"70","130","30","20","#000","#fff");
  b2=doBox("B2",b2,null,"110","130","30","20","#000","#fff");
  c2=doBox("C2",c2,null,"150","130","30","20","#000","#fff");

  a3=doBox("A3",a3,null,"70","160","30","20","#000","#fff");
  b3=doBox("B3",b3,null,"110","160","30","20","#000","#fff");
  c3=doBox("C3",c3,null,"150","160","30","20","#000","#fff");
   }


Hoping for answers,
Thanks,
JJ

JimJoyce
Posts: 37
Joined: Fri Jun 19, 2009 7:06 pm

Re: SVG with JS

Postby JimJoyce » Thu Jan 19, 2012 2:32 am

Hi, again, Should I say more?
Lets forget about the non-Opera failures,
though I'm disappointed with Firefox.

But Question 2 is what really bothers me.
I'm building a simple block of buttons, within a frame, within a frame, within a frame.

The key point is I'm trying to use SVG without embedding it in HTML.
Moreover, I'm building the SVG indirectly, using only JS.

<svg onload="init();">
<script>
function init() { ...}
</script>
</svg>

JimJoyce
Posts: 37
Joined: Fri Jun 19, 2009 7:06 pm

Re: SVG with JS

Postby JimJoyce » Sun Jan 22, 2012 12:42 am

I have now embedded 'svg.js' within 'test.html'
to make it more comparable with 'test.svg'.

They both hold virtually identical javascript.
The only real difference is that the JS in the HTML
needs to initiate SVG (function initSVG().

Both scripts contain an onload function init(),
which starts things off, and then calls
function doBox(...) 6 times,
building 3 buttons, nested within 3 containers.

In Opera, test.html works perfectly, but test.svg fails when
it tries to append the first container to the parent svg.
Alerts tell me that the parent svg object,
within test.html is svg = [object SVGSVGElement],
but within test.svg it is svg = [object SVGDocument].

I'm sure that should be telling me something.
Is there something wrong with init(evt) within test.svg :
if ( window.SVGDocument == null )
{ svg = evt.target.ownerDocument; }

Here is the HTML

Code: Select all

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
         xml:lang="en" lang="en">
<head><title>Test Boxes</title>

<script type="text/javascript">
var svg;
var svgns = "http://www.w3.org/2000/svg";
var g1, g2, g3   // wrap, main, cont
var a1, a2, a3; // buttons

function rct(x,y, w,h, s,f)
   {
   var rc;
   rc = document.createElementNS(svgns, 'rect');
   rc.setAttributeNS(svgns, "x", x);
   rc.setAttributeNS(svgns, "y", y);
   rc.setAttributeNS(svgns, "width", w);
   rc.setAttributeNS(svgns, "height", h);
   rc.setAttributeNS(svgns, "stroke", s);
   rc.setAttributeNS(svgns, "fill", f);
   return rc;
   }

function txt(i, x, y, words)
   {
   var cc = document.createTextNode(words);
   var tx = document.createElementNS(svgns, "text");
   tx.setAttributeNS(svgns, "id", i);
   tx.setAttributeNS(svgns, "x", x);
   tx.setAttributeNS(svgns, "y", y);
   tx.appendChild(cc);
   return tx;
   }

function doBox(id,par, x,y,w,h, s,f)
   {
   var grp, tx, xt, yt;
   grp = document.createElementNS(svgns, "g");
   grp.setAttribute("id", id);
   bx = rct(x,y,w,h,s,f);
   grp.appendChild(bx);
   xt=parseInt(x,10)+6;
   yt=parseInt(y,10)+16;
alert("DOBOX x,y="+xt+','+yt);
   tx = txt(null, xt+' ', yt+' ', id);
   grp.appendChild(tx);
   par.appendChild(grp);
  return grp;
   }

function initSVG()
   {
   svg = document.createElementNS(svgns, 'svg');
   svg.setAttributeNS(svgns, 'width', '250');
   svg.setAttributeNS(svgns, 'height', '190');
   svg.setAttributeNS(svgns, 'version', '1.1');
   document.body.appendChild(svg);
   return svg;
   }
 
function init(evt)
  {
  svg = initSVG();
alert("INIT svg="+svg);

  g1=doBox("wrap",svg,"10","10","230","170","#000","#999");
  g2=doBox("main",g1,"30","40","190","120","#000","#bbb");
  g3=doBox("cont",g2,"50","70","150","70","#000","#ddd");

  a1=doBox("A1",g3,"70","100","30","20","#000","#fff");
  b1=doBox("B1",g3,"110","100","30","20","#000","#fff");
  c1=doBox("C1",g3,"150","100","30","20","#000","#fff");
   }

</script>
</head>

<body onload="init()">
</body>
</html>

And here the problem SVG

Code: Select all

<?xml version="1.0" standalone="no"?>
<svg version="1.1" baseProfile="full"
      xmlns="http://www.w3.org/2000/svg"
      width="250"   height="250"
      onload="init(evt)">

<script type="text/javascript">
var svg;
var svgns = "http://www.w3.org/2000/svg";
var g1, g2, g3   // wrap, main, cont
var a1, a2, a3; // buttons

function rct(x,y, w,h, s,f)
   {
   var rc;
   rc = document.createElementNS(svgns, 'rect');
   rc.setAttributeNS(svgns, "x", x);
   rc.setAttributeNS(svgns, "y", y);
   rc.setAttributeNS(svgns, "width", w);
   rc.setAttributeNS(svgns, "height", h);
   rc.setAttributeNS(svgns, "stroke", s);
   rc.setAttributeNS(svgns, "fill", f);
   return rc;
   }

function txt(i, x,y, msg)
   {
   var cc = document.createTextNode(w);
   var tx = document.createElementNS(svgns, "text");
   tx.setAttributeNS(svgns, "id", i);
   tx.setAttributeNS(svgns, "x", x);
   tx.setAttributeNS(svgns, "y", y);
   tx.appendChild(cc);
   return tx;
   }

function doBox(id,par, x,y, w,h, s,f)
   {
   var grp, bx, tx, xt, yt;
   grp = document.createElementNS(svgns, "g");
   grp.setAttribute("id", id);
   bx = rct(x,y,w,h,s,f);
   xt=parseInt(x,10)+6+' '
   yt=parseInt(y,10)+16+' ';
   tx = txt(null, xt, yt, id);
alert("DOBOX x,y="+xt+','+yt);
   grp.appendChild(bx);
   grp.appendChild(tx);
   par.appendChild(grp);
  return grp;
   }

function init(evt)
  {
   svg = document;
alert("INIT svg="+svg);
   if ( window.SVGDocument == null )
      {   svg = evt.target.ownerDocument; }
alert("INIT svg="+svg);

  g1=doBox("wrap",svg,"10","10","230","230","#000","#999");
  g2=doBox("main",g1, "30","40","190","180","#000","#bbb");
  g3=doBox("cont",g2, "50","70","150","130","#000","#ddd");

  a1=doBox("A1",g3, "70","100","30","20","#000","#fff");
  b1=doBox("B1",g3,"110","100","30","20","#000","#fff");
  c1=doBox("C1",g3,"150","100","30","20","#000","#fff");

  a2=doBox("A2",g3, "70","130","30","20","#000","#fff");
  b2=doBox("B2",g3,"110","130","30","20","#000","#fff");
  c2=doBox("C2",g3,"150","130","30","20","#000","#fff");

  a3=doBox("A3",g3, "70","160","30","20","#000","#fff");
  b3=doBox("B3",g3,"110","160","30","20","#000","#fff");
  c3=doBox("C3",g3,"150","160","30","20","#000","#fff");
   }
</script>

</svg>

Does anyone know how I should address the parent svg
from within the embedded JS ?

JimJoyce
Posts: 37
Joined: Fri Jun 19, 2009 7:06 pm

Re: SVG with JS

Postby JimJoyce » Sun Jan 22, 2012 12:50 am

I've just spotted a missing semicolon in line 10
of both test.html and test.svg.
var g1, g2, g3; // wrap, main, cont
That's not the problem. It was correct in both originals.

JimJoyce
Posts: 37
Joined: Fri Jun 19, 2009 7:06 pm

Re: SVG with JS

Postby JimJoyce » Sun Jan 22, 2012 2:26 am

Here I am again, for the fourth time !
Just another footnote:

I looked again at the article by Jonathan Watt on
'SVG Authoring Guidelines' which covers SVG and DOCTYPES
(among other things) v. https://jwatt.org/svg/authoring/.

At the end he recommended what I thought might be useful:
property = evt.target.ownerDocument.documentElement;
Sure enough, it produced svg = [object SVGSVGElement].

Not that that made any difference. test.svg still fails.

User avatar
brynn
Posts: 10309
Joined: Wed Sep 26, 2007 4:34 pm
Location: western USA
Contact:

Re: SVG with JS

Postby brynn » Sun Jan 22, 2012 9:50 am

Hi JJ,
I'm sorry no one has replied. I guess no one here must know the solution. I wish I could help, but SVG and JS are both over my head. But I wanted to suggest that you might try the mailing list or the IRC channel, which I have the impression are visited by more higher level users (coding etc.) and developers than this forum. You should be able to find the addresses at Inkscape.org

JimJoyce
Posts: 37
Joined: Fri Jun 19, 2009 7:06 pm

Re: SVG with JS

Postby JimJoyce » Sun Jan 22, 2012 10:19 pm

SUCCESS !, well partly !
Thanks, Brynn, for your suggestions.

I've succeeded in my challenge :
to code SVG with ALL the SVG instructions
simplified within contained javascript.
Isn't that the essence of a SVG framework ?
Isn't that the secret of Pergola?
Someone put me wise !

I think I've removed all my typos from test.svg.
Now, test.html and test.svg are almost identical.
Test.html needs an extra function: initSVG().
Function init() starts slightly differently in the two.

Both test.html and test.svg work in Opera
Still no luck with either in Firefox.
But that is Mozilla's problem, not Inkscape's.

By the way, my SVG never produces anything in Inkscape.
What am I doing that's wrong.

When I'm testing in Firefox I have noticed
a tiny strange 'inverse T' (or alt 193, in some fonts).
In test.html output, it is at about 50,15px
In test.svg it occurs at about 50,5px.


These are the two versions :

Code: Select all

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
         xml:lang="en" lang="en">
<head><title>Test Boxes</title>

<script type="text/javascript">
var svg;
var svgns="http://www.w3.org/2000/svg";
var g1,g2,g3;   // wrap,main,cont
var a1,b1,c1; // buttons

function rct(x,y,w,h,s,f)
   {
   var rc;
   rc=document.createElementNS(svgns,'rect');
   rc.setAttributeNS(svgns,"x",x);
   rc.setAttributeNS(svgns,"y",y);
   rc.setAttributeNS(svgns,"width",w);
   rc.setAttributeNS(svgns,"height",h);
   rc.setAttributeNS(svgns,"stroke",s);
   rc.setAttributeNS(svgns,"fill",f);
   return rc;
   }

function txt(id,x,y,msg)
   {
   var cc=document.createTextNode(msg);
   var tx=document.createElementNS(svgns,"text");
   tx.setAttributeNS(svgns,"id",id);
   tx.setAttributeNS(svgns,"x",x);
   tx.setAttributeNS(svgns,"y",y);
   tx.appendChild(cc);
   return tx;
   }

function doBox(id,par,x,y,w,h,s,f)
   {
   var grp,bx,tx,xt,yt;
   grp=document.createElementNS(svgns,"g");
   grp.setAttribute("id",id);
   bx=rct(x,y,w,h,s,f);
   xt=parseInt(x,10)+6+' ';
   yt=parseInt(y,10)+16+' ';
alert("DOBOX x,y="+xt+','+yt);
   tx=txt(null,xt,yt,id);
   grp.appendChild(bx);
   grp.appendChild(tx);
   par.appendChild(grp);
  return grp;
   }

function initSVG()
   {
   svg=document.createElementNS(svgns,'svg');
   svg.setAttributeNS(svgns,'width','250');
   svg.setAttributeNS(svgns,'height','190');
   svg.setAttributeNS(svgns,'version','1.1');
   document.body.appendChild(svg);
   return svg;
   }
 
function init(evt)
  {
  svg=initSVG();
alert("INIT svg="+svg);

  g1=doBox("wrap",svg,"10","10","230","170","#000","#999");
  g2=doBox("main",g1,"30","40","190","120","#000","#bbb");
  g3=doBox("cont",g2,"50","70","150","70","#000","#ddd");

  a1=doBox("A1",g3,"70","100","30","20","#000","#fff");
  b1=doBox("B1",g3,"110","100","30","20","#000","#fff");
  c1=doBox("C1",g3,"150","100","30","20","#000","#fff");
   }

</script>
</head>

<body onload="init()">
</body>
</html>


Code: Select all

<?xml version="1.0" standalone="no"?>
<svg version="1.1" baseProfile="full"
      xmlns="http://www.w3.org/2000/svg"
      width="250"   height="250"
      onload="init(evt)">

<script type="text/javascript">
var svg;
var svgns="http://www.w3.org/2000/svg";
var g1,g2,g3;   // wrap,main,cont
var a1,b1,c1; // buttons

function rct(x,y,w,h,s,f)
   {
   var rc;
   rc=document.createElementNS(svgns,'rect');
   rc.setAttributeNS(svgns,"x",x);
   rc.setAttributeNS(svgns,"y",y);
   rc.setAttributeNS(svgns,"width",w);
   rc.setAttributeNS(svgns,"height",h);
   rc.setAttributeNS(svgns,"stroke",s);
   rc.setAttributeNS(svgns,"fill",f);
   return rc;
   }

function txt(id,x,y,msg)
   {
   var cc=document.createTextNode(msg);
   var tx=document.createElementNS(svgns,"text");
   tx.setAttributeNS(svgns,"id",id);
   tx.setAttributeNS(svgns,"x",x);
   tx.setAttributeNS(svgns,"y",y);
   tx.appendChild(cc);
   return tx;
   }

function doBox(id,par,x,y,w,h,s,f)
   {
   var grp,bx,tx,xt,yt;
   grp=document.createElementNS(svgns,"g");
   grp.setAttribute("id",id);
   bx=rct(x,y,w,h,s,f);
   xt=parseInt(x,10)+6+' ';
   yt=parseInt(y,10)+16+' ';
   tx=txt(null,xt,yt,id);
alert("DOBOX x,y="+xt+','+yt);
   grp.appendChild(bx);
   grp.appendChild(tx);
   par.appendChild(grp);
  return grp;
   }

function init(evt)
  {
   svg=evt.target.ownerDocument.documentElement;
alert("INIT svg="+svg);

  g1=doBox("wrap",svg,"10","10","230","170","#000","#999");
  g2=doBox("main",g1,"30","40","190","120","#000","#bbb");
  g3=doBox("cont",g2,"50","70","150","70","#000","#ddd");

  a1=doBox("A1",g3,"70","100","30","20","#000","#fff");
  b1=doBox("B1",g3,"110","100","30","20","#000","#fff");
  c1=doBox("C1",g3,"150","100","30","20","#000","#fff");
   }

</script>
</svg>


Return to “SVG / XML Code”