una tablas tabla obtener mano lineas firma figuras ejemplos dibujar datos con capturar alzada agregar javascript canvas

tablas - ¿Cómo dibujo a mano sobre lienzo con JavaScript?



obtener datos de una tabla html javascript (6)

Pregunta

¿Cómo puedo dibujar libremente (usando mi mouse / dedos) en un elemento del lienzo como puedes hacerlo pintando con un lápiz?

Sobre esta pregunta

Hay muchas preguntas que quieren lograr el dibujo a mano alzada en lienzo:

  • dibujar con el mouse con HTML5 Canvas
  • KineticJS - Dibuja gratis con el mouse
  • Dibujo libre sobre lienzo usando fabric.js
  • Dibujando con JS
  • Lienzo de pintura no funciona correctamente
  • Posición del ratón sobre lienzo de pintura.
  • Implementando el dibujo suave y el dibujo en el elemento.

Así que pensé que sería una buena idea hacer una pregunta de referencia, donde cada respuesta es wiki de la comunidad y contiene una explicación de exactamente una biblioteca de JavaScript / JavaScript puro sobre cómo pintar en el lienzo.

Estructura de respuestas

Las respuestas deben ser wiki de la comunidad y usar la siguiente plantilla:

## [Name of library](Link to project page) ### Simple example A basic, complete example. That means it has to contain HTML and JavaScript. You can start with this: <!DOCTYPE html> <html> <head> <title>Simple example</title> <script type=''text/javascript'' src=''http://cdnjs.com/[your library]''></script> <style type=''text/css''> #sheet { border:1px solid black; } </style> <script type=''text/javascript''> window.onload=function(){ // TODO: Adjust } </script> </head> <body> <canvas id="sheet" width="400" height="400"></canvas> </body> </html> If possible, this example should work with both, mouse and touch events. [JSFiddle](Link to code on jsfiddle.net) This solution works with: <!-- Please test it the following way: Write "Hello World" Problems that you test this way are: * Does it work at all? * Are lines separated? * Does it get slow when you write too much? --> * Desktop computers: * [Browser + Version list] * Touch devices: * [Browser + Version list] on [Device name] ### Import / Export Some explanations how to import / export user drawn images. ### Line smoothing Explanations about how to manipulate the line the user draws. This can include: * Bézier curves * Controlling thickness of lines


JavaScript simple

Ejemplo simple

