A p5.js sketch is creating a plot that I would like to export as SVG.
The plot is not static: it must be modified (in the demo by clicking on the circle) and then saved by pressing the Save SVG
button.
P5.js alas doesn't provide beginDraw()
and endDraw()
as the standard Processing.
I am using https://github.com/zenozeng/p5.js-svg/, as described in this blog: https://makeyourownalgorithmicart.blogspot.de/2018/03/creating-svg-with-p5js.html
Saving a static SVG (without user interaction) is easy: uncommenting p.SVG
and p.save()
the code works:
<html>
<head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/p5.min.js"></script>
<script type="text/javascript" src="https://github.com/zenozeng/p5.js-svg/releases/download/v0.5.2/p5.svg.js"></script>
</head>
<body>
<script>
let colors = ["red", "orange", "yellow", "lime", "green", "blue", "fuchsia"];
let idx = 0;
let sketch = function (p) {
p.setup = function () {
p.createCanvas(400, 400); // (400, 400, p.SVG); <--------------
p.noLoop();
};
p.draw = function () {
p.background("white");
p.fill(colors[idx]);
p.stroke("black");
p.strokeWeight(3);
p.ellipse(200, 200, 200,200);
// p.save(); // <-----------------------------------
};
p.mousePressed = function() {
if (p.dist(p.mouseX, p.mouseY, 200,200) < 100) {
idx++;
idx %= colors.length;
p.redraw();
}
}
};
let myp5 = new p5(sketch, "my_image");
let save_svg = function() {
// ???? <------------------------------
}
</script>
<div id="my_image"></div>
<button onclick="save_svg()">Save SVG</button>
</body>
</html>
How can the user modify the plot and then save the final version only upon request?
Is this possible using p5.js-svg
or any other library?
I also tried https://github.com/gliffy/canvas2svg but I could not have it working at all.
I found a solution: not the cleanest one, but it works. A bug concerns fonts: if you load a font, inside the SVG it is rendered as geometry. This means the SVG can be huge if there is a lot of text and slow to visualize.
I create a double canvas: a normal one and a SVG. The latter is put into a hidden div. Whenever I am done playing with it, I call the SVG save function that will use the latest calculated parameters (they must be shared between the two, of course).
<html>
<head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/p5.min.js"></script>
<script type="text/javascript" src="https://github.com/zenozeng/p5.js-svg/releases/download/v0.5.2/p5.svg.js"></script>
</head>
<body>
<script>
let colors = ["red", "orange", "yellow", "lime", "green", "blue", "fuchsia"];
let idx = 0;
let sketch = function (p) {
p.setup = function () {
if (p.type === "SVG") {
p.createCanvas(400, 400, p.SVG);
}
else if (p.type === "NORMAL") {
p.createCanvas(400, 400);
}
else {
alert("don't know which canvas to create")
}
p.noLoop();
};
p.draw = function () {
p.background("white");
p.fill(colors[idx]);
p.stroke("black");
p.strokeWeight(3);
p.ellipse(200, 200, 200,200);
p.fill("black");
p.noStroke();
p.textStyle(p.NORMAL);
p.text("test", 100, 100);
p.textStyle(p.BOLD);
p.text("bold", 200, 200);
waiting = false;
};
p.mousePressed = function() {
if (p.dist(p.mouseX, p.mouseY, 200,200) < 100) {
idx++;
idx %= colors.length;
p.redraw();
}
};
p.save_canvas = function() {
p.draw();
p.save();
}
};
cvs = new p5(sketch, "my_image");
cvs.type = "NORMAL";
svg = new p5(sketch, "hidden_div");
svg.type = "SVG";
</script>
<div id="my_image"></div>
<div id="hidden_div" style="display:none"></div>
<button onclick="svg.save_canvas()">Save SVG</button>
</body>
</html>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With