Export KinteticJS drawing to SVG? - javascript

Is it possible to export Kinetic JS object to SVG?
Or workaround is to convert Kintetic JS's canvas to SVG.
EDIT:
The best is to use fabricJS since it supports canvas to SVG rendering while working with fabric objects.
I accepted Phrogz's answer since it also does conversion canvas to svg without using some other library for drawing on canvas.
EDIT 2: OK, i messed up, Phrogz's library is wrapper around canvas element so you use it's methods to draw on canvas (I thought that it just 'listens' on canvas and creates SVG paths). So the best solution is fabricJS definitely.

The best solution is to use Fabric.js!

I've created an alpha version of a library that allows you to extend an HTML5 Canvas Context such that it tracks all vector drawing commands and stores them as an array SVG elements in a ctx.svgObjects property of the context.
You can see the library in action here: http://phrogz.net/svg/HTML5CanvasRecordsSVG.html
The demo turns on recording, draws a few shapes to the HTML5 Canvas, and then appends the 'recorded' SVG objects to an SVG container next door.
In general the library:
Keeps track of the current context transformation via an SVGMatrix object. (This is because the HTML5 Context api lets you set the current transform to a matrix, but does not let you get the current matrix.) It does this by intercepting calls like translate() and rotate() and updating the matrix accordingly.
Intercepts beginPath() and creates a new SVG Path element, and then intercepts further commands like moveTo() and lineTo() in order to add the equivalent path commands to the SVG path.
Note: not all path commands are supported or tested in the library at the time of this writing.
Intercepts fill() and stroke() to add a copy of the current SVG <path> to the svgObjects array, setting the current transformation matrix, fill and stroke styles.
Note: not all stroke styles (lineCap, lineJoin, miterLimit) are supported as of this writing.
Note: calling fill() followed by stroke() creates two separate SVG elements; there is no optimization to differentiate this specific case from stroke/fill, or changing the transform or path between calls.
Intercepts fillRect() and strokeRect() to create an SVG <rect> element.
More work could be done on this library to flesh out all the commands (not just path commands, but also things like fillText()). But it's not something that I personally need, so I'm not inclined to spend hours carrying it over the finish line.

basicly you can convert the canvas to base64 png and then put it on svg
maybe this could help you
http://svgkit.sourceforge.net/tests/canvas_tests.html

Related

How to download dom as svg in html2canvas?

how can I save a dom as svg file using html2canvas ?
For downlading as png , I've done something like below :
html2canvas(document.querySelector('#demo')).then(function(canvas) {
saveAs(canvas.toDataURL(), 'image.png');
});
How can I achieve similar result to save it as svg file ?
You don't.
The reason you can export to png/jpg/etc is that the canvas is a pixel graphic presentation layer, so for convenience it knows how to generate the browser-supported image types that use embedded bitmaps.
If you want vector graphics instead, then you'll need to actually draw vectors, and that means not relying on the canvas APIs. You either roll your own vector drawing instruction set (directly generating SVG yourself, or rasterizing objects to the canvas purely as presentation layer), which I would recommend against, or you use one of several vector graphics packages already out there like Paper.js, Three.js, Rafael, and so forth.

How can I do a generated image on a website?

I'm trying to figure out how to make a website image, just some little blob of color without actually creating an image and putting an image tag and all of that. Is it possible?
Would I be drawing it with CSS, Javascript, or HTML5? If drawing it on the fly with something like Javascript, is that something that is a good idea? drawing over and over?
Not sure where to start looking? Thanks for any help.
Here is an example of an image I'd like to make: https://dl2.pushbulletusercontent.com/0P1OxQU6AoPT5LnWG3jROJgEmdWoPKUw/image.png
SVG is a good choice. It allows you to use a document structure, much like that of HTML, for vector graphics. The <rect> element makes a rectangle. For more complex shapes like your example, check out paths. More info here: Rounded corner only on one side of svg <rect>
Vector graphics are easy to generate and manipulate programatically. They can also be sized and scaled without pixelation.
If you need complex filtering or want raster graphics instead, a Canvas element and its 2D drawing context are a good choice.

Is it possible to use kineticjs with native canvas?

I'm creating an animated diagram and I'm trying to use a native canvas element as well as kineticjs for the animations. I know that kinetic creates a hidden canvas element, but my question is. Is it possible to stop kinetic from doing this and implement the kinetic framework into a native canvas element?
Every KineticJS layer is a visible drawing canvas plus an invisible canvas used for Kinetic's internal purposes.
The drawing canvas is a "native canvas element".
Normally Kinetic does all the drawing for you, but...
You can use Kinetic.Shape objects to issue native drawing commands directly to the html canvas element.
The Kinetic.Shape object gives you a canvas context that you can use to create your custom diagram.
This context is actually a Kinetic wrapper around the actual context. If there is a command that the wrapper hasn't implemented yet you can get the real canvas context like this:
var myRealCanvasContext=this.getContext()._context;

javascipt:Need to smooth the the lines drawn on canvas

so i have been trying to work on a canvas sketching app. and i had this problem where the line drawn are very unclean. As you can see from image below.
then i tried this and got the below result which is what i desire.
But this created a new problem, the eraser function wont work. Now I've been trying to make this two work for sometime, but just could'nt do it.
So what i want is a new smoothing technique or a way to make the above two work.
BTW here is the demo without smoothing: http://jsbin.com/axarun/1/edit
and here is the demo with smoothing: http://jsbin.com/aviluk/2/edit
Thnx in advance.
Method 1:
You can "force" the canvas to use anti-aliasing by doing this:
ctx.translate(0.5, 0.5);
Force in quotes as this is dependent on actual implementation in the browser you're using. Currently there is no way to enable/disable anti-alias by intention.
Method 2:
Set the canvas to "high-resolution" by setting the canvas itself to double size, but force it to be displayed in the original size by styling the canvas element with CSS rules:
<canvas id="myCanvas" width="1600" height="1200"
style="width:800px;height:600px" />
Just remember to double your mouse-coordinates as well as pen-width. This will eat 4x more memory and performance, but will give you high-resolution lines (in appearance).
In this case the browser will treat the canvas as an image and apply anti-aliasing as it does for any scaled image, and not the canvas' method for anti-alias.
Please note that this is not the same as applying scale transform to the canvas.
See demo of "hi-res canvas" here:
http://jsfiddle.net/q2t5A/
Method 3-ish:
For actual smooth lines you can check out my function to do so here:
http://www.codeproject.com/Tips/562175/Draw-Smooth-Lines-on-HTML5-Canvas
This takes an array of x/y couples and smooths the line (cardinal spline). The lines will go through the original points and no control points are needed.
This will of course imply that you record the actual points, and when mouse up you redraw the canvas using the curve() function in this code. That would be a correct approach in any case, to record the strokes in an array and then redraw (this will also allow you to use layers). There are workarounds to avoid render everything by using off-screen
canvases to store f.ex. each layer. By drawing a canvas onto another with a small non-integer offset will force anti-alias (but see point 1).

Extrude, or, make 2d SVG path into 3d

I am wondering if anyone has heard of some javascript which can take a simple SVG path that took maybe 30 seconds to create in illustrator or something and convert it into something that looks 3d. There is an extrude function in illustrator which does this. It is also called polling in sketchUp.
I am using Raphael.js now, but am open to other suggestions. A simple solution would be to make a copy of the path and move it a couple pixels down and to the right and give it a darker color behind the original path, but I am looking for something that might have a little more shading.
Thanks!
There is always a possibility to use three.js for extruding the path for use in webGL in browser:
http://alteredqualia.com/three/examples/webgl_text.html#D81F0A21010#23a
(More samples here:http://stemkoski.github.io/Three.js/)
It uses js-fonts and parses the path commands on them, extrudes the paths and renders the scene. In the same way it should be possible to take an SVG path and extrude it. Raphael has Raphael.parsePathString() which gives you the path segments as an array of individual segments. If you first convert the path commands to cubic curves using Raphael.path2curve() and Raphael._pathToabsolute(), you have only only one segment type so you can use three.js:s BEZIER_CURVE_TO command. If you have transformations applied on the path (which is usually the case in Illustrator export) you can flatten them using function from here: https://stackoverflow.com/a/13102801/1691517.
One possible starting point is here (click the fiddle of the answer):
Extruding multiple polygons with multiple holes and texturing the combined shape
Three.js supports few path commands, but have not tested all of them (
http://threejsdoc.appspot.com/doc/three.js/src.source/extras/core/Path.js.html, see below).
THREE.PathActions = {
MOVE_TO: 'moveTo',
LINE_TO: 'lineTo',
QUADRATIC_CURVE_TO: 'quadraticCurveTo', // Bezier quadratic curve
BEZIER_CURVE_TO: 'bezierCurveTo', // Bezier cubic curve
CSPLINE_THRU: 'splineThru', // Catmull-rom spline
ARC: 'arc' // Circle
};
I have used a custom rather complex function to polygonize SVG path, so was no need to rely to other commands than moveto and lineto.
The downside is of course rather low support level for webGL, 31-53%: http://caniuse.com/webgl
Other more cross-browser solution is this SVG3d library if lesser quality and slowness is not an issue:
http://debeissat.nicolas.free.fr/svg3d.php
https://code.google.com/p/svg3d/
I think this resource could be helpful to you, he uses d3 to generate 2D visualization and then uses d3-threeD to extrude.
Sounds like you want to use svg filters. Webplatform.org has a pretty good tutorial about that. Scroll down a bit and you'll find some lighting filters that looks like 3d.
Raphaƫl doesn't support filters though, so either you'll need to extend it, or just use svg directly.

Categories