Script customizable and reactive vector graphic files for browser or CNC

Similar projects worth following
In the maker community many makers still rely on proprietary graphic editors like Illustrator, sketchup, fusion, solidworks or even autocad. Editors for the browser are starting to emerge but most of them offer a complete application with integration in a cloud where you store your very own artifacts. Or you end up with mandatory fees and other regulations.
In addition it is very hard to find software capable of creating customizable reactive graphics.

I have taken up the gauntlet and created iPath a javascript library for scripting online, customizable and reactive graphics in your browser. iPath lets you create graphics in a not so traditional way: "Thou shall script." and lets you formalize a (vector)path for an online pen or a concrete computer controlled nozzle like a plasma, laser, millingbit or waterjet.

First a few words about iPath & stretchsketch..

stretchsketch is a website (developed and maintained by me) where you can view, modify and edit graphics which are scripted with (or rather in) iPath. In contrast with iPath, stretchsketch' source is not on github because, it is not something I'm very proud of and it I think it is not interesting to anyone. In case you're interested you're of course free to inspect its source etc.

Once an image has been selected, you can

Now.. let us formalize a path for a square in iPath:

var square = new iPath().line(20,0).line(0,20)
to create the same square with a more configurable dimension:
var length = 20;
var square = new iPath().line(length,0).line(0,length)

If you want to move the pen (or nozzle) without leaving a trace use move:

var window = new iPath().line(length,0).line(0,length)

And if you want to create an "array of x windows"

var x = 3;

and convert to a path's d-attribute window.dPath(3);

The coordinate system above is just in x,y also known as Cartesian system. An alternative to the Cartesian system is the polar coordinate system. iPath supports this also and one should not use line but turtleLine:

var turtleWindow = new iPath().turtleLine({r: lenght, a: Math.PI/2}) 
Turtle line comes from Logo, and it presents the idea of guiding a turtle on the screen, with supplying an direction and length. The argument to turtleLine is a Javascript object with an r and a attribute. The r stands for radius and is equal to the length, a is the angle (in radians). Again the repitition can be applied:
Which will show our square again. Using this technique we can create a gear-wheel quite "simple" (or relative little code):
gear.r = 70;
gear.n = 15;
gear.h = 2.7;

gear.ribbon = gear.r * Math.sin(Math.PI/gear.n) * 2 ;
gear.toothAngle = Math.atan(2* gear.h, gear.ribbon);
gear.toothSide = gear.ribbon / (2*Math.cos(gear.toothAngle));
gear.iPath = new iPath().turtleLine({a: (2*Math.PI / gear.n) - gear.toothAngle, r: gear.toothSide})
	      .turtleLine({a: 2*gear.toothAngle, r: gear.toothSide}).turtleLine({a:-gear.toothAngle})

Will produce an image like:


an iPath file for Ikea Lillabo train crossing. Simply drop this file in the "drop spot". Inspiration from

