计算画布渐变的旋转角度

10

我正在尝试使用渐变填充画布的某个区域,但我想能够设置渐变的角度。

我知道可以通过在创建渐变时使用不同的值(ctx.createLinearGradient(x1, y1, x2, y2))来实现,就像这里所示:

Gradient creation graphic

但我似乎无法理解需要将角度(弧度)转换为产生相同角度的渐变大小所需的数学公式(我所指的角度是垂直于渐变方向的角度,因此0弧度的角度会显示在右侧的渐变)

简而言之,如何将弧度数量转换为X和Y形状?

$(document).ready(function(){
    var canvas = document.getElementById("test");
    var ctx = canvas.getContext("2d");
    var angle = 0.5;
    
    ctx.beginPath();
    ctx.moveTo(100, 100);
    ctx.arc(100, 100, 100, 0, -angle, true);
    ctx.lineTo(100, 100);
    ctx.closePath();

    // Convert angle into coordinates to tilt the grad
    // grad should be perpendicular to the top edge of the arc
    var grad = ctx.createLinearGradient(0, 0, 0, 100);
    
    grad.addColorStop(0, "rgba(0,0,0,0)");
    grad.addColorStop(1, "rgba(0,0,0,0.8)");
    ctx.fillStyle = grad;
    ctx.fill();
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="test" width="500" height="500"></canvas>

(这样没人会浪费时间:我特意不想在这种情况下使用 context.rotate()


嘿@DBS,你设法让它工作了吗?我正在尝试使用Canvas,特别是Konva,但似乎无法复制CSS线性渐变的效果。如果你有任何想法,请告诉我。这里是codesandbox,如果您想查看→https://codesandbox.io/s/linear-gradient-in-react-konva-cpgrk?file=/src/App.tsx - deadcoder0904
你能否查看我的问题,它与此非常相似 → https://dev59.com/AcDqa4cB1Zd3GeqPfYUU - deadcoder0904
1个回答

13

您可以使用cos和sin的角度来定义给出梯度的线。接下来要做的就是给出长度:

var length = 100, angle = 0;
ctx.createLinearGradient(x, y, x + Math.cos(angle) * length, y + Math.sin(angle) * length);

渐变将沿给定的线(垂直)呈现。

并未说明,但如果您需要根据角度和框计算线的长度,则可以使用正弦定理来进行计算(以这种方式使用)。下面的示例使用了固定半径。您还可以通过计算斜边从(x1,x2)的最大长度来计算长度:length = Math.sqrt(diffX*diffX + diffY*diffY);

示例

var ctx = c.getContext("2d"),
    x1 = 150, y1 = 150, x2, y2, angle,
    length = 150;

render();
cAngle.oninput = render;

function render() {
  
  angle = +cAngle.value / 180 * Math.PI;

  // calculate gradient line based on angle
  x2 = x1 + Math.cos(angle) * length;
  y2 = y1 + Math.sin(angle) * length;
  
  // create and render gradient
  ctx.fillStyle = ctx.createLinearGradient(x1, y1, x2, y2);
  ctx.fillStyle.addColorStop(0, "#fff");
  ctx.fillStyle.addColorStop(1, "#07f");
  ctx.fillRect(0, 0, 300, 300);
  
  // show definition line
  ctx.beginPath();
  ctx.moveTo(x1, y1);
  ctx.lineTo(x2, y2);
  ctx.stroke();
}
<label>Angle: <input id=cAngle max=359 type=range value=0></label><br>
<canvas id=c height=300></canvas>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接