HarmonyOS7 渐变色不是只会写背景:CanvasGradientPalette 实战解析
文章目录



前言
很多界面一旦想做得更有质感,渐变色几乎绕不过去。问题是,很多人一提到渐变,就只会想到普通组件上的背景渐变。到了 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。
它表示颜色停靠在渐变轴上的位置,范围是 0 到 1。也就是:
0表示起点1表示终点- 中间值表示中间位置
这意味着你不只是能决定“有哪些颜色”,还能决定“哪一段颜色过渡更快,哪一段过渡更慢”。这就是渐变真正有设计空间的地方。
为什么多色渐变比双色更考验节制
案例最后一条彩虹渐变看上去挺吸睛,但真实业务里要谨慎用。
因为多色渐变信息密度高,适合用在演示画布、品牌视觉、海报装饰、数据强调上。如果你把它大面积铺在严肃的业务页面里,很容易显得吵。
这也是为什么前两条双色渐变更实用。它们更容易用在:
- 卡片头图
- 图表高亮区域
- 活动氛围条
- Banner 背景块
说到底,渐变不怕艳,怕乱。
渐变和普通填充的区别,不只是“更好看”
这一点很多人没意识到。
普通纯色填充,传递的是明确、稳定、功能型信息。渐变填充,除了功能,还会多一层方向感和情绪感。
比如水平蓝紫渐变,会天然带一点流动感和科技感;垂直红黄渐变,则更容易让人想到热度、警示或活跃氛围。
也就是说,渐变不仅在填颜色,也在传递视觉语义。
createRadialGradient() 为什么案例只提不演示
案例最后用文字提示了另一个 API:
createRadialGradient(x0, y0, r0, x1, y1, r1)
这类径向渐变更适合做光斑、按钮焦点、球体高光、发散式氛围层。它比线性渐变更有立体感,但也更容易用过头。
这页先不展开反而是对的。因为线性渐变已经够你覆盖大多数常规需求,先把这一类吃透,再碰径向渐变更稳。
常见坑先说透
第一个坑,是渐变轴线方向和填充区域不匹配,结果画出来颜色变化很怪。
第二个坑,是 addColorStop() 位置乱写,导致某一段颜色挤在一起,过渡不自然。
第三个坑,是渐变配色太多但没有层级主次,页面一眼看过去很花。
第四个坑,是忘了渐变对象要重新赋给 fillStyle,以为创建完就会自动生效。
这类能力适合用在哪
如果你做的是数据面板、插图卡片、品牌活动页、图形引导页,Canvas 渐变会非常好用。因为它可以让你在一块完全自控的画布里,把普通色块升级成更有表现力的视觉单元。
而且它和图形、文字、动画是能自然组合的,这点比纯样式配置更有延展性。
写在最后
渐变真正厉害的地方,不是让页面“看起来高级”,而是让你开始有能力控制画面的气质和节奏。Canvas 里的渐变尤其如此,因为它不是预设样式,而是你自己亲手调出来的。
把这页练明白,后面你再去做按钮高光、图表高亮、视觉海报,会明显多出一层设计自由度。
更多推荐


所有评论(0)