gliffy / canvas2svg Goto Github PK
View Code? Open in Web Editor NEWTranslates HTML5 Canvas draw commands to SVG
License: MIT License
Translates HTML5 Canvas draw commands to SVG
License: MIT License
Here's my code that I need to export to svg:
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.stroke();
ctx.fill('evenodd')
let region = new Path2D();
var h1 = document.getElementById("myCanvas1");
var ctx = c.getContext("2d");
ctx.strokeStyle = "#7AD7F0";
ctx.lineWidth = 30;
ctx.beginPath();
ctx.rotate(10 * Math.PI / 360);
ctx.arc(41,288,55,25,3);
ctx.stroke();
var h2 = document.getElementById("myCanvas2");
var ctx = c.getContext("2d");
ctx.strokeStyle = "#7AD7F0";
ctx.lineWidth = 30;
ctx.beginPath();
ctx.rotate(0 * Math.PI / 360);
ctx.arc(151,278,55,25,3);
ctx.stroke();
ctx.closePath();
var h3 = document.getElementById("myCanvas3");
var ctx = c.getContext("2d");
ctx.strokeStyle = "#7AD7F0";
ctx.lineWidth = 30;
ctx.beginPath();
ctx.rotate(15 * Math.PI / 360);
ctx.arc(293,232,55,25,3);
ctx.stroke();
ctx.closePath();
var h4 = document.getElementById("myCanvas4");
var ctx = c.getContext("2d");
ctx.strokeStyle = "#7AD7F0";
ctx.lineWidth = 30;
ctx.beginPath();
ctx.rotate(-8 * Math.PI / 360);
ctx.arc(385,240,55,25,3);
ctx.stroke();
var h5 = document.getElementById("myCanvas5");
var ctx = c.getContext("2d");
ctx.strokeStyle = "#7AD7F0";
ctx.lineWidth = 30;
ctx.beginPath();
ctx.rotate(-5 * Math.PI / 360);
ctx.arc(485,245,55,25,3);
ctx.stroke();
ctx.closePath();
var h6 = document.getElementById("myCanvas6");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.rotate(-12 * Math.PI / 360);
ctx.rect(0, 349, 550, 0);
ctx.stroke();
ctx.closePath();
var paat = document.getElementById("myCanvas7");
var ctx = c.getContext("2d");
ctx.fillStyle="#654321";
ctx.translate(40, 60);
ctx.beginPath();
ctx.moveTo(350,150);
ctx.lineTo(300,300);
ctx.lineTo(100,300);
ctx.lineTo(50,150);
ctx.lineTo(120,150);
ctx.bezierCurveTo(
120, 220,
220, 220,
220, 150
);
ctx.fill();
ctx.closePath();
var h8 = document.getElementById("myCanvas8");
var ctx = c.getContext("2d");
ctx.strokeStyle="#101";
ctx.lineWidth = 4;
ctx.beginPath();
ctx.moveTo(170, 130);
ctx.lineTo(170, 205);
ctx.stroke();
ctx.closePath();
var h9 = document.getElementById("myCanvas9");
var ctx = c.getContext("2d");
ctx.strokeStyle="#101";
ctx.lineWidth = 4;
ctx.translate(145, -120);
ctx.beginPath();
ctx.rotate(160 * Math.PI / 360);
ctx.arc(130,0,120,25,13);
ctx.stroke();
ctx.closePath();
var h10 = document.getElementById("myCanvas10");
var ctx = c.getContext("2d");
ctx.strokeStyle="#101";
ctx.lineWidth = 4;
ctx.translate(280, -180);
ctx.beginPath();
ctx.rotate(280 * Math.PI / 360);
ctx.arc(125,23,130,55,18);
ctx.stroke();
ctx.translate(83, 5);
ctx.moveTo(165, -35);
ctx.lineTo(125, -85);
ctx.stroke();
ctx.closePath();
var h11 = document.getElementById("myCanvas11");
var ctx = c.getContext("2d");
ctx.strokeStyle="#101";
ctx.lineWidth = 4;
ctx.beginPath();
ctx.rotate(90 * Math.PI / 360);
ctx.arc(-45,-55,120,55,18);
ctx.stroke();
ctx.closePath();
var bob = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.strokeStyle = "black";
ctx.lineWidth = 2;
ctx.translate(43, -295);
ctx.rotate(910 * Math.PI / 360);
ctx.beginPath();
ctx.arc(60,40,13,0,10);
ctx.stroke();
var bobsilm1 = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.strokeStyle = "black";
ctx.lineWidth = 1;
ctx.beginPath();
ctx.arc(60,35,4,0,10);
ctx.stroke();
var bobsilm2 = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.strokeStyle = "black";
ctx.lineWidth = 1;
ctx.beginPath();
ctx.arc(59,36,1,0,10);
ctx.fillStyle = "#101";
ctx.fill();
ctx.stroke();
var bobkeha = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.strokeStyle = "black";
ctx.lineWidth = 3;
ctx.beginPath();
ctx.moveTo(60, 54);
ctx.lineTo(60, 80);
ctx.stroke();
var bobkehajalg1 = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.strokeStyle = "black";
ctx.lineWidth = 3;
ctx.moveTo(60, 80);
ctx.lineTo(50, 100);
ctx.stroke();
var bobkehajalg2 = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.moveTo(60, 80);
ctx.lineTo(70, 100);
ctx.stroke();
var bobkehakasi1 = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.moveTo(60, 60);
ctx.lineTo(19, 60);
ctx.stroke();
var bobkehakasi2 = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.moveTo(60, 60);
ctx.lineTo(70, 80);
ctx.stroke();
var bobsuu = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.strokeStyle = "black";
ctx.lineWidth = 2;
ctx.beginPath();
ctx.arc(55,45,2,0,3);
ctx.stroke();
var ruupur = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.strokeStyle = "black";
ctx.lineWidth = 2;
ctx.translate(10, 32);
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(0, 35);
ctx.moveTo(0, 0);
ctx.lineTo(25, 3);
ctx.moveTo(25, 3);
ctx.lineTo(37, 11);
ctx.moveTo(0, 35);
ctx.lineTo(37, 11);
ctx.stroke();
var tutt1 = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.strokeStyle = "black";
ctx.lineWidth = 2;
ctx.rotate(280 * Math.PI / 360);
ctx.beginPath();
ctx.arc(-51,-27,12,0,1);
ctx.stroke();
var tutt2 = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.strokeStyle = "black";
ctx.lineWidth = 2;
ctx.rotate(50 * Math.PI / 360);
ctx.translate(8, 8);
ctx.beginPath();
ctx.arc(-71,-15,12,0,1);
ctx.stroke();
var tutt3 = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.strokeStyle = "black";
ctx.lineWidth = 2;
ctx.rotate(50 * Math.PI / 360);
ctx.translate(-5, 10);
ctx.beginPath();
ctx.arc(-71,0,12,0,1);
ctx.stroke();
var paadinina = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.strokeStyle = "black";
ctx.lineWidth = 3;
ctx.rotate(-190 * Math.PI / 360);
ctx.beginPath();
ctx.arc(31,-42,50,0,1);
ctx.stroke();
var heli1 = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.strokeStyle = "black";
ctx.lineWidth = 2;
ctx.translate(-5, 35);
ctx.rotate(-50 * Math.PI / 360);
ctx.beginPath();
ctx.arc(18,-18,20,0,1);
ctx.arc(15,8,15,0,1);
ctx.stroke();
var heli2 = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.strokeStyle = "black";
ctx.lineWidth = 2;
ctx.translate(-15, 37);
ctx.beginPath();
ctx.arc(18,-18,20,0,1);
ctx.arc(15,8,15,0,1);
ctx.stroke();
var heli3 = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.strokeStyle = "black";
ctx.lineWidth = 2;
ctx.translate(25, -28);
ctx.beginPath();
ctx.arc(18,-23,20,0,1);
ctx.arc(15,8,15,0,1);
ctx.stroke();
var heli4 = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.strokeStyle = "black";
ctx.lineWidth = 2;
ctx.translate(-15, 37);
ctx.beginPath();
ctx.arc(18,-18,20,0,1);
ctx.arc(15,8,15,0,1);
ctx.stroke();
Hi. I am trying to use this library to export a chart created with chart.js to SVG, but it seems that chart.js can't use 'fake' context created by C2S. I am getting error_: "Failed to create chart: can't acquire context from the given item"_ when I try to draw a chart in C2S context.
See Codepen here for full example.
My Stackoverflow question is here.
Is there a way around this?
Or am I missing something?
Thanks.
Not vital, of course, but this method is currently missing: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash
I am attempting to snapshot canvas renders as SVGs from points in time of playback of a CreateJS timeline. So I want set the timeline to a certain frame and snapshot the EaselJS submodule output which writes to the canvas object.
I have no control over the composition of the graphics I am working with in these timelines, so re-drawing the graphics to workaround this issue is not an option.
The issue is that the EaselJS module frequently applies the following sequence of commands while drawing path, at the point at which it wants to stroke the path and move on to the next graphic entity:
ctx.strokeStyle = this.style;
// this.ignoreScale is by default falsy
if (this.ignoreScale) { ctx.save(); ctx.setTransform(1,0,0,1,0,0); }
ctx.stroke();
if (this.ignoreScale) { ctx.restore(); }
The intent here is to re-use the current canvas state except for the transform. The problem is that the library interprets any call to ctx.save
as not only stack push for the style state, but also calls for a new group element to be attached the SVG tree, I imagine, since SVG is declarative and has no state, to persist the state changes being called between ctx.save
and ctx.restore
, but this does not capture the range of intents in using ctx.save
and ctx.restore
.
So when its stroking a path, which is usually the last thing it calls for that path, this library changes elements and attempts to write a path to the newly create <g>
instead of the path
its supposed to write to. This creates incorrect output. I've attached a screenshot where the SVG output is to the left and the Canvas render to the right.
The outlining paths used to "ink" the graphic as in the Canvas render all end up missing, and once can see multiple path
s without a populated d
attribute followed by an empty g
peer.
Make canvas with filter or globalCompositeOperation function.
Convert it into svg.
Expected: Canvas and svg output should be the same.
Actual: Svg output is different.
Hey, thanks for your great work. But I have encountered a bug.
beginPath();
lineTo(30, 20);
bezierCurveTo(80, 0, 80, 75, 30, 75);
bezierCurveTo(50, 80, 60, 25, 30, 20);
fill();
stroke();
closePath();
The path generated is L 30 20 C 80 0 80 75 30 75 C 50 80 60 25 30 20
, which actually should be M 30 20 C 80 0 80 75 30 75 C 50 80 60 25 30 20
.
According to W3's doc, Canvas's moveTo(x, y) method must create a new subpath with the specified point as its first (and only) point. And canvas's lineTo(x, y) method must ensure there is a subpath for (x, y) if the object's path has no subpaths. Otherwise, it must connect the last point in the subpath to the given point (x, y) using a straight line, and must then add the given point (x, y) to the subpath.
However, SVG's lineto only draw straight lines from the current point to a new point.
See also: http://www.w3.org/TR/2015/WD-2dcontext-20150514/#dom-context-2d-lineto
See also: http://www.w3.org/TR/SVG/paths.html#PathDataLinetoCommands
So in canvas2svg, when lineTo called, we should check if there is a subpath, and use M x y
instead of L x y
if the object's path has no subpaths.
This issue is fixed in zenozeng@1c49685. But this fix need #20 to be merged. I will pull a new request for this issue as soon as pull#20 merged.
See also: zenozeng/p5.js-svg#44
When this line of code is called...
var ctx = C2S(304.797, 26.109);
... then it gets the error...
Cannot set property 'width' of undefined
When I set a breakpoint in canvas2svg on line 196 in Chrome, sure enough "this" is undefined.
Sometimes if I step through it slowly enough though, "this" will be "Window". And even in that circumstance, I get this error...
Object [object global] has no method '__setDefaultStyles'
on line 202...
this.__setDefaultStyles();
I'm trying to render a text balloon using lines and arcs, the first arc looks correct using canvas in multiple browsers (Chrome, FF, IE), after the conversion to SVG the arc is rendered incorrectly, for all other arcs large-arc-flag is not set, and editing the SVG manually fixes the issue.
Code:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="canvas2svg.js" type="text/javascript"></script>
</head>
<body>
<canvas id="testCanvas"></canvas>
<div id="svgImage"></div>
<p id="svgText"></p>
<script>
function drawBalloon(_drawingContext) {
_drawingContext.beginPath();
_drawingContext.lineWidth = 4;
_drawingContext.moveTo(19, 10);
_drawingContext.lineTo(110, 10);
_drawingContext.arc(110, 20, 10, 1.5*Math.PI, 0);
_drawingContext.lineTo(120, 50);
_drawingContext.arc(110, 50, 10, 0, 0.5*Math.PI);
_drawingContext.lineTo(90, 60);
_drawingContext.lineTo(100, 80);
_drawingContext.lineTo(70, 60);
_drawingContext.lineTo(20, 60);
_drawingContext.arc(20, 50, 10, 0.5*Math.PI, Math.PI);
_drawingContext.lineTo(10, 20);
_drawingContext.arc(20, 20, 10, Math.PI, 1.5*Math.PI);
_drawingContext.stroke();
}
var canvas = document.querySelector("#testCanvas");
canvas.width = 130;
canvas.height = 85;
var canvasContext = canvas.getContext("2d");
drawBalloon(canvasContext);
var SVGContext = C2S(130, 85);
drawBalloon(SVGContext);
document.querySelector("#svgImage").appendChild(SVGContext.getSvg());
document.querySelector("#svgText").textContent =
SVGContext.getSerializedSvg(true);
</script>
</body>
</html>
Uncaught TypeError: Cannot read property '1' of null
canvas2svg:886 (in 6983b3d).
The problem was with a ctx.font = 'bold 270px sans-serif'; -- apparently, the 'bold' was the problem.
Hi,
I have an error when I want to use a gradient for a line strokeStyle:
"TypeError: value.indexOf is not a function"
I tried to use a gradient for fillStyle and it works perfectly.
I made a JSFiddle:
http://jsfiddle.net/5bbn59rs/4/
Thanks in advance
Any chance you could put this up on NPM? Should just be a case of running npm publish
. That would let me use it easily from webpack :).
Solution from here looks better than the crazy regex
https://stackoverflow.com/questions/5618676/how-to-parse-css-font-shorthand-format
var parsedStyleForCSS = function(cssString){
var el = document.createElement("span");
el.setAttribute("style", cssString);
return el.style; // CSSStyleDeclaration object
};
var parsedStyle = parsedStyleForCSS("font: bold italic small-caps 1em/1.5em verdana,sans-serif");
console.log(parsedStyle["fontWeight"]); // bold
console.log(parsedStyle["fontStyle"]); // italic
console.log(parsedStyle["fontVariant"]); // small-caps
console.log(parsedStyle["fontSize"]); // 1em
console.log(parsedStyle["lineHeight"]); // 1.5em
console.log(parsedStyle["fontFamily"]); // verdana, sans-serif
For the record, the original
var regex = /^\s*(?=(?:(?:[-a-z]+\s*){0,2}(italic|oblique))?)(?=(?:(?:[-a-z]+\s*){0,2}(small-caps))?)(?=(?:(?:[-a-z]+\s*){0,2}(bold(?:er)?|lighter|[1-9]00))?)(?:(?:normal|\1|\2|\3)\s*){0,3}((?:xx?-)?(?:small|large)|medium|smaller|larger|[.\d]+(?:\%|in|[cem]m|ex|p[ctx]))(?:\s*\/\s*(normal|[.\d]+(?:\%|in|[cem]m|ex|p[ctx])))?\s*([-_,\'\"\sa-z0-9]+?)\s*$/i;
has been slightly adapted from https://stackoverflow.com/questions/10135697/regex-to-parse-any-css-font
I was trying to find a way to export google spreadsheet charts in vector format when I stumbled upon this. I was wondering if you could help me know if is it possible and how?
Although this is valid Canvas operation the following results in the error "Attempted to apply path command to node g":
var ctx = new C2S()
ctx.rect(0, 0, 100, 100)
ctx.scale(2, 2)
ctx.fill()
ctx.getSerializedSvg()
I'll investigate into why this is happening.
I would like to save an already created canvas as SVG. My plan was to use getImageData to get the data from the canvas, and then use putImageData to create the SVG file. Unfortunately, canvas2svg does not support putImageData yet. Will this be implemented in the future, or does anyone know another solution?
Add UMD support so this can be used in a node context or browser context using the module import pattern.
Hi,
I'm using your script inside my whiteboard tool to create a preview image and I plan to use it for exporting the screen as well.
But in my tool I use different custom fonts (usual on whiteboards). Is it possible to render the text to vector in the SVG? Otherwise I see in the exported SVG only text with a Times font instead the selected one.
Thanks in advance
Frank
My code calls ctx.drawImage(img, startX, startY, width, height)
on the C2S object I maintain for my canvas, but when I serialize and download the SVG, the x
and y
attributes are missing from the <image>
tag. Width and height are preserved, but the image is at (0, 0)
throw new Error("Inavlid number of arguments passed to drawImage: " + arguments.length);
should be
"Invalid"
I have transformed text to look it like slant using the below code but it is being exported plain (Non Slant)
Is there a way to export it with applied transformations???
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.font = "20px Georgia";
//Slant LEFT
ctx.setTransform(1, 0, -0.3, 1, 0, 0);
Rather than just taking an existing canvas and using drawImage to insert an image tag inside of an svg tag, I was expecting a direct translation of each node into a path or text or other valid svg options.
Is this something that is planned, rather than having to use the mock canvas?
The reason I ask is that I am currently prototyping html2canvas.js in an attempt to get a screenshot on the client-side to be persisted for auditing purposes. This does work, but I was wondering about a side-by-side comparison and svg would also give event options too.
Thanks
Image opacity can be easily supported by adding the last line here:
} else if (image.nodeName === "CANVAS" || image.nodeName === "IMG") {
//canvas or image
svgImage = this.__createElement("image");
svgImage.setAttribute("opacity", this.globalAlpha || 1);
Dear all
I used following code (sample)
var ctx = new C2S(500,500);
ctx.font = "normal 36px Times";
ctx.fillStyle = "#000000";
ctx.fillText("A Text Example", 50, 50);
ctx.font = "normal 36px Arial";
ctx.strokeStyle = "#000000";
ctx.strokeText("A Text Example", 50, 90);
var svg = ctx.getSvg();
console.log(svg);
then I copy/paste the result below :
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="500" height="500"><text fill="#000000" stroke="none" font-family="Times" font-size="36px" font-style="normal" font-weight="normal" text-decoration="none" x="50" y="50" text-anchor="start" dominant-baseline="alphabetic">A Text Example<text fill="none" stroke="#000000" font-family="Arial" font-size="36px" font-style="normal" font-weight="normal" text-decoration="none" x="50" y="90" text-anchor="start" dominant-baseline="alphabetic" stroke-miterlimit="10">A Text Example
-> First of all, I do not get the same show in page http://gliffy.github.io/canvas2svg/ for simple example.
-> My output does not work when i copy/paste into SVG editor,
Could you please help me
Hey,
Great work. I'm just wondering if it's possible to use this plugin on an existing canvas element or if I have to create a new element and perform all of the drawing on the new element?
Cheers!
ctx.moveTo(150,20);
ctx.lineTo(150,170);
ctx.stroke();
first ctx.moveTo
fails. Of course, because ctx.beginPath
never got called.
Is it required to call ctx.beginPath();
? I got here some internet examples that do not call it.
Chrome/Firefox accepts the above code and renders it correctly (when rendering into canvas).
Even if it's required by the canvas-standart... Any good idea how to support this case ?
I am thinking of adding a inexplicit ctx.beginPath()
in ctx.prototype.__addPathCommand
Hi thank you for this great plugin its very useful for me in my project but I'm unable to find how to convert a rendered canvas image to SVG can you help me how to do this.
The latest version in GitHub: v1.0.19
The latest version in NPM: v1.0.16 (https://www.npmjs.com/package/canvas2svg)
I was getting constant errors until I realized that the code cannot handle decimal RGB values. In general, most places its integers but in applications with Color Picker where it has more precision, it can be decimal.
Here is the regex command to allow decimal RGB. I hope it helps others.
regex = /rgba\(\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\s*,\s*(\d?\.?\d*)\s*\)/gi;
See attached SVG (zipped) - SVG patterns don't repeat when the pattern is a PNG so the following doesn't work:
var pattern = ctx.createPattern(img, 'repeat');
ctx.fillStyle = pattern;
Possible workarounds:
ctx.fill("evenodd") doesn't take account of the parameter. Simple fix is to change method to
ctx.prototype.fill = function (fillRule) {
if (this.__currentElement.nodeName === "path") {
this.__currentElement.setAttribute("paint-order", "stroke fill markers");
if (fillRule == "evenodd") {
this.__currentElement.setAttribute("fill-rule", "evenodd");
}
}
this.__applyCurrentDefaultPath();
this.__applyStyleToCurrentElement("fill");
};
I faced problem with missed XMLSerializer.
(node:19466) UnhandledPromiseRejectionWarning: ReferenceError: XMLSerializer is not defined
at ctx.getSerializedSvg (/home/work/schema-docs/node_modules/canvas2svg/canvas2svg.js:396:26)
at ERDGenerator.asSvg (/home/work/schema-docs/src/ERDGenerator.ts:184:29)
at /home/liteman/work/schema-docs/src/DocsGenerator.ts:75:42
at DocsGenerator.generate (/home/work/schema-docs/src/DocsGenerator.ts:42:21)
(node:19466) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:19466) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code
```.
I think maybe should not use fill #fff for clearRect, what about using clipPath instead? Then we can provide transparency for clearRect.
https://github.com/gliffy/canvas2svg/blob/master/canvas2svg.js#L647
https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Clipping_and_masking
Minimal test case (hangs browser on "ctx.fill();")
http://test.geogebra.org/~mike/canvas2svgPatternBug/imageFill.html
Proof of concept for suggested fix:
http://test.geogebra.org/~mike/canvas2svgPatternBug/imageFill_fixed.html
Changing
while(value.__ctx.__defs.childNodes.length) {
id = value.__ctx.__defs.childNodes[0].getAttribute("id");
this.__ids[id] = id;
this.__defs.appendChild(value.__ctx.__defs.childNodes[0]);
}
to
var len = value.__ctx.__defs.childNodes.length;
for (var i = 0 ; i < len ; i++) {
id = value.__ctx.__defs.childNodes[i].getAttribute("id");
this.__ids[id] = id;
this.__defs.appendChild(value.__ctx.__defs.childNodes[i]);
}
seems to fix it although maybe removing the elements would be better (I guess there's a line of code missing to do that)
Can you please push the current version to the NPM, please.
Thanks.
If canvases use drawImage with a URL, it would be nice to have to option of embedding the images as base64 instead of linking to them. If I made a pull request with such an option, would it be likely to be accepted?
A clear HTML5 canvas should have nothing on it. In my usage, calling ```ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
and then drawing new stuff on the canvas still results in a #FFF rect being put in the resulting SVG. Is there a way to clear the canvas that's to spec with HTML5 canvas?
Hello. Great job and idea. Is it possible to export a text from canvas as paths?
Thank you.
I have a working textBaseline
in 5031052 and 51a1860
But with some problems..
5031052 uses dominant-baseline
which isn't supported in IE
51a1860 shifts y-coordiantes based on the font.size
which works in IE, but does same strong assumptions fontEmSize = fontEmSize / 1.25;
and fontSize = fontEmSize / 1.25;
http://www.w3.org/TR/2014/CR-2dcontext-20140821/#text-styles see graph,
too bad it's not possible to access the font metrics directly..
Any idea how to tackle this nicely ?
With following code SVG and canvas will have different behavior:
ctx.fillStyle = 'gray';
ctx.strokeStyle = '#000';
ctx.lineWidth = 20;
ctx.rect(20, 20, 50, 50);
ctx.stroke();
ctx.fill();
The left one is SVG, and the second one is Canvas.
Does this support getImageData() function?
This line of text is returning undefined...
var imageData = ctx.getImageData(0, 0, width, height);
Seen on v1.0.15.
Sorry to tell but I gave up understanding this regex :
regex = /^\s*(?=(?:(?:[-a-z]+\s*){0,2}(italic|oblique))?)(?=(?:(?:[-a-z]+\s*){0,2}(small-caps))?)(?=(?:(?:[-a-z]+\s*){0,2}(bold(?:er)?|lighter|[1-9]00))?)(?:(?:normal|\1|\2|\3)\s*){0,3}((?:xx?-)?(?:small|large)|medium|smaller|larger|[.\d]+(?:%|in|[cem]m|ex|p[ctx]))(?:\s*/\s*(normal|[.\d]+(?:%|in|[cem]m|ex|p[ctx])))?\s*([-,"\sa-z]+?)\s*$/i;
Shouldn't "normal 12px 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif" be parseable ?
Chrome console shows as follows :
ERROR TypeError: Cannot read property '1' of null
at ctx.push../node_modules/canvas2svg/canvas2svg.js.ctx.__parseFont (VM9279 vendor.js:90992)
at ctx.push../node_modules/canvas2svg/canvas2svg.js.ctx.__applyText (VM9279 vendor.js:91039)
at ctx.push../node_modules/canvas2svg/canvas2svg.js.ctx.fillText (VM9279 vendor.js:91066)
at fillText (VM9279 vendor.js:106831)
je veux utilise se canvas
Looks like ctx.shadowColor isn't implemented in the latest version of the library. If anyone wants to add this, I'll pay a bounty.
Currently the ctx.imageSmoothingEnabled property isn't respected in ctx.drawImage, so it's not possible to override the default (true
) behavior.
OMG, thank you for such an awesome and helpful library! I'm connecting this with chart.js
so the issue might be there, but I'm not getting opacity to carry through when exporting. For example, if I create a chart with semi-transparent bars, they show up onscreen correctly. But when exporting as an svg
they come out opaque.
I am using these tweaks suggested on SO, so maybe the problem is coming from there too?
function tweakLib() {
C2S.prototype.getContext = function(contextId) {
if (contextId === '2d' || contextId === '2D') {
return this;
}
return null;
}
C2S.prototype.style = function() {
return this.__canvas.style;
}
C2S.prototype.getAttribute = function(name) {
return this[name];
}
C2S.prototype.addEventListener = function(type, listener, eventListenerOptions) {
// nothing to do here, but we need this function :)
}
}
Any pointers would be great – happy to fix and submit a PR!
Why does this error come anytime text is drawn
Hi, I am using the library to render OpenStreetMap data with kothic.js to svg and I encountered this potential endless loop when trying to fill a polygon with an svg as fill image.
//copy over defs
while(value.__ctx.__defs.childNodes.length) {
id = value.__ctx.__defs.childNodes[0].getAttribute("id");
this.__ids[id] = id;
this.__defs.appendChild(value.__ctx.__defs.childNodes[0]);
}
I logged the condition of the while loop and it didn't change, therefore resulting in an endless loop. Looking at the code, I cannot see how this would stop in any case, as the childNodes are not removed anywhere.
Am I overlooking something? I fixed the issue for me by changing the code to a for loop, Ill be happy to make a pull request, just thought id check if I am missing something here first.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.