javascript - 如何在 Canvas 中为线条着色?

标签 javascript html css canvas

编辑:我试图让一条线着色,而不是整个网格

所以,我想要做的是,当单击 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

最佳答案

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

您可以做的是,将每个节点在两个轴上的速度中值保存为表示它们当前所受力的平均值,并在您的绘图部分中获取将组成每个线段的所有节点的中值你的网格并从中合成一种颜色。

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

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>

现在,一种性能更高但不太好看的方法是在点击发生的地方绘制一个径向渐变,通过一些合成,您可以获得一些便宜的东西,但它会实际上需要大量的编码才能同时获得多个这样的梯度......

关于javascript - 如何在 Canvas 中为线条着色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52941520/

相关文章:

html - 为什么不使用星号重置 CSS?

javascript - 单击时增加图像尺寸和高度

html - 如何在文本对齐 :left? 时将 tbody 居中放置在表格中

javascript - Css 抖动文本翻译

javascript - 以 Angular 5 上传前的图像预览

javascript - audio.js 播放器无法在 IE 9 及更低版本中加载

javascript - 使用ajax和php将数据显示到html表时遇到问题

python - Django 处理可选的 url 参数

php - 如何将下拉菜单中的数据显示到文本输入中

javascript - PERMISSION_DENIED(为错误的数据库产品设置的规则)