movimiento metodos lineas examples ejemplos dibujar aprender javascript html5 canvas drawing paint

javascript - metodos - Implementando un boceto suave y dibujando en el elemento<canvas>



metodos canvas javascript (6)

¿Por qué no usas croquis.js ?

Tiene una implementación ordenada de pincel como photoshop :)

Y aquí está Demo que está usando croquis.js.

Estoy tratando de crear un área de dibujo con lienzo. Estoy teniendo problemas para que las líneas se vean suaves al dibujar curvas y también tengo un grosor de línea cambiante en mi algoritmo, que también se ve mal porque el tamaño también aumenta demasiado y se puede ver dónde cambió el tamaño. Encontré este enlace en stackoverflow, pero esto fue para una aplicación nativa de iPhone y no puedo entenderlo.

Aquí está mi código JS actual. y Aquí está corriendo en 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; }

Gracias a todos de antemano.

Esto es lo que parece ahora si dibujas.

... y esto es lo que me gustaría lograr:


Eche un vistazo a este código:

http://jsfiddle.net/aMmVQ/

Lo que estoy haciendo es comenzar una nueva lista de puntos en mouseDown, luego para cada mousemove agrego un punto a la lista. Una vez que tengo suficientes puntos (6 o más) empiezo a dibujar curvas cuadráticas, con el punto de control de la curva como el promedio del punto actual y el punto siguiente.

drawPoints es la parte que funciona esta magia:

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() }


Hice algo como esto hace un tiempo y lo convertí en un plugin jquery. echa un vistazo aquí, si es lo que buscas, publicaré una respuesta más detallada y extraeré la versión simplificada de jquery de mis archivos:

http://jsfiddle.net/95tft/

EDITAR

OK, lo siento, no pude hacer esto ayer:

Originalmente, el código anterior se bifurcó del dibujante de armonía del Sr. Doob aquí: http://mrdoob.com/projects/harmony/#ribbon

(que creo que es la mejor solución). Pero lo descompuse y lo rehice para mis propios fines en otro proyecto. He pirateado mi propio complemento un poco para que sea un poco más fácil aún aquí:

http://jsfiddle.net/dh3bj/

Lo único que podría querer cambiar es cambiarlo para que funcione en mousedown / mouseup, que debería ser fácil, eche un vistazo a la configuración en la parte inferior del complemento, debería poder obtener el efecto que desea jugando con el tamaño del pincel, color, alfa (rgba), etc.

Espero que ayude


Para aquellos interesados ​​en una versión de clic del código proporcionado por @Alex, he reescrito su script aquí:

http://jsbin.com/aqoqad/3/


Parece que necesitas usar algunos pinceles en tu lienzo. Es difícil decir qué tipo de pincel exactamente necesita, pero hay muchas bibliotecas JS que ya han implementado la tecnología de pincel.

Por ejemplo, ¿miraste estas bibliotecas?

Laso en la web puede encontrar muchos pinceles implementados en el proyecto Mr. Doob Harmony . Por ejemplo, Proyecto stringy o Harmony-Brushes de armonía en github.


Sugiera que la representación se realice con una cadena de curvas bezier que rodean la curva que de este modo se llena. (es decir, terminar con ctx.fill) Aún hay mucho trabajo por hacer, pero espero que esto ayude.

Adaptado una buena aplicación de demostración para curvas bezier

lo agregó a un tenedor de tu violín http://jsfiddle.net/d3zFU/1/

El código es

/* * Canvas curves example * * By Craig Buckler, http://twitter.com/craigbuckler * of OptimalWorks.net http://optimalworks.net/ * for SitePoint.com http://sitepoint.com/ * * Refer to: * http://blogs.sitepoint.com/html5-canvas-draw-quadratic-curves/ * http://blogs.sitepoint.com/html5-canvas-draw-bezier-curves/ * * This code can be used without restriction. */