jsvg - 1.92 kB - 05/08/2016 at 11:03


  • Bar stool

    jeroen05/20/2016 at 20:27 0 comments

    Find below the Bar Stool, easy in flatpack and convenient popped up. You are free to modify all parameters in the model, including the thickness of your plywood sheet. So you can make this template fit on any piece of plywood. The photo is a bar stool created from wasted concrete plywood collected out of the bins on a buildingspot in Amsterdam. Use this link to view the 2D model of the barstool.

  • stolen stool

    jeroen05/15/2016 at 09:44 0 comments

    The idea is stolen from this kickstarter campaign and is scripted in iPath so the design files are online and customizable.

    view it in stretchsketch

  • 123, Test test

    jeroen05/14/2016 at 13:15 0 comments

    Every software library should have a testsuite attached and iPath is not different. Being written in Javascript a few options are available for a Test framework, and I have chosen Jasmin.

    A test suite consists of a tests which will compare the outcome of a function on a certain input against a reference value. When your testsuite is in place and covers enough of your code, you can refactor and extend your code with far more confidence than without a proper testsuite.

    A very simple javascript function which doubles a numeric value, can look like:

    function double (v) {
          return 2*v;
    A very simple jasmin test could look like:
      it ("tests the double function",function () {
          var b = 5;
    the iPath functionality is in general a bit more complex than the function above. And involves testing of svg and dxf output. An example for testing a piece of code to convert a bezier to a chain of polylines is displayed below:
      it ("tests a bezier in dxf",function () {
          var b = new Bezier2Poly(0.5),pb = new PathBuilder(3);
          	  var array = [{x:20, y:0}, {x:0,y:20}, {x:20, y:20}];
    	  expect(JSON.stringify(b.convert(array), signy))
    Normally a test executed during a build cycle but, but for iPath this is done by accessing a test page which is publicly accessible here

  • A square peg and a round hole

    jeroen05/13/2016 at 15:05 0 comments

    In the previous blog I showed the possibilities of the fillet function: "arcing" the sharp junction of two lines. When milling this fillet comes for free (the radius is equal to the radius of the milling bit) in particular for inside pockets and these fillets may be unwanted, especially when creating a peg-hole connection. Toolpath software like vCarve provide a solution for this, known as the overcut or dogbone.

    (see here for a detailed description in vCarve)

    And iPath also offers this solution, comparable to the fillet:

    var dogBone = new iPath().line(15,0).overcut(1.5).line(0,7).overcut(1.5).line(-15,0).overcut(1.5).line(0,-7).overcut(1.5);
    Also comparable to the fillet this feature is not available in iPath yet, and you have to revert to the helper functions introduced earlier:
       dogbone.pts = [{x:dogbone.length/2, y:0},{br: dogbone.bitradius},{y:dogbone.width, x:0},{br: dogbone.bitradius}
         , {x:-dogbone.length, y:0},{br: dogbone.bitradius},{y:-dogbone.width, x:0},{br: dogbone.bitradius}
         , {x:dogbone.length/2, y:0}];
       dogbone.path = arcPath(dogbone.pts);
    The array dogbone.pts again is with relative points. At the junction of 2 lines there is no fillet-radius but a bit-radius, which indicates that the milling bit should mill some extra to make sure the square corners are free for the square peg

    This feature eliminates the need for adding the dogbones junction in your toolpath software, and reduces the risk of forgetting one or more junctions and a faster time to materialisation.

    The blackline indicates the wanted form to be milled, the redline indicates, the milling result without the overcut and finally the green line is the result with the overcut. As you can see a little bit extra is removed at the corners, but the corners are now ready for the square peg.

    Below a picture to show how the materialize result looks like on a sheet of concreteplex, because of the irregularites in the material the chosen thickness includes a margin which is also visible.

  • Train Crossing

    jeroen05/08/2016 at 19:58 0 comments

    In the previous log I described how iPath was extended (with helper functions) to provide for functionality to complete the traincross.

    This short log will display show how the train cross is realized:

    tc.pts=[{x:3, y:0},{x:5,y:3},{fr:6}, {x:0, y:9},{fr:6}
       , {x:tc.gutter/2-8, y:2}, {x:0, y: tc.boneLength-14}
       , {x:(tc.width-tc.gutter)/2, y:0}
       , {x:0, y:-tc.length}, {fr:tc.length*tc.filletratio}];
    tc.path = arcPath(reflectPath(reflectPath(reflectPath(tc.pts
       , {x:1, y:1}), {x:1,y:0}), {x:0,y:1}));
    tc.rails = new iPath().move(0,tc.boneLength).move(tc.railsWidth/2,0)

    The variables tc.width, tc.boneLength etc must be declared upfront or can be made user-customizable. The {x:.., y:..} indicate relative points, they are connected with straight lines.. The {fr: ..} objects indicates the fillet, the arc between two lines. Note that the fillet will effectively modify (shorten) the surrounding lines. The arcPath function returns an iPath which can be materialized into an SVG path-d attribute or DXF file.

    It would have been possible to concat the tc.path and tc.rails into one object. But when exporting to DXF one can only assign one layer per object. The rails are different from the outside boundary: the cutting depth is different. CNC operators normally want one layer per cutting action and this is possible by constructing 2 iPaths.

    The complete jsvg file can be downloaded from this project's file section. The result can be viewed in StretchSketch

  • iPath extended

    jeroen05/08/2016 at 19:43 0 comments

    As a first challenge I'm targeting

    My idea is to use iPath instead to define the toolpath for the cross. The careful viewer will notice that this cross is an example of 8-times symmetry.

    reflecting the above image 3 times will yield the outer boundary of the cross.

    It would be nice If you can do something like:

    var part = new iPath().line(3,0).line(4,4).fillet(4).line(4,0)....
    the fillet will put an arc with given radius between two straight lines:

    And reflect will append itself reversed and mirrored in the provided vector.

    Unfortunately I have not been able to implement reflect and fillet reliable in iPath. As an alternative for now I use an array with line points, these will all be rendered in visible line, or arc segments. This array can passed as arguments to the functions reflectPath and arcPath.

View all 6 project logs

Enjoy this project?



jeroen wrote 05/13/2016 at 18:46 point

Thank you for your question, and it is a very relevant one indeed. Openjscad is a terrific project, and if I would have known about it’s existence before I started with iPat's predecessor I probably would have considered using and possibly contributing to it.

Having said that, iPath is now a relatively independent small javascript library focussing on scripting pen movements. It can be included in your own website without any trouble. I also think that iPath is in its domain (2D graphics) faster and easier than openjscad.

Above thatiPath has more possibilities for cnc-specific functionality like overcut, fillet, reflection. bezier and bezier to poly conversion. I’m not sure that openjscad can export to dxf, my - or rather my CNC shop’s- preferred format. Not sure how well the openjscad format’s like STL or X3D are accepted in 2D oriented CNC shops. iPath has also more cnc materialised example objects, like stools, cupboards tables etc.

I’m still planning an export builder to generate openjscad paths from iPath, so I can make 3D models with extrusion etc, but this is still on my backlog.

Hope this answers your question.

  Are you sure? yes | no

RandyKC wrote 05/13/2016 at 15:22 point

How does this project differ from

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates