平滑线条并创建渐变

Smoothing a line and creating a gradient

我正在为 class 做这个,我已经设法创建了一个绘图应用程序,其中笔划对鼠标的速度作出反应,并且笔划的颜色根据角度而变化。

链接here

不过看起来真的很粗糙,我想了解如何通过连接笔划来平滑线条(这样它看起来就像是改变宽度的单个笔划),以及是否可以创建渐变,从红色到绿色。我试图从老师那里得到一些帮助,但我们每周大约有 10 分钟的时间专门为我们的项目获得个人帮助,很难提出所有这些问题并理解代码中发生的事情......

请注意,我在这方面得到了很多帮助。我以前使用 paper.js 做过类似的事情,但我的老师更喜欢我为此使用 "pure" canvas。我有网页设计的背景,但它远非编程,我只知道标记语言和使用 html 和 css,偶尔使用一些 jquery 滑块。因此,即使是最简单的教程,我也完全感到困惑,我尝试按照 this 进行操作,但我什至不明白将所有内容放在哪里,而且它根本不起作用。

如果有人能在这方面给我一些帮助,我将非常高兴...ELI5,拜托了。我学得很快,但我仍然处于困惑状态,被所有这些我(还)不理解但真的很想理解的代码行弄得不知所措。

提前致谢!

几个提示:

  • 设置context.lineCap='round'。这四舍五入每行的开头和结尾。该舍入有助于在视觉上将一行合并到下一行。

  • 将您的线宽限制在一个较小的范围内。这使您的线条在视觉上更流畅,因为当用户快速更改速度时,尺寸不会有很大的跳跃。

这是重构代码和演示:

// cache a reference to the canvas element & its context
// because they are used often
var canvas=$('#canvas')[0];
var context = canvas.getContext('2d');

//full-screen
canvas.width = 500;
canvas.height = 500;

// style lines with rounded end-caps & rounded joins
context.lineJoin='round';
context.lineCap='round';

var mouseX = undefined;
var mouseY = undefined;
var mouseIsDown = false;

var PI2=Math.PI*2;
var speed=-1000;
(function(){Math.clamp=function(a,b,c){return Math.max(b,Math.min(c,a));}})();

onMouseDown = function( event ){
  // tell the browser we're handling this event
  event.preventDefault();
  event.stopPropagation();
  mouseIsDown = true;
}

onMouseMove = function( event ){
  // tell the browser we're handling this event
  event.preventDefault();
  event.stopPropagation();

  var previousMouseX = mouseX;
  var previousMouseY = mouseY;

  mouseX = event.pageX;
  mouseY = event.pageY;

  var dx = Math.abs( mouseX - previousMouseX );
  var dy = Math.abs( mouseY - previousMouseY );


  var speed = Math.sqrt( dx * dx + dy * dy );

  // limit the min/max width of the line
  speed=Math.clamp(speed,2,12);

  var angle = 2 * Math.PI * Math.acos( dx / ( speed + 0.00001 ) );

  if( angle < Math.PI ){
    context.strokeStyle = 'rgb( 0, 255, 0 )';
  }
  else{
    context.strokeStyle = 'rgb( 255, 0, 0 )';
  }

  if( mouseIsDown ){
    context.lineWidth=speed;
    context.beginPath();
    context.moveTo( previousMouseX, previousMouseY );
    context.lineTo( mouseX, mouseY );
    context.stroke();
  }
}
//drawing only is the mouse is down
onMouseUp = function( event ){
  // tell the browser we're handling this event
  event.preventDefault();
  event.stopPropagation();

  mouseIsDown = false;
}

$( '#canvas' ).on( 'mousedown', onMouseDown );
$( '#canvas' ).on( 'mousemove', onMouseMove );
$( '#canvas' ).on( 'mouseup', onMouseUp );
$( '#canvas' ).on( 'mouseout', onMouseUp );
canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<canvas id="canvas" width=500 height=500></canvas>

应用渐变要困难得多。您将必须:

  • 保存每个鼠标点
  • 在每个鼠标点之间插入点,使每个新点与前一个点相距 1px。
  • 清除canvas
  • 在每个鼠标点之间重新绘制一条线,每条线的 strokeStyle 根据您想要的渐变变化。