2014-10-03 5 views
0

, поэтому я пытаюсь создать инструмент рисования в холсте HTML5, где вес хода увеличивается, чем быстрее вы перемещаете мышь, тем меньше вы перемещаетесь. Я использую ctx.lineTo(), но на мои первые попытки заметил, что если я двигаться слишком быстро изменение толщины регистрируются как приращения очевидных квадратных (а не плавное увеличение веса)сглаживание линии. Изменение ширины в холсте lineTo

first try

так я изменил ctx.lineJoin и ctx.lineCap на «круглый», и это стало немного лучше

current state

, но это еще не так гладко, как хотелось бы. я снимаю что-то вроде этого

what i'd like

какие-либо советы о том, как внести изменения в весе немного мягче было бы здорово! вот работает демо: http://jsfiddle.net/0fhag522/1/

и вот предварительный просмотр моего „точка“ объекта (перо) и моя ничья функции:

var dot = {   
     start: false, 
     weight: 1, 
     open: function(x,y){ 
      ctx.lineJoin = "round"; 
      ctx.lineCap = "round"; 
      ctx.beginPath(); 
      ctx.moveTo(x,y); 
     }, 
     connect: function(x,y){ 
      ctx.lineWidth = this.weight; 
      ctx.lineTo(x,y); 
      ctx.stroke(); 
      ctx.closePath(); 
      ctx.beginPath(); 
      ctx.moveTo(x,y); 
     }, 
     close: function(){ 
      ctx.closePath(); 
     } 
    } 

    function draw(){ 
     if(down){ 
      if(!dot.start){ 
       dot.close(); 
       prevx = mx; prevy = my; 
       dot.open(mx,my); 
       dot.start=true; 
      } 
      else { 
       var dx = (prevx>mx) ? prevx-mx : mx-prevx; 
       var dy = (prevy>my) ? prevy-my : my-prevy; 
       dot.weight = Math.abs(dx-dy)/2; 
       dot.connect(mx,my); 
       prevx = mx; prevy = my; 
      } 
     } 
    } 

ответ

0

Поскольку полотно не имеет переменную ширина линии вы должны рисовать закрытые пути между вашими точками линии.

Однако это оставляет видимое стыковое соединение.

enter image description here

Чтобы сгладить стыковой шов, вы можете нарисовать круг на каждом суставе.

enter image description here

Вот пример кода и демо:

var canvas = document.getElementById("canvas"); 
 
var ctx = canvas.getContext("2d"); 
 
var cw = canvas.width; 
 
var ch = canvas.height; 
 
var $canvas = $("#canvas"); 
 
var canvasOffset = $canvas.offset(); 
 
var offsetX = canvasOffset.left; 
 
var offsetY = canvasOffset.top; 
 
var scrollX = $canvas.scrollLeft(); 
 
var scrollY = $canvas.scrollTop(); 
 

 
var isDown = false; 
 
var startX; 
 
var startY; 
 

 
var PI = Math.PI; 
 
var halfPI = PI/2; 
 
var points = []; 
 

 
$("#canvas").mousedown(function(e) { 
 
    handleMouseDown(e); 
 
}); 
 

 
function handleMouseDown(e) { 
 
    e.preventDefault(); 
 
    e.stopPropagation(); 
 

 
    mx = parseInt(e.clientX - offsetX); 
 
    my = parseInt(e.clientY - offsetY); 
 

 
    var pointsLength = points.length; 
 

 
    if (pointsLength == 0) { 
 
    points.push({ 
 
     x: mx, 
 
     y: my, 
 
     width: Math.random() * 5 + 2 
 
    }); 
 
    } else { 
 
    var p0 = points[pointsLength - 1]; 
 
    var p1 = { 
 
     x: mx, 
 
     y: my, 
 
     width: Math.random() * 5 + 2 
 
    }; 
 
    addAngle(p0, p1); 
 
    p0.angle = p1.angle; 
 
    addEndcap(p0); 
 
    addEndcap(p1); 
 
    points.push(p1); 
 
    extendLine(p0, p1); 
 
    } 
 
} 
 

 
function addAngle(p0, p1) { 
 
    var dx = p1.x - p0.x; 
 
    var dy = p1.y - p0.y; 
 
    p1.angle = Math.atan2(dy, dx); 
 
} 
 

 
function addEndcap(p) { 
 
    p.x0 = p.x + p.width * Math.cos(p.angle - halfPI); 
 
    p.y0 = p.y + p.width * Math.sin(p.angle - halfPI); 
 
    p.x1 = p.x + p.width * Math.cos(p.angle + halfPI); 
 
    p.y1 = p.y + p.width * Math.sin(p.angle + halfPI); 
 
} 
 

 
function extendLine(p0, p1) { 
 
    ctx.beginPath(); 
 
    ctx.moveTo(p0.x0, p0.y0); 
 
    ctx.lineTo(p0.x1, p0.y1); 
 
    ctx.lineTo(p1.x1, p1.y1); 
 
    ctx.lineTo(p1.x0, p1.y0); 
 
    ctx.closePath(); 
 
    ctx.fillStyle = 'blue'; 
 
    ctx.fill(); 
 
    // draw a circle to cover the butt-joint 
 
    ctx.beginPath(); 
 
    ctx.moveTo(p1.x, p1.y); 
 
    ctx.arc(p1.x, p1.y, p1.width, 0, Math.PI * 2); 
 
    ctx.closePath(); 
 
    ctx.fill(); 
 
}
body{ background-color: ivory; } 
 
#canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 
 
<h4>Click to add line segments.</h4> 
 
<canvas id="canvas" width=300 height=300></canvas>

Смежные вопросы