(función () {

var canvas, ctx, code, point, style, drag = null, dPoint; // define initial points function Init(quadratic) { point = { p1: { x:100, y:250 }, p2: { x:400, y:250 } }; if (quadratic) { point.cp1 = { x: 250, y: 100 }; } else { point.cp1 = { x: 150, y: 100 }; point.cp2 = { x: 350, y: 100 }; } // default styles style = { curve: { width: 6, color: "#333" }, cpline: { width: 1, color: "#C00" }, point: { radius: 10, width: 2, color: "#900", fill: "rgba(200,200,200,0.5)", arc1: 0, arc2: 2 * Math.PI } } // line style defaults ctx.lineCap = "round"; ctx.lineJoin = "round"; // event handlers canvas.onmousedown = DragStart; canvas.onmousemove = Dragging; canvas.onmouseup = canvas.onmouseout = DragEnd; DrawCanvas(); } // draw canvas function DrawCanvas() { ctx.clearRect(0, 0, canvas.width, canvas.height); // control lines ctx.lineWidth = style.cpline.width; ctx.strokeStyle = style.cpline.color; ctx.fillStyle = style.cpline.color; ctx.beginPath(); ctx.moveTo(point.p1.x, point.p1.y); ctx.lineTo(point.cp1.x, point.cp1.y); if (point.cp2) { ctx.moveTo(point.p2.x, point.p2.y); ctx.lineTo(point.cp2.x, point.cp2.y); } else { ctx.lineTo(point.p2.x, point.p2.y); } ctx.stroke(); // curve ctx.lineWidth = 1 ; //style.curve.width; ctx.strokeStyle = style.curve.color; ctx.beginPath(); ctx.moveTo(point.p1.x, point.p1.y); if (point.cp2) { ctx.bezierCurveTo(point.cp1.x, point.cp1.y, point.cp2.x, point.cp2.y, point.p2.x, point.p2.y); ctx.bezierCurveTo(point.cp2.x, point.cp2.y+12, point.cp1.x, point.cp1.y+12, point.p1.x, point.p1.y); } else { ctx.quadraticCurveTo(point.cp1.x, point.cp1.y, point.p2.x, point.p2.y); } //ctx.stroke(); ctx.fill(); // control points for (var p in point) { ctx.lineWidth = style.point.width; ctx.strokeStyle = style.point.color; ctx.fillStyle = style.point.fill; ctx.beginPath(); ctx.arc(point[p].x, point[p].y, style.point.radius, style.point.arc1, style.point.arc2, true); ctx.fill(); ctx.stroke(); } ShowCode(); } // show canvas code function ShowCode() { if (code) { code.firstChild.nodeValue = "canvas = document.getElementById(/"canvas/");/n"+ "ctx = canvas.getContext(/"2d/")/n"+ "ctx.lineWidth = " + style.curve.width + ";/nctx.strokeStyle = /"" + style.curve.color + "/";/nctx.beginPath();/n" + "ctx.moveTo(" + point.p1.x + ", " + point.p1.y +");/n" + (point.cp2 ? "ctx.bezierCurveTo("+point.cp1.x+", "+point.cp1.y+", "+point.cp2.x+", "+point.cp2.y+", "+point.p2.x+", "+point.p2.y+");" : "ctx.quadraticCurveTo("+point.cp1.x+", "+point.cp1.y+", "+point.p2.x+", "+point.p2.y+");" ) + "/nctx.stroke();" ; } } // start dragging function DragStart(e) { e = MousePos(e); var dx, dy; for (var p in point) { dx = point[p].x - e.x; dy = point[p].y - e.y; if ((dx * dx) + (dy * dy) < style.point.radius * style.point.radius) { drag = p; dPoint = e; canvas.style.cursor = "move"; return; } } } // dragging function Dragging(e) { if (drag) { e = MousePos(e); point[drag].x += e.x - dPoint.x; point[drag].y += e.y - dPoint.y; dPoint = e; DrawCanvas(); } } // end dragging function DragEnd(e) { drag = null; canvas.style.cursor = "default"; DrawCanvas(); } // event parser function MousePos(event) { event = (event ? event : window.event); return { x: event.pageX - canvas.offsetLeft, y: event.pageY - canvas.offsetTop } } // start canvas = document.getElementById("canvas"); code = document.getElementById("code"); if (canvas.getContext) { ctx = canvas.getContext("2d"); Init(canvas.className == "quadratic"); }

}) ();