2014-10-03 67 views
0

所以我试图在HTML5画布中创建一个绘图工具,笔划的重量越大,移动鼠标的速度越快,移动的速度越慢。我使用ctx.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>