processing / p5.js

p5.js is a client-side JS platform that empowers artists, designers, students, and anyone to learn to code and express themselves creatively on the web. It is based on the core principles of Processing. http://twitter.com/p5xjs —
http://p5js.org/
GNU Lesser General Public License v2.1
21.12k stars 3.22k forks source link

Dealing with SVGs #458

Closed shiffman closed 6 years ago

shiffman commented 9 years ago

Students working on a final that makes use of SVGs asked about SVGs and p5. I looked and don't see an issue discussing this so thought I would open one. I noticed there is some a commented out p5.Shape object. Some stream of consciousness questions:

Apologies if this is covered somewhere else and I'm missing something obvious.

lmccart commented 9 years ago

I started a few months back on trying to create a basic p5.Shape object and realized the PShape API from Processing will likely need some rethinking, and I think it needs someone with more SVG experience to help think about this.

also, @runemadsen did a pretty neat test that allows exporting p5 canvas to svg. https://github.com/runemadsen/p5-svg-test

darbicus commented 9 years ago

yeah going from svg to canvas and back is fairly simple. But do we really need a SVG to do shapes? couldn't we just do another canvas that doesn't display, like a buffer canvas or 2. And Id be willing to make a 2d point array matrix transformation library.. I probably have one laying around my computer from when I was working on processing.js. If you are concerned about the matrix multiplication slowing down the drawing of the images I could setup a webworker to do it without binding up the main window.

workergnome commented 9 years ago

This is being pursued as part of the 2015 Google Summer of Code by Zeno Zeng.

dhowe commented 9 years ago

@workergnome does the 'this' you refer to include integration of pdf/svg into some p5.Shape object, and if so, do we have someone working on implementing the 2d/canvas components of such an object? I am particularly interested in this as it relates to typography, and being able to return glyph paths to users via p5.Shape objects... Lastly, do we have any spec for what our p5.Shape object should look like?

shiffman commented 9 years ago

Adding @dannewoo and @zenozeng to this discussion.

zenozeng commented 9 years ago

@dhowe I am now working on p5.js-svg and for now it uses canvas2svg with patches. I hope basically we can write once and run on both canvas and svg. So we can use canvas for perfermence and use svg for exporting or oop api. Also, I hope that we could only maintain the 2d shapes in canvas API, and let p5.js-svg automatically render it in SVG.

There are still some bugs in the canvas2svg layer. I am now working on it and add more unit tests for canvas2svg. And after that (hopefully this week or next week), I will begin working on the SVGShape API:

Current API Design:

s = new SVGShape();
s.circle();
s.rect();
s.translate(100, 100); // move towards right and bottom
s.translate(100, 100); // again
s.rotate(angle); // should respect p5's angleMode
s.rotateTo(angle);
blur5 = new SVGFilter.Blur(5);
s.addFilter(blur5);
s.removeFilter(blur5);
s.scale(scale);
s.scaleTo(scale);
c = new SVGShape.Circle(x, y, r);
c.x = newX; // update using javascript setter API
c.y = newY;
c.r = newR;

As for p5.Shape, I don't know if there is already a plan for it. I am afraid that some features of SVGShape API might be SVG only. However, I would be happy to make SVGShape somehow compatiable with p5.Shape's API. Let me know if you have any suggestions on the API design.

See also:

workergnome commented 9 years ago

So, @dhowe, @zenozeng, to clarify my understanding of what we're saying:

@zenozeng, are you also working on loading SVGs into the canvas, or are you only looking into export the canvas as an SVG?

I think the other interesting question here is if we are trying to support all of SVG (which is a huge bear of a spec) or if we're trying to support the subset of SVG that maps closely to Canvas? Currently, Processing has basic input/output of SVGs through the PShape api. @zenozeng, it sounds like you're trying to achieve a more ambitious goal—could you clarify more what your end goal is? Is there a subset of p5.js that you're trying to achieve export of?

zenozeng commented 9 years ago

@workergnome I am now only working on render p5.js in and has no plan for implementation of PShape. p5.js-svg is a runtime for p5.js plus some API designed for SVG. And this is my future plan: https://github.com/zenozeng/p5.js-svg/blob/master/plan.md

As for the API, I hope most of p5.js current API could be run on p5.js-svg. For now, almost all Shape/2d_primitives works. See the test page I mentioned above. I will add unit tests and implementation of other API later.

