为一篇 HarmonyOS7 技术文章生成一张对比插图,主题是“普通背景 vs Canvas 渐变绘

为一篇 HarmonyOS7 Canvas 教程生成一张手绘流程框架图,主题是“Canvas 渐变从

为一篇 HarmonyOS7 技术教程生成一张手绘笔记风信息图,主题是“CanvasGradient

前言

很多界面一旦想做得更有质感,渐变色几乎绕不过去。问题是,很多人一提到渐变,就只会想到普通组件上的背景渐变。到了 Canvas 里,渐变的用法其实更灵活,因为它不是某个样式糖,而是一种真正可控的绘制资源。

这一页案例的价值,就在于它把 Canvas 渐变拆得很基础:水平渐变、垂直渐变、多色渐变。看起来不复杂,但足够把最核心的思路讲透。

这个案例适合学什么

如果你刚好处在“会画图形了,但画面还很素”的阶段,这一页非常适合继续往前走。它能帮你理解:

  • 渐变对象怎么创建
  • 颜色停靠点怎么加
  • 同样都是矩形,为什么换成渐变后观感会完全不同

说得直接一点,渐变是 Canvas 里把“能画”推进到“有设计感”的第一步。

完整代码

import { DEMO_BG_COLOR, DEMO_CARD_COLOR, DEMO_THEME_COLOR, DEMO_SUBTEXT_COLOR } from './types'

@Entry
@Component
struct CanvasGradientPalette {
  @State isShow: boolean = true
  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)

  build() {
    Column() {
      if (this.isShow) {
        Scroll() {
          Column({ space: 16 }) {
            Text('Canvas 渐变效果').fontSize(16).fontColor(DEMO_THEME_COLOR).fontWeight(FontWeight.Bold)

            Column() {
              Text('线性渐变效果').fontSize(13).fontColor('#4D96FF').margin({ bottom: 8 })
              Column() {
                Canvas(this.context)
                  .onReady(() => {
                    let gradient = this.context.createLinearGradient(0, 0, 380, 0)
                    gradient.addColorStop(0, '#4D96FF')
                    gradient.addColorStop(1, '#9B59B6')
                    this.context.fillStyle = gradient
                    this.context.fillRect(10, 10, 360, 50)

                    gradient = this.context.createLinearGradient(0, 70, 0, 120)
                    gradient.addColorStop(0, '#FF6B6B')
                    gradient.addColorStop(1, '#FFD93D')
                    this.context.fillStyle = gradient
                    this.context.fillRect(10, 70, 360, 50)

                    gradient = this.context.createLinearGradient(0, 130, 380, 130)
                    gradient.addColorStop(0, '#FF6B6B')
                    gradient.addColorStop(0.3, '#FFD93D')
                    gradient.addColorStop(0.5, '#6BCB77')
                    gradient.addColorStop(0.7, '#4D96FF')
                    gradient.addColorStop(1, '#9B59B6')
                    this.context.fillStyle = gradient
                    this.context.fillRect(10, 130, 360, 50)

                    this.context.font = '12px sans-serif'
                    this.context.fillStyle = '#999999'
                    this.context.fillText('createLinearGradient 线性渐变', 10, 200)
                    this.context.fillText('createRadialGradient 径向渐变 (圆心)', 10, 220)
                  })
                  .width('100%')
                  .height(240)
                  .backgroundColor('#F0F0F0')
                  .borderRadius(8)
              }
            }
            .backgroundColor(DEMO_CARD_COLOR)
            .padding(12)
            .borderRadius(12)

            Column({ space: 6 }) {
              Text('渐变 API 详解').fontSize(14).fontColor(DEMO_THEME_COLOR).fontWeight(FontWeight.Bold)
              Text('createLinearGradient(x0, y0, x1, y1) 线性渐变').fontSize(12).fontColor('#4D96FF')
              Text('createRadialGradient(x0, y0, r0, x1, y1, r1) 径向渐变').fontSize(12).fontColor('#9B59B6')
              Text('gradient.addColorStop(position, color) 添加色标').fontSize(12).fontColor('#333333')
              Text('position: 0.0 ~ 1.0 位置百分比').fontSize(12).fontColor('#333333')
              Text('可添加多个 addColorStop 实现多色渐变').fontSize(12).fontColor('#333333')
            }
            .width('100%')
            .backgroundColor('#E8F4FD')
            .padding(14)
            .borderRadius(12)
          }
          .width('100%')
        }
      }

      Text('CanvasGradientPalette - 线性与多色渐变')
        .fontSize(12)
        .fontColor(DEMO_SUBTEXT_COLOR)
        .margin({ top: 12 })
    }
    .width('100%')
    .height('100%')
    .backgroundColor(DEMO_BG_COLOR)
    .padding(16)
  }
}

