画一个角/弧,在画布上充满了光芒

Drawing a angle / arc, filled with a radiant in canvas?

本文关键字:光芒 一个      更新时间:2023-09-26

问题:我在画布上画一艘宇宙飞船。当我将鼠标悬停在x/y上时,我在画布上画一个弧,表示星际飞船的武器角度和范围(考虑到星际飞船当前的朝向)。目前确定的角度是用绿色绘制的,并延伸到武器范围值允许的范围内。

然而,我想用一个渐变来填充确定的弧线,以表明精度的下降(即渐变从绿色开始,移动到橙色,从距离飞船位置的角度越远就变成红色)。

然而,我不知道如何用渐变代替我的库存ctx.fill()。

var ship {
  loc: {x, y}, // lets say 100, 100
  facing: facing // lets say facing 0, i.e. straight right
  weapons: objects (range, startArc, endArc) // lets say 50, 300, 60 -> 120 degree angle, so -60 and +60 from facing (0/360)
}
        for (var i = 0; i < weapon.arc.length; i++){
            var p1 = getPointInDirection(weapon.range, weapon.arc[i][0] + angle, pos.x, pos.y);
            var p2 = getPointInDirection(weapon.range, weapon.arc[i][1] + angle, pos.x, pos.y)
            var dist = getDistance( {x: pos.x, y: pos.y}, p1);
            var rad1 = degreeToRadian(weapon.arc[i][0] + angle);
            var rad2 = degreeToRadian(weapon.arc[i][1] + angle);        
            fxCtx.beginPath();          
            fxCtx.moveTo(pos.x, pos.y);
            fxCtx.lineTo(p1.x, p1.y);   
            fxCtx.arc(pos.x, pos.y, dist, rad1, rad2, false);
            fxCtx.closePath();
            fxCtx.globalAlpha = 0.3;
            fxCtx.fillStyle = "green";
            fxCtx.fill();
            fxCtx.globalAlpha = 1;
}

是否可以将arc/globalalpha/fill替换为渐变流而不是固定的颜色,如果可以,如何替换?

谢谢

用渐变填充圆弧,动画只是为了好玩。

使用径向渐变,并将颜色停止设置为距离的一小部分。

createRadialGradient函数接受6个数字:梯度的位置x、y和起始半径以及位置x、y和结束半径。

颜色停止是通过渐变对象addColorStop函数添加的,该函数的值为渐变的内部0到外部1,颜色作为CSS颜色字符串。"#F00"或"rgba(200,0,0,0.5)"或"RED"

然后使用渐变作为填充样式。

var canvas = document.createElement("canvas");
document.body.appendChild(canvas);
var ctx = canvas.getContext("2d");
function update(time) {
  ctx.fillStyle = "black";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  // position of zones in fractions
  var posRed = 0.8  + Math.sin(time / 100) * 0.091; 
  var posOrange = 0.5 + Math.sin(time / 200) * 0.2;
  var posGreen = 0.1 + Math.sin(time / 300) * 0.1;
  var pos = {
    x: canvas.width / 2,
    y: canvas.height / 2
  };
  var dist = 100;
  var ang1 = 2 + Math.sin(time / 1000) * 0.5;
  var ang2 = 4 + Math.sin(time / 1300) * 0.5;
  var grad = ctx.createRadialGradient(pos.x, pos.y, 0, pos.x, pos.y, dist);
  grad.addColorStop(0, "#0A0");
  grad.addColorStop(posGreen, "#0A0");
  grad.addColorStop(posOrange, "#F80");
  grad.addColorStop(posRed, "#F00");
  grad.addColorStop(1, "#000");
  ctx.fillStyle = grad;
  ctx.beginPath();
  ctx.moveTo(pos.x, pos.y);
  ctx.arc(pos.x, pos.y, dist, ang1, ang2);
  ctx.fill();
  requestAnimationFrame(update);
}
requestAnimationFrame(update);