<!DOCTYPE html> <html> <head> <title>Simple example</title> <style type=''text/css''> #sheet { border:1px solid black; } </style> </head> <body> <canvas id="sheet" width="400" height="400"></canvas> <script type=''text/javascript''> /*jslint browser:true */ "use strict"; var context = document.getElementById(''sheet'').getContext("2d"); var canvas = document.getElementById(''sheet''); context = canvas.getContext("2d"); context.strokeStyle = "#ff0000"; context.lineJoin = "round"; context.lineWidth = 5; var clickX = []; var clickY = []; var clickDrag = []; var paint; /** * Add information where the user clicked at. * @param {number} x * @param {number} y * @return {boolean} dragging */ function addClick(x, y, dragging) { clickX.push(x); clickY.push(y); clickDrag.push(dragging); } /** * Redraw the complete canvas. */ function redraw() { // Clears the canvas context.clearRect(0, 0, context.canvas.width, context.canvas.height); for (var i = 0; i < clickX.length; i += 1) { if (!clickDrag[i] && i == 0) { context.beginPath(); context.moveTo(clickX[i], clickY[i]); context.stroke(); } else if (!clickDrag[i] && i > 0) { context.closePath(); context.beginPath(); context.moveTo(clickX[i], clickY[i]); context.stroke(); } else { context.lineTo(clickX[i], clickY[i]); context.stroke(); } } } /** * Draw the newly added point. * @return {void} */ function drawNew() { var i = clickX.length - 1 if (!clickDrag[i]) { if (clickX.length == 0) { context.beginPath(); context.moveTo(clickX[i], clickY[i]); context.stroke(); } else { context.closePath(); context.beginPath(); context.moveTo(clickX[i], clickY[i]); context.stroke(); } } else { context.lineTo(clickX[i], clickY[i]); context.stroke(); } } function mouseDownEventHandler(e) { paint = true; var x = e.pageX - canvas.offsetLeft; var y = e.pageY - canvas.offsetTop; if (paint) { addClick(x, y, false); drawNew(); } } function touchstartEventHandler(e) { paint = true; if (paint) { addClick(e.touches[0].pageX - canvas.offsetLeft, e.touches[0].pageY - canvas.offsetTop, false); drawNew(); } } function mouseUpEventHandler(e) { context.closePath(); paint = false; } function mouseMoveEventHandler(e) { var x = e.pageX - canvas.offsetLeft; var y = e.pageY - canvas.offsetTop; if (paint) { addClick(x, y, true); drawNew(); } } function touchMoveEventHandler(e) { if (paint) { addClick(e.touches[0].pageX - canvas.offsetLeft, e.touches[0].pageY - canvas.offsetTop, true); drawNew(); } } function setUpHandler(isMouseandNotTouch, detectEvent) { removeRaceHandlers(); if (isMouseandNotTouch) { canvas.addEventListener(''mouseup'', mouseUpEventHandler); canvas.addEventListener(''mousemove'', mouseMoveEventHandler); canvas.addEventListener(''mousedown'', mouseDownEventHandler); mouseDownEventHandler(detectEvent); } else { canvas.addEventListener(''touchstart'', touchstartEventHandler); canvas.addEventListener(''touchmove'', touchMoveEventHandler); canvas.addEventListener(''touchend'', mouseUpEventHandler); touchstartEventHandler(detectEvent); } } function mouseWins(e) { setUpHandler(true, e); } function touchWins(e) { setUpHandler(false, e); } function removeRaceHandlers() { canvas.removeEventListener(''mousedown'', mouseWins); canvas.removeEventListener(''touchstart'', touchWins); } canvas.addEventListener(''mousedown'', mouseWins); canvas.addEventListener(''touchstart'', touchWins); </script> </body> </html>

JSFiddle

  • El ancho de las líneas se puede controlar con context.lineWidth .
  • El color de las líneas se puede controlar con strokeStyle .

Esta solución funciona con:

  • Computadores de escritorio:
    • Cromo 33
    • Firefox 28
  • Dispositivos táctiles:
    • Firefox 28 en Nexus 4

No funciona con

  • Dispositivos táctiles:
    • Chrome 34 / Opera 20 en Nexus 4 (ver issue )

Importación y exportación

La importación y exportación de la imagen se puede hacer importando / exportando clickX , clickY y clickDrag .

Suavizado de linea

Eventualmente se puede hacer reemplazando lineTo() con bezierCurveTo()


Fabric.js

<!DOCTYPE html> <html> <head> <title>Simple example</title> <script type=''text/javascript'' src=''http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.4.0/fabric.min.js''></script> <style type=''text/css''> #sheet { border:1px solid black; } </style> <script type=''text/javascript''> window.onload=function(){ var canvas = new fabric.Canvas(''sheet''); canvas.isDrawingMode = true; canvas.freeDrawingBrush.width = 5; canvas.freeDrawingBrush.color = "#ff0000"; } </script> </head> <body> <canvas id="sheet" width="400" height="400"></canvas> </body> </html>

JSFiddle - Demo

  • El ancho de las líneas se puede controlar con canvas.freeDrawingBrush.width .
  • El color de las líneas se puede controlar con canvas.freeDrawingBrush.color .

Esta solución funciona con:

  • Computadores de escritorio:
    • Cromo 33
    • Firefox 28
  • Dispositivos táctiles:
    • Chrome 34 en Nexus 4
    • Opera 20 en Nexus 4
    • Firefox 28 en Nexus 4

Importación y exportación

Solo es posible mediante la serialización del lienzo completo, ver Tutorial

Suavizado de linea

Se realiza de forma automática y parece que no es posible desactivarlo.


Paper.js

Ejemplo simple

