12 个稳定版本
2.3.1 | 2024 年 6 月 27 日 |
---|---|
2.3.0 | 2024 年 4 月 19 日 |
2.1.3 | 2024 年 2 月 27 日 |
1.2.0 | 2024 年 2 月 19 日 |
#56 in 图形 API
每月 39 次下载
94KB
2K SLoC
📚 目录
👀 尝试它
README 中使用的所有图像都可以在 examples
文件夹中找到,无需编程即可运行!
git clone https://github.com/nidhoggfgg/rsille.git
cd rsille
cargo run --example cube
这将生成一个旋转的立方体。
要获取更多示例或尝试生成有趣的图案,您可以使用 cargo run --example
,您将找到所有无需编程即可运行的示例。
当然,还有更多示例,例如 bad-apple 等。您可以通过查看用法来了解如何使用此库。
🔧 安装
这是一个 Rust 库,所以您只需要将以下代码添加到您的 Cargo.toml 中即可使用它
[dependencies]
rsille = "2.1.0"
🚀 使用
由于空间限制,这里只提供了常用 API 和通用使用方法。
有关详细 API,请访问 doc.rs。
基础
最基本的函数是 set
。
use rsille::Canvas;
fn main() {
let mut c = Canvas::new();
for x in -360..360 {
let x = x as f64;
c.set(x / 10.0, x.to_radians().sin() * 10.0);
}
c.print();
}
为什么是 (x / 10.0, x.to_radians().sin() * 10.0) 而不是 (x, x.sin())?您可以尝试添加、减去、乘以和除以来改变绘制的坐标。一个小提示:⠿
包含 8 个点。如果您真的不理解或想知道为什么,可以直接在您的算法中使用 (x, y)。我可能以后会写一篇文章关于盲文代码。
set
的相反操作是 unset
,它会擦除已设置的点。
另一个有用的方法是 toggle
,它会擦除已设置的点并设置尚未设置的点。
use rsille::Canvas;
fn main() {
let mut c = Canvas::new();
for x in (0..360).step_by(4) {
let x = x as f64;
c.set(x / 4.0, x.to_radians().sin() * 30.0);
}
for x in 0..=30 {
for y in 0..=30 {
c.toggle(x, y);
c.toggle(x + 30, y - 30);
c.toggle(x + 60, y);
}
}
c.print();
}
这个例子稍微长一点,让我们来解释一下。
(0..360).step_by(4)
遍历区间[0, π)内的x,并且使用step_by(4)
进行下采样以使线条更细(值太低可能会导致不精确)。- 第一个
for
循环用于绘制f(x) = sin(x)的图形。为了使其看起来更好,对x和y都应用了某种缩放。 - 第二个
for
循环用于创建那些toggle
块,每个块的大小为31x31。
在toggle
中,没有使用f64
,因为所有方法都支持泛型,可以接受各种数字类型!然而,仍然强烈建议使用f64
以获得更高的精度。
龟形图
在Python中,有一个有趣的库叫做turtle。它允许初学者在开始使用Python时体验编程的乐趣。这个库也实现了turtle中的大多数方法。
use rsille::{extra::Turtle, Canvas};
fn main() {
let mut canvas = Canvas::new();
let mut t = Turtle::new();
for _ in 0..5 {
t.forward(50);
t.right(144);
}
canvas.paint(&t, 0, 0).unwrap();
canvas.print();
}
paint
方法中的两个0不是固定的;它们将绘制对象放置在(0, 0)。这是任意的,但始终在(0, 0)处绘制单个对象是个好主意。
不再介绍turtle;您可以直接复制Python代码并稍作修改后使用。
3D 对象
这个库还支持3D对象,并提供方便的方法来轻松构建对象。
use rsille::{extra::Object3D, Animation};
fn main() {
let mut anime = Animation::new();
let cube = Object3D::cube(30);
anime.push(
cube,
|cube| {
cube.rotate((1.0, 2.0, 3.0));
false
},
(0, 0),
);
anime.run();
}
在这里,使用Animation
创建动画,这些动画也是内部支持的。您可以查看动画以获取更多信息。
Object3D
主要有两个有用的方法:rotate
用于旋转对象,zoom
用于缩放对象。
康威的生命游戏
康威的生命游戏非常有趣,因此它也是库的一部分。
use rsille::{extra::LifeGame, Animation};
fn main() {
let mut anime = Animation::new();
let lg = LifeGame::from(r#"x = 47, y = 47, rule = B3/S23
18bo$18b3o$21bo$20b2o$$32b2o$32b2o$26bobo$28bo$$22b3o$15b2o5bo2bo$15b2o
2o5bo3bo$5b2o19bo$5b2o15bo3bo$22bo2bo8b2o$22b3o9b2o$$7b2o36b2o$45bo$7b
o4b3o28bobo$11bo3bo27b2o$10bo5bo13b3ob3o$10bo5bo13bo5bo$10b3ob3o13bo5b
o$2b2o27bo3bo$bobo28b3o4bo$bo$2o36b2o$$11b2o9b3o$11b2o8bo2bo$20bo3bo
15b2o$20bo19b2o$20bo3bo5b2o$21bo2bo5b2o$22b3o$$18bo$18bobo$13b2o$13b2o
$$25b2o$25bo$26b3o$28bo!"#).unwrap();
anime.push(
lg,
|lg| lg.update(),
(0, 0),
);
anime.run();
}
在这里,仍然使用Animation
,并解析康威的生命游戏的rle
文件。解析rle
文件所需的一切都已经写入Lifegame
内部,没有任何额外的依赖项,并且解析代码非常轻量。
图像
使用盲文代码绘制图像也是一个不错的选择。然而,用于解析images
的图像库有点大,因此默认不启用。要使用它,请在您的Cargo.toml中添加以下内容
[dependencies]
rsille = { version = "2.1.0", features = ["img"] }
这里是一个使用示例。注意:请填写图像文件路径!
use rsille::{extra::Imgille, Canvas};
fn main() {
let mut canvas = Canvas::new();
let img = Imgille::new("path/to/img").unwrap();
canvas.paint(&img, 0, 0).unwrap();
canvas.print();
}
默认情况下,它使用颜色,这对灰度图像或黑白图像(如xkcd中的图像)不是很友好,并且可能会降低清晰度!
因此,对于它们,您必须肯定调用color(false)
!
它还支持反转,例如上面两个xkcd图像,以黑色为主色的那个没有反转,以白色为主色的那个反转了。调用invert(true)
来反转颜色。对于彩色图像,不使用颜色也是一个好选择,例如
此外,图像大小将自动与终端缩放,无论是长终端还是宽终端,都始终正确缩放!
动画
生成一些对象,然后在 Canvas
上绘制它们,然后更新对象,并重新绘制。您还需要设置帧率,处理用户输入等。使用基本 Canvas
创建动画的代码总是非常麻烦!更不用说适当的屏幕清除和防止闪烁等。
因此,这个库封装了所有这些麻烦的事情。只需用 3 行代码就可以使用它创建动画!
- 创建一个新的动画
let mut anime = Animation::new()
- 加载一个可绘制对象和一个更新函数
anime.push()
- 运行
anime.run()
这非常简单!
use rsille::{extra::Object3D , Animation};
fn main() {
let cube = Object3D::cube(30);
let mut anime = Animation::new();
anime.push(cube, |cube| { cube.rotate((1.0, 2.0, 3.0)); false }, (0, 0));
anime.run();
}
push
方法的参数如下
- 对象,直接传递即可。
- 一个返回布尔值的闭包,作为更新函数。这个闭包会每帧运行一次。当闭包返回 true 时,对象停止更新,将不再执行更新函数,但它仍然会在画布上绘制。当所有对象完成更新后,动画停止。
- (x, y),对象放置的位置,通常只在有多个对象时使用。
对于用户输入处理,目前,只有 ctrl+c 和 esc 可以用来退出。将来可能会支持自定义处理。
📌 TODO
- 优化
Animation
的多线程。 - 为
Animation
添加更多功能。 - 添加更多可绘制对象。
- 为
Lifegame
添加有界版本。 - 更多示例。
📝 许可证
依赖项
~0.8–6.5MB
~31K SLoC