I want to implement a drawing pane (similar but smaller version to what visio gives for flow charts) in mozilla canvas.
Is there any support for this?
I have used jQuery till now to create the rectangles and move them around. While this is easy here..creating lines (connections between objects) is a real pain. I am using some crude way to color pixel by pixel in javascript and it is neither looking good nor scalable and also I need to build a lot of functions to make the connections stick to a set of objects etc.
Does anyone know if the canvas and the functions available there will make my life easier.
Any pointers to what is a better solution in this case. (I am hoping it is not applet)
Thanks in advance.
Yes you can use canvas for that. Drawing simple shapes and scaling them is pretty simple.
But if you need to edit the shapes after you have drawn them, you will have to invest some more work. Canvas draws in a so called "immediate mode", which means, that it does not know what you have painted right after you have painted it. It does not keep track of painted shapes. If you need that you will have to implement that on your own.
I have done this using the isPointInPath() function which can be used to test if a user clicks on a particular point. I keep track of my painted objects using the MVC-Pattern (Model-View-Controller), so that I can find out which Shape has been clicked on.
Another alternative might be fabrics.js which should be very close to what you need.
Please follow this link :
https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial
LMK if it helps!
Following steps may help:
1. Create and add a canvas to the DOM :
var myCanvas = document.createElement('canvas'); document.body.appendChild(myCanvas);
2. Set the width-height of canvas :
myCanvas.width=200;
myCanvas.height=200;
3. Get the context of the canvas and start drawing on it :
var gc = myCanvas.getContext('2d');
4. Code to draw rectangle :
gc.strokeRect(50,50,50,50);
5. After this, add mousehandlers(mousedown,mousemove,mouseup)/touchhandlers(touchdown,touchmove,touchup) on the canvas and handle the movement accordingly.
Either of these jQuery plugins are great for drawing panes:
jCanvas For drawing any simple and even complex shapes
sketch.js for drawing in general.
They are both responsive and compatible.
Related
I am working on a drawing app as a personal project (currently living at http://draw.ist/) and I'd like to get the drawn strokes smooth around the edges but it seems the only way to accomplish this is using clearRect. However, clearRect also clears the canvas every time I start a new path and I'd like to prevent that so the canvas actually accumulates the strokes.
I've seen stuff about creating a secondary canvas to save strokes to or something so the clear doesn't wipe them (at least I think it works somewhat like that) however that method would require a lot of additional code that I'd like to avoid. Most recently I've tried saving the canvas as an imageURL on mouseup and then re-placing it with drawImage right after every clearRect, and this seems to do the trick nicely but it has some bizarre interactions with my eraser and straightline tools, as well as some flickering every time it loads in the saved canvas image.
There isn't necessarily any particular snippet of relevant code here, but for reference the entire site can be found at http://draw.ist/ (Controls: hold shift to draw straight lines, hold spacebar to erase, scroll mousewheel to change brush size)
I'd like all drawn lines to be smooth and have antialiasing but without using the "secondary canvas as memory" method IF POSSIBLE. I think what could help me here as well is understanding why exactly clearRect is necessary to apply antialiasing to strokes in canvas and how it works exactly in layman's terms. I greatly appreciate any assistance on this, whether it's actually helpful or not!
I use canvas in Qml. How do I draw the following shape using canvas? What else can I do if it is not possible with the canvas? (It will be an animation.)
Start state:
End state:
Thanks.
I am not sure to understand what you really want, but I will try to answer.
First, I think you can do it all using Canvas. But it is very greedy, so if you do it for embedded devices, you should avoid Canvas.
Sorted by efficiency, here's how you can draw complex form :
[C++] Create class derived from QQuickItem and override QQuickItem::updatePaintNode()
[C++] Create class derived from QQuickPaintedItem and override QQuickPaintedItem::paint()
[QML] Create Canvas-based item
Also, if you have all the images (meaning every step needed for the animation) and have plenty of power, you could use it directly, using QPixmap, QGraphicsScene [C++], or Images [QML].
In any case, I advice you to edit you question and ask a more accurate question. (Sorry I can't put this in the comment section my reputation is bellow 50).
I am now entering Kinetic and it has made it far easier for me to draw on canvas. However, building a game app, I need to clear the rectangle on every animation request. They're controlled by an fps cap script, but still, there are about 50 updates per second.
Kinetic's .removeChildren() method not only clears the canvas, it deletes the canvas node from the DOM. Doing so not only makes DOM queries inconsistent by intervals of .02 second, but also drops my FPS rate by about 60% in comparison to stock HTML5 canvas handling on every machine I ran the game on.
Is there a KineticJS method for clearing the canvas in a manner such as clearRect()'s?
Edit:
I have also made sure it's not a problem on any other part of the program. Call stack doesn't overflow, the FPS drop is just due to DOM changing twice every .02 second.
Edit 2:
I have tried the following:
Ignore the layer before and create a blank rectangle to fill up the visible part of the canvas. It dropped my frame rate to about 14 FPS;
Use the .clear() method. It solved the DOM consistency problem but the frame rate got even lower than before.
It seems the only solution would be calling the default HTML5 clearRect() method, but that would mean creating the canvas element by hand (and possibly making Kinetic useless as a library for my app).
Edit 3:
As for the app, I've started using standard HTML5 canvas since I have a deadline. I'd still like to see a Kinetic solution though - it might be helpful in the future. It surprises me to see such a simple thing is so hard, if not impossible, in a popular library like KineticJS.
You can use layer.clear with a bounding area to clear just the "dirty" part of your layer.
// tell layer not to auto-clear on layer.draw
layer.setClearBeforeDraw(false);
// clear the "dirty" portion of the canvas
layer.clear(100, 100, 150, 150);
// adjust some animation values and
// just draw the element that has changed
myRect.draw();
You should try to create new Layer for example:
var newLayer = new Kinetic.Layer();
Or call this function:
Canvas.clear();
Kinetic makes it very easy to draw using layers, groups and shapes.
If your view is properly make of these items you can easily remove them and they will be removed from the stage.
Perhaps you need to rewrite you code to make it work better in kinetic.
if you think your code is properly written you can try (as a workaround) to create kinetic rectangle and fill it with whatever you want to simulate a clear.
I am looking to animate an image onto a canvas via a circle 'brush' [Think Photoshop default brush] wherever the circle moves on a path the image is revealed.
The image would be a bitmap, not a vector file.
The brush will not have any additional detail beyond displaying the image its 'painting'
As additional clarification, the circle brush is moving automatically the user does not move the brush. It is just animated along a path.
I am really curious to see how this can be done with Raphael.
Thanks in advance!
If you want to achieve something like that, you better think of using Canvas. Since Raphael is a library oriented exclusively to SVG. You can use non-svg images, but you are going to face lots of limitations.
On the other hand, Canvas is pixel oriented, so what you are trying to do is going to be easier.
Raphael is great when it comes to SVG and user interaction, because the elements you create, are nodes inside the DOM, and you can easily bind them to events.
If you still want to achieve something like that with Raphael, you are going to need to start digging a bit into Raphael's methods. Is to difficult for someone to explain the whole process. You better start trying, and ask some question on more particular problems.
Apart from Raphael's documentation, I recommend this exaggeratedly colorful, but useful site which have some working examples.
Either way I think you should reconsider using Raphale over Canvas!
I hope that helps!!
If I have a canvas with a circle that changes color upon clicking on it, I can use a click event on the canvas element and handle the math for that (distance formula calculation <= radius). But what if I have two circles that overlap (like a van diagram), and I click in the middle of the two circles assuming that only the top circle should change color? If the math of the first circle is applied in this case, both circles would change color.
How would I deal with events in the canvas in terms of overlapping objects like the example above? With hopefully a fast/efficient algorithm?
You might want a framework like EaselJS that has a better api for what you're trying to do. Barebones canvas 2d-context doesn't provide much in terms of display-object / sprite behavior.
Responses above also mention some sort of list to represent layers. I don't think the implementation would be very difficult, just another condition to check for along with the radius.
Canvas isn't really like Flash or like a DOM tree whereby things have sort orders or z-indexes. Its a bit more like a flat rastered image and you have to rely upon other logic in your javascript to remember the sequence & stacking order of things you have drawn.
If you need this kind of interactivity I've always found it best to use a 3rd party library (unless it really is just a case of one or two circles which dont do much).
For interactive 'shape' based javascript graphics I would sugest Raphael.js or D3 which are actually more of SVG tools than a canvas one so maybe it's not for you but they are simple and cross-browser.
There's also processing.js (js port of Processing the Java lib) which feels a bit like flash and again can track all of the levels and objects. Theres a tonne of others but thats another topic.
If it's super simple the options might be:
Hold the co-ordinates of all shapes/elements composited on the canvas inside an object or array which also tracks their z-index/sort sequence, thereby letting you know whats on top.
Using the imagedata at the mouse coordinate of the click to establish what has been clicked
using multiple canvases composited on each other and letting the DOM do the work for the click events