<!DOCTYPE html> <html> <head> <title>Paper.js example</title> <script type=''text/javascript'' src=''http://paperjs.org/assets/js/paper.js''></script> <style type=''text/css''> #sheet { border:1px solid black; } </style> </head> <body> <script type="text/paperscript" canvas="sheet"> var path; function onMouseDown(event) { // If we produced a path before, deselect it: if (path) { path.selected = false; } // Create a new path and set its stroke color to black: path = new Path({ segments: [event.point], strokeColor: ''black'', strokeWidth: 3 }); } // While the user drags the mouse, points are added to the path // at the position of the mouse: function onMouseDrag(event) { path.add(event.point); } // When the mouse is released, we simplify the path: function onMouseUp(event) { path.simplify(); } </script> <canvas id="sheet" width="400" height="400"></canvas> </body> </html>

JSFiddle

  • El ancho de las líneas se puede controlar con strokeWidth .
  • El color de las líneas se puede controlar con strokeColor .

Esta solución funciona con:

  • Computadores de escritorio:
    • Cromo 33

Importación y exportación

?

Suavizado de linea

El suavizado de líneas se puede hacer ajustando path.simplify(); .


EaselJs

Ejemplo simple

A basic, complete example. That means it has to contain HTML and JavaScript. You can start with this: <!DOCTYPE html> <html> <head> <title>EaselJS example</title> <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/EaselJS/0.7.1/easeljs.min.js"></script> <script> var canvas, stage; var drawingCanvas; var oldPt; var oldMidPt; var color; var stroke; var index; function init() { if (window.top != window) { document.getElementById("header").style.display = "none"; } canvas = document.getElementById("sheet"); index = 0; //check to see if we are running in a browser with touch support stage = new createjs.Stage(canvas); stage.autoClear = false; stage.enableDOMEvents(true); createjs.Touch.enable(stage); createjs.Ticker.setFPS(24); drawingCanvas = new createjs.Shape(); stage.addEventListener("stagemousedown", handleMouseDown); stage.addEventListener("stagemouseup", handleMouseUp); stage.addChild(drawingCanvas); stage.update(); } function stop() {} function handleMouseDown(event) { color = "#ff0000"; stroke = 5; oldPt = new createjs.Point(stage.mouseX, stage.mouseY); oldMidPt = oldPt; stage.addEventListener("stagemousemove" , handleMouseMove); } function handleMouseMove(event) { var midPt = new createjs.Point(oldPt.x + stage.mouseX>>1, oldPt.y+stage.mouseY>>1); drawingCanvas.graphics.clear().setStrokeStyle(stroke, ''round'', ''round'').beginStroke(color).moveTo(midPt.x, midPt.y).curveTo(oldPt.x, oldPt.y, oldMidPt.x, oldMidPt.y); oldPt.x = stage.mouseX; oldPt.y = stage.mouseY; oldMidPt.x = midPt.x; oldMidPt.y = midPt.y; stage.update(); } function handleMouseUp(event) { stage.removeEventListener("stagemousemove" , handleMouseMove); } </script> </head> <body onload="init();"> <canvas id="sheet" width="400" height="400"></canvas> </body> </html>

Demo

Las partes interesantes en la documentación son:

Esta solución funciona con:

  • Computadores de escritorio:
    • Cromo 33
    • Firefox 28
  • Dispositivos táctiles:
    • Chrome 34 / Firefox 28 / Opera 20 en Nexus 4

Importación y exportación

?

Suavizado de linea

?


(Descargo de responsabilidad: escribí esta biblioteca)

Scrawl.js

Ejemplo simple

