如何在画布上涂色线?

时间:2018-10-23 05:05:21

标签: javascript html css canvas

编辑:我正在尝试为线着色,而不是整个网格

所以,我要尝试的是单击画布时,选定的行会移动并变为彩色。

我已经移动了行,但是无法get them colored。我知道我必须使用strokeStyle属性,但是如何使特定的行变成彩色?

我尝试将strokeStyle放在draw_each方法下,但这不起作用,我也不知道为什么。这是我的代码:

  //draw each line in array
function draw_each(p1, p2, p3, p4) {

    $.moveTo(p1.x, p1.y);
    $.lineTo(p2.x, p2.y);
    $.moveTo(p1.x, p1.y);
    $.lineTo(p4.x, p4.y);

    if (p1.ind_x == gnum - 2) {
      $.moveTo(p3.x, p3.y);
      $.lineTo(p4.x, p4.y);
    }
    if (p1.ind_y == gnum - 2) {
      $.moveTo(p3.x, p3.y);
      $.lineTo(p2.x, p2.y);
    }
  }

https://codepen.io/diazabdulm/pen/qJyrZP?editors=0010

2 个答案:

答案 0 :(得分:2)

在我看来,您想要的实际上是根据所施加的力为每个段生成一种颜色,从而使波浪效果保持其效果。

您可以做的是保存每个节点在两个轴上的速度的中值,以表示它们当前承受的力,并在图形部分中获取组成每个段的所有节点的中值并从中组成颜色。

但这有一个缺点:您的代码编写得很好,足以将整个网格组成一个子路径,从而限制了所需的图形数量。但是现在,我们必须将每个段都设为自己的子路径(因为它们将具有自己的颜色),因此我们将在性能方面失去很多...

var gnum = 90; //num grids / frame
var _x = 2265; //x width (canvas width)
var _y = 1465; //y height (canvas height)
var w = _x / gnum; //grid sq width
var h = _y / gnum; //grid sq height
var $; //context
var parts; //particles 
var frm = 0; //value from
var P1 = 0.0005; //point one
var P2 = 0.01; //point two
var n = 0.98; //n value for later
var n_vel = 0.03; //velocity
var ŭ = 0; //color update
var msX = 0; //mouse x
var msY = 0; //mouse y
var msdn = false; //mouse down flag

var Part = function() {
  this.x = 0; //x pos
  this.y = 0; //y pos
  this.vx = 0; //velocity x
  this.vy = 0; //velocity y
  this.ind_x = 0; //index x
  this.ind_y = 0; //index y
};

Part.prototype.frame = function() {

  if (this.ind_x == 0 || this.ind_x == gnum - 1 || this.ind_y == 0 || this.ind_y == gnum - 1) {
    return;
  }

  var ax = 0; //angle x
  var ay = 0; //angle y
  //off_dx, off_dy = offset distance x, y
  var off_dx = this.ind_x * w - this.x;
  var off_dy = this.ind_y * h - this.y;
  ax = P1 * off_dx;
  ay = P1 * off_dy;

  ax -= P2 * (this.x - parts[this.ind_x - 1][this.ind_y].x);
  ay -= P2 * (this.y - parts[this.ind_x - 1][this.ind_y].y);

  ax -= P2 * (this.x - parts[this.ind_x + 1][this.ind_y].x);
  ay -= P2 * (this.y - parts[this.ind_x + 1][this.ind_y].y);

  ax -= P2 * (this.x - parts[this.ind_x][this.ind_y - 1].x);
  ay -= P2 * (this.y - parts[this.ind_x][this.ind_y - 1].y);

  ax -= P2 * (this.x - parts[this.ind_x][this.ind_y + 1].x);
  ay -= P2 * (this.y - parts[this.ind_x][this.ind_y + 1].y);

  this.vx += (ax - this.vx * n_vel);
  this.vy += (ay - this.vy * n_vel);
//EDIT\\
// store the current velocity (here base on 100 since it will be used with hsl())
  this.color = (Math.abs(this.vx)+Math.abs(this.vy)) * 50;


  this.x += this.vx * n;
  this.y += this.vy * n;
  if (msdn) {
    var dx = this.x - msX;
    var dy = this.y - msY;
    var ɋ = Math.sqrt(dx * dx + dy * dy);
    if (ɋ > 50) {
      ɋ = ɋ < 10 ? 10 : ɋ;
      this.x -= dx / ɋ * 5;
      this.y -= dy / ɋ * 5;
    }
  }
  
};