BTW, I am a little confused, canvas's drawImage method could draw SVG directly, which means that the following code should already work in p5.js:

var img;
function preload() {
    img = loadImage('test.svg');
}

function setup() {
    background(100);
    createCanvas(1000, 1000);
}

function draw() {
    image(img, 0, 0);
}
workergnome commented 9 years ago

@zenozeng—that will certainly work, but it loads it as an image, not as a vector object. You can display it, but you cannot use the data contained within the SVG programmatically within p5.js.

I hadn't realized that what you were doing was trying to re-implement p5.js, drawing to an SVG instead of a canvas. That's a much more ambitious goal that I had thought, closer to something like processing.py (or p5.js itself) than just a helper library—or am I misinterpreting what you're working on?

Thank you for taking the time to explain this work to me.

dhowe commented 9 years ago

As @lmccart suggests above, Processing's PShape seems rather overloaded, encompassing SVG and OBJ import, curves/paths, color-handling, drawing, textures, lighting, transforms/matrices, etc. So I'm not sure we want to mirror its API... For the purposes of typography, it would be nice to have some type of object that encapsulates one or more paths, which could be part of a PShape (as is the case in Processing) or perhaps be its own p5.Path object. I'm not sure, as @workergnome says, that exposing all, or even much, of SVG's functionality within p5js makes much sense. Perhaps we separate SVG functions into a library like sound (perhaps @zenozeng's work goes in this direction?) or we allow SVG objects to be loaded via a PShape, but then only expose the native SVG object to the user, rather than implementing lots of SVG-specific functions in p5js core objects.

lmccart commented 9 years ago

Pinging @shiffman here, who may have more thoughts about SVG / PShape / etc. I think it'd be nice at some point to be able to load an SVG file as an object or create a new shape, mirroring the loadShape(), createShape(), p5.Shape functionality of Processing. I'm not sure if this is outside the scope of the GSoC project or not.

I also spoke with @codeanticode and @indefinit about how this might fit in with 3D. If I understood correctly, PShape is used sometimes in 3D mode of Processing to achieve more of a scene graph like system, which feels like it may be too much, and we discussed the possibility of splitting some of this functionality out into an object like p5.Graph (or p5.SceneGraph?).

shiffman commented 9 years ago

This is certainly a complex discussion as "SVG + p5.js" has so many pieces/components/possibilities. If this is helpful, the two things I see used the most by students in the context of an intro "creative coding" course are:

  1. "Export something I drew to SVG for high-res printing." A good reference for this is supporting the kind of work outlined in @runemadsen's Printing Code.
  2. "Load an SVG (or other path data, like a font) and get all the vertex points so I can draw my own stuff along that path." The geomerative library gets used a lot for this and PShape also has some of this functionality.

The dream of the magical PShape for loading, manipulating, and exporting shape data hasn't really caught on in Processing. I don't see it get used that often and beginners just don't need it that often and/or it confuses them. This may change or I may be blind to some use I'm not seeing.

I do think, however, that there are larger questions alluded to here (that I don't have good answers for) given how the browser can natively handle SVGs. Do we envision someday a createSVG() used instead of createCanvas()? That sounds dangerous, but also intriguing.

I guess after this rambling, I might say that p5.Shape is a bit outside the scope of what @zenozeng is working on at the moment, but we could have a discussion sometime soon to see what, if anything, could be added to the summer goals. It would be great to be able to easily do some of the things @dhowe mentions like grab the glyph paths of a font, etc.

scotthmurray commented 9 years ago

+1 to @shiffman's rambling. :-)

Some form of SVG support would be great, though it's unclear what the most p5-ish way of doing this would be. (Can one load in SVGs? Can you export them? Can you manipulate them in the DOM, as with D3, or do they render to the canvas element, more like Processing?)

zenozeng commented 9 years ago

I think I can add some API for manipulating SVG and Path in p5.SVG.

Assume we have the following svg file:

<svg>
    <g>
        <path fill="gray" stroke="#000" paint-order="stroke fill markers" 
                  d=" M 35 65 L 32 42 A 20 20 0 0 1 52 20 Z" 
                  stroke-miterlimit="10" stroke-width="3">
        </path>
    </g>
</svg>

Maybe I am wrong, but I think PShape is somehow vertex based and SVG's path should be Command based. I don't know how to do it with PShape, so I designed a SVGPath API as below:

Read path

var svg = loadSVG('path-to-svg-file.svg');
var paths = svg.getPaths();
var path = paths[0];
var commands = path.getCommands(); // get d attribute for current <path>
for (var i = 0; i < commands.length; i++) {
    console.log(command);
}
// in console, we will get:

// moveTo 35, 65
// {type: 'M', length: 2, 0: 35, 1: 65}

// lineTo 32, 42
// {type: 'L', length: 2, 0: 32, 1: 42}

// arc curve
// {type: 'A', length: 7, 0: 20, 1: 20, 2: 0, 3: 0, 4: 1, 5: 52, 6: 20}

// closePath
// {type: 'Z', length: 0}

Manipulate path

var commands = path.getCommands();
var moveto = commands[0];
moveto[0] = 40; // now move to 40, 65
commands.insert(new SVGPathCommand('L 10, 10'), indexWillBe=2);
// or commands.insert('L 10, 10', indexWillBe=2);
path.setCommands(commands);
// now the svg path: M 40 65 L 32 42 L 10 10 A ...
saveSVG(svg, 'filename.svg');

Manipulate SVG Element

var svg = loadSVG('filename.svg');
var path = svg.querySelector('path');
path.setAttribute('stroke', 'red');

Draw on existing SVG

var svg = loadSVG('filename.svg');
var shape = new SVGShape();
shape.rect(args);
shape.ellipse(args);
svg.querySelector('g').append(shape);
workergnome commented 9 years ago

I think that we should have an 'stored, ordered vertexes in two or three dimensions for drawing a shape" thing. We need it for @dhowe's font glyphs, and to hang a bunch of utility methods off—area, tessellation, simplification, things like that.

I don't think that there's a big call for arrays of these—javascript arrays are really nice, and I know that i'd rather just use them than a custom, nested group:

var shapes, shape1, shape2;

function setup() {
  shape1 = new pShape();
  shape1.addVertex(0,0);
  shape1.addVertex(10,-10);
  shape1.addVertex(-10,-10);
  shape1.close();

  shape2 = new pShape();
  shape2.addVertex(0,0);
  shape2.addVertex(10,10);
  shape2.addVertex(-10,10);
  shape2.close();

  shapes = [shape1, shape2];
}

function draw() {
  shapes.forEach(shape) { 
    shape.draw();
  }
}

As far as SVGs go:

Having played a bit with SVG, SVG import as data is...problematic. Without implementing the entire spec, we're never going to get it to work—even the very simple SVGs that I created for the moon drawings project weren't able to be loaded in Processing, for reasons we never managed to figure out, and they were a single black line. Picking which paths to render, what order, how to support all of the nuances of fills, and corners, and gradients, etc...

SVG export, however, is super-useful, and not that hard. Choosing which way to implement it, and making sure that you can round-trip through p5.js would be useful. A very limited import, that promises to work with a very strict subset of SVG, that could be useful, but might be too hard to support.

dhowe commented 9 years ago

This makes good sense, though the API sketched above would only support polygons? For SVG-style paths (e.g., font outlines), seems we'd need to add at least the functions below; there are others, but this would be a minimal set:

  shape.moveTo(x, y);
  shape.lineTo(x, y);
  shape.quadTo(x1, y1, x, y);                  // quadratic bezier
  shape.curveTo(x1, y1, x2, y2, x, y);         // cubic bezier
zenozeng commented 9 years ago

@lmccart @workergnome @dhowe I think Vertex is somehow limited. In canvas, there is an API named Path2D, which is used to declare paths. Maybe we can provide similar API for building path or shapes?

zenozeng commented 9 years ago

@lmccart @workergnome @dhowe Or should we provide some API for vertex and links?

shape1 = new pShape();
shape1.addVertex(0,0);
shape1.addVertex(10,-10);
shape1.addVertex(20,-10);
shape1.addLink(0, 1, 'line');
shape1.addLink(1, 2, 'bezierCurve', cp1.x, cp1.y, cp2.x, cp2.y);
coreygo commented 8 years ago

Not sure if this is the best place for input but please consider support for linear and radial SVG gradients…

nick-jonas commented 8 years ago

I'm outputting SVG's that are rather complex, like this:

screen shot 2016-01-15 at 5 12 36 pm

When I go to save it, I'm doing it like this:

var svg = document.getElementsByTagName('svg')[0];
svg = new XMLSerializer().serializeToString(svg);
var b64 = btoa(unescape(encodeURIComponent(svg)));
var img = document.createElement('img');
img.src = "data:image/svg+xml;base64,\n"+b64;
img.alt = "file.svg";
var url = img.src.replace(/^data:image\/[^;]/, 'data:application/octet-stream');
window.open(url);

And the end result has a ton of lines/circles nested, this is the bottom of the svg:

<g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/><g/></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></g></svg>

Because of that, I get this error message when opening up in Illustrator:

screen shot 2016-01-15 at 5 15 27 pm

And the image looks a little messed up:

screen shot 2016-01-15 at 5 16 29 pm

Is there any better way to avoid all these objects getting nested? I'm just using the ellipse()``,point(), andline()``` methods.

lmccart commented 8 years ago

you might try using this library by @zenozeng https://github.com/zenozeng/p5.js-svg. i'm not sure if it accomplishes what you're trying to do but it adds a lot of svg functionality.

nick-jonas commented 8 years ago

Yep, that's what I'm using - sorry I should probably post this over there!

raphaelschaad commented 8 years ago

+1 for a simple, built-in way of exporting to vectors – something like saveCanvas('myCanvas', 'pdf');.

Context: I found my way here googling for "p5js SVG/PDF export".

Reading this thread I realize that this seemingly simple thing requires complex design decisions I'm not able to contribute to, but wanted to share the view/wish/need of a beginner that might help.

AnnaMag commented 8 years ago

hi everybody- I wanted to check in whether there were any new thoughts on the topic. Having spoken with Lauren, and based on my previous work with SVG's, I set off to start implementing it in p5.js. Directly porting PShape from Processing did not seem like a proper way to go, so I in my fork I defined p5.Shape as a set of paths, which would be p5 objects themselves and could be rendered to canvas using Path2D API. e.g. p5.Path could have the description: { anchor_point: x: 10, y: 40 , code: 'a', command: 'elliptical arc', relative: true, rx: 5, ry: 5, xAxisRotation: 20, largeArc: false,sweep: true,x: -10, y: -10 }, where anchor_point is the last point of the previous path, if any. Those entries are parsed from an SVG directly and would require some additional rendering definitions (aside of already implemented curves, e.g. render elliptic arc) and can include additional attributes like color etc. An SVG can have a few p5.Shapes in it. LoadSVG could then return an Array of p5.Shapes, which in turn would consist of p5.Paths. The problem I see is with manipulating those Paths is no way of knowing which Path corresponds to which fragment of the figure. Say we are drawing a face and want to make the nose larger, how can we say which paths are part?:) Some SVGs group paths per elements, some don't. In this sense, it does not seem like a useful functionality. I haven't worked with fonts, so maybe missing on its usefulness in this regard.

In summary: happy to contribute, yet confused at the moment whether it is a 'p5' style of implementation and thinking of API design, and whether the direction is useful at all. Curious to hear your thoughts on that!

lmccart commented 8 years ago

Hi @AnnaMag thanks for this preliminary research. I am not such an svg pro but would like to be able to help add some input here. First, is it possible for you to link to or add a couple svgs to use as discussion cases?

It might be helpful to look at a few other libraries that deal with SVGs. Here are a few that come to mind:

I'd also add, if it seems like one or more of these are already doing a sufficient job, and that svg handling seems to be more complex in p5.js than Processing, maybe we don't need to reinvent the wheel. We could consider either a more minimal handling of SVGs in p5, or none at all with a suggestion to combine with one of these other tools instead.

@sciutoalex's d3+p5 cookbook is a nice example of supporting the flow between p5 and a different library.

also pinging @dhowe to see if there are any particular considerations with regard to p5.Font here.

runemadsen commented 8 years ago

I'll be happy to help answer any questions you may have about these things. My Rune.js library is modeled very close to the native SVG functionality, but if it's helpful, you can take a look at the implementation of the Rune.Polygon and Rune.Path classes:

https://github.com/runemadsen/rune.js/blob/rendering/src/shapes/polygon.js https://github.com/runemadsen/rune.js/blob/rendering/src/shapes/path.js

Rune.Polygon is a class that can only hold closed shapes with straight lines, whereas Rune.Path is for more complex open/closed shapes with curves. This is a distinction from the SVG spec that is really nice when doing computational geometry calculations, but I'm not sure that Processing would want this.

You can also take a look at the Rune.Font plugin that can load TrueType font files and convert them into Rune.Path shapes.

https://github.com/runemadsen/rune.font.js

Let me know if I can help in any way.

limzykenneth commented 8 years ago

Just a +1 and a note here, I did find myself wanting SVG functionality when using p5.js especially when dealing with text since text in SVG can be selected and read as a DOM element. I wonder if it would be possible to have p5 plugin wrappers around libraries like rune.js so that we don't really have to implement SVG functionality in the core while having a consistent API when people wanted to use SVG with p5 specifically.

sunnyhome-io commented 7 years ago

+1 trying to convert a p5js canvas into vectors for a project

bmoren commented 7 years ago

I'm quite interested in this as well for getting basic 2d geom paths out for working with drawing machines. I'm not concerned with having the full p5 feature set translate to SVG, 2D geom + text would be sufficient imo for 90% of case uses. @lmccart what do you think is the best way to go about a simple approach, is @zenozeng's approach of creating a new p5 render the direction this should go in, or is there another place that we can start working? I've looked at @runemadsen's simple canvas2svg example, but cannot get a similar approach working with the current build of p5. Perhaps there is a way to still integrate with canvas2svg which would expose the drawing context more directly to work with these types of libraries?

biovisualize commented 7 years ago

Although superimposing an SVG over a canvas would work great, serializing an SVG and rendering it on a canvas is easy too (see this example). Possible APIs for working with SVG, as I get from this discussion, include:

But in all cases, having an API that manipulates the SVG, in a visible DOM or an offline one with a command to render it on canvas, is probably easier than forcing a retained mode API into an immediate mode API.

Converting from Canvas to SVG is more difficult, as it usually involves using an abstraction that can write to both (as PShape does with PShapeOBJ and PShapeSVG). Here are other canvas/svg abstractions I would add to those mentioned by @lmccart for inspiration:

I wonder if simply writing an adaptor to Snap.SVG with an API inspired by PShape would not be the easiest. The result could be rendered into a canvas on-the-fly, but could also be exported directly as SVG.

bobcgausa commented 7 years ago

I implemented an SVG parser that implements path, line, circle, text, rect, polygon, polyline, polygon, transform and basic text. Only one level of is supported. Styles not at all. Check it out at http://jsfiddle.net/bobcook/2p9tqzze/

Paste your SVG file into the great app at https://petercollingridge.appspot.com/svg-editor Remove white space to create a single string rep of the file Call my svgParse with your string. I can post on github if there's enough interest.

lehni commented 7 years ago

If it's of use or interest, here the Paper.js code that parses SVG strings:

https://github.com/paperjs/paper.js/blob/develop/src/path/PathItem.js#L127

It has been thoroughly tested against all kinds of SVG path definitions, and was designed to be compact and rather framework agnostic, while hopefully remaining legible.

And here some of the strange edge cases we've encountered that our parser was initially choking on:

https://github.com/paperjs/paper.js/blob/develop/test/tests/PathItem.js#L15

bobcgausa commented 7 years ago

Thx much but I needed code that used P5 api.

Sent from my Windows 10 phone

From: Jürg Lehnimailto:notifications@github.com Sent: Wednesday, March 15, 2017 6:40 AM To: processing/p5.jsmailto:p5.js@noreply.github.com Cc: bobcgausamailto:bobcook47@hotmail.com; Commentmailto:comment@noreply.github.com Subject: Re: [processing/p5.js] Dealing with SVGs (#458)

If it's of use or interest, here the Paper.js code that parses SVG strings:

https://github.com/paperjs/paper.js/blob/develop/src/path/PathItem.js#L127

It has been thoroughly tested against all kinds of SVG path definitions, and was designed to be very compact while remaining legible.

— You are receiving this because you commented. Reply to this email directly, view it on GitHubhttps://github.com/processing/p5.js/issues/458#issuecomment-286704481, or mute the threadhttps://github.com/notifications/unsubscribe-auth/ACgphMWb0tiwj-MhXJvGvEhpQDaxgUZ8ks5rl8AdgaJpZM4DG5ED.

lehni commented 7 years ago

Of course. I just posted it thinking it may be of use to borrow approaches, where it makes sense. The path drawing API is rather interchangeable I think.

mxa commented 6 years ago

@nick-jonas you might want to give Inkscape a try, I found Adobes SVG implementation half-hearted. They have nothing to gain when supporting an open standard.

lmccart commented 6 years ago

given the current scope of the library and considering maintenance and priorities, I am going to close this for now.

modermo commented 6 years ago

Where are we at with this? Was anything implemented?

I'm hoping to just be able to use SVGs in a sketch and control the fill color...

bmoren commented 6 years ago

This is closed for now, as an alternative I suggest taking a look at http://paperjs.org/ which has maximum SVG functionality.

runemadsen commented 6 years ago

As an alternative to Paper.js, I created Rune.js as a solution to this. The API is close to P5.js, and it renders SVG's.

http://runemadsen.github.io/rune.js/

limzykenneth commented 6 years ago

Sorry to be digging old issues here but I wanted to gauge interest for integrating SVG into p5.js as a general idea because I'm interested in pitching this as a Processing Fellowship project but I need to know if this would be something that the community is looking for.

I haven't have too much opinion on how to proceed at this moment, maybe I'll build on @zenozeng's existing work, maybe I'll attempt to emulate other libraries like rune.js or paper.js, but as mentioned, I wanted to gauge interest first. Personally I think this is a good feature to have as it opens up more native controls of paths that are not rasterised and also opens up a whole field of manipulating text that was only emulated with textToPoints in the current library.

Pinging @shiffman @lmccart @zenozeng @dhowe please ping anyone else that you think may be interested in chipping in. Thanks!

bmoren commented 6 years ago

I've thought about this quite a bit for the past year as I've been trying to integrate more digital fabrication, specifically the laser cutter and plotter into my classes. my main issue with @zenozeng's approach was that it required a secondary step setup which is fine for seasoned devs, but was quite opaque for beginners. If this is to move forward, I'm convinced it should live as one of 2ish directions: Direction 1: an additional render for p5js which is a drop in replacement for the 2D render. Things become trickier here with dealing with images, but its seems doable, this is the direction @zenozeng was heading and I think it's likely the most ideal. Direction 2: as a library which essentially takes whats happening in the 2d renderer and replicates it into a distinct svg instance. This is closer to some earlier trials, and is maybe a but more related to canvas2svg.js. This direction is perhaps a little more roundabout in terms of setup, but it could provide a nice platform to talk about the distinction of SVGs vs Canvas. A third option could be a more hybrid approach where it's an external library which adds a render, AFAIK no one has done this yet with a library, so that could open up some really interesting space and possibility to add additional renderers in the future as technologies evolve. Thats my $0.02, I'd love to be involved if you decide to move forward with it!

dannewoo commented 6 years ago

I mentored @zenozeng for this project and hope to revive it in the future. I personally need the option to easily export SVGs or PDFs from p5js for my design students to use in other programs like Adobe Illustrator or bring the designs to a laser cutter. I use rune.js and paper.js mainly but would love to see an SVG component included as a part of p5js core. I don’t have the time to focus on this right now, but I second someone else taking this challenge on!

bobcgausa commented 6 years ago

Kenneth et al

Here's my SVG input P5 code, which is pretty complete, except for nested .

http://jsfiddle.net/bobcook/2p9tqzze/

I needed it so that the kids i teach could write apps w images online without running into cross-domain loading restrictions.

I'd be happy to help but feel confident a good student could finish it as a semester project.

bob cook

professorcook.org


From: Kenneth Lim notifications@github.com Sent: Thursday, November 30, 2017 4:42 AM To: processing/p5.js Cc: bobcgausa; Comment Subject: Re: [processing/p5.js] Dealing with SVGs (#458)

Sorry to be digging old issues here but I wanted to gauge interest for integrating SVG into p5.js as a general idea because I'm interested in pitching this as a Processing Fellowship project but I need to know if this would be something that the community is looking for.

I haven't have too much opinion on how to proceed at this moment, maybe I'll build on @zenozenghttps://github.com/zenozeng's existing work, maybe I'll attempt to emulate other libraries like rune.js or paper.js, but as mentioned, I wanted to gauge interest first. Personally I think this is a good feature to have as it opens up more native controls of paths that are not rasterised and also opens up a whole field of manipulating text that was only emulated with textToPoints in the current library.

Pinging @shiffmanhttps://github.com/shiffman @lmccarthttps://github.com/lmccart @zenozenghttps://github.com/zenozeng @dhowehttps://github.com/dhowe please ping anyone else that you think may be interested in chipping in. Thanks!

— You are receiving this because you commented. Reply to this email directly, view it on GitHubhttps://github.com/processing/p5.js/issues/458#issuecomment-348134809, or mute the threadhttps://github.com/notifications/unsubscribe-auth/ACgphCx6HYg3hlx8bXgpE63t5fAi8Gazks5s7niDgaJpZM4DG5ED.

shiffman commented 6 years ago

Adding @runemadsen to this discussion as I know he's thought a lot about this for rune.js and programmingdesignsystems.com!

runemadsen commented 6 years ago

Thanks @shiffman. I think the general idea of supporting a Processing-like SVG export mode is great. There's lots to say about this, but my overall comment would be this: Given the P5.js API with setup() and draw(), I think this SVG export mode needs to have an explicit call to beginRecord() and endRecord() just like Processing. If it doesn't (for example, if it's implemented as a render mode), most users of P5.js would end up with tons of garbage SVG tags from older calls to the draw() loop. In HTML5 canvas, a function like background() can simply paint the pixel values and be done with it. But in SVG this is more problematic because every drawing function creates an SVG tag.

This is where SVG is different than other output formats: It encourages the idea of a scene graph (because HTML is a scene graph) with persistent objects that are updated over time. This is why Rune.js is built as a scene graph with a very different API than P5.js (Look at my explanation of this problem in the Rune.js documentation).

Anyway, just my two cents.

lmccart commented 6 years ago

I'm excited about this functionality. I think it's very much needed to open up applications of printing and design. At the same time, I worry that already the library is beyond the scope that I am successfully able to maintain it and I wonder how we would maintain a whole new area. That's my concern, but a fellowship project is meant to be experimental and push into new areas, so I think we should separate the two questions of exploration / development and maintenance feasibility. Or, it could be an argument to go in the direction of packaging this as a library that is separate from the core.

bmoren commented 6 years ago

It does seem like a good candidate for something in the lines of p5.dom and p5.sound and would add a similar kind of spoke to the p5js hub!

bobcgausa commented 6 years ago

I vote for library. Add a altGraphics hook for getImage then for line etc. If altGraphics then altGraphics.line

That way new libraries could be added to meet future needs

On Dec 5, 2017 9:04 PM, Lauren McCarthy notifications@github.com wrote:

I'm excited about this functionality. I think it's very much needed to open up applications of printing and design. At the same time, I worry that already the library is beyond the scope that I am successfully able to maintain it and I wonder how we would maintain a whole new area. That's my concern, but a fellowship project is meant to be experimental and push into new areas, so I think we should separate the two questions of exploration / development and maintenance feasibility. Or, it could be an argument to go in the direction of packaging this as a library that is separate from the core.

— You are receiving this because you commented. Reply to this email directly, view it on GitHubhttps://github.com/processing/p5.js/issues/458#issuecomment-349506418, or mute the threadhttps://github.com/notifications/unsubscribe-auth/ACgphELr9AdKTyMNQPLDBkyYgprKbKQwks5s9fZHgaJpZM4DG5ED.

limzykenneth commented 6 years ago

Thanks everyone for their comments and please do keep them coming! I do go through all of them and gave them individually some thoughts and they are all great points to go forward with.

One point that I did not thought of before asking here is the possibility of exporting SVG for laser cutters and plotters which I think is a major point of this feature so special thanks for bringing up this idea.

Another very interesting point that I think really need close attention is what @runemadsen mentioned about the need for a scene graph system and how it may diverge from the classic Processing/p5.js drawing methods. This will probably be a key point in the implementation decisions.

Also vey valid point from @lmccart about creating a whole new area that needs to be maintained over time which I also agree with @bmoren idea about making a separate addon at least to start with which can help ease the overall scale of p5.js as a project.

I will be submitting this as a Processing Fellowship project but it may be that I will work on something else for the Fellowship, that'll depend on discussions with the board but if anyone is interested in working on this, we can either work together or you can take over the project, just let me know.

raphaelschaad commented 5 years ago

I understand this is tricky and closed, but in summary, if one would like to procedurally generate an SVG, is p5js' recommendation to not use p5js and instead use one of the alternatives listed in this thread?