渐变对象不是颜色值,而是一种可复用画刷

很多人第一次看这段代码时,会下意识把 gradient 当成“某种特殊颜色”。这种理解不完全错,但不够准确。

更准确的说法是,它是一种画刷配置。

比如:

let gradient = this.context.createLinearGradient(0, 0, 380, 0)
gradient.addColorStop(0, '#4D96FF')
gradient.addColorStop(1, '#9B59B6')
this.context.fillStyle = gradient

这里的 gradient 不是一个普通字符串颜色,而是一个带有方向和颜色分布规则的对象。你把它赋值给 fillStyle 后,后面的填充区域就会按这套规则上色。

createLinearGradient() 的四个参数到底在说什么

这句是全篇核心:

this.context.createLinearGradient(x0, y0, x1, y1)

它定义的是渐变轴线的起点和终点。你可以把它理解成“颜色沿着哪条线流动”。

案例里的第一个渐变:

createLinearGradient(0, 0, 380, 0)

起点和终点在同一水平线上,说明颜色是从左往右变化,所以它是水平渐变。

第二个:

createLinearGradient(0, 70, 0, 120)

x 不变,y 在变,所以它是从上到下变化的垂直渐变。

你如果把这个轴线概念理解了,后面做对角线渐变、局部渐变,都会很顺。

addColorStop() 决定渐变节奏

案例里用了多个 addColorStop()

gradient.addColorStop(0, '#FF6B6B')
gradient.addColorStop(0.3, '#FFD93D')
gradient.addColorStop(0.5, '#6BCB77')
gradient.addColorStop(0.7, '#4D96FF')
gradient.addColorStop(1, '#9B59B6')

这里最重要的不是颜色本身,而是前面的 position

它表示颜色停靠在渐变轴上的位置,范围是 01。也就是:

  • 0 表示起点
  • 1 表示终点
  • 中间值表示中间位置

这意味着你不只是能决定“有哪些颜色”,还能决定“哪一段颜色过渡更快,哪一段过渡更慢”。这就是渐变真正有设计空间的地方。

为什么多色渐变比双色更考验节制

案例最后一条彩虹渐变看上去挺吸睛,但真实业务里要谨慎用。

因为多色渐变信息密度高,适合用在演示画布、品牌视觉、海报装饰、数据强调上。如果你把它大面积铺在严肃的业务页面里,很容易显得吵。

这也是为什么前两条双色渐变更实用。它们更容易用在:

  • 卡片头图
  • 图表高亮区域
  • 活动氛围条
  • Banner 背景块

说到底,渐变不怕艳,怕乱。

渐变和普通填充的区别,不只是“更好看”

这一点很多人没意识到。

普通纯色填充,传递的是明确、稳定、功能型信息。渐变填充,除了功能,还会多一层方向感和情绪感。

比如水平蓝紫渐变,会天然带一点流动感和科技感;垂直红黄渐变,则更容易让人想到热度、警示或活跃氛围。

也就是说,渐变不仅在填颜色,也在传递视觉语义。

createRadialGradient() 为什么案例只提不演示

案例最后用文字提示了另一个 API:

createRadialGradient(x0, y0, r0, x1, y1, r1)

这类径向渐变更适合做光斑、按钮焦点、球体高光、发散式氛围层。它比线性渐变更有立体感,但也更容易用过头。

这页先不展开反而是对的。因为线性渐变已经够你覆盖大多数常规需求,先把这一类吃透,再碰径向渐变更稳。

常见坑先说透

第一个坑,是渐变轴线方向和填充区域不匹配,结果画出来颜色变化很怪。

第二个坑,是 addColorStop() 位置乱写,导致某一段颜色挤在一起,过渡不自然。

第三个坑,是渐变配色太多但没有层级主次,页面一眼看过去很花。

第四个坑,是忘了渐变对象要重新赋给 fillStyle,以为创建完就会自动生效。

这类能力适合用在哪

如果你做的是数据面板、插图卡片、品牌活动页、图形引导页,Canvas 渐变会非常好用。因为它可以让你在一块完全自控的画布里,把普通色块升级成更有表现力的视觉单元。

而且它和图形、文字、动画是能自然组合的,这点比纯样式配置更有延展性。

写在最后

渐变真正厉害的地方,不是让页面“看起来高级”,而是让你开始有能力控制画面的气质和节奏。Canvas 里的渐变尤其如此,因为它不是预设样式,而是你自己亲手调出来的。

把这页练明白,后面你再去做按钮高光、图表高亮、视觉海报,会明显多出一层设计自由度。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