function go() {
    parts = []; //particle array
    for (var i = 0; i < gnum; i++) {
      parts.push([]);
      for (var j = 0; j < gnum; j++) {
        var p = new Part();
        p.ind_x = i;
        p.ind_y = j;
        p.x = i * w;
        p.y = j * h;
        parts[i][j] = p;
      }
    }
  }
  //move particles function
function mv_part() {
    for (var i = 0; i < gnum; i++) {
      for (var j = 0; j < gnum; j++) {
        var p = parts[i][j];
        p.frame();
      }
    }
  }
  //draw grid function
function draw() {
//EDIT
// we unfortunately have to break the drawing part
// since each segment has its own color, we can't have a single sub-path anymore...
    ŭ -= .5;
    for (var i = 0; i < gnum - 1; i += 1) {
      for (var j = 0; j < gnum - 1; j += 1) {
        var p1 = parts[i][j];
        var p2 = parts[i][j + 1];
        var p3 = parts[i + 1][j + 1];
        var p4 = parts[i + 1][j];
        draw_each(p1, p2, p3, p4);
      }
    }

  }
  //draw each in array
function draw_each(p1, p2, p3, p4) {
    // for each segment we set the color
    $.strokeStyle = `hsl(0deg, ${(p1.color+p2.color+p3.color+p4.color) / 4}%, 50%)`;
    // begin a new sub-path
    $.beginPath();
    $.moveTo(p1.x, p1.y);
    $.lineTo(p2.x, p2.y);
    $.moveTo(p1.x, p1.y);
    $.lineTo(p4.x, p4.y);

    if (p1.ind_x == gnum - 2) {
      $.moveTo(p3.x, p3.y);
      $.lineTo(p4.x, p4.y);
    }
    if (p1.ind_y == gnum - 2) {
      $.moveTo(p3.x, p3.y);
      $.lineTo(p2.x, p2.y);
    }
    // and stroke it
    $.stroke();
  }
  //call functions to run
function calls() {
    $.fillStyle = "hsla(0, 0%, 7%, 1)";
    $.fillRect(0, 0, _x, _y);

    mv_part();
    draw();
    frm++;
  }

var c = document.getElementById('canv');
var $ = c.getContext('2d');
$.fillStyle = "hsla(0, 0%, 7%, 1)";
$.fillRect(0, 0, _x, _y);

function resize() {
  if (c.width < window.innerWidth) {
    c.width = window.innerWidth;
  }

  if (c.height < window.innerHeight) {
    c.height = window.innerHeight;
  }
}
requestAnimationFrame(go);

document.addEventListener('click', MSMV, false);
document.addEventListener('click', MSDN, false);

function MSDN(e) {
  msdn = true;
  window.setTimeout(function() {
    msdn = false;
  }, 100);
}

function MSUP(e) {
  msdn = false;
}

function MSMV(e) {
  var rect = e.target.getBoundingClientRect();
  msX = e.clientX - rect.left;
  msY = e.clientY - rect.top;
}

window.onload = function() {
  run();

  function run() {
    requestAnimationFrame(calls);
    requestAnimationFrame(run);
  }
  resize();
};
onresize = resize;
body {
  width: 100%;
  overflow: hidden;
  cursor:move;
}
<canvas id="canv" width="150" height="150"></canvas>

现在,一种性能更高但外观不太好的方法是在发生点击的位置绘制一个径向渐变,并进行一些合成,您将能够获得便宜的产品,但可能会起作用。实际上要进行大量编码才能同时获得多个这样的渐变...

答案 1 :(得分:0)

对我有用:

  //draw each line in array
function draw_each(p1, p2, p3, p4) {

    $.moveTo(p1.x, p1.y);
    $.lineTo(p2.x, p2.y);
    $.moveTo(p1.x, p1.y);
    $.lineTo(p4.x, p4.y);

    if (p1.ind_x == gnum - 2) {
      $.moveTo(p3.x, p3.y);
      $.lineTo(p4.x, p4.y);
    }
    if (p1.ind_y == gnum - 2) {
      $.moveTo(p3.x, p3.y);
      $.lineTo(p2.x, p2.y);
    }

    $.strokeStyle = '#458920';
  }