2012-04-12 2 views
4

Zuerst möchte ich sagen, dass ich eine Menge Forschung gemacht habe und mich selbst ohne Erfolg versuche.Erstellen Sie ein realistisches Bleistift-Werkzeug für eine Malerei-App mit HTML5 Canvas

ich auf einer MSPaint artigen Anwendung arbeitete Leinwand verwenden und Ich mag ein Bleistift-Tool erstellen, die wie handgemachte Zeichnungen realistisch aussieht ... Hier ist ein Beispiel in dem unten stehenden Link mit dem Standard-Tool: http://www.onemotion.com/flash/sketch-paint/

Ich habe versucht, mit mousespeed und Linienbreite Eigenschaften zu spielen, aber es funktioniert nicht gut (die gesamte Linie vergrößern und verkleinern, wie ich die Maus bewegen). Ich habe keine Ahnung von einem Algorithmus, der auf Pixelrohdaten einwirkt.

Kennen Sie etwas vorhanden oder einen geeigneten Algorithmus? Vielen Dank für Ihre Hilfe

EDIT

ich die Lösung hinzuzufügen, entschied ich mich entschieden, weil es Interesse vieler Menschen scheint. Also, das Beste, was ich bisher gefunden habe, ist ein Bild auf die Leinwand zu zeichnen, mit der hier erläuterten Technik: http://css.dzone.com/articles/sketching-html5-canvas-and. Es funktioniert wie ein Zauber, das Ergebnis ist wirklich überzeugend und das ist ziemlich einfach zu implementieren. Versuchen Sie es hier heraus: http://tricedesigns.com/portfolio/sketch/brush.html#

Antwort

23

Sie so etwas wie die folgende Demo versuchen könnte

Live Demo

Ihr höchstwahrscheinlich mit moveTo und lineTo die Pfade zu erstellen, wenn Sie es auf diese Weise tun die Eigenschaften werden für den Pfad freigegeben werden, bis Sie den Pfad schließen. Also jedes Mal, wenn Sie die Dicke ändern, müssen Sie wieder closePath und dann beginPath aufrufen.

In meinem Beispiel verwende ich Bresenham's line algorithm, um die Punkte zu plotten. Im Grunde genommen beginnt es zu malen. Anschließend vergleicht es die aktuellen Koordinaten mit den letzten Koordinaten und zeichnet alle dazwischen liegenden Punkte auf. Es verwendet auch fillRect zu malen. Je nachdem, wie schnell Sie die Linie bewegen, wird sie dicker oder dünner.

Heres der Code für die Zeichenfunktion

var canvas = document.getElementById("canvas"), 
    ctx = canvas.getContext("2d"), 
    painting = false, 
    lastX = 0, 
    lastY = 0, 
    lineThickness = 1; 

canvas.width = canvas.height = 600; 
ctx.fillRect(0, 0, 600, 600); 

canvas.onmousedown = function(e) { 
    painting = true; 
    ctx.fillStyle = "#ffffff"; 
    lastX = e.pageX - this.offsetLeft; 
    lastY = e.pageY - this.offsetTop; 
}; 

canvas.onmouseup = function(e){ 
    painting = false; 
} 

canvas.onmousemove = function(e) { 
    if (painting) { 
     mouseX = e.pageX - this.offsetLeft; 
     mouseY = e.pageY - this.offsetTop; 

     // find all points between   
     var x1 = mouseX, 
      x2 = lastX, 
      y1 = mouseY, 
      y2 = lastY; 


     var steep = (Math.abs(y2 - y1) > Math.abs(x2 - x1)); 
     if (steep){ 
      var x = x1; 
      x1 = y1; 
      y1 = x; 

      var y = y2; 
      y2 = x2; 
      x2 = y; 
     } 
     if (x1 > x2) { 
      var x = x1; 
      x1 = x2; 
      x2 = x; 

      var y = y1; 
      y1 = y2; 
      y2 = y; 
     } 

     var dx = x2 - x1, 
      dy = Math.abs(y2 - y1), 
      error = 0, 
      de = dy/dx, 
      yStep = -1, 
      y = y1; 

     if (y1 < y2) { 
      yStep = 1; 
     } 

     lineThickness = 5 - Math.sqrt((x2 - x1) *(x2-x1) + (y2 - y1) * (y2-y1))/10; 
     if(lineThickness < 1){ 
      lineThickness = 1; 
     } 

     for (var x = x1; x < x2; x++) { 
      if (steep) { 
       ctx.fillRect(y, x, lineThickness , lineThickness); 
      } else { 
       ctx.fillRect(x, y, lineThickness , lineThickness); 
      } 

      error += de; 
      if (error >= 0.5) { 
       y += yStep; 
       error -= 1.0; 
      } 
     } 



     lastX = mouseX; 
     lastY = mouseY; 

    } 
} 

+2

nice stuff danke. – jazzytomato

+0

@Loktar Ich habe versucht, die gleiche Sache mit Jquery Mobile zu implementieren. Ich bin in der Lage, Touchevents zu bekommen, aber nicht in der Lage, die Linie zu ziehen. Kannst du bitte dabei helfen? Vielen Dank:) – Beginner