<!DOCTYPE html> <html> <head> <title>Simple example</title> <style type=''text/css''> #sheet {border:1px solid black;} </style> </head> <body> <canvas id="sheet" width="400" height="400"></canvas> <script src="http://scrawl.rikweb.org.uk/js/scrawlCore-min.js"></script> <script> var mycode = function(){ //define variables var myPad = scrawl.pad.sheet, myCanvas = scrawl.canvas.sheet, sX, sY, here, drawing = false, currentSprite = false, startDrawing, endDrawing; //event listeners startDrawing = function(e){ drawing = true; currentSprite = scrawl.newShape({ start: here, lineCap: ''round'', lineJoin: ''round'', method: ''draw'', lineWidth: 4, strokeStyle: ''red'', data: ''l0,0 '', }); sX = here.x; sY = here.y; if(e){ e.stopPropagation(); e.preventDefault(); } }; myCanvas.addEventListener(''mousedown'', startDrawing, false); endDrawing = function(e){ if(currentSprite){ currentSprite = false; } drawing = false; if(e){ e.stopPropagation(); e.preventDefault(); } }; myCanvas.addEventListener(''mouseup'', endDrawing, false); //animation object scrawl.newAnimation({ fn: function(){ //get current mouse position here = myPad.getMouse(); if(here.active){ if(drawing){ if(here.x !== sX || here.y !== sY){ //extend the line currentSprite.set({ data: currentSprite.data+'' ''+(here.x - sX)+'',''+(here.y - sY), }); sX = here.x; sY = here.y; } } } else{ //stop drawing if mouse leaves canvas area if(currentSprite){ endDrawing(); } } //update display scrawl.render(); }, }); }; //Scrawl is modular - load additional modules scrawl.loadModules({ path: ''js/'', modules: [''animation'', ''shape''], callback: function(){ window.addEventListener(''load'', function(){ scrawl.init(); //start Scrawl mycode(); //run code }, false); }, }); </script> </body> </html>

JSFiddle

Esta solución funciona con:

  • versiones recientes de IE, Chrome, Firefox, Opera (escritorio)
  • (no probado en dispositivos móviles / táctiles)

Añadiendo soporte táctil

  • (intente agregar una biblioteca táctil dedicada como Hammer.js?)

Importación y exportación

Alisado de líneas y otras manipulaciones de sprites.

  • los datos de línea se guardan internamente como un valor SVGTiny Path.d: cualquier algoritmo que pueda tomar datos de línea en ese formato y sin problemas debe funcionar
  • Los atributos de línea (grosor, color, posicionamiento, rotación, etc.) se pueden configurar y animar.

Aquí, prueba mi lienzo de dibujo libre y borra.

https://jsfiddle.net/richardcwc/d2gxjdva/

//Canvas var canvas = document.getElementById(''canvas''); var ctx = canvas.getContext(''2d''); //Variables var canvasx = $(canvas).offset().left; var canvasy = $(canvas).offset().top; var last_mousex = last_mousey = 0; var mousex = mousey = 0; var mousedown = false; var tooltype = ''draw''; //Mousedown $(canvas).on(''mousedown'', function(e) { last_mousex = mousex = parseInt(e.clientX-canvasx); last_mousey = mousey = parseInt(e.clientY-canvasy); mousedown = true; }); //Mouseup $(canvas).on(''mouseup'', function(e) { mousedown = false; }); //Mousemove $(canvas).on(''mousemove'', function(e) { mousex = parseInt(e.clientX-canvasx); mousey = parseInt(e.clientY-canvasy); if(mousedown) { ctx.beginPath(); if(tooltype==''draw'') { ctx.globalCompositeOperation = ''source-over''; ctx.strokeStyle = ''black''; ctx.lineWidth = 3; } else { ctx.globalCompositeOperation = ''destination-out''; ctx.lineWidth = 10; } ctx.moveTo(last_mousex,last_mousey); ctx.lineTo(mousex,mousey); ctx.lineJoin = ctx.lineCap = ''round''; ctx.stroke(); } last_mousex = mousex; last_mousey = mousey; //Output $(''#output'').html(''current: ''+mousex+'', ''+mousey+''<br/>last: ''+last_mousex+'', ''+last_mousey+''<br/>mousedown: ''+mousedown); }); //Use draw|erase use_tool = function(tool) { tooltype = tool; //update }

canvas { cursor: crosshair; border: 1px solid #000000; }

<canvas id="canvas" width="800" height="500"></canvas> <input type="button" value="draw" onclick="use_tool(''draw'');" /> <input type="button" value="erase" onclick="use_tool(''erase'');" /> <div id="output"></div>