How to antialias strokes drawn in canvas without using clearRect - javascript

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!

Related

Concurrent freehand drawing in fabric.js

I'm using fabric.js for a collaborative whiteboard project. I want freehand drawing paths to be drawn concurrently by several users. To do this I figured I could create a new PencilBrush for each remote user and simulate freehand drawing by calling the onMouseDown(), onMouseMove() and onMouseUp() methods of the PencilBrush class whenever the remote user performs those actions. I've created a jsfiddle that does something like that: http://jsfiddle.net/dkostro/7sx8N/21/
It draws two paths concurrently and the user can also draw on the canvas meanwhile. As you see one of the paths is never seen before onMouseUp() and freehand drawing it's not very pretty. I figured the problem was that each PencilBrush instance clears the upper canvas element before calling the _render function, thus only one of the paths can appear simultaneously.
Can you think of a way to make it work smoothly without having to mess up too much with fabric.js code? The one solution I thought of is having a separate canvas element for each PencilBrush, but that would be messing up with fabric.js code, and may not be a clean way to do it. Any other suggestions?
EDIT
I have implemented this one solution I have been thinking of in my question (separate canvas element for each user). http://jsfiddle.net/stropitek/DzygL/14/. I am not sure to what number of users this can scale to, or if this is a good solution, but in this example at least it seems to work well.

Drawing App - Curve Fitting

I'm currently working on a web-based drawing app, where I use the position of the pointer to generate a line. The speed determines the width of the line.
My problem is that the browser events does not produce clean data when getting the position, so the width becomes quite "jittery" other then being soft and smooth.
I'm wondering what is the best way to smooth out that sort of data as the drawing is being made? I was thinking on curve fitting, but I'm not sure which algorithm could work better in my case.
P.S. I'm not redrawing the line from start every single time on canvas, I'm only adding the "final part".
Thanks!
You might try pulling both the "smooth" and "simplify" functions out of paper.js (their MIT license allows this). It worked well for me in an edge detection project. Check it out here: http://paperjs.org/tutorials/paths/smoothing-simplifying-flattening.

canvas tile grid with hover effects, tilesheet, etc

I've been working on building a tile-based display grid for canvas. This is what I have so far: http://jsfiddle.net/dDmTf/7/
Some problems I'm having, and can't quite grasp are:
The initial load time is ridiculous... I don't understand what I'm doing wrong - fixed, found out I was rendering ^32 more than I was supposed to
The hover effect, which "should" just highlight the border of the tile, erases it, and I have no way of recovering the previous tile without re-rendering the entire canvas.
How do I use tilesheets, providing me a single image instead of a bunch of small ones
Resizing the window (which resizes the canvas) also erases the canvas. Do I need to re-render? Or can I maintain state of various things when width/height is changed - added an onresize callback, which re-renders the map. Might not be the best way though?
Multiple layers? How would I go about allowing transparency .png files overlaying each-other
Those are the main problems I'm stuck on right now, and any guidance would be majorly appreciated.
Also, if you have any pointers for my javascript, feel free! I'm learning it more as I go, and I'm sure I'm doing a lot of things wrong.
Edit
As an FYI, I just copy-pasted the sprite map currently being shown on the jsfiddle. It's not the one I'm planning to use, but it was easier than uploading one. I plan to maintain a 32x32 grid instead of (what appears to be) a 16x16 grid from that tilesheet
Edit
I've got the a 32x32 tilesheet displaying on there now, but the hover effect is still breaking it, and I'm not sure how to "know" what the old value was.
The problem is that you are not redrawing your tiles after 'mouseout'.
You either need to redraw the single tile after you move out of it, but this can get tricky as things get more complicated or better yet on mouse move do the following.
Clear the canvas
draw the grid
draw your tiles
then do the highlighting/clearing that cell.
If you end up having any sort of animation this is the process that will be used anyhow otherwise as something moves from one tile to another it will leave ghost images behind.

javascript matrix script, inefficient/slow for some reason

I've made a beginning of a script to achieve the "matrix effect" (to use in the background) in JavaScript. I used the Canvas element, but for some reason its kinda slow but i don't know why.
Matrix effect: Those (green) text lines which are scrolling from top to bottom.
script:
http://dominiquedebrabander.nl/matrix/matrix.js
i've linked the script, 'cause its to long for this textarea. I hope you guys know why, or have some tips.
greetings, Dominique
Why are you calling clearRect if you are just gonna fill it with black? Remove that call
Don't set the font over and over if it never changes, just set it once at the start.
drawing text is slow, see my post here. Consider painting every letter to a second invisible canvas and using drawImage to draw parts of that canvas to your real canvas
If you really want it to be done the way you are doing it now it will be much faster if you draw everything to a large offscreen canvas and you just draw that single canvas over and over, but then you wouldn't be able to have the letters fall at different speeds from each other. And it would look more matrix-like if you did that, say put the y at += Math.random()*4.5 (or so) instead of 0.5

html5 canvas "graphics persistence" on reposition/resize

I noticed that when you move a canvas around or when you resize it, everything inside gets erased. I remember having a similar problem in windows forms applications in C#.
Anyway, what's the best way to keep the graphics on canvas, even after it moves etc.? (using javascript)
I've been working on a paint using canvas and websockets, you can see my problem here: http://students.info.uaic.ro/~tudor.berechet/ (just go to Coboards, select the Brush tool, click a bunch of times on canvas and then resize the window or enlarge the canvas)
One more thing I noticed, running the site off my HDD, this problem doesn't occur. which makes me wonder if there's some strange error somewhere.
I definitely need a persistent canvas, because I'm gonna have to implement the hand tool to move it around...
What say you?
The problem seems to have gone after cleaning up my code a bit. I still don't know what was causing it, but it seems that the canvas drawings now remain intact even after I move/resize the canvas.
Please confirm. [EDIT] confirmed.
The point is, my original assumption that canvas graphics are not persistent seems to have been wrong. There was most likely some coding error that was "erasing" my canvas.

Categories