p5.js 渐变填充的实现方式

本文简介

p5.js 作为一款艺术类的 canvas 库,对颜色方面的支持是挺下功夫的,比如本文要介绍的渐变方法。


lerpColor()

要实现渐变效果,可以使用 lerpColor() 方法。

lerpColor 的作用是混合两个颜色以找到一个介于它们之间的颜色。

语法是这样的:

lerpColor(c1, c2, amt)
  • c1: 开始颜色
  • c2: 结束颜色
  • amt: 介于0和1的数字


举个例子,我想取出红色和蓝色中间的那个过渡颜色的值,可以这样写

file
function setup() {
  createCanvas(300, 300)
  noStroke()

  const red = color(255, 0, 0)
  const blue = color(0, 0, 255)

  const interim = lerpColor(red, blue, 0.5)

  fill(red)
  rect(10, 10, 30, 60)

  fill(interim)
  rect(40, 10, 30, 60)

  fill(blue)
  rect(70, 10, 30, 60)

  console.log(interim)
}

在这个例子中,我使用红色和蓝色作为基础色,使用 lerpColor() 方法获取这两个色的中间值,最终出来的效果是紫色。

我分别将这3个颜色填充到3个矩形里。

最后我在控制台输出这个过渡颜色:

file



线性渐变 1

基于上面这个特性,如果我们把矩形的数量增多,把矩形的宽度变小就能实现线性渐变的效果。

和前一个例子一样,从红色渐变到蓝色。我分20个方块慢慢渐变过去。

file
function setup() {
  createCanvas(400, 400)
  noStroke()
  // 创建渐变颜色
  let red = color(255, 0, 0) // 起始颜色(红色)
  let blue = color(0, 0, 255) // 终止颜色(蓝色)
  
  // 在矩形中应用渐变填充
  for (let i = 0; i < 20; i++) {
    let amt = i / 20 // 计算渐变百分比
    let c = lerpColor(red, blue, amt) // 计算渐变颜色
    fill(c)
    rect(i * 20, 0, 20, height)
  }
}

通过 for 循环20次,每次生成一个 20 * 400 的矩形,根据循环时的 i 值计算每个矩形应该出现的位置 rect(i * 20, 0, 20, height)

最最重要的是 amt ,每次循环都会计算本次循环生成的矩形的渐变颜色。可以自己在控制台输出 amt


如果理解了这个例子,我们再试试把每个矩形的宽度设为1,创建400个矩形实现渐变。

file
function setup() {
  createCanvas(400, 400)
  noStroke()
  // 创建渐变颜色
  let c1 = color(255, 0, 0) // 起始颜色(红色)
  let c2 = color(0, 0, 255) // 终止颜色(蓝色)
  
  // 在矩形中应用渐变填充
  for (let i = 0; i < width; i++) {
    let amt = map(i, 0, width - 1, 0, 1) // 计算渐变百分比
    let c = lerpColor(c1, c2, amt) // 计算渐变颜色
    fill(c)
    rect(i, 0, 1, height)
  }
}

这次看上去就更加丝滑了,工友们可以自己在控制台输出 amt ,看看每次循环时渐变百分比的变化。



线性渐变2

上面的渐变方法看上去有点笨拙,按照上面的逻辑我们如果要换个渐变角度,实现起来就更加困难了。

canvas 本身是支持渐变的,我在《Canvas 从进阶到退学》里有提到过。

p5.js 作为一款 canvas 库,很自觉的提供了 drawingContext 给开发者访问 canvas 上下文。

我们就可以通过这个方法去实现渐变。

比如我想让红蓝渐变从左上角往右下角过渡,可以这么写:

file
function setup() {
  createCanvas(400, 400)
  noStroke()
  // 创建线性渐变
  let gradient = drawingContext.createLinearGradient(
    0, 0, width, height // 渐变起始和终止坐标
  )
  gradient.addColorStop(0, 'red') // 渐变起始颜色
  gradient.addColorStop(1, 'blue') // 渐变终止颜色

  // 应用线性渐变填充
  drawingContext.fillStyle = gradient
  rect(0, 0, width, height)
}

这属于 canvas 的基础知识,还不太了解的工友可以查阅 《Canvas 从进阶到退学》渐变章节



径向渐变

要实现径向渐变,我们也同样用回前面说的『线性渐变2』的方法。

file
function setup() {
  createCanvas(400, 400)
  noStroke()
  // 创建径向渐变
  let gradient = drawingContext.createRadialGradient(
    width / 2, height / 2, 50, // 渐变中心坐标
    width / 2, height / 2, 200 // 渐变半径
  )
  gradient.addColorStop(0, 'red') // 渐变起始颜色
  gradient.addColorStop(1, 'blue') // 渐变终止颜色

  // 应用径向渐变填充
  drawingContext.fillStyle = gradient
  rect(0, 0, width, height)
}

这个同样是 canvas 的基础知识。

上面的代码用到 widthheightp5.js 提供的变量,这是画布的宽度和高度的意思。



小题目

《Canvas 从进阶到退学》 里提到 canvas 可以设置描边渐变,那在 p5.js 里应该如何实现描边渐变呢?



推荐阅读

👍《p5.js 光速入门》

👍《p5.js 使用npm安装p5.js后如何使用?》

👍《p5.js 3D图形-立方体》

👍《p5.js 开发点彩画派的绘画工具》

👍《p5.js画布操作实战:创建,绑定指定元素,动态调整大小,隐藏滚动条,删除画布》

👍《p5.js 视频播放指南》



点赞 + 关注 + 收藏 = 学会了
代码仓库

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容