鸿蒙Next一文了解Canvas绘制渐变色 原创

auhgnixgnahz
发布于 2025-9-4 22:21
浏览
0收藏

Canvas提供了线性渐变、径向渐变、圆锥渐变三种渐变效果,今天通过动画直观地看一下每个渐变的效果。

线性渐变

createLinearGradient(x0: number, y0: number, x1: number, y1: number)
x0,y0:起点的坐标,默认单位:vp
x1,y1:终点的坐标,默认单位:vp
设置渐变断点值:addColorStop(offset: number, color: string)
offset:渐变点距离起点的位置占总体长度的比例,可以理解为开始渐变的位置
演示效果:
鸿蒙Next一文了解Canvas绘制渐变色-鸿蒙开发者社区

径向渐变

createRadialGradient(x0: number, y0: number, r0: number, x1: number, y1: number, r1: number)
x0,y0, r0:起始圆的坐标和半径,默认单位:vp
x1,y1, r1:终点圆的坐标和半径,默认单位:vp
演示效果:
鸿蒙Next一文了解Canvas绘制渐变色-鸿蒙开发者社区

圆锥渐变

createConicGradient(startAngle: number, x: number, y: number)
startAngle: 从中心右侧水平开始,顺时针,单位:弧度
x,y:圆锥渐变的中心坐标,默认单位:vp
这里需要注意一下第一个参数是弧度0-2派
角度制和弧度制换算:1°=派/180
演示效果:
鸿蒙Next一文了解Canvas绘制渐变色-鸿蒙开发者社区
线性渐变源码

@Entry
@ComponentV2
struct CanvasLinearGradientTest{
  private settings: RenderingContextSettings = new RenderingContextSettings(true);
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
  @Local startY:number=20
  @Local endY:number=20
  @Local gradualStart:number=0
  @Local gradualEnd:number=0.5
  @Monitor('startY','endY','gradualStart','gradualEnd')
  draw(){
    this.context.reset()
    this.context.lineWidth = 0.5;
    this.context.strokeStyle = Color.Black;
    //绘制网格
    for (let i = 0; i < this.context.width / 20; i++) {
      this.context.beginPath()
      this.context.moveTo(i*20, 0)
      this.context.lineTo(i*20, this.context.height);
      this.context.stroke();
    }
    for (let i = 0; i < this.context.height / 20; i++) {
      this.context.beginPath()
      this.context.moveTo(0,i*20)
      this.context.lineTo(this.context.height,i*20);
      this.context.stroke();
    }

    let linearGradient = this.context.createLinearGradient(20,this.startY, 320,this.endY)
    linearGradient.addColorStop(this.gradualStart, '#ff0000')
    linearGradient.addColorStop(this.gradualEnd, '#ffffff')
    linearGradient.addColorStop(1.0, '#00ff00')
    this.context.fillStyle = linearGradient
    this.context.fillRect(20,20, 300, 300)

    this.context.lineWidth =3;
    //绘制 起点
    this.context.beginPath();
    this.context.arc(20, this.startY, 3, 0, 2*Math.PI);
    this.context.stroke();
    //绘制 终点
    this.context.beginPath();
    this.context.arc(320, this.endY, 3, 0, 2*Math.PI);
    this.context.stroke();

    this.context.textBaseline = 'middle';
    this.context.textAlign = 'center';
    this.context.font='30vp'
    this.context.fillStyle = '#ff0000';
    this.context.fillText('线性渐变', 200, 540);
  }
  build() {
    Stack({alignContent:Alignment.Top}){
      Canvas(this.context)
        .width('100%')
        .height('100%')
        .onReady(()=>{
          this.draw()
        })
      Column(){
        Row({ space: 10 }) {
          Text('起点Y轴坐标:' + this.startY)
          Slider({
            value: this.startY,
            min: 20,
            max: 320,
            style: SliderStyle.OutSet
          }).width('50%')
            .onChange((value: number) => {
              this.startY = value;
            })
        }
        Row({ space: 10 }) {
          Text('终点Y轴坐标:' + this.endY)
          Slider({
            value: this.endY,
            min: 20,
            max: 320,
            style: SliderStyle.OutSet
          }).width('50%')
            .onChange((value: number) => {
              this.endY = value;
            })
        }
        Row({ space: 10 }) {
          Text('红色占比:' + this.gradualStart)
          Slider({
            value: this.gradualStart,
            min: 0,
            max: 0.5,
            step:0.1,
            style: SliderStyle.OutSet
          }).width('50%')
            .onChange((value: number) => {
              this.gradualStart = Number.parseFloat(value.toFixed(1));
            })
        }
        Row({ space: 10 }) {
          Text('白色占比:' + this.gradualEnd)
          Slider({
            value: this.gradualEnd,
            min: this.gradualStart,
            max: 1,
            step:0.1,
            style: SliderStyle.OutSet
          }).width('50%')
            .onChange((value: number) => {
              this.gradualEnd = Number.parseFloat(value.toFixed(1));
            })
        }
      }
      .backgroundColor(Color.Gray)
      .margin({top:340})
    }
  }
}

径向渐变和圆锥渐变实现方式和线性渐变大同小异,感兴趣可以复制上面代码运行起来玩一玩。

原创不易,感谢您的认可!如果您喜欢这篇文章,请点赞支持,您的鼓励是我前进的动力!

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
收藏
回复
举报
回复
    相关推荐