点赞 + 关注 + 收藏 = 学会了
在 p5.js 中,arc()
函数用于绘制圆弧,它是创建各种圆形图形和动画的基础。圆弧本质上是椭圆的一部分,由中心点、宽度、高度、起始角度和结束角度等参数定义。通过灵活运用 arc()
函数可以轻松创建饼图、仪表盘、时钟等常见 UI 组件,以及各种创意图形效果。
arc() 的基础语法
基础语法
arc()
函数的完整语法如下:
js
arc(x, y, w, h, start, stop, [mode], [detail])
核心参数解释:
-
x, y:圆弧所在椭圆的中心点坐标
-
w, h:椭圆的宽度和高度,如果两者相等,则绘制的是圆形的一部分
-
start, stop:圆弧的起始角度和结束角度,默认以弧度(radians)为单位
可选参数:
-
mode :定义圆弧的填充样式,可选值为
OPEN
(开放式半圆)、CHORD
(封闭式半圆)或PIE
(闭合饼图) -
detail:仅在 WebGL 模式下使用,指定组成圆弧周长的顶点数量,默认值为 25
角度单位与转换
在 p5.js 中,角度可以使用弧度或角度两种单位表示:
-
默认单位是弧度:0 弧度指向正右方(3 点钟方向),正角度按顺时针方向增加
-
使用角度单位 :可以通过
angleMode(DEGREES)
函数将角度单位设置为角度
两种单位之间的转换关系:
-
360 度 = 2π 弧度
-
180 度 = π 弧度
-
90 度 = π/2 弧度
p5.js 提供了两个辅助函数用于单位转换:
-
radians(degrees)
:将角度转换为弧度 -
degrees(radians)
:将弧度转换为角度
举个例子(基础示例)
举个例子讲解一下如何使用 arc()
函数绘制不同角度的圆弧。

js
function setup() {
createCanvas(400, 400);
angleMode(DEGREES); // 使用角度单位
}
function draw() {
background(220);
// 绘制不同角度的圆弧
arc(100, 100, 100, 100, 0, 90); // 90度圆弧
arc(250, 100, 100, 100, 0, 180); // 180度圆弧
arc(100, 250, 100, 100, 0, 270); // 270度圆弧
arc(250, 250, 100, 100, 0, 360); // 360度圆弧(整圆)
}
这段代码会在画布上绘制四个不同角度的圆弧,从 90 度到 360 度不等。注意,当角度为 360 度时,实际上绘制的是一个完整的圆形。
三种圆弧模式:OPEN、CHORD 与 PIE
arc()
函数的第七个参数mode决定了圆弧的填充方式,有三种可选值:
-
OPEN(默认值):仅绘制圆弧本身,不填充任何区域
-
CHORD:绘制圆弧并连接两端点形成闭合的半圆形区域
-
PIE:绘制圆弧并连接两端点与中心点形成闭合的扇形区域
这三种模式不需要手动定义,p5.js 已经在全局范围内定义好了这些常量。
举个例子:

js
function setup() {
createCanvas(400, 200);
angleMode(DEGREES);
}
function draw() {
background(220);
// 绘制不同模式的圆弧
arc(100, 100, 100, 100, 0, 270, OPEN);
arc(220, 100, 100, 100, 0, 270, CHORD);
arc(340, 100, 100, 100, 0, 270, PIE);
}
这段代码会在画布上绘制三个 270 度的圆弧,分别展示 OPEN
、CHORD
和 PIE
三种模式的效果。可以明显看到,OPEN
模式只绘制弧线,CHORD
模式连接两端点形成闭合区域,而 PIE
模式则从两端点连接到中心点形成扇形。
如何选择合适的模式
选择圆弧模式时,应考虑以下因素:
-
视觉效果需求 :需要纯弧线效果时选择
OPEN
,需要闭合区域时选择CHORD
或PIE
-
应用场景 :饼图通常使用
PIE
模式,仪表盘可能使用CHORD
模式,而简单装饰线条可能使用OPEN
模式 -
填充与描边需求:不同模式对填充和描边的处理方式不同,需要根据设计需求选择
值得注意的是,arc()
函数绘制的默认是填充的扇形区域。如果想要获取纯圆弧(没有填充区域),可以使用 noFill()
函数拒绝 arc()
函数的填充。
做几个小demo玩玩
简易数字时钟
在这个示例中,我将使用 arc()
函数创建一个简单的数字时钟,显示当前的小时、分钟和秒数。

