I am trying to create a drawing area with canvas. I am having trouble with making the lines look smooth when drawing curves and I also have changing line thickness in my algorithm which looks bad as well because the size jumps to much as well and you can see where the size changed. I did find this link on stackoverflow but this was for a native iPhone app and I can't figure it out.
Here is my current JS code. and Here is it running on jsFiddle
var xStart, xEnd, yStart, yEnd, paint, ctx; $(document).ready(function (){ ctx = $('canvas')[0].getContext("2d"); ctx.strokeStyle = '#000'; ctx.lineJoin="round"; ctx.lineCap="round"; ctx.lineWidth = 1; $('canvas').bind('mousedown mousemove mouseup mouseleave touchstart touchmove touchend', function(e){ var orig = e.originalEvent; if(e.type == 'mousedown'){ e.preventDefault(); e.stopPropagation(); xStart = e.clientX - $(this).offset().left; yStart = e.clientY - $(this).offset().top; xEnd = xStart; yEnd = yStart; paint = true; draw(e.type); }else if(e.type == 'mousemove'){ if(paint==true){ xEnd = e.clientX - $(this).offset().left; yEnd = e.clientY - $(this).offset().top; lineThickness = 1 + Math.sqrt((xStart - xEnd) *(xStart-xEnd) + (yStart - yEnd) * (yStart-yEnd))/5; if(lineThickness > 10){ lineThickness = 10; } ctx.lineWidth = lineThickness; draw(e.type); } }else if(e.type == 'mouseup'){ paint = false; }else if(e.type == 'mouseleave'){ paint = false; }else if(e.type == 'touchstart'){ if(orig.touches.length == 1){ e.preventDefault(); e.stopPropagation(); xStart = orig.changedTouches[0].pageX - $(this).offset().left; yStart = orig.changedTouches[0].pageY - $(this).offset().top; xEnd = xStart; yEnd = yStart; paint = true; draw(e.type); } }else if(e.type == 'touchmove'){ if(orig.touches.length == 1){ if(paint==true){ xEnd = orig.changedTouches[0].pageX - $(this).offset().left; yEnd = orig.changedTouches[0].pageY - $(this).offset().top; lineThickness = 1 + Math.sqrt((xStart - xEnd) *(xStart-xEnd) + (yStart - yEnd) * (yStart-yEnd))/6; if(lineThickness > 10){ lineThickness = 10; } ctx.lineWidth = lineThickness; draw(e.type); } } }else if(e.type == 'touchend'){ paint = false; } }); }); function draw(event){ if(event == 'mousedown'){ ctx.beginPath(); ctx.moveTo(xStart, yStart); ctx.lineTo(xEnd, yEnd); ctx.stroke(); }else if(event == 'mousemove'){ ctx.beginPath(); ctx.moveTo(xStart, yStart); ctx.lineTo(xEnd, yEnd); ctx.stroke(); }else if(event == 'touchstart'){ ctx.beginPath(); ctx.moveTo(xStart, yStart); ctx.lineTo(xEnd, yEnd); ctx.stroke(); }else if(event == 'touchmove'){ ctx.beginPath(); ctx.moveTo(xStart, yStart); ctx.lineTo(xEnd, yEnd); ctx.stroke(); } xStart = xEnd; yStart = yEnd; }
Thank you all in advance.
This is what it looks like right now if you draw.
... and this is what I would love to achieve:
The HTML <canvas> element is used to draw graphics, on the fly, via scripting (usually JavaScript). The <canvas> element is only a container for graphics. You must use a script to actually draw the graphics. Canvas has several methods for drawing paths, boxes, circles, text, and adding images.
There are the following methods to draw a straight line on the canvas. beginPath(): This method is used to begin the path that we are going to draw. It does not take any arguments. moveTo(): This method takes two arguments which will be the starting point of any path.
I made something like this a while ago and turned it into a jquery plugin. have a look over here, if it's what you're after I'll post a more detailed answer and dig out the simplified jquery version from my archives:
http://jsfiddle.net/95tft/
EDIT
OK, sorry I couldn't do this yesterday:
Originally the code above was forked from Mr Doob's 'harmony' sketcher over here: http://mrdoob.com/projects/harmony/#ribbon
(which I think is the best solution). But I kinda broke it down and remade it for my own purposes on another project. I've hacked my own plugin a bit to make it a bit easier still over here:
http://jsfiddle.net/dh3bj/
The only thing you might want to change is to change it to work on mousedown/mouseup which should be easy also have a look at the settings at the bottom of the plugin, you should be able to get the effect you want by playing with the brush size, colour, alpha (rgba) etc.
Hope that helps
Have a look at this code:
http://jsfiddle.net/aMmVQ/
What I'm doing is starting a new list of points on mouseDown, then for each mousemove I add a point to the list. Once I get enough points (6 or so) I start drawing quadratic curves, with the control point of the curve being the average of the current point and the next point.
drawPoints
is the bit that works this magic:
function drawPoints(ctx, points) { // draw a basic circle instead if (points.length < 6) { var b = points[0]; ctx.beginPath(), ctx.arc(b.x, b.y, ctx.lineWidth / 2, 0, Math.PI * 2, !0), ctx.closePath(), ctx.fill(); return } ctx.beginPath(), ctx.moveTo(points[0].x, points[0].y); // draw a bunch of quadratics, using the average of two points as the control point for (i = 1; i < points.length - 2; i++) { var c = (points[i].x + points[i + 1].x) / 2, d = (points[i].y + points[i + 1].y) / 2; ctx.quadraticCurveTo(points[i].x, points[i].y, c, d) } ctx.quadraticCurveTo(points[i].x, points[i].y, points[i + 1].x, points[i + 1].y), ctx.stroke() }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With