【问题标题】:Implementing HTML5 canvas gradients in React在 React 中实现 HTML5 画布渐变
【发布时间】:2019-03-05 15:51:23
【问题描述】:

我正在尝试创建一个应用程序,让您可以创建具有两种不同颜色的背景渐变,我正在使用 React。渐变的第一种颜色看起来应该是这样,但渐变的第二种颜色更像是纯色,带有锯齿状的边框。这是一张图片来演示:

我的目标是获得与此类似的东西:

颜色混合的地方。

我指的是MDN docs,并且弄乱了半径和x、y 属性。我正在根据父组件的 prop 更改更改画布,这是我的代码:

import React, { Component } from "react";

class Canvas extends Component {
  componentDidMount() {
    const { gradientOne, gradientTwo } = this.props.canvasState.backgroundColor;
    this.ctx = this.canvas.getContext("2d");
    this.radialGradient = this.ctx.createRadialGradient(
      0,
      0,
      300,
      260,
      160,
      100
    );

    this.ctx.fillStyle = this.radialGradient;
    this.ctx.rect(0, 0, this.canvas.width, this.canvas.height);
    this.radialGradient.addColorStop(0, gradientOne);
    this.radialGradient.addColorStop(1, gradientTwo);
    this.ctx.fill();
  }

  componentDidUpdate(prevProps, prevState) {
    const { gradientOne, gradientTwo } = this.props.canvasState.backgroundColor;
    if (prevProps.canvasState.backgroundColor.gradientOne !== gradientOne) {
      this.ctx.fillStyle = this.radialGradient;
      this.radialGradient.addColorStop(0, gradientOne);
      this.ctx.fill();
    } else if (
      prevProps.canvasState.backgroundColor.gradientTwo !== gradientTwo
    ) {
      this.ctx.fillStyle = this.radialGradient;
      this.radialGradient.addColorStop(1, gradientTwo);
      this.ctx.fill();
    }
  }
  render() {
    return (
      <main className="canvasContainer">
        <canvas ref={ref => (this.canvas = ref)} id="canvas">
          YOUR BROWSER DOESN'T SUPPORT THIS FEATURE :(
        </canvas>
      </main>
    );
  }
}

export default Canvas;

感谢您的帮助!

【问题讨论】:

    标签: javascript reactjs html canvas html5-canvas


    【解决方案1】:

    CanvasGradient 的色标(无论是线性的还是径向的)无法修改或移除。
    当您在与前一个相同的索引处添加新的色标时,它会立即放置在前一个色标之后。所以不是只有两个色标,而是四个。

    这意味着如果你有一个像这样的原始渐变

     <-red -------------------------------------------- green->
    

    如果您在位置01 添加两个新的色标blueyellow,您将拥有类似

     <-red[blue -------------------------------- green]yellow->
    

    也就是说,红色和蓝色之间没有渐变,黄色和绿色之间也没有渐变:

    const ctx = canvas.getContext('2d');
    ctx.strokeStyle = 'white';
    // an horizontal gradient
    // 0 is at pixel 50, and 1 at pixel 250 on the x axis
    const grad = ctx.createLinearGradient(50,0,250,0);
    grad.addColorStop(0, 'red');
    grad.addColorStop(1, 'green');
    ctx.fillStyle = grad;
    // top is two color stops version
    ctx.fillRect(0,0,300,70);
    
    // bottom is four color stops version
    grad.addColorStop(0, 'blue');
    grad.addColorStop(1, 'yellow');
    ctx.fillStyle = grad;
    ctx.fillRect(0,80,300,70);
    
    //  mark color stops
    ctx.moveTo(49.5,0);
    ctx.lineTo(49.5,150);
    ctx.moveTo(249.5,0);
    ctx.lineTo(249.5,150);
    ctx.stroke();
    canvas { border: 1px solid };
    &lt;canvas id="canvas"&gt;&lt;/canvas&gt;

    这就是您在代码中所做的,因为您在 componentDidMount 中添加了两个色标,然后在 componentDidUpdate 中添加更多。

    为避免这种情况,只需在 componentDidUpdate 中覆盖您的 gradient 属性,以便您每次都以新的渐变开始。

    const ctx = canvas.getContext('2d');
    let radialGradient;
    function didMount() {
      radialGradient = ctx.createRadialGradient(
        0,0,300,
        260,160,100
       );
      radialGradient.addColorStop(0, c1.value);
      radialGradient.addColorStop(1, c2.value);
      ctx.fillStyle = radialGradient;
      ctx.fillRect(0,0,canvas.width,canvas.height);
    }
    function didUpdate() {
      // reset radialGradient to a new one
      radialGradient = ctx.createRadialGradient(
        0,0,300,
        260,160,100
       );
      radialGradient.addColorStop(0, c1.value);
      radialGradient.addColorStop(1, c2.value);
      ctx.fillStyle = radialGradient;
      ctx.fillRect(0,0,canvas.width,canvas.height);
    }
    
    didMount();
    c1.oninput = c2.oninput = didUpdate;
    canvas { border: 1px solid };
    <input id="c1" type="color" value="#22CC22">
    <input id="c2" type="color" value="#FF2222">
    <canvas id="canvas"></canvas>

    【讨论】:

      猜你喜欢
      • 2019-01-26
      • 1970-01-01
      • 2014-03-13
      • 2011-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-21
      • 1970-01-01
      相关资源
      最近更新 更多