js
let hours, minutes, seconds;
function setup() {
createCanvas(400, 400);
angleMode(DEGREES); // 使用角度单位
}
function draw() {
background(220);
// 获取当前时间
let now = new Date();
hours = now.getHours();
minutes = now.getMinutes();
seconds = now.getSeconds();
// 绘制时钟边框
stroke(0);
strokeWeight(2);
noFill();
arc(width/2, height/2, 300, 300, 0, 360);
// 绘制小时刻度
strokeWeight(2);
for (let i = 0; i < 12; i++) {
let angle = 90 - i * 30;
let x1 = width/2 + 140 * cos(radians(angle));
let y1 = height/2 + 140 * sin(radians(angle));
let x2 = width/2 + 160 * cos(radians(angle));
let y2 = height/2 + 160 * sin(radians(angle));
line(x1, y1, x2, y2);
}
// 绘制分钟刻度
strokeWeight(1);
for (let i = 0; i < 60; i++) {
let angle = 90 - i * 6;
let x1 = width/2 + 150 * cos(radians(angle));
let y1 = height/2 + 150 * sin(radians(angle));
let x2 = width/2 + 160 * cos(radians(angle));
let y2 = height/2 + 160 * sin(radians(angle));
line(x1, y1, x2, y2);
}
// 绘制小时指针
let hourAngle = 90 - (hours % 12) * 30 - minutes * 0.5;
let hourLength = 80;
let hx = width/2 + hourLength * cos(radians(hourAngle));
let hy = height/2 + hourLength * sin(radians(hourAngle));
line(width/2, height/2, hx, hy);
// 绘制分钟指针
let minuteAngle = 90 - minutes * 6;
let minuteLength = 120;
let mx = width/2 + minuteLength * cos(radians(minuteAngle));
let my = height/2 + minuteLength * sin(radians(minuteAngle));
line(width/2, height/2, mx, my);
// 绘制秒针
stroke(255, 0, 0);
let secondAngle = 90 - seconds * 6;
let secondLength = 140;
let sx = width/2 + secondLength * cos(radians(secondAngle));
let sy = height/2 + secondLength * sin(radians(secondAngle));
line(width/2, height/2, sx, sy);
// 显示当前时间文本
noStroke();
fill(0);
textSize(24);
text(hours + ":" + nf(minutes, 2, 0) + ":" + nf(seconds, 2, 0), 50, 50);
}
关键点解析:
-
获取当前时间:使用Date()对象获取当前的小时、分钟和秒数
-
角度计算:根据时间值计算指针的旋转角度,注意将角度转换为 p5.js 使用的坐标系(0 度指向正上方)
-
刻度绘制:使用循环绘制小时和分钟刻度,每个小时刻度间隔 30 度,每个分钟刻度间隔 6 度
-
指针绘制:根据计算的角度和长度绘制小时、分钟和秒针,注意秒针使用红色以区分
-
时间文本显示:使用text()函数在画布左上角显示当前时间
饼图
在这个示例中,我将创建一个简单的饼图,展示不同类别数据的比例。

js
let data = [30, 10, 45, 35, 60, 38, 75, 67]; // 示例数据
let total = 0;
let lastAngle = 0;
function setup() {
createCanvas(720, 400);
angleMode(DEGREES); // 使用角度单位
noStroke(); // 不绘制边框
total = data.reduce((a, b) => a + b, 0); // 计算数据总和
}
function draw() {
background(100);
pieChart(300, data); // 调用饼图绘制函数
}
function pieChart(diameter, data) {
lastAngle = 0; // 重置起始角度
for (let i = 0; i < data.length; i++) {
// 设置圆弧的灰度值,map函数将数据映射到0-255的灰度范围
let gray = map(i, 0, data.length, 0, 255);
fill(gray);
// 计算当前数据点的角度范围
let startAngle = lastAngle;
let endAngle = lastAngle + (data[i] / total) * 360;
// 绘制圆弧
arc(
width / 2,
height / 2,
diameter,
diameter,
startAngle,
endAngle,
PIE // 使用PIE模式创建扇形
);
lastAngle = endAngle; // 更新起始角度为下一个数据点做准备
}
}
关键点解析:
-
数据准备:定义示例数据数组data,并计算数据总和total
-
颜色设置:使用map()函数将数据索引映射到 0-255 的灰度范围,实现渐变效果
-
角度计算:根据每个数据点的值与总和的比例计算对应的角度范围
-
圆弧绘制:使用PIE模式绘制每个数据点对应的扇形,形成完整的饼图
这个饼图示例可以通过添加标签、交互效果或动态数据更新来进一步增强功能。
描边效果
在 p5.js 中,我们可以通过以下函数定制圆弧的描边效果:
-
stroke(color):设置描边颜色
-
strokeWeight(weight):设置描边宽度
-
strokeCap(cap):设置描边端点样式(可选值:BUTT, ROUND, SQUARE)
-
strokeJoin(join):设置描边转角样式(可选值:MITER, ROUND, BEVEL)
以下示例展示了如何定制圆弧的描边效果:

