4 个版本

0.4.3 2022年5月23日
0.4.2 2022年5月3日
0.4.1 2022年3月10日
0.4.0 2022年3月9日

GUI 中排名第 992

Download history 7/week @ 2024-02-22 7/week @ 2024-02-29 1/week @ 2024-03-14 12/week @ 2024-03-28 4/week @ 2024-04-04

每月下载量 131

MIT 许可证

110KB
2K SLoC

Stretch2

GitHub CI crates.io

stretch2 是从已废弃的 vislyhq/stretch 分支出来的,并修复了一些关键错误。现在已弃用;有关未来的开发,请参阅 DioxusLabs/sprawl。如果您想为 Rust 的布局构建未来,请来贡献吧!

stretch 是用 Rust 编写的 Flexbox 实现。stretch 的目标是提供一个可靠的跨平台布局基础,特别关注移动端。从长远来看,我们希望 stretch 不仅支持 flexbox,还支持许多其他布局算法,如网格布局。stretch 是为 https://visly.app 而创建并提供的。

目标

在使用或为 stretch 贡献之前,了解项目的核心目标是很重要的。这些是我们正在努力实现的目标,而不仅仅是当前支持的功能。

  • 高性能
  • 跨平台
  • 二进制文件体积小
  • 支持多个布局系统
  • 多线程布局
  • 为大多数常见语言提供语言绑定

支持的平台

  • Rust
  • Android
  • iOS
  • JavaScript / TypeScript

用法

stretch 用 Rust 构建,但附带了对多种语言和平台的绑定,因此您可以以对项目自然的方式使用它。

Rust

# Cargo.toml

[dependencies]
stretch2 = "0.4.3"
// main.rs

use stretch2::geometry::Size;
use stretch2::style::*;

fn main() -> Result<(), stretch2::Error> {
    let mut stretch2 = stretch2::node::Stretch::new();

    let child = stretch.new_node(
        Style { size: Size { width: Dimension::Percent(0.5), height: Dimension::Auto }, ..Default::default() },
        vec![],
    )?;

    let node = stretch.new_node(
        Style {
            size: Size { width: Dimension::Points(100.0), height: Dimension::Points(100.0) },
            justify_content: JustifyContent::Center,
            ..Default::default()
        },
        vec![child],
    )?;

    stretch.compute_layout(node, Size::undefined())?;
    dbg!(stretch.layout(node)?);
}

Android

// Build.gradle

android {
    splits {
        abi {
            enable true
        }
    }
}

dependencies {
    implementation 'app.visly.stretch:stretch:0.3.2'
}
// MainActivity.kt

val node = Node(
  Style(size = Size(Dimension.Points(100f), Dimension.Points(100f)), justifyContent = JustifyContent.Center),
  listOf(
    Node(Style(size = Size(Dimension.Percent(0.5f), Dimension.Percent(0.5f))), listOf())
  ))

val layout = node.computeLayout(Size(null, null))
Log.d(TAG, "width: ${layout.width}, height: ${layout.height}")

iOS

# Podfile

pod 'StretchKit', '~> 0.3.2'
// ViewController.swift

let node = Node(
  style: Style(size: Size(width: .points(100.0), height: .points(100.0)), justifyContent: .center),
  children: [
    Node(style: Style(size: Size(width: .percent(0.5), height: .percent(0.5))), children: [])
  ])

let layout = node.computeLayout(thatFits: Size(width: nil, height: nil))
print("width: \(layout.width), height: \(layout.height)")

JavaScript

> npm install --save stretch-layout
// index.js

import { Allocator, Node, JustifyContent } from 'stretch-layout';

const allocator = new Allocator();
const node = new Node(allocator, {width: 100, height: 100, justifyContent: JustifyContent.Center});
node.addChild(new Node(allocator, {width: '50%', height: '50%'}));
const layout = node.computeLayout();

console.log(layout.width, layout.height);

安装

如果您还没有安装 Rust,您必须先安装它,然后安装一些我们用于格式化和检查代码库的组件。有关 Rust 的更多信息,请参阅他们的 网站

curl https://sh.rustup.rs -sSf | sh
rustup component add rustfmt
rustup component add clippy

完成后,您可以克隆存储库并进行一些基本检查,以确保一切正常工作。

git clone https://github.com/vislyhq/stretch.git
cd stretch
cargo test

如果您对API进行了任何更改,也应更新并运行位于 /bindings/* 的所有平台绑定的测试。

测试

Stretch2通过验证在stretch2中编写的布局与在Chrome中执行相同来测试。这是通过在HTML中渲染等效布局,然后生成一个Rust测试用例来完成的,该测试用例断言通过stretch运行的结果布局是相同的。

您可以在不设置webdriver环境的情况下运行这些测试,但如果您想添加任何测试用例,则需要安装 chromedriver。如果您在macOS上开发,可以通过brew轻松完成此操作。

brew tap homebrew/cask
brew cask install chromedriver

一旦您安装了chromedriver并将其添加到 PATH 中,您可以通过运行 cargo run --package gentest 来重新生成所有测试。

要添加新的测试用例,请将另一个HTML文件添加到 /test_fixtures,并按照当前测试作为新测试的模板。

基准测试

基准测试建立在与测试相同的架构之上,实际上基准测试是从测试固定值自动生成的,就像测试一样。运行 cargo bench 在本地运行基准测试。

与Yoga的关系

Yoga 是用C编写的跨平台Flexbox实现。Yoga是一个非常出色的项目,但存在一些基本问题,我们希望解决这些问题。与Yoga相比,我们旨在更严格地遵循网络标准,具有灵活的架构,最终支持多个布局算法,以及包括多线程布局在内的未来性能改进。除此之外,我们还旨在使用更安全的语言和更现代的代码库。

依赖关系

~2–2.8MB
~61K SLoC