cant draw a path using svg.draw.js - javascript

I am making a very simple designing tool using svg.js and svg.draw.js, in which user make a simple design using line, polylines, rectangles and free hand drawing as well. svg.draw.js is an extension of svg.js which allows to draw elements with your mouse.
Now lets take a look at very simple example. If we want to make any shape (such as polyline) using svg.js, we simply do like this:
var draw = SVG('drawing').size(300, 300)
draw.polyline('0,0 100,50 50,100').fill('none').stroke({color:'blue'})
<script src="https://cdnjs.cloudflare.com/ajax/libs/svg.js/2.6.3/svg.js"></script>
<div id="drawing">
</div>
To draw this polyline by mouse, i used svg.draw.js. Its very easy, we only have to include draw() function of this extension at the end of the above snippet. Also, we dont have to give any argument in the draw.polyline() function as well.
var draw = SVG('drawing').size(300, 300);
draw.polyline().fill('none').stroke({color:'blue'}).draw()
By including svg.draw.js library and draw() function at the end you will be able to create a polyline by mouse. For demo goto this link.
PROBLEM: Now you see that by adding draw() we can create all the svg elements by mouse clicks. By using same tactic, i want to do free hand drawing. I am using path svg element for it but it doesnot work for me.
draw.path().stroke({color:'blue'}).draw()
The above line is giving this error:
If svg.draw.js is supporting rectangles (draw.rect()), polylines(draw.polyline()) etc then why not paths? I want to create something like this, but this free hand drawing snippet is in d3.js
and i want to do it using svg.draw.js. Any help will be much appreciated.

You can only draw lines, rectangle or circle etc. through mouse as you mentioned using this library. svg.draw.js don't have anything like Draw.path().

Related

How to implement an editable quadrilateral with Konva.js

I would like to draw a rectangle with the mouse and after that be able to edit it is a quadrilateral (polygon) by dragging the corners (to be clear about editing, I found a similar behavior on Konva.js: https://codesandbox.io/s/oxwx9q9ko6 and Fabric.js - click the "Toggle editing polygon" button: http://fabricjs.com/custom-controls-polygon)
I didn't find a ready-made solution and decided implement it myself.
And I have 2 options how to do it:
I can use Rect for drawing, after convert Rect to Line by points and continue to work with shape like as Line, as in the example: https://codesandbox.io/s/oxwx9q9ko6
I can use Line for draw and edit corners like in the example above: https://codesandbox.io/s/oxwx9q9ko6
But in this case, I have to implement the drawing of the rectangle myself, like as Rect
Could you help me with these 2 options and share your opinion and experience?
Maybe I can implement it in simpler way (with Transformer, for example) and I don't know about it.
P.S. I have a React web application and plan to use the react-konva package
Thank you!

Is there a way to use Fabric.js and p5.js on the same canvas

I'm working on a project and would like to use both p5.js and fabric.js on the same canvas. I need the functionality of fabric.js to drag around pictures on the canvas and p5.js to dynamically draw lines between the pictures as they're being dragged. I'm not sure if this is possible because it seems like both have their own separate canvas creation functions
p5.js
createCanvas(100, 50);
fabric.js
canvas = new fabric.Canvas('c');
The fabric line class seems a little too rigid to accomplish the effect I'm after, so I'm looking for either an idea for a workaround or a different library that would be better for drawing dynamic lines on a fabric canvas.
It is not possible to combine both of them with one canvas element. These libraries take full control of the canvas of reference. Even if you were able to initialise both libraries on the same canvas element you will loose whatever was displayed by p5.js on the first FarbicJS canvas.renderAll() function call.
I don't know what exactly is your problem, but as an alternative I think you could try to have two canvases on top of each other (since the canvas element is invisible by default). One running on FabricJS and one on p5.js and somehow interact with each other. But, that will add some additional complexity.

Selecting Canvas Elements [duplicate]

Take a look at this example:
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
// First rectangle created
ctx.fillRect(20,20,150,100);
// Second rectangle created
ctx.fillRect(20,150,150,100);
// Third rectangle created
ctx.fillRect(20,300,150,100);
I created three rectangles here. After creating third rectangle I want to rotate first rectangle. How do i get reference of first rectangle now?
A canvas is just a dumb grid of pixels. It doesn't understand what shapes have been drawn on it. Your code (or a library that your code uses) must keep track of the shapes that you've drawn.
Instead, it sounds like you want a library to create a scene graph, like EaselJS, Paper.js, or KineticJS. These libraries will maintain a data structure that tracks what shapes have been drawn on the canvas, and they will then redraw them when you want to manipulate those shapes.
You don't "get the reference" of a rectangle or something with canvas. All you have is a canvas with a context. On which you can draw. Period.
If you want to move the first rectangle, then clear it (using clearRect) and redraw the new one.
Canvas itself is just pixels. It knows how to draw rectangles, but doesn't keep them layered.
To quote Simon Sarris:
HTML5 Canvas is simply a drawing surface for a bit map. You set up a
draw (Say with a color and line thickness) , draw that thing, and then
the Canvas has no knowledge of that thing: It doesn't know where it is
or what it is, it's just pixels. If you want to draw rectangles and
have them move around or be selectable then you have to code all of
that from scratch, including the code to remember that you drew them.
The only exception is the isPointInPath method, but it has limitations.
However, there are some libraries that provide object-oriented interface for Canvas. Like Fabric.js or KineticJS. They remember what you draw as objects (rectangles, circles and so on) and can layer them one over another, move around and add mouse/touch events. Much like DOM.
Drawing functions like fillRect() does not return anything (returns void).
Meaning it simply renders the pixels, it does not create a rectangle object and return it. You'll need to store the rectangle coordinates yourself.

putting d3.js elements on the slider

Please first take a look on this picture : https://docs.google.com/file/d/0By25CEM_KEOiYzdYaWVicnp6Zm8/edit?usp=sharing
Now i want to make something like that but i want to put d3.js elements on a slider like that instead of images like a rectange, circle, square, triangle so that user can move them with arrow buttons shown in the image.
I just wanted to know if it is possible with d3.js and if Yes, please tell me how or from where to start?
You could make something like that using D3.
One way you could do it is to draw the tiles as rectangles using SVG and then have a clip path that hides the tiles that are outside of the frame of what you want to see. The left and right arrows would update the xScale domain which would slide the tiles left and right. And, you can register click events on the rect elements to create links on the tiles.
See this for some ideas on how to start: http://bl.ocks.org/mbostock/1667367
If you aren't already somewhat familiar with d3, you should probably start with a basic tutorial like: http://mbostock.github.io/d3/tutorial/bar-1.html before you dive into the deep end.

How do I get reference of old generated elements in HTML Canvas?

Take a look at this example:
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
// First rectangle created
ctx.fillRect(20,20,150,100);
// Second rectangle created
ctx.fillRect(20,150,150,100);
// Third rectangle created
ctx.fillRect(20,300,150,100);
I created three rectangles here. After creating third rectangle I want to rotate first rectangle. How do i get reference of first rectangle now?
A canvas is just a dumb grid of pixels. It doesn't understand what shapes have been drawn on it. Your code (or a library that your code uses) must keep track of the shapes that you've drawn.
Instead, it sounds like you want a library to create a scene graph, like EaselJS, Paper.js, or KineticJS. These libraries will maintain a data structure that tracks what shapes have been drawn on the canvas, and they will then redraw them when you want to manipulate those shapes.
You don't "get the reference" of a rectangle or something with canvas. All you have is a canvas with a context. On which you can draw. Period.
If you want to move the first rectangle, then clear it (using clearRect) and redraw the new one.
Canvas itself is just pixels. It knows how to draw rectangles, but doesn't keep them layered.
To quote Simon Sarris:
HTML5 Canvas is simply a drawing surface for a bit map. You set up a
draw (Say with a color and line thickness) , draw that thing, and then
the Canvas has no knowledge of that thing: It doesn't know where it is
or what it is, it's just pixels. If you want to draw rectangles and
have them move around or be selectable then you have to code all of
that from scratch, including the code to remember that you drew them.
The only exception is the isPointInPath method, but it has limitations.
However, there are some libraries that provide object-oriented interface for Canvas. Like Fabric.js or KineticJS. They remember what you draw as objects (rectangles, circles and so on) and can layer them one over another, move around and add mouse/touch events. Much like DOM.
Drawing functions like fillRect() does not return anything (returns void).
Meaning it simply renders the pixels, it does not create a rectangle object and return it. You'll need to store the rectangle coordinates yourself.

Categories

Resources