js
function setup() {
createCanvas(400, 200);
angleMode(DEGREES);
}
function draw() {
background(220);
// 示例1:粗红色描边
stroke(255, 0, 0);
strokeWeight(10);
arc(100, 100, 100, 100, 0, 270);
// 示例2:带圆角端点的描边
stroke(0, 255, 0);
strokeWeight(10);
strokeCap(ROUND);
arc(220, 100, 100, 100, 0, 270);
// 示例3:带阴影效果的描边
stroke(0, 0, 255);
strokeWeight(15);
strokeCap(SQUARE);
arc(340, 100, 100, 100, 0, 270);
// 恢复默认设置
noStroke();
}
关键点解析:
-
颜色设置:使用stroke()函数设置不同颜色的描边
-
宽度设置:使用strokeWeight()函数调整描边粗细
-
端点样式:使用strokeCap()函数设置描边端点的样式(圆角效果特别适合圆弧)
-
阴影效果:通过增加描边宽度并偏移绘制位置可以创建简单的阴影效果
填充效果
在 p5.js 中,我们可以通过以下函数定制圆弧的填充效果:
-
fill(color):设置填充颜色
-
noFill():禁用填充效果
-
colorMode(mode):设置颜色模式(RGB、HSB 等)
-
alpha():设置颜色透明度
以下示例展示了如何定制圆弧的填充效果:

js
function setup() {
createCanvas(400, 200);
angleMode(DEGREES);
colorMode(HSB, 360, 100, 100); // 使用HSB颜色模式
}
function draw() {
background(220);
// 示例1:单色填充
fill(120, 100, 100); // 绿色
arc(100, 100, 100, 100, 0, 270);
// 示例2:渐变填充
noFill();
stroke(0, 0, 100);
strokeWeight(10);
for (let i = 0; i < 360; i += 10) {
fill(i, 100, 100);
arc(220, 100, 100, 100, i, i+10);
}
// 示例3:透明填充
fill(240, 100, 100, 50); // 半透明蓝色
arc(340, 100, 100, 100, 0, 270);
// 恢复默认设置
noFill();
stroke();
}
关键点解析:
-
颜色模式:使用colorMode()函数切换到 HSB 模式,方便创建渐变效果
-
单色填充:直接使用fill()函数设置单一填充颜色
-
渐变填充:通过循环绘制多个小角度的圆弧,每个使用不同的色相值实现渐变效果
-
透明度设置:在fill()函数中添加第四个参数(0-100)设置透明度
旋转圆弧
在 p5.js 中创建圆弧动画非常简单,主要通过以下方法实现:
-
**draw()**函数:每秒自动执行约 60 次,用于更新动画帧
-
变量控制:使用变量控制圆弧的参数(如位置、大小、角度等)
-
frameRate(fps):设置动画帧率(可选)
-
millis():获取当前时间(毫秒),用于精确控制动画时间
圆弧动画效果示例:

js
let angle = 0;
function setup() {
createCanvas(400, 400);
angleMode(DEGREES);
}
function draw() {
background(220);
// 绘制旋转的红色圆弧
stroke(255, 0, 0);
strokeWeight(10);
arc(width/2, height/2, 300, 300, angle, angle + 90);
// 更新角度值,实现旋转效果
angle += 2; // 调整这个值可以改变旋转速度
// 恢复默认设置
noStroke();
}
关键点解析:
-
角度变量 :使用
angle
变量控制圆弧的起始角度 -
角度更新 :在每次
draw()
调用时增加angle值,实现旋转效果 -
速度控制:通过调整每次增加的角度值(这里是 2 度)控制旋转速度
弧度与角度的转换技巧
在 p5.js 中,arc()函数默认使用弧度作为角度单位,但我们通常更习惯使用角度。以下是一些转换技巧:
-
角度转弧度 :使用
radians(degrees)
函数将角度转换为弧度 -
弧度转角度 :使用
degrees(radians)
函数将弧度转换为角度 -
设置角度单位 :使用
angleMode(DEGREES)
函数将全局角度单位设置为角度,这样arc()
函数就可以直接使用角度值 -
常见角度值 :记住一些常用角度的弧度值,如 90 度 = PI/2,180 度 = PI,270 度 = 3PI/2,360 度 = 2PI
圆弧绘制的常见问题与解决方案
在使用 arc()
函数时,可能会遇到以下问题:
-
arc () 函数中的 bug :当
start_angle == end_angle
时,可能会出现意外绘制效果。例如,当start_angle == end_angle == -PI/2
时会绘制一个半圆,这不符合预期。解决方案是避免start_angle
和end_angle
相等。 -
起始角度的位置 :在 p5.js 中,0 弧度(或 0 度,如果使用
angleMode(DEGREES)
)指向正右方(3 点钟方向),而不是数学上的正上方。这可能导致方向与预期不符。 -
描边宽度的影响 :较宽的描边会使圆弧看起来比实际大。这是因为描边会向路径的两侧扩展。如果需要精确控制大小,可以考虑将arc()的尺寸适当减小,或者使用
shapeMode()
函数调整坐标系。 -
浮点精度问题 :在进行角度计算时,尤其是涉及到除法和循环时,可能会遇到浮点精度问题。建议使用
nf()
函数(如nf(value, 2, 0)
)来格式化显示的数值,避免显示过多的小数位。
以上就是本文的全部内容啦,如果想了解更多 p5.js 的玩法可以关注 《P5.js中文教程》
点赞 + 关注 + 收藏 = 学会了