前言
最近在做assignment的时候,想要在画面中加入一个填充渐变色的圆形,用来表示宇宙中的各个星球。
在度娘和Google搜索无果后,受到P5.js reference中的一个demo —— linear gradient 的启发,写了这个方法,实测效果还不错,因此记录一下~
demo 分析
// Constants
const Y_AXIS = 1;
const X_AXIS = 2;
let b1, b2, c1, c2;
function setup() {
createCanvas(710, 400);
// Define colors
b1 = color(255);
b2 = color(0);
c1 = color(204, 102, 0);
c2 = color(0, 102, 153);
noLoop();
}
function draw() {
// Background
setGradient(0, 0, width / 2, height, b1, b2, X_AXIS);
setGradient(width / 2, 0, width / 2, height, b2, b1, X_AXIS);
// Foreground
setGradient(50, 90, 540, 80, c1, c2, Y_AXIS);
setGradient(50, 190, 540, 80, c2, c1, X_AXIS);
}
function setGradient(x, y, w, h, c1, c2, axis) {
noFill();
if (axis === Y_AXIS) {
// Top to bottom gradient
for (let i = y; i <= y + h; i++) {
let inter = map(i, y, y + h, 0, 1);
let c = lerpColor(c1, c2, inter);
stroke(c);
line(x, i, x + w, i);
}
} else if (axis === X_AXIS) {
// Left to right gradient
for (let i = x; i <= x + w; i++) {
let inter = map(i, x, x + w, 0, 1);
let c = lerpColor(c1, c2, inter);
stroke(c);
line(i, y, i, y + h);
}
}
}
这是官网上的demo,我们重点看 setGradient的实现方法。
利用直线(line)密集的循环平铺,并且每次绘制 line之前,改变 lerpColor 中的间隔值 (inter),从而确保整个矩形区域内的颜色呈现渐变效果。当然,实例中也为我们提供垂直渐变和水平渐变两种方法,中心思想就是在计算 inter 值的时候,是用水平坐标还是垂直作为基准,并且每次循环递增。
let inter = map(i, y, y + h, 0, 1);
渐变圆实现方法
直接放代码
function drawAcircleWizLines(x,y,radius,from,to){
noFill();
let len = 0;
for(let i = 0; i <= radius; i++){
let inter = map(i, 0, radius, 0, 1);
let c = lerpColor(from, to, inter - 0.1);
stroke(c);
len = Math.sqrt(radius * radius - i * i);
line(x-len,y+i,x+len,y+i);
line(x-len,y-i,x+len,y-i)
}
}
基本思想:
已知半径,并且距离圆心的距离我们知道,那么利用勾股定理求出另一条直角边,从而算出直线的长度。
再得知直线长度之后,仿照demo中的方法,从下至上,平铺直线,从而绘制出渐变圆。
实际效果展示
图中的三个渐变圆便是我用此方法绘制的,效果还不错~