Feat/ui编辑器与code agent整合 #237
@@ -1715,6 +1715,7 @@ dependencies = [
|
||||
"image",
|
||||
"jsonschema",
|
||||
"libc",
|
||||
"maud",
|
||||
"nalgebra",
|
||||
"oxc_allocator",
|
||||
"oxc_ast",
|
||||
@@ -2734,6 +2735,28 @@ dependencies = [
|
||||
"rawpointer",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "maud"
|
||||
version = "0.27.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8156733e27020ea5c684db5beac5d1d611e1272ab17901a49466294b84fc217e"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"maud_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "maud_macros"
|
||||
version = "0.27.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7261b00f3952f617899bc012e3dbd56e4f0110a038175929fa5d18e5a19913ca"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"proc-macro2-diagnostics",
|
||||
"quote",
|
||||
"syn 2.0.118",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.8.2"
|
||||
@@ -3967,6 +3990,18 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2-diagnostics"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.118",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "psl-types"
|
||||
version = "2.0.11"
|
||||
|
||||
@@ -58,6 +58,7 @@ unicode-normalization = "0.1"
|
||||
uuid = { version = "1", features = ["v4"] }
|
||||
zip = { version = "2", default-features = false, features = ["deflate"] }
|
||||
tauri-plugin-clipboard-manager = "2.3.2"
|
||||
maud = "0.27.0"
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
libc = "0.2"
|
||||
|
||||
@@ -19,6 +19,10 @@ Implement the user's actual game request in the current project. Choose DOM, Can
|
||||
|
||||
Call `agc_read_skill_resource` with `skillName="agc-web-game-development"` and `relativePath="references/game-quality-checklist.md"` when implementing a new game loop or a broad gameplay revision.
|
||||
|
||||
# Notes
|
||||
* UI Editor's JSON formated is a special kind asset; Never edit it or read it directly. User can export to `ui/generated-<digest>.js` and want u to use it;
|
||||
Read it instead, the doc embedded will instruct you how to use it.
|
||||
|
||||
## Reporting
|
||||
|
||||
Report the files changed, observable gameplay behavior, real validation performed, and any remaining limitation. Do not report a test or browser pass that did not run.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"schemaVersion": "agc-skill-pack.v1",
|
||||
"version": "2026-08-26.4",
|
||||
"version": "2026-08-26.9",
|
||||
"skills": [
|
||||
{
|
||||
"name": "agc-project-structure",
|
||||
@@ -61,7 +61,7 @@
|
||||
"agents/openai.yaml",
|
||||
"references/game-quality-checklist.md"
|
||||
],
|
||||
"sha256": "b54646fc83eb48ffa270a726c63cdea5f05099d7990ec99024b00e255fb38d6c"
|
||||
"sha256": "b197a242b75dc5e39739693e793acd25ac62dd2c72bc264305797936da47f356"
|
||||
},
|
||||
{
|
||||
"name": "agc-browser-playtest",
|
||||
|
||||
@@ -1247,7 +1247,7 @@ mod tests {
|
||||
"agc_import_account_assets",
|
||||
"agc_create_or_derive_resource",
|
||||
"agc_remove_background",
|
||||
"agc_browser_playtest"
|
||||
"agc_browser_playtest",
|
||||
]
|
||||
);
|
||||
let serialized = specs.to_string();
|
||||
|
||||
@@ -347,6 +347,15 @@ fn save_ui_design_state(
|
||||
ui_editor::persistence::save_ui_design_state_at(input)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn generate_ui_design_code(
|
||||
input: ui_editor::persistence::GenerateUiDesignCodeInput,
|
||||
) -> Result<ui_editor::persistence::GenerateUiDesignCodeResult, String> {
|
||||
let root = Path::new(input.project_path.trim());
|
||||
enforce_project_permission_policy(root, "file.write")?;
|
||||
ui_editor::persistence::generate_ui_design_code_at(input)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn ensure_ui_design_resource_for_prototype(
|
||||
input: ui_editor::resource_bridge::EnsureUiDesignResourceForPrototypeInput,
|
||||
@@ -2469,6 +2478,7 @@ fn main() {
|
||||
bind_components,
|
||||
load_ui_design_state,
|
||||
save_ui_design_state,
|
||||
generate_ui_design_code,
|
||||
ensure_ui_design_resource_for_prototype,
|
||||
generate_platform_art_asset,
|
||||
open_canvas_project,
|
||||
|
||||
@@ -1429,7 +1429,7 @@ pub(crate) fn resolve_preview_path(root: &Path, url_path: &str) -> Result<PathBu
|
||||
if first.is_empty() || first == "." || first == ".." || first.contains('\\') {
|
||||
return Err("预览路径非法".to_string());
|
||||
}
|
||||
if first == "game" || first == "assets" {
|
||||
if first == "game" || first == "assets" || first == "ui" {
|
||||
file_path.push(first);
|
||||
} else {
|
||||
// `/` serves the resolved game entry (project-root index.html or the
|
||||
@@ -1492,7 +1492,7 @@ fn canonical_preview_path(root: &Path, file_path: &Path) -> Result<PathBuf, Stri
|
||||
}
|
||||
}
|
||||
|
||||
for segment in ["game", "assets"] {
|
||||
for segment in ["game", "assets", "ui"] {
|
||||
let allowed_dir = root.join(segment);
|
||||
let metadata = match fs::symlink_metadata(&allowed_dir) {
|
||||
Ok(metadata) => metadata,
|
||||
@@ -1517,7 +1517,7 @@ fn canonical_preview_path(root: &Path, file_path: &Path) -> Result<PathBuf, Stri
|
||||
return Ok(canonical_file);
|
||||
}
|
||||
}
|
||||
Err("预览路径只能访问真实 game/ 或 assets/ 目录".to_string())
|
||||
Err("预览路径只能访问真实 game/、assets/ 或 ui/ 目录".to_string())
|
||||
}
|
||||
|
||||
fn percent_decode_path(path: &str) -> Option<String> {
|
||||
@@ -1659,4 +1659,30 @@ mod tests {
|
||||
assert!(resolve_preview_path(root.path(), "/.agent/secret.json").is_err());
|
||||
assert!(resolve_preview_path(root.path(), "/memory/private.md").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn legacy_layout_serves_root_ui_modules() {
|
||||
let root = tempfile::tempdir().expect("create preview root");
|
||||
fs::create_dir_all(root.path().join("game")).expect("create game directory");
|
||||
fs::create_dir_all(root.path().join("ui")).expect("create ui directory");
|
||||
fs::write(root.path().join("game/index.html"), "<!doctype html>")
|
||||
.expect("write game entry");
|
||||
fs::write(root.path().join("ui/generated-x.js"), "export {};")
|
||||
.expect("write generated module");
|
||||
|
||||
let expected = root
|
||||
.path()
|
||||
.join("ui/generated-x.js")
|
||||
.canonicalize()
|
||||
.expect("canonical generated module");
|
||||
assert_eq!(
|
||||
resolve_preview_path(root.path(), "/ui/generated-x.js").unwrap(),
|
||||
expected
|
||||
);
|
||||
|
||||
let response = build_preview_response(root.path(), "GET", "/ui/generated-x.js");
|
||||
let response_text = String::from_utf8_lossy(&response);
|
||||
assert!(response_text.starts_with("HTTP/1.1 200 OK\r\n"));
|
||||
assert!(response_text.contains("export {};"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
|
k88936 marked this conversation as resolved
|
||||
use maud::{Markup, PreEscaped};
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
pub(super) fn font_face_rule(
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
font: &crate::ui_editor::resource::font::FontAsset,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
family: &str,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
) -> Result<String, String> {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
let path = asset_url(&font.path)?;
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
Ok(format!("@font-face{{font-family:'{family}';src:url('{path}') format('{}');font-style:{};font-weight:{};}}", font.metadata.format.css_format(), if font.metadata.italic { "italic" } else { "normal" }, font.metadata.weight))
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
pub(super) fn html_comment(label: &str, value: serde_json::Value) -> Markup {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
let mut text = serde_json::to_string_pretty(&value).unwrap_or_else(|_| "{}".to_string());
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
while text.contains("--") {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
text = text.replace("--", "- -");
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
PreEscaped(format!("<!-- {label}:\n{text}\n-->"))
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
pub(super) fn asset_url(path: &str) -> Result<String, String> {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
let path = path.trim();
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
if path.is_empty()
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
|| path.starts_with('/')
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
|| path.contains('\\')
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
|| path.split('/').any(|part| part == "..")
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
|| path.chars().any(|character| {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
character.is_control() || matches!(character, '<' | '>' | '\'' | '"' | '`' | '(' | ')')
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
})
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
{
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
return Err(format!("资源路径无效:{path}"));
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
Ok(format!("/{path}"))
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
pub(super) fn finite(value: f32, field: &str) -> Result<f32, String> {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
if value.is_finite() {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
Ok(value)
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
} else {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
Err(format!("{field} 必须是有限数值"))
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
pub(super) fn finite_positive(value: f32, field: &str) -> Result<f32, String> {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
finite(value, field).and_then(|v| {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
if v > 0.0 {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
Ok(v)
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
} else {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
Err(format!("{field} 必须大于 0"))
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
})
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
pub(super) fn trim_float(value: f32) -> String {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
let text = format!("{value:.4}");
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
text.trim_end_matches('0').trim_end_matches('.').to_string()
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
#[cfg(test)]
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
mod tests {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
use super::font_face_rule;
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
use crate::ui_editor::resource::font::{FontAsset, FontAssetMetadata, FontFormat};
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
use crate::ui_editor::utils::FontAssetId;
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
fn font(format: FontFormat) -> FontAsset {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
FontAsset {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
asset_id: FontAssetId::new("font-main").expect("valid font id"),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
metadata: FontAssetMetadata {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
family_name: "测试字体".to_string(),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
face_name: "Regular".to_string(),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
weight: 400,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
italic: false,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
format,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
source_file_name: format!("font.{}", format.extension()),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
},
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
path: format!("assets/font.{}", format.extension()),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
content_sha256: "0".repeat(64),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
#[test]
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
fn font_face_rule_uses_standard_css_format_names() {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
let truetype = font_face_rule(&font(FontFormat::TrueType), "ui-font").unwrap();
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
let opentype = font_face_rule(&font(FontFormat::OpenType), "ui-font").unwrap();
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
assert!(truetype.contains("format('truetype')"));
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
assert!(opentype.contains("format('opentype')"));
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
pub(super) fn hex_id(value: &str) -> String {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
value
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
.as_bytes()
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
.iter()
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
.map(|byte| format!("{byte:02x}"))
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
.collect()
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:这里把 FontFormat 的文件扩展名( 审查 head sha: P1:这里把 FontFormat 的文件扩展名(`ttf`/`otf`)直接作为 CSS `format()` 值输出。CSS Fonts 的 format 标识应为 `truetype`/`opentype`(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
@@ -0,0 +1,228 @@
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
use crate::ui_editor::component::image::{
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
FillMethod, HorizontalFillOrigin, ImageType, Radial180Origin, Radial360Origin, Radial90Origin,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
VerticalFillOrigin,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
};
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
use crate::ui_editor::html_renderer::assets::{finite_positive, trim_float};
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
const UI_SCALE: &str = "var(--ui-scale, 1)";
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
pub(in crate::ui_editor::html_renderer) fn image_styles(
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
image_type: &ImageType,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
sprite: &crate::ui_editor::resource::sprite::SpriteAsset,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
src: &str,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
) -> Result<(String, Option<String>), String> {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
match image_type {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
ImageType::Simple { preserve_aspect } => Ok((
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
"position:absolute;inset:0;overflow:hidden;".to_string(),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
Some(format!(
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
"width:100%;height:100%;display:block;object-fit:{};",
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
if *preserve_aspect { "contain" } else { "fill" }
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
)),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
)),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
ImageType::Filled {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
preserve_aspect,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
method,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
amount,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
} => {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
let mut image = format!(
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
"width:100%;height:100%;display:block;object-fit:{};",
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
if *preserve_aspect { "contain" } else { "fill" }
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
);
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
if let Some(clip) = fill_clip_path(method, amount.clamp(0.0, 1.0)) {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
if clip.starts_with("conic-gradient") {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
image.push_str(&format!("mask-image:{clip};-webkit-mask-image:{clip};"));
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
} else {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
image.push_str(&format!("clip-path:{clip};"));
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
Ok((
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
"position:absolute;inset:0;overflow:hidden;".to_string(),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
Some(image),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
))
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
ImageType::Tiled {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
pixels_per_unit_multiplier,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
..
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
} => {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
// TODO: Tiled.fill_center=false 当前暂不支持,保持整块 repeat fallback。
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
let w = finite_positive(
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
sprite.pixel_size.x
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
/ (sprite.pixels_per_unit().get() * pixels_per_unit_multiplier.get()),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
"tile width",
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
)?;
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
let h = finite_positive(
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
sprite.pixel_size.y
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
/ (sprite.pixels_per_unit().get() * pixels_per_unit_multiplier.get()),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
"tile height",
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
)?;
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
Ok((format!("position:absolute;inset:0;background-image:url(\"{src}\");background-repeat:repeat;background-position:top left;background-size:calc({}px * {}) calc({}px * {});overflow:hidden;", trim_float(w), UI_SCALE, trim_float(h), UI_SCALE), None))
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
ImageType::Sliced {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
fill_center,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
pixels_per_unit_multiplier,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
} => {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
let border = sprite.border();
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
let scale = finite_positive(
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
sprite.pixels_per_unit().get() * pixels_per_unit_multiplier.get(),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
"slice scale",
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
)?;
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
let widths = [
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
border.top() as f32 / scale,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
border.right() as f32 / scale,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
border.bottom() as f32 / scale,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
border.left() as f32 / scale,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
];
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
Ok((format!("position:absolute;inset:0;overflow:hidden;border-style:solid;border-width:calc({}px * {}) calc({}px * {}) calc({}px * {}) calc({}px * {});border-image-source:url(\"{src}\");border-image-slice:{} {} {} {}{};border-image-width:calc({}px * {}) calc({}px * {}) calc({}px * {}) calc({}px * {});border-image-repeat:stretch;", trim_float(widths[0]), UI_SCALE, trim_float(widths[1]), UI_SCALE, trim_float(widths[2]), UI_SCALE, trim_float(widths[3]), UI_SCALE, border.top(), border.right(), border.bottom(), border.left(), if *fill_center { " fill" } else { "" }, trim_float(widths[0]), UI_SCALE, trim_float(widths[1]), UI_SCALE, trim_float(widths[2]), UI_SCALE, trim_float(widths[3]), UI_SCALE), None))
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
fn fill_clip_path(method: &FillMethod, amount: f32) -> Option<String> {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
if amount >= 1.0 {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
return None;
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
if amount <= 0.0 {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
return Some("inset(0 0 0 100%)".to_string());
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
match method {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
FillMethod::Horizontal(HorizontalFillOrigin::Left) => Some(format!(
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
"inset(0 {}% 0 0)",
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
trim_float((1.0 - amount) * 100.0)
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
)),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
FillMethod::Horizontal(HorizontalFillOrigin::Right) => Some(format!(
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
"inset(0 0 0 {}%)",
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
trim_float((1.0 - amount) * 100.0)
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
)),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
FillMethod::Vertical(VerticalFillOrigin::Top) => Some(format!(
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
"inset(0 0 {}% 0)",
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
trim_float((1.0 - amount) * 100.0)
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
)),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
FillMethod::Vertical(VerticalFillOrigin::Bottom) => Some(format!(
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
"inset({}% 0 0 0)",
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
trim_float((1.0 - amount) * 100.0)
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
)),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
FillMethod::Radial90 { origin, clockwise } => Some(conic_mask(
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
radial_origin_angle_90(*origin) - if *clockwise { 90.0 } else { 0.0 },
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
*clockwise,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
amount,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
90.0,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
)),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
FillMethod::Radial180 { origin, clockwise } => Some(conic_mask(
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
radial_origin_angle_180(*origin) - if *clockwise { 90.0 } else { 0.0 },
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
*clockwise,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
amount,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
180.0,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
)),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
FillMethod::Radial360 { origin, clockwise } => Some(conic_mask(
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
radial_origin_angle_360(*origin) - if *clockwise { 90.0 } else { 0.0 },
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
*clockwise,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
amount,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
360.0,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
)),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
#[cfg(test)]
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
mod tests {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
use super::{fill_clip_path, FillMethod, Radial180Origin, Radial360Origin, Radial90Origin};
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
#[test]
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
fn clockwise_radial_180_and_360_start_ninety_degrees_before_origin() {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
let radial_180 = fill_clip_path(
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
&FillMethod::Radial180 {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
origin: Radial180Origin::Top,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
clockwise: true,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
},
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
0.5,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
)
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
.unwrap();
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
let radial_360 = fill_clip_path(
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
&FillMethod::Radial360 {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
origin: Radial360Origin::Right,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
clockwise: true,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
},
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
0.25,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
)
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
.unwrap();
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
assert!(radial_180.contains("from -90deg"));
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
assert!(radial_360.contains("from 0deg"));
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
#[test]
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
fn counter_clockwise_radial_start_angles_remain_unchanged() {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
let radial_180 = fill_clip_path(
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
&FillMethod::Radial180 {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
origin: Radial180Origin::Top,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
clockwise: false,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
},
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
0.5,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
)
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
.unwrap();
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
assert!(radial_180.contains("from -90deg"));
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
#[test]
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
fn radial_90_matches_preview_for_all_origins_and_directions() {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
let cases = [
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
(Radial90Origin::TopLeft, 0.0),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
(Radial90Origin::TopRight, 90.0),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
(Radial90Origin::BottomRight, 180.0),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
(Radial90Origin::BottomLeft, 270.0),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
];
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
for (origin, angle) in cases {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
let clockwise = fill_clip_path(
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
&FillMethod::Radial90 {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
origin,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
clockwise: true,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
},
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
0.5,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
)
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
.unwrap();
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
let counter_clockwise = fill_clip_path(
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
&FillMethod::Radial90 {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
origin,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
clockwise: false,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
},
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
0.5,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
)
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
.unwrap();
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
assert!(clockwise.contains(&format!("from {}deg", angle - 90.0)));
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
assert!(counter_clockwise.contains(&format!("from {}deg", angle - 45.0)));
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
fn conic_mask(origin: f32, clockwise: bool, amount: f32, max_sweep: f32) -> String {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
let sweep = amount * max_sweep;
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
let start = if clockwise { origin } else { origin - sweep };
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
format!(
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
"conic-gradient(from {}deg, #000 0deg {}deg, transparent {}deg 360deg)",
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
trim_float(start),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
trim_float(sweep),
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
trim_float(sweep)
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
)
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
fn radial_origin_angle_90(origin: Radial90Origin) -> f32 {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
match origin {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
Radial90Origin::TopLeft => 0.0,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
Radial90Origin::TopRight => 90.0,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
Radial90Origin::BottomRight => 180.0,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
Radial90Origin::BottomLeft => 270.0,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
fn radial_origin_angle_180(origin: Radial180Origin) -> f32 {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
match origin {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
Radial180Origin::Top => 0.0,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
Radial180Origin::Right => 90.0,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
Radial180Origin::Bottom => 180.0,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
Radial180Origin::Left => 270.0,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
fn radial_origin_angle_360(origin: Radial360Origin) -> f32 {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
match origin {
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
Radial360Origin::Top => 0.0,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
Radial360Origin::Right => 90.0,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
Radial360Origin::Bottom => 180.0,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
Radial360Origin::Left => 270.0,
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
}
|
||||
|
k88936 marked this conversation as resolved
kdletters
commented
P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 审查 head sha: P1:Radial90 的顺时针分支在这里额外把起始角减了 90°,而前端 `componentToCss.ts` 的同一规则直接以 `originAngle` 作为 clockwise 起始角;因此同一个 Filled/Radial90 组件在编辑器预览和导出的 `generated-*.js` 中会发生 90° 方向偏移。建议复用同一角点/起始角映射(或抽共享规则),并增加四个 origin、双向和部分 amount 的前后端一致性测试。
审查 head sha: a63a477a6b88c823f57fa091531601f767e2e131
|
||||
@@ -0,0 +1,60 @@
|
||||
use super::assets::{asset_url, hex_id};
|
||||
use crate::ui_editor::component::text::FontSource;
|
||||
use crate::ui_editor::component::Component;
|
||||
use crate::ui_editor::state::State;
|
||||
use image::image_styles;
|
||||
use maud::{html, Markup};
|
||||
use text::text_style;
|
||||
|
||||
mod image;
|
||||
mod text;
|
||||
|
||||
pub(super) fn render_component(state: &State, component: &Component) -> Result<Markup, String> {
|
||||
match component {
|
||||
Component::Text(text) => {
|
||||
let mut style = text_style(
|
||||
text.font_style,
|
||||
text.alignment,
|
||||
text.font_sizing,
|
||||
text.color,
|
||||
text.line_spacing.get(),
|
||||
text.horizontal_overflow,
|
||||
text.vertical_overflow,
|
||||
);
|
||||
if let FontSource::Bound(font_id) = &text.font {
|
||||
state
|
||||
.font_assets
|
||||
.get(font_id)
|
||||
.ok_or_else(|| format!("Text 缺少字体资源:{}", font_id.as_str()))?;
|
||||
let family = format!("ui-editor-font-{}", hex_id(font_id.as_str()));
|
||||
style.push_str(&format!("font-family:'{family}';"));
|
||||
return Ok(html! {
|
||||
div style=(style) {
|
||||
(text.content)
|
||||
}
|
||||
});
|
||||
}
|
||||
Ok(html! { div style=(style) { (text.content) } })
|
||||
}
|
||||
Component::Image(image) => {
|
||||
let sprite_id = image
|
||||
.target_graphic
|
||||
.as_ref()
|
||||
.ok_or_else(|| "Image 缺少 target_graphic".to_string())?;
|
||||
let sprite = state
|
||||
.sprite_assets
|
||||
.get(sprite_id)
|
||||
.ok_or_else(|| format!("Image 缺少 Sprite 资源:{}", sprite_id.as_str()))?;
|
||||
let src = asset_url(&sprite.path)?;
|
||||
let (style, image_style) = image_styles(&image.image_type, sprite, &src)?;
|
||||
Ok(match image_style {
|
||||
Some(image_style) => html! {
|
||||
div style=(style) {
|
||||
img src=(src) alt="" aria-hidden="true" draggable="false" style=(image_style);
|
||||
}
|
||||
},
|
||||
None => html! { div style=(style) {} },
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
use crate::ui_editor::component::text::{
|
||||
FontSizing, FontStyle, HorizontalTextOverflow, TextAlignment, VerticalTextOverflow,
|
||||
};
|
||||
|
||||
const UI_SCALE: &str = "var(--ui-scale, 1)";
|
||||
|
||||
pub(in crate::ui_editor::html_renderer) fn text_style(
|
||||
font_style: FontStyle,
|
||||
alignment: TextAlignment,
|
||||
sizing: FontSizing,
|
||||
color: [u8; 4],
|
||||
line_spacing: f32,
|
||||
horizontal_overflow: HorizontalTextOverflow,
|
||||
vertical_overflow: VerticalTextOverflow,
|
||||
) -> String {
|
||||
let [r, g, b, a] = color;
|
||||
let (justify, align, text_align) = match alignment {
|
||||
TextAlignment::UpperLeft | TextAlignment::MiddleLeft | TextAlignment::LowerLeft => (
|
||||
"flex-start",
|
||||
if matches!(alignment, TextAlignment::MiddleLeft) {
|
||||
"center"
|
||||
} else if matches!(alignment, TextAlignment::LowerLeft) {
|
||||
"flex-end"
|
||||
} else {
|
||||
"flex-start"
|
||||
},
|
||||
"left",
|
||||
),
|
||||
TextAlignment::UpperCenter | TextAlignment::MiddleCenter | TextAlignment::LowerCenter => (
|
||||
"center",
|
||||
if matches!(alignment, TextAlignment::MiddleCenter) {
|
||||
"center"
|
||||
} else if matches!(alignment, TextAlignment::LowerCenter) {
|
||||
"flex-end"
|
||||
} else {
|
||||
"flex-start"
|
||||
},
|
||||
"center",
|
||||
),
|
||||
_ => (
|
||||
"flex-end",
|
||||
if matches!(alignment, TextAlignment::MiddleRight) {
|
||||
"center"
|
||||
} else if matches!(alignment, TextAlignment::LowerRight) {
|
||||
"flex-end"
|
||||
} else {
|
||||
"flex-start"
|
||||
},
|
||||
"right",
|
||||
),
|
||||
};
|
||||
let (weight, italic) = match font_style {
|
||||
FontStyle::Normal => (400, "normal"),
|
||||
FontStyle::Bold => (700, "normal"),
|
||||
FontStyle::Italic => (400, "italic"),
|
||||
FontStyle::BoldItalic => (700, "italic"),
|
||||
};
|
||||
let size = match sizing {
|
||||
FontSizing::Fixed(value) => value.get(),
|
||||
FontSizing::BestFit(range) => range.min().get(),
|
||||
};
|
||||
let (white_space, overflow, wrap) = match (horizontal_overflow, vertical_overflow) {
|
||||
(HorizontalTextOverflow::Wrap, VerticalTextOverflow::Truncate) => {
|
||||
("normal", "hidden", "anywhere")
|
||||
}
|
||||
(HorizontalTextOverflow::Wrap, VerticalTextOverflow::Overflow) => {
|
||||
("normal", "visible", "anywhere")
|
||||
}
|
||||
(HorizontalTextOverflow::Overflow, VerticalTextOverflow::Truncate) => {
|
||||
("nowrap", "hidden", "normal")
|
||||
}
|
||||
(HorizontalTextOverflow::Overflow, VerticalTextOverflow::Overflow) => {
|
||||
("nowrap", "visible", "normal")
|
||||
}
|
||||
};
|
||||
format!("position:absolute;inset:0;display:flex;width:100%;height:100%;box-sizing:border-box;padding:0;color:rgba({r},{g},{b},{});font-family:system-ui,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif;font-size:calc({size}px * {UI_SCALE});font-weight:{weight};font-style:{italic};align-items:{align};justify-content:{justify};text-align:{text_align};line-height:{};white-space:{white_space};overflow:{overflow};overflow-wrap:{wrap};", f32::from(a) / 255.0, line_spacing)
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
use super::assets::trim_float;
|
||||
use crate::ui_editor::layout::control_layout::{Container, ControlLayout};
|
||||
|
||||
const UI_SCALE: &str = "var(--ui-scale, 1)";
|
||||
|
||||
pub(super) fn container_style(container: &Container) -> Result<String, String> {
|
||||
Ok(match container {
|
||||
Container::None => String::new(),
|
||||
Container::HBox { alignment, separation } => format!("display:flex;flex-direction:row;justify-content:{};gap:{};min-width:0;min-height:0;", alignment_css(*alignment), scaled_px(*separation)?),
|
||||
Container::VBox { alignment, separation } => format!("display:flex;flex-direction:column;justify-content:{};gap:{};min-width:0;min-height:0;", alignment_css(*alignment), scaled_px(*separation)?),
|
||||
Container::Grid { columns, h_separation, v_separation } => format!("display:grid;grid-template-columns:repeat({},minmax(0,1fr));column-gap:{};row-gap:{};min-width:0;min-height:0;", columns, scaled_px(*h_separation)?, scaled_px(*v_separation)?),
|
||||
Container::Margin { margin_left, margin_top, margin_right, margin_bottom } => format!("display:grid;padding-left:{};padding-top:{};padding-right:{};padding-bottom:{};min-width:0;min-height:0;", scaled_px(*margin_left)?, scaled_px(*margin_top)?, scaled_px(*margin_right)?, scaled_px(*margin_bottom)?),
|
||||
Container::Center { .. } => "display:grid;place-items:center;min-width:0;min-height:0;".to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn child_container_style(
|
||||
layout: &ControlLayout,
|
||||
parent: &Container,
|
||||
) -> Result<String, String> {
|
||||
let min_w = scaled_px(layout.custom_minimum_size.x)?;
|
||||
let min_h = scaled_px(layout.custom_minimum_size.y)?;
|
||||
Ok(match parent {
|
||||
Container::HBox { .. } => format!(
|
||||
"min-width:{min_w};min-height:{min_h};{}align-self:{};",
|
||||
flex_grow(
|
||||
layout.size_flags_horizontal,
|
||||
layout.size_flags_stretch_ratio
|
||||
),
|
||||
cross_axis(layout.size_flags_vertical)
|
||||
),
|
||||
Container::VBox { .. } => format!(
|
||||
"min-width:{min_w};min-height:{min_h};{}align-self:{};",
|
||||
flex_grow(layout.size_flags_vertical, layout.size_flags_stretch_ratio),
|
||||
cross_axis(layout.size_flags_horizontal)
|
||||
),
|
||||
Container::Margin { .. } => {
|
||||
"grid-area:1 / 1;align-self:stretch;justify-self:stretch;".to_string()
|
||||
}
|
||||
Container::Center { use_top_left } => {
|
||||
if *use_top_left {
|
||||
"justify-self:center;align-self:center;transform:translate(50%,50%);".to_string()
|
||||
} else {
|
||||
"justify-self:center;align-self:center;".to_string()
|
||||
}
|
||||
}
|
||||
Container::Grid { .. } | Container::None => {
|
||||
format!("min-width:{min_w};min-height:{min_h};")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn scaled_px(value: f32) -> Result<String, String> {
|
||||
if !value.is_finite() {
|
||||
return Err("layout px 必须是有限数值".to_string());
|
||||
}
|
||||
Ok(format!("calc({}px * {})", trim_float(value), UI_SCALE))
|
||||
}
|
||||
fn alignment_css(
|
||||
value: crate::ui_editor::layout::control_layout::ContainerAlignment,
|
||||
) -> &'static str {
|
||||
match value {
|
||||
crate::ui_editor::layout::control_layout::ContainerAlignment::Begin => "flex-start",
|
||||
crate::ui_editor::layout::control_layout::ContainerAlignment::Center => "center",
|
||||
crate::ui_editor::layout::control_layout::ContainerAlignment::End => "flex-end",
|
||||
}
|
||||
}
|
||||
fn cross_axis(value: u8) -> &'static str {
|
||||
if value & 1 != 0 {
|
||||
"stretch"
|
||||
} else if value == 4 {
|
||||
"center"
|
||||
} else if value == 8 {
|
||||
"flex-end"
|
||||
} else {
|
||||
"flex-start"
|
||||
}
|
||||
}
|
||||
fn flex_grow(flags: u8, ratio: f32) -> String {
|
||||
if flags & 2 != 0 && ratio.is_finite() && ratio >= 0.0 {
|
||||
format!("flex-grow:{};", trim_float(ratio))
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,286 @@
|
||||
mod assets;
|
||||
mod component;
|
||||
mod container;
|
||||
mod node;
|
||||
|
||||
use self::assets::{font_face_rule, hex_id, html_comment, trim_float};
|
||||
use self::component::render_component;
|
||||
use self::container::{child_container_style, container_style};
|
||||
use self::node::{is_container, transform_style};
|
||||
use crate::ui_editor::layout::children_display_mode::ChildrenDisplayMode;
|
||||
use crate::ui_editor::layout::control_layout::Container;
|
||||
use crate::ui_editor::layout::node::Node;
|
||||
use crate::ui_editor::state::{State, UITree};
|
||||
use maud::{html, Markup, PreEscaped};
|
||||
use serde_json::json;
|
||||
|
||||
pub(crate) fn render_ui_design_state_html(state: &State) -> Result<String, String> {
|
||||
let mut trees = Vec::with_capacity(state.ui_trees.len());
|
||||
for (index, tree) in state.ui_trees.iter().enumerate() {
|
||||
if index > 0 {
|
||||
trees.push("\n<!-- ui-tree-separator -->\n".to_string());
|
||||
}
|
||||
trees.push(render_tree(state, tree)?.into_string());
|
||||
}
|
||||
let font_faces = state
|
||||
.font_assets
|
||||
.values()
|
||||
.map(|font| {
|
||||
let family = format!("ui-editor-font-{}", hex_id(font.asset_id.as_str()));
|
||||
font_face_rule(font, &family)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?
|
||||
.join("");
|
||||
let fragment_comment = html_comment(
|
||||
"genarrative-ui-fragment",
|
||||
json!({
|
||||
"format": "html-fragment",
|
||||
"treeCount": state.ui_trees.len(),
|
||||
}),
|
||||
);
|
||||
let fonts = (!font_faces.is_empty()).then(|| {
|
||||
html! {
|
||||
style data-ui-fonts { (PreEscaped(font_faces)) }
|
||||
}
|
||||
.into_string()
|
||||
});
|
||||
let mut fragment = String::new();
|
||||
fragment.push_str(&fragment_comment.into_string());
|
||||
if let Some(fonts) = fonts {
|
||||
fragment.push_str(&fonts);
|
||||
}
|
||||
fragment.push_str(&trees.concat());
|
||||
Ok(fragment)
|
||||
}
|
||||
|
||||
pub(crate) fn render_ui_design_state_js(
|
||||
state: &State,
|
||||
) -> Result<(String, Vec<String>, usize), String> {
|
||||
// 生成阶段只渲染已由保存流程 validate_state 校验过的 State;不重复执行领域校验。
|
||||
let font_faces = state
|
||||
.font_assets
|
||||
.values()
|
||||
.map(|font| {
|
||||
let family = format!("ui-editor-font-{}", hex_id(font.asset_id.as_str()));
|
||||
font_face_rule(font, &family)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?
|
||||
.join("");
|
||||
let mut exports = Vec::with_capacity(state.ui_trees.len());
|
||||
let mut modules = Vec::with_capacity(state.ui_trees.len());
|
||||
let mut node_count = 0usize;
|
||||
for tree in &state.ui_trees {
|
||||
let export_name = format!(
|
||||
"{}_{}",
|
||||
tree_export_name(tree.src_ui_design.as_str()),
|
||||
hex_id(tree.root.id.as_str())
|
||||
);
|
||||
exports.push(export_name.clone());
|
||||
let image = state
|
||||
.ui_design_images
|
||||
.get(&tree.src_ui_design)
|
||||
.ok_or_else(|| format!("UITree 缺少 src_ui_design:{}", tree.src_ui_design.as_str()))?;
|
||||
let tree_comment = html_comment(
|
||||
"genarrative-ui-tree",
|
||||
json!({
|
||||
"srcUiDesign": tree.src_ui_design.as_str(),
|
||||
"name": image.metadata.name,
|
||||
"description": image.metadata.description,
|
||||
}),
|
||||
)
|
||||
.into_string();
|
||||
let root = render_node_with_scale(
|
||||
state,
|
||||
&tree.root,
|
||||
None,
|
||||
Some((image.pixel_size.x, image.pixel_size.y)),
|
||||
)?
|
||||
.into_string();
|
||||
node_count += count_nodes(&tree.root);
|
||||
let mut fragment = String::new();
|
||||
fragment.push_str(&tree_comment);
|
||||
if !font_faces.is_empty() {
|
||||
fragment.push_str(
|
||||
&html! { style data-ui-fonts { (PreEscaped(font_faces.as_str())) } }.into_string(),
|
||||
);
|
||||
}
|
||||
fragment.push_str(&root);
|
||||
let escaped = escape_template_literal(&pretty_html_fragment(&fragment));
|
||||
modules.push(format!("export const {export_name} = `\n{escaped}\n`;"));
|
||||
}
|
||||
let mut output = String::from(
|
||||
r#"
|
||||
//这是从用户手动调整过的UI设计文档生成的html片段, 需要在合适的位置注入游戏中.
|
||||
// 注入示例:
|
||||
// import { tree_example } from '/ui/generated-xxx.js'; // 统一使用绝对路径这里
|
||||
// document.body.insertAdjacentHTML('beforeend', tree_example);
|
||||
// 生成规则默认根节点(们)占据整个窗口.
|
||||
//
|
||||
// 禁止直接修改本js模块因为它随时会被用户重新导出覆盖
|
||||
// 应用逻辑/修改方式, 使用稳定的ui-node-id来查找某个元素然后使用js修改.
|
||||
// const node = document.querySelector('[ui-node-id="..."]');
|
||||
//
|
||||
// html片段内注释包含了丰富的元数据需要你理解并且尽可能实现它们
|
||||
// 对于交互逻辑, 页面关系, 有不清楚的地方可以向用户询问
|
||||
// 对于动态内容, 此文档给出的可能只是一个(或几个在列表中)例子, 需要你根据游戏逻辑, 在js中动态实现.
|
||||
// 对于容器式布局, 文档可能错误地使用position来描述, 需要你合理地使用flex, grid, scrollable, overflow等重写.
|
||||
//
|
||||
// 必要时鼓励清理冗余的示例性的元素, 原则: 尽量保留复用原来的父级面板, patch其中的元素, 而不是替换整个面板
|
||||
"#,
|
||||
);
|
||||
|
||||
output.push_str(&modules.join("\n\n"));
|
||||
if !output.ends_with('\n') {
|
||||
output.push('\n');
|
||||
}
|
||||
Ok((output, exports, node_count))
|
||||
}
|
||||
|
||||
fn render_tree(state: &State, tree: &UITree) -> Result<Markup, String> {
|
||||
let image = state
|
||||
.ui_design_images
|
||||
.get(&tree.src_ui_design)
|
||||
.ok_or_else(|| format!("UITree 缺少 src_ui_design:{}", tree.src_ui_design.as_str()))?;
|
||||
let tree_comment = html_comment(
|
||||
"genarrative-ui-tree",
|
||||
json!({
|
||||
"srcUiDesign": tree.src_ui_design.as_str(),
|
||||
}),
|
||||
);
|
||||
let style = "position:relative;width:100%;height:100%;min-height:0;";
|
||||
Ok(html! {
|
||||
(tree_comment)
|
||||
div style=(style) { (render_node(state, &tree.root, None)?) }
|
||||
})
|
||||
}
|
||||
|
||||
fn render_node(
|
||||
state: &State,
|
||||
node: &Node,
|
||||
parent_container: Option<&Container>,
|
||||
) -> Result<Markup, String> {
|
||||
render_node_with_scale(state, node, parent_container, None)
|
||||
}
|
||||
|
||||
fn render_node_with_scale(
|
||||
state: &State,
|
||||
node: &Node,
|
||||
parent_container: Option<&Container>,
|
||||
root_scale: Option<(f32, f32)>,
|
||||
) -> Result<Markup, String> {
|
||||
let mut style = transform_style(&node.layout, parent_container.is_some())?;
|
||||
if let Some((width, height)) = root_scale {
|
||||
if !width.is_finite() || width <= 0.0 || !height.is_finite() || height <= 0.0 {
|
||||
return Err("UI 设计尺寸必须为正有限数值".to_string());
|
||||
}
|
||||
style.push_str(&format!(
|
||||
"--ui-scale:min(calc(100vw / {}px),calc(100vh / {}px));",
|
||||
trim_float(width),
|
||||
trim_float(height)
|
||||
));
|
||||
}
|
||||
style.push_str("border:0;outline:0;background:transparent;overflow:visible;");
|
||||
style.push_str(&container_style(&node.layout.container)?);
|
||||
if let Some(parent) = parent_container {
|
||||
style.push_str(&child_container_style(&node.layout, parent)?);
|
||||
}
|
||||
let comment = html_comment(
|
||||
"genarrative-ui-node",
|
||||
json!({
|
||||
"nodeId": node.id.as_str(),
|
||||
"name": node.metadata.name,
|
||||
"description": node.metadata.description,
|
||||
}),
|
||||
);
|
||||
let exclusive_comment = matches!(node.children_display_mode, ChildrenDisplayMode::Exclusive)
|
||||
.then(|| {
|
||||
html_comment(
|
||||
"genarrative-ui-node-group",
|
||||
json!({"childrenDisplayMode": "Exclusive", "childrenRendered": "all"}),
|
||||
)
|
||||
});
|
||||
let components = node
|
||||
.components
|
||||
.iter()
|
||||
.map(|component| render_component(state, component))
|
||||
.collect::<Result<Vec<_>, _>>()?
|
||||
.into_iter()
|
||||
.map(|fragment| fragment.into_string())
|
||||
.collect::<Vec<_>>();
|
||||
let children = node
|
||||
.children
|
||||
.iter()
|
||||
.map(|child| {
|
||||
render_node_with_scale(
|
||||
state,
|
||||
child,
|
||||
is_container(&node.layout.container).then_some(&node.layout.container),
|
||||
None,
|
||||
)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?
|
||||
.into_iter()
|
||||
.map(|fragment| fragment.into_string())
|
||||
.collect::<Vec<_>>();
|
||||
Ok(html! {
|
||||
(comment)
|
||||
@if let Some(group_comment) = exclusive_comment { (group_comment) }
|
||||
div ui-node-id=(node.id.as_str()) style=(style) {
|
||||
(PreEscaped(components.concat()))
|
||||
(PreEscaped(children.concat()))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn count_nodes(node: &Node) -> usize {
|
||||
1 + node.children.iter().map(count_nodes).sum::<usize>()
|
||||
}
|
||||
|
||||
fn tree_export_name(id: &str) -> String {
|
||||
let mut name = String::from("tree_");
|
||||
for character in id.chars() {
|
||||
if character.is_ascii_alphanumeric() || character == '_' {
|
||||
name.push(character);
|
||||
} else {
|
||||
name.push('_');
|
||||
}
|
||||
}
|
||||
name
|
||||
}
|
||||
|
||||
fn escape_template_literal(value: &str) -> String {
|
||||
value
|
||||
.replace('\\', "\\\\")
|
||||
.replace('`', "\\`")
|
||||
.replace("${", "\\${")
|
||||
}
|
||||
|
||||
fn pretty_html_fragment(value: &str) -> String {
|
||||
let mut depth = 0usize;
|
||||
let mut lines = Vec::new();
|
||||
for raw in value.replace("><", ">\n<").lines() {
|
||||
let line = raw.trim();
|
||||
if line.is_empty() {
|
||||
continue;
|
||||
}
|
||||
let closing = line.starts_with("</");
|
||||
if closing {
|
||||
depth = depth.saturating_sub(1);
|
||||
}
|
||||
lines.push(format!("{}{}", " ".repeat(depth), line));
|
||||
if line.starts_with('<')
|
||||
&& !closing
|
||||
&& !line.starts_with("<!--")
|
||||
&& !line.starts_with("<!")
|
||||
&& !line.ends_with("/>")
|
||||
&& !line.starts_with("<img")
|
||||
&& !line.starts_with("<input")
|
||||
&& !line.starts_with("<br")
|
||||
&& !line.starts_with("<hr")
|
||||
&& !line.contains("</")
|
||||
{
|
||||
depth += 1;
|
||||
}
|
||||
}
|
||||
lines.join("\n")
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
use super::assets::{finite, trim_float};
|
||||
use crate::ui_editor::layout::control_layout::ControlLayout;
|
||||
|
||||
const UI_SCALE: &str = "var(--ui-scale, 1)";
|
||||
|
||||
pub(super) fn transform_style(
|
||||
layout: &ControlLayout,
|
||||
in_container: bool,
|
||||
) -> Result<String, String> {
|
||||
let transform = &layout.transform;
|
||||
for value in transform
|
||||
.anchor_min
|
||||
.iter()
|
||||
.chain(transform.anchor_max.iter())
|
||||
.chain(transform.offset_min.iter())
|
||||
.chain(transform.offset_max.iter())
|
||||
{
|
||||
if !value.is_finite() {
|
||||
return Err("Transform 包含非有限数值".to_string());
|
||||
}
|
||||
}
|
||||
if transform.anchor_min.x > transform.anchor_max.x
|
||||
|| transform.anchor_min.y > transform.anchor_max.y
|
||||
{
|
||||
return Err("Transform anchors must be ordered".to_string());
|
||||
}
|
||||
if in_container {
|
||||
return Ok(format!(
|
||||
"position:relative;min-width:{};min-height:{};",
|
||||
scaled_px(layout.custom_minimum_size.x)?,
|
||||
scaled_px(layout.custom_minimum_size.y)?
|
||||
));
|
||||
}
|
||||
Ok(format!(
|
||||
"position:absolute;left:{};top:{};right:{};bottom:{};",
|
||||
css_length(transform.anchor_min.x * 100.0, transform.offset_min.x)?,
|
||||
css_length(transform.anchor_min.y * 100.0, transform.offset_min.y)?,
|
||||
css_length(
|
||||
(1.0 - transform.anchor_max.x) * 100.0,
|
||||
-transform.offset_max.x
|
||||
)?,
|
||||
css_length(
|
||||
(1.0 - transform.anchor_max.y) * 100.0,
|
||||
-transform.offset_max.y
|
||||
)?
|
||||
))
|
||||
}
|
||||
|
||||
fn css_length(percent: f32, offset: f32) -> Result<String, String> {
|
||||
if !percent.is_finite() || !offset.is_finite() {
|
||||
return Err("Transform 无法转换为 CSS".to_string());
|
||||
}
|
||||
if percent == 0.0 {
|
||||
return Ok(format!("calc({}px * {})", trim_float(offset), UI_SCALE));
|
||||
}
|
||||
if offset == 0.0 {
|
||||
return Ok(format!("{}%", trim_float(percent)));
|
||||
}
|
||||
Ok(format!(
|
||||
"calc({}% {} {}px * {})",
|
||||
trim_float(percent),
|
||||
if offset < 0.0 { '-' } else { '+' },
|
||||
trim_float(offset.abs()),
|
||||
UI_SCALE
|
||||
))
|
||||
}
|
||||
|
||||
fn scaled_px(value: f32) -> Result<String, String> {
|
||||
finite(value, "layout px")?;
|
||||
Ok(format!("calc({}px * {})", trim_float(value), UI_SCALE))
|
||||
}
|
||||
|
||||
pub(super) fn is_container(
|
||||
container: &crate::ui_editor::layout::control_layout::Container,
|
||||
) -> bool {
|
||||
!matches!(
|
||||
container,
|
||||
crate::ui_editor::layout::control_layout::Container::None
|
||||
)
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
pub mod commands;
|
||||
pub mod component;
|
||||
pub(crate) mod html_renderer;
|
||||
pub mod layout;
|
||||
pub mod persistence;
|
||||
pub mod resource;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::ui_editor::component::text::FontSource;
|
||||
use crate::ui_editor::component::Component;
|
||||
use crate::ui_editor::html_renderer::render_ui_design_state_js;
|
||||
use crate::ui_editor::layout::node::Node;
|
||||
use crate::ui_editor::resource::ui_design_image::{
|
||||
UIDesignImage, UIDesignImageMetadata, UIDesignImageRole,
|
||||
@@ -9,6 +10,7 @@ use crate::ui_editor::utils::UIDesignImageId;
|
||||
use crate::*;
|
||||
use nalgebra::Vector2;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::collections::HashSet;
|
||||
use std::fs::{self, File};
|
||||
use std::io::{Read, Write};
|
||||
@@ -18,6 +20,7 @@ use typed_floats::tf32::StrictlyPositiveFinite;
|
||||
|
||||
const UI_DESIGN_STATE_SCHEMA_VERSION: &str = "game-creator-ui-design-state.v1";
|
||||
const UI_DESIGN_STATE_MAX_BYTES: usize = 2 * 1024 * 1024;
|
||||
const UI_DESIGN_CODE_MAX_BYTES: usize = UI_DESIGN_STATE_MAX_BYTES * 8;
|
||||
const UI_DESIGN_STATE_MAX_IMAGES: usize = 4;
|
||||
const UI_DESIGN_STATE_MAX_SPRITES: usize = 1_024;
|
||||
pub(crate) const UI_DESIGN_STATE_MAX_NODES: usize = 10_000;
|
||||
@@ -43,6 +46,23 @@ pub(crate) struct LoadUiDesignStateInput {
|
||||
pub(crate) asset_id: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(deny_unknown_fields, rename_all = "camelCase")]
|
||||
pub(crate) struct GenerateUiDesignCodeInput {
|
||||
pub(crate) project_path: String,
|
||||
pub(crate) expected_project_id: String,
|
||||
pub(crate) asset_id: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub(crate) struct GenerateUiDesignCodeResult {
|
||||
pub(crate) relative_path: String,
|
||||
pub(crate) tree_exports: Vec<String>,
|
||||
pub(crate) tree_count: usize,
|
||||
pub(crate) node_count: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(deny_unknown_fields, rename_all = "camelCase")]
|
||||
pub(crate) struct SaveUiDesignStateInput {
|
||||
@@ -149,6 +169,52 @@ pub(crate) fn load_ui_design_state_at(
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn generate_ui_design_code_at(
|
||||
input: GenerateUiDesignCodeInput,
|
||||
) -> Result<GenerateUiDesignCodeResult, String> {
|
||||
let root = Path::new(input.project_path.trim());
|
||||
let expected_project_id = required_identifier(&input.expected_project_id, "expectedProjectId")?;
|
||||
let asset_id = required_identifier(&input.asset_id, "assetId")?;
|
||||
let _lock = acquire_project_write_lock(root, "ui_design.code_generate")?;
|
||||
let asset = ui_design_asset(root, &expected_project_id, &asset_id)?;
|
||||
let document =
|
||||
read_ui_design_document_locked(root, &asset.local_path, &expected_project_id, &asset_id)?;
|
||||
let (content, tree_exports, node_count) = render_ui_design_state_js(&document.state)?;
|
||||
let relative_path = format!("ui/generated-{}.js", generated_file_stem(&asset_id));
|
||||
let path = resolve_local_project_path(root, &relative_path)?;
|
||||
write_ui_design_raw_file_with_limit(
|
||||
&path,
|
||||
"UI 设计生成代码",
|
||||
content.as_bytes(),
|
||||
UI_DESIGN_CODE_MAX_BYTES,
|
||||
)?;
|
||||
Ok(GenerateUiDesignCodeResult {
|
||||
relative_path,
|
||||
tree_count: tree_exports.len(),
|
||||
tree_exports,
|
||||
node_count,
|
||||
})
|
||||
}
|
||||
|
||||
fn generated_file_stem(asset_id: &str) -> String {
|
||||
let mut stem = String::new();
|
||||
for character in asset_id.chars() {
|
||||
if character.is_ascii_alphanumeric() || matches!(character, '_' | '-') {
|
||||
stem.push(character);
|
||||
} else {
|
||||
stem.push('_');
|
||||
}
|
||||
}
|
||||
let readable_stem = if stem.is_empty() {
|
||||
"ui-design"
|
||||
} else {
|
||||
stem.as_str()
|
||||
};
|
||||
// 保留可读前缀,并追加摘要以避免不同 ID 映射到同一路径。
|
||||
let digest = format!("{:x}", Sha256::digest(asset_id.as_bytes()));
|
||||
format!("{readable_stem}-{}", &digest[..16])
|
||||
}
|
||||
|
||||
pub(crate) fn save_ui_design_state_at(
|
||||
input: SaveUiDesignStateInput,
|
||||
) -> Result<SaveUiDesignStateResult, String> {
|
||||
@@ -382,8 +448,17 @@ fn serialize_ui_design_document(document: &PersistedUiDesignState) -> Result<Vec
|
||||
/// runtime sidecar protocol: a stable `.previous` is recoverable after a
|
||||
/// process crash, unlike a random `.replace.<pid>.<nonce>` file.
|
||||
fn write_ui_design_raw_file(path: &Path, label: &str, bytes: &[u8]) -> Result<(), String> {
|
||||
if bytes.len() > UI_DESIGN_STATE_MAX_BYTES {
|
||||
return Err(format!("{label} 超过 {UI_DESIGN_STATE_MAX_BYTES} 字节上限"));
|
||||
write_ui_design_raw_file_with_limit(path, label, bytes, UI_DESIGN_STATE_MAX_BYTES)
|
||||
}
|
||||
|
||||
fn write_ui_design_raw_file_with_limit(
|
||||
path: &Path,
|
||||
label: &str,
|
||||
bytes: &[u8],
|
||||
max_bytes: usize,
|
||||
) -> Result<(), String> {
|
||||
if bytes.len() > max_bytes {
|
||||
return Err(format!("{label} 超过 {max_bytes} 字节上限"));
|
||||
}
|
||||
let parent = path.parent().ok_or_else(|| format!("{label} 缺少父目录"))?;
|
||||
fs::create_dir_all(parent).map_err(|error| format!("创建 {label} 目录失败:{error}"))?;
|
||||
@@ -920,6 +995,15 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generated_file_stem_keeps_distinct_asset_ids_distinct() {
|
||||
let first = generated_file_stem("a.b");
|
||||
let second = generated_file_stem("a/b");
|
||||
assert_ne!(first, second);
|
||||
assert!(first.starts_with("a_b-"));
|
||||
assert_eq!(first.len(), "a_b-".len() + 16);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preserves_sprite_asset_when_saving_a_dragged_node_transform() {
|
||||
let (directory, asset_id) = fixture();
|
||||
@@ -959,6 +1043,34 @@ mod tests {
|
||||
assert_eq!(loaded.state, state);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preserves_ordered_out_of_range_transform_anchors() {
|
||||
let (directory, asset_id) = fixture();
|
||||
let mut state = state_with_sprite_and_dragged_transform();
|
||||
let transform = &mut state.ui_trees[0].root.children[0].layout.transform;
|
||||
transform.anchor_min = Vector2::new(-0.25, -0.5);
|
||||
transform.anchor_max = Vector2::new(1.5, 1.25);
|
||||
|
||||
let saved = save_ui_design_state_at(input(directory.path(), &asset_id, 0, state.clone()))
|
||||
.expect("save ordered out-of-range anchors");
|
||||
assert!(matches!(
|
||||
saved,
|
||||
SaveUiDesignStateResult::Saved {
|
||||
revision: 1,
|
||||
state: ref installed,
|
||||
..
|
||||
} if installed == &state
|
||||
));
|
||||
|
||||
let loaded = load_ui_design_state_at(LoadUiDesignStateInput {
|
||||
project_path: directory.path().to_string_lossy().into_owned(),
|
||||
expected_project_id: PROJECT_ID.to_string(),
|
||||
asset_id,
|
||||
})
|
||||
.expect("load ordered out-of-range anchors");
|
||||
assert_eq!(loaded.state, state);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_inverted_transform_anchors() {
|
||||
let state: State = serde_json::from_value(serde_json::json!({
|
||||
|
||||
@@ -30,6 +30,15 @@ impl FontFormat {
|
||||
Self::Woff2 => "woff2",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn css_format(self) -> &'static str {
|
||||
match self {
|
||||
Self::TrueType => "truetype",
|
||||
Self::OpenType => "opentype",
|
||||
Self::Woff => "woff",
|
||||
Self::Woff2 => "woff2",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize, TS)]
|
||||
@@ -210,4 +219,12 @@ mod tests {
|
||||
.expect_err("reject unparseable web font")
|
||||
.contains("无法安全解析"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn font_format_uses_css_format_strings() {
|
||||
assert_eq!(FontFormat::TrueType.css_format(), "truetype");
|
||||
assert_eq!(FontFormat::OpenType.css_format(), "opentype");
|
||||
assert_eq!(FontFormat::Woff.css_format(), "woff");
|
||||
assert_eq!(FontFormat::Woff2.css_format(), "woff2");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -410,7 +410,11 @@ export function GddApprovalCard({
|
||||
const canDecide = Boolean(
|
||||
pending && state.state === 'ready_for_approval' && !state.recoveryPending,
|
||||
);
|
||||
const decisionDisabled = !canDecide || decisionBusy || hydrateBusy;
|
||||
// `hydrateBusy` only describes an in-flight background read. Once a card is rendered, the
|
||||
// loaded projection remains the actionable snapshot until it explicitly reports
|
||||
// `recoveryPending`; otherwise a refresh racing the first render can transiently disable an
|
||||
// already-open dialog before the user has had a chance to submit it.
|
||||
const decisionDisabled = !canDecide || decisionBusy;
|
||||
|
||||
const submitComment = () => {
|
||||
// 方案 §18.2:`recoveryPending` 期间只允许重试同一 ID,不允许提交决定。触发按钮
|
||||
|
||||
@@ -14,6 +14,13 @@ export type UiDesignStateSaveResult =
|
||||
}
|
||||
| { status: 'conflict'; current: UiDesignStateSnapshot };
|
||||
|
||||
export type UiDesignCodeGenerationResult = {
|
||||
relativePath: string;
|
||||
treeExports: string[];
|
||||
treeCount: number;
|
||||
nodeCount: number;
|
||||
};
|
||||
|
||||
export type IUiDesignStateStore = {
|
||||
load(assetId: string): Promise<UiDesignStateSnapshot>;
|
||||
save(
|
||||
@@ -21,6 +28,7 @@ export type IUiDesignStateStore = {
|
||||
expectedRevision: number,
|
||||
state: State,
|
||||
): Promise<UiDesignStateSaveResult>;
|
||||
generateCode(assetId: string): Promise<UiDesignCodeGenerationResult>;
|
||||
};
|
||||
|
||||
export function createTauriUiDesignStateStore(
|
||||
@@ -44,6 +52,11 @@ export function createTauriUiDesignStateStore(
|
||||
},
|
||||
});
|
||||
},
|
||||
generateCode(assetId) {
|
||||
return invoke<UiDesignCodeGenerationResult>('generate_ui_design_code', {
|
||||
input: { projectPath, expectedProjectId, assetId },
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -76,6 +89,9 @@ export const uiDesignStateStore: IUiDesignStateStore = {
|
||||
committedProjectRevision: 0,
|
||||
};
|
||||
},
|
||||
async generateCode() {
|
||||
throw new Error('当前环境不支持生成代码');
|
||||
},
|
||||
};
|
||||
|
||||
export const EMPTY_UI_DESIGN_STATE = EMPTY_UI_EDITOR_STATE;
|
||||
|
||||
@@ -80,14 +80,22 @@ function fillClipPath(method: FillMethod, amount: number): string | undefined {
|
||||
const sweep = amount * maxSweep;
|
||||
const origin = config.origin;
|
||||
const originAngle =
|
||||
origin === 'Top' || origin === 'TopLeft' || origin === 'TopRight'
|
||||
? 0
|
||||
: origin === 'Right' || origin === 'BottomRight'
|
||||
? 90
|
||||
: origin === 'Bottom' || origin === 'BottomLeft'
|
||||
? 180
|
||||
: 270;
|
||||
const start = config.clockwise ? originAngle : originAngle - sweep;
|
||||
kind === 'Radial90'
|
||||
? origin === 'TopLeft'
|
||||
? 0
|
||||
: origin === 'TopRight'
|
||||
? 90
|
||||
: origin === 'BottomRight'
|
||||
? 180
|
||||
: 270
|
||||
: origin === 'Top'
|
||||
? 0
|
||||
: origin === 'Right'
|
||||
? 90
|
||||
: origin === 'Bottom'
|
||||
? 180
|
||||
: 270;
|
||||
const start = originAngle - (config.clockwise ? 90 : sweep);
|
||||
// CSS conic gradients provide a deterministic browser preview for radial
|
||||
// fills. Exact engine parity is intentionally deferred.
|
||||
return `conic-gradient(from ${start}deg, #000 0deg ${sweep}deg, transparent ${sweep}deg 360deg)`;
|
||||
@@ -141,6 +149,7 @@ function imageTypeModel(
|
||||
const size = logicalSize(sprite, multiplier);
|
||||
|
||||
if ('Tiled' in imageType) {
|
||||
// TODO: Tiled.fill_center=false 当前暂不支持,保持浏览器 repeat fallback。
|
||||
return {
|
||||
kind: 'background',
|
||||
src,
|
||||
|
||||
@@ -367,8 +367,6 @@ export function TransformEditor({
|
||||
const warning =
|
||||
transform.anchor_min[0] > transform.anchor_max[0] ||
|
||||
transform.anchor_min[1] > transform.anchor_max[1] ||
|
||||
transform.anchor_min.some((value) => value < 0 || value > 1) ||
|
||||
transform.anchor_max.some((value) => value < 0 || value > 1) ||
|
||||
geometry?.invalid;
|
||||
|
||||
return (
|
||||
|
||||
@@ -39,7 +39,7 @@ export function WorkflowActionCard({
|
||||
<button
|
||||
type="button"
|
||||
className="rounded-lg bg-orange-600 px-3 py-1.5 text-xs font-semibold text-white disabled:cursor-wait disabled:opacity-60"
|
||||
disabled={workflow.isAiRunning}
|
||||
disabled={workflow.isBusy}
|
||||
onClick={() => void action.action()}
|
||||
>
|
||||
{running ? action.runningLabel : hasRun ? '重新运行' : action.label}
|
||||
@@ -48,7 +48,7 @@ export function WorkflowActionCard({
|
||||
<button
|
||||
type="button"
|
||||
className="rounded-lg border border-(--platform-subpanel-border) px-3 py-1.5 text-xs disabled:cursor-wait disabled:opacity-60"
|
||||
disabled={workflow.isAiRunning}
|
||||
disabled={workflow.isBusy}
|
||||
onClick={workflow.continueToNextStep}
|
||||
>
|
||||
继续
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ChevronLeft } from 'lucide-react';
|
||||
import { type ReactNode, useMemo, useState } from 'react';
|
||||
import { type ReactNode, useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import { ThemedModal } from '../../components/modal/ThemedModal';
|
||||
import {
|
||||
@@ -22,6 +22,12 @@ import {
|
||||
useUiEditorSession,
|
||||
} from './useUiEditorPage';
|
||||
|
||||
function saveAndGenerateLabel(isSaving: boolean, isGenerating: boolean) {
|
||||
if (isSaving) return '保存中…';
|
||||
if (isGenerating) return '生成中…';
|
||||
return '保存并生成代码';
|
||||
}
|
||||
|
||||
export default function UiEditorPage({
|
||||
projectPath,
|
||||
resourceId,
|
||||
@@ -60,7 +66,21 @@ export default function UiEditorPage({
|
||||
);
|
||||
const [saveWarningOpen, setSaveWarningOpen] = useState(false);
|
||||
const [saveAfterReturn, setSaveAfterReturn] = useState(false);
|
||||
const [generateAfterWarning, setGenerateAfterWarning] = useState(false);
|
||||
const [generateSuccess, setGenerateSuccess] = useState<string | null>(null);
|
||||
const [returnConfirmOpen, setReturnConfirmOpen] = useState(false);
|
||||
const saveDisabled =
|
||||
session.save.isSaving ||
|
||||
session.save.isGenerating ||
|
||||
session.save.isLoading ||
|
||||
session.workflow.isAiRunning ||
|
||||
Boolean(session.save.loadError) ||
|
||||
session.save.persistedRevision === null ||
|
||||
session.save.isLocked;
|
||||
|
||||
useEffect(() => {
|
||||
if (session.save.isDirty) setGenerateSuccess(null);
|
||||
}, [session.save.isDirty]);
|
||||
|
||||
async function save(afterReturn = false) {
|
||||
if (await session.save.save()) {
|
||||
@@ -71,11 +91,22 @@ export default function UiEditorPage({
|
||||
}
|
||||
}
|
||||
|
||||
async function saveAndGenerate() {
|
||||
setGenerateSuccess(null);
|
||||
const result = await session.save.saveAndGenerateCode();
|
||||
if (result) {
|
||||
setGenerateAfterWarning(false);
|
||||
setGenerateSuccess(`代码已生成:${result.relativePath}`);
|
||||
}
|
||||
}
|
||||
|
||||
function requestSave(afterReturn = false) {
|
||||
if (!resourceId || session.save.isSaving || session.workflow.isAiRunning) {
|
||||
return;
|
||||
}
|
||||
setGenerateSuccess(null);
|
||||
setSaveAfterReturn(afterReturn);
|
||||
setGenerateAfterWarning(false);
|
||||
if (session.save.hasWarnings()) {
|
||||
setSaveWarningOpen(true);
|
||||
return;
|
||||
@@ -83,6 +114,25 @@ export default function UiEditorPage({
|
||||
void save(afterReturn);
|
||||
}
|
||||
|
||||
function requestSaveAndGenerate() {
|
||||
if (
|
||||
!resourceId ||
|
||||
session.save.isSaving ||
|
||||
session.save.isGenerating ||
|
||||
session.workflow.isAiRunning
|
||||
) {
|
||||
return;
|
||||
}
|
||||
setSaveAfterReturn(false);
|
||||
setGenerateSuccess(null);
|
||||
setGenerateAfterWarning(true);
|
||||
if (session.save.hasWarnings()) {
|
||||
setSaveWarningOpen(true);
|
||||
return;
|
||||
}
|
||||
void saveAndGenerate();
|
||||
}
|
||||
|
||||
function requestBack() {
|
||||
if (session.save.isDirty) {
|
||||
setReturnConfirmOpen(true);
|
||||
@@ -111,17 +161,22 @@ export default function UiEditorPage({
|
||||
<button
|
||||
type="button"
|
||||
className="rounded-lg bg-orange-600 px-3 py-1.5 text-sm font-semibold text-white disabled:opacity-60"
|
||||
disabled={
|
||||
session.save.isSaving ||
|
||||
session.save.isLoading ||
|
||||
Boolean(session.save.loadError) ||
|
||||
session.save.persistedRevision === null ||
|
||||
session.save.isLocked
|
||||
}
|
||||
disabled={saveDisabled}
|
||||
onClick={() => requestSave()}
|
||||
>
|
||||
{session.save.isSaving ? '保存中…' : '保存'}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="rounded-lg border border-orange-600 px-3 py-1.5 text-sm font-semibold text-orange-700 disabled:opacity-60"
|
||||
disabled={saveDisabled}
|
||||
onClick={requestSaveAndGenerate}
|
||||
>
|
||||
{saveAndGenerateLabel(
|
||||
session.save.isSaving,
|
||||
session.save.isGenerating,
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
) : null}
|
||||
@@ -133,10 +188,26 @@ export default function UiEditorPage({
|
||||
<span>{session.save.saveError}</span>
|
||||
</div>
|
||||
) : null}
|
||||
{session.save.generateError ? (
|
||||
<div
|
||||
className="mx-4 mt-3 flex shrink-0 items-center justify-between gap-3 rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-xs text-red-800"
|
||||
role="alert"
|
||||
>
|
||||
<span>代码生成失败:{session.save.generateError}</span>
|
||||
</div>
|
||||
) : null}
|
||||
{generateSuccess ? (
|
||||
<div
|
||||
className="mx-4 mt-3 shrink-0 rounded-lg border border-emerald-200 bg-emerald-50 px-3 py-2 text-xs text-emerald-800"
|
||||
role="status"
|
||||
>
|
||||
{generateSuccess}
|
||||
</div>
|
||||
) : null}
|
||||
<ToolNavigation
|
||||
activeStep={session.workflow.activeStep}
|
||||
furthestStepIndex={session.workflow.furthestStepIndex}
|
||||
disabled={session.workflow.isAiRunning}
|
||||
disabled={session.workflow.isBusy}
|
||||
onChange={session.workflow.requestStepChange}
|
||||
/>
|
||||
<div className="grid min-h-0 min-w-0 flex-1 grid-cols-[minmax(0,24fr)_minmax(0,44fr)_minmax(0,32fr)] overflow-hidden">
|
||||
@@ -205,12 +276,7 @@ export default function UiEditorPage({
|
||||
<button
|
||||
type="button"
|
||||
className="rounded-lg bg-orange-600 px-3 py-2 text-xs font-semibold text-white disabled:opacity-60"
|
||||
disabled={
|
||||
session.save.isSaving ||
|
||||
Boolean(session.save.loadError) ||
|
||||
session.save.persistedRevision === null ||
|
||||
session.save.isLocked
|
||||
}
|
||||
disabled={saveDisabled}
|
||||
onClick={() => requestSave(true)}
|
||||
>
|
||||
{session.save.isSaving ? '保存中…' : '保存并返回'}
|
||||
@@ -273,10 +339,14 @@ export default function UiEditorPage({
|
||||
className="rounded-lg bg-orange-600 px-3 py-2 text-xs font-semibold text-white"
|
||||
onClick={() => {
|
||||
setSaveWarningOpen(false);
|
||||
void save(saveAfterReturn);
|
||||
if (generateAfterWarning) {
|
||||
void saveAndGenerate();
|
||||
} else {
|
||||
void save(saveAfterReturn);
|
||||
}
|
||||
}}
|
||||
>
|
||||
仍然保存
|
||||
{generateAfterWarning ? '仍然保存并生成' : '仍然保存'}
|
||||
</button>
|
||||
</div>
|
||||
</ThemedModal>
|
||||
|
||||
@@ -186,6 +186,8 @@ export function useUiEditorSession(
|
||||
);
|
||||
const [saveError, setSaveError] = useState<string | null>(null);
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
const [generateError, setGenerateError] = useState<string | null>(null);
|
||||
const [isGenerating, setIsGenerating] = useState(false);
|
||||
const normalizedInitialStepIndex =
|
||||
initialStep === 'reference-analysis'
|
||||
? 0
|
||||
@@ -255,6 +257,8 @@ export function useUiEditorSession(
|
||||
setPersistedRevision(0);
|
||||
setSavedStateSignature(JSON.stringify(EMPTY_UI_EDITOR_STATE));
|
||||
setSaveError(null);
|
||||
setGenerateError(null);
|
||||
setIsGenerating(false);
|
||||
setHiddenNodeIds(new Set());
|
||||
return;
|
||||
}
|
||||
@@ -263,6 +267,9 @@ export function useUiEditorSession(
|
||||
setIsLoading(true);
|
||||
setLoadError(null);
|
||||
setPersistedRevision(null);
|
||||
setSaveError(null);
|
||||
setGenerateError(null);
|
||||
setIsGenerating(false);
|
||||
void stateStore
|
||||
.load(resourceId)
|
||||
.then(({ state, revision }) => {
|
||||
@@ -365,6 +372,8 @@ export function useUiEditorSession(
|
||||
!isSlaveToDescendant(images, id as UIDesignImageId, activeImageId),
|
||||
);
|
||||
const isAiRunning = isSuggesting || isRecognizing || isBinding || isMerging;
|
||||
const isWorkflowBusy =
|
||||
isAiRunning || isSaving || isGenerating || isLoading || editor.isLocked;
|
||||
const stateSignature = JSON.stringify(editor.state);
|
||||
const isDirty =
|
||||
resourceId !== undefined &&
|
||||
@@ -658,7 +667,7 @@ export function useUiEditorSession(
|
||||
}
|
||||
|
||||
function requestStepChange(step: UiEditorStepId) {
|
||||
if (step === activeStep || isAiRunning) return;
|
||||
if (step === activeStep || isWorkflowBusy) return;
|
||||
const leavingIssues = postCheckIssuesForStep(editor.state, activeStep);
|
||||
const enteringIssues = prerequisiteIssuesForStep(editor.state, step);
|
||||
if (leavingIssues.length === 0 && enteringIssues.length === 0) {
|
||||
@@ -929,7 +938,7 @@ export function useUiEditorSession(
|
||||
}
|
||||
|
||||
async function suggestUiDesignSemantics() {
|
||||
if (isSuggesting) return;
|
||||
if (isSuggesting || isWorkflowBusy) return;
|
||||
setSuggestionStatus(null);
|
||||
setIsSuggesting(true);
|
||||
try {
|
||||
@@ -952,7 +961,7 @@ export function useUiEditorSession(
|
||||
}
|
||||
|
||||
async function recognizeUi() {
|
||||
if (isRecognizing) return;
|
||||
if (isRecognizing || isWorkflowBusy) return;
|
||||
setRecognitionStatus(null);
|
||||
setIsRecognizing(true);
|
||||
try {
|
||||
@@ -977,7 +986,7 @@ export function useUiEditorSession(
|
||||
|
||||
async function mergeUi() {
|
||||
// TODO: This experimental operation is intentionally outside the formal workflow.
|
||||
if (isMerging) return;
|
||||
if (isMerging || isWorkflowBusy) return;
|
||||
setMergeStatus(null);
|
||||
setIsMerging(true);
|
||||
try {
|
||||
@@ -995,7 +1004,7 @@ export function useUiEditorSession(
|
||||
}
|
||||
|
||||
async function bindComponents() {
|
||||
if (isBinding) return;
|
||||
if (isBinding || isWorkflowBusy) return;
|
||||
setBindingStatus(null);
|
||||
setIsBinding(true);
|
||||
try {
|
||||
@@ -1037,7 +1046,9 @@ export function useUiEditorSession(
|
||||
if (
|
||||
!resourceId ||
|
||||
isSaving ||
|
||||
isGenerating ||
|
||||
isLoading ||
|
||||
isAiRunning ||
|
||||
loadError ||
|
||||
persistedRevision === null ||
|
||||
editor.isLocked
|
||||
@@ -1045,24 +1056,26 @@ export function useUiEditorSession(
|
||||
return false;
|
||||
}
|
||||
setSaveError(null);
|
||||
setGenerateError(null);
|
||||
setIsSaving(true);
|
||||
const snapshot = structuredClone(editor.state);
|
||||
const snapshotSignature = JSON.stringify(snapshot);
|
||||
try {
|
||||
const result = await stateStore.save(
|
||||
resourceId,
|
||||
persistedRevision,
|
||||
snapshot,
|
||||
);
|
||||
if (result.status === 'conflict') {
|
||||
setSaveError('资源已在别处更新;请重新加载后再保存。');
|
||||
return false;
|
||||
}
|
||||
setPersistedRevision(result.revision);
|
||||
if (JSON.stringify(editor.state) === snapshotSignature) {
|
||||
setSavedStateSignature(snapshotSignature);
|
||||
}
|
||||
return true;
|
||||
return await editor.runWithStateLocked(async (snapshot) => {
|
||||
const snapshotSignature = JSON.stringify(snapshot);
|
||||
const result = await stateStore.save(
|
||||
resourceId,
|
||||
persistedRevision,
|
||||
snapshot,
|
||||
);
|
||||
if (result.status === 'conflict') {
|
||||
setSaveError('资源已在别处更新;请重新加载后再保存。');
|
||||
return false;
|
||||
}
|
||||
setPersistedRevision(result.revision);
|
||||
if (JSON.stringify(editor.state) === snapshotSignature) {
|
||||
setSavedStateSignature(snapshotSignature);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
} catch {
|
||||
setSaveError('保存失败,请稍后重试。');
|
||||
return false;
|
||||
@@ -1071,6 +1084,78 @@ export function useUiEditorSession(
|
||||
}
|
||||
}
|
||||
|
||||
async function generateCode() {
|
||||
if (
|
||||
!resourceId ||
|
||||
isGenerating ||
|
||||
isSaving ||
|
||||
isLoading ||
|
||||
isAiRunning ||
|
||||
loadError ||
|
||||
persistedRevision === null ||
|
||||
editor.isLocked
|
||||
) {
|
||||
setGenerateError('当前状态不允许生成代码,请稍后重试。');
|
||||
return null;
|
||||
}
|
||||
setGenerateError(null);
|
||||
setIsGenerating(true);
|
||||
try {
|
||||
return await editor.runWithStateLocked(() =>
|
||||
stateStore.generateCode(resourceId),
|
||||
);
|
||||
} catch (cause) {
|
||||
setGenerateError(cause instanceof Error ? cause.message : String(cause));
|
||||
return null;
|
||||
} finally {
|
||||
setIsGenerating(false);
|
||||
}
|
||||
}
|
||||
|
||||
async function saveAndGenerateCode() {
|
||||
if (
|
||||
!resourceId ||
|
||||
isSaving ||
|
||||
isGenerating ||
|
||||
isLoading ||
|
||||
isAiRunning ||
|
||||
loadError ||
|
||||
persistedRevision === null ||
|
||||
editor.isLocked
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
setSaveError(null);
|
||||
setGenerateError(null);
|
||||
setIsSaving(true);
|
||||
setIsGenerating(true);
|
||||
try {
|
||||
return await editor.runWithStateLocked(async (snapshot) => {
|
||||
const snapshotSignature = JSON.stringify(snapshot);
|
||||
const saved = await stateStore.save(
|
||||
resourceId,
|
||||
persistedRevision,
|
||||
snapshot,
|
||||
);
|
||||
if (saved.status === 'conflict') {
|
||||
setSaveError('资源已在别处更新;请重新加载后再保存。');
|
||||
return null;
|
||||
}
|
||||
setPersistedRevision(saved.revision);
|
||||
if (JSON.stringify(editor.state) === snapshotSignature) {
|
||||
setSavedStateSignature(snapshotSignature);
|
||||
}
|
||||
return await stateStore.generateCode(resourceId);
|
||||
});
|
||||
} catch (cause) {
|
||||
setGenerateError(cause instanceof Error ? cause.message : String(cause));
|
||||
return null;
|
||||
} finally {
|
||||
setIsGenerating(false);
|
||||
setIsSaving(false);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
input: {
|
||||
projectPath,
|
||||
@@ -1197,6 +1282,7 @@ export function useUiEditorSession(
|
||||
furthestStepIndex,
|
||||
nextStep,
|
||||
isAiRunning,
|
||||
isBusy: isWorkflowBusy,
|
||||
pendingStepChange: pendingWorkflowStepChange,
|
||||
isSuggesting,
|
||||
hasSuggested,
|
||||
@@ -1237,9 +1323,13 @@ export function useUiEditorSession(
|
||||
isSaving,
|
||||
isDirty,
|
||||
saveError,
|
||||
isGenerating,
|
||||
generateError,
|
||||
hasWarnings: () => postCheckIssuesForSave(editor.state).length > 0,
|
||||
warnings: () => postCheckIssuesForSave(editor.state),
|
||||
save,
|
||||
generateCode,
|
||||
saveAndGenerateCode,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -137,6 +137,7 @@ async function renderLoadedSession(state: State) {
|
||||
const stateStore: IUiDesignStateStore = {
|
||||
load: vi.fn().mockResolvedValue({ revision: 0, state }),
|
||||
save: vi.fn(),
|
||||
generateCode: vi.fn().mockRejectedValue(new Error('测试未配置代码生成')),
|
||||
};
|
||||
const hook = renderHook(() =>
|
||||
useUiEditorSession('/tmp/ui-editor', 'ui-resource', stateStore),
|
||||
@@ -150,6 +151,7 @@ describe('UiEditorPage', () => {
|
||||
const stateStore: IUiDesignStateStore = {
|
||||
load: vi.fn().mockResolvedValue(structuredClone(EMPTY_SNAPSHOT)),
|
||||
save: vi.fn(),
|
||||
generateCode: vi.fn().mockRejectedValue(new Error('测试未配置代码生成')),
|
||||
};
|
||||
|
||||
render(
|
||||
@@ -193,6 +195,7 @@ describe('UiEditorPage', () => {
|
||||
state: stateWithPages(['page']),
|
||||
}),
|
||||
save: vi.fn(),
|
||||
generateCode: vi.fn().mockRejectedValue(new Error('测试未配置代码生成')),
|
||||
};
|
||||
const hook = renderHook(
|
||||
({ resourceId }) =>
|
||||
@@ -248,6 +251,7 @@ describe('UiEditorPage', () => {
|
||||
const stateStore: IUiDesignStateStore = {
|
||||
load: vi.fn(() => new Promise(() => undefined)),
|
||||
save: vi.fn(),
|
||||
generateCode: vi.fn().mockRejectedValue(new Error('测试未配置代码生成')),
|
||||
};
|
||||
const hook = renderHook(() =>
|
||||
useUiEditorSession('/tmp/ui-editor', 'ui-resource', stateStore),
|
||||
@@ -355,6 +359,7 @@ describe('UiEditorPage', () => {
|
||||
state: stateWithPages(['gameplay-page']),
|
||||
}),
|
||||
save: vi.fn(),
|
||||
generateCode: vi.fn().mockRejectedValue(new Error('测试未配置代码生成')),
|
||||
};
|
||||
|
||||
render(
|
||||
@@ -594,6 +599,7 @@ describe('UiEditorPage', () => {
|
||||
const stateStore: IUiDesignStateStore = {
|
||||
load: vi.fn().mockResolvedValue(structuredClone(EMPTY_SNAPSHOT)),
|
||||
save: vi.fn().mockRejectedValue(new Error('临时存储不可用')),
|
||||
generateCode: vi.fn().mockRejectedValue(new Error('测试未配置代码生成')),
|
||||
};
|
||||
render(
|
||||
createElement(UiEditorPage, {
|
||||
@@ -627,6 +633,7 @@ describe('UiEditorPage', () => {
|
||||
status: 'conflict',
|
||||
currentRevision: 1,
|
||||
}),
|
||||
generateCode: vi.fn().mockRejectedValue(new Error('测试未配置代码生成')),
|
||||
};
|
||||
render(
|
||||
createElement(UiEditorPage, {
|
||||
|
||||
P1:这里把 FontFormat 的文件扩展名(
ttf/otf)直接作为 CSSformat()值输出。CSS Fonts 的 format 标识应为truetype/opentype(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。审查 head sha:
a63a477a6bP1:这里把 FontFormat 的文件扩展名(
ttf/otf)直接作为 CSSformat()值输出。CSS Fonts 的 format 标识应为truetype/opentype(woff/woff2 才与扩展名相同);浏览器会因此跳过 TTF/OTF source,导出 UI 的字体回退到系统字体,导致字体选择和视觉布局失真。建议增加 FontFormat -> CSS format 的显式映射并覆盖 TTF/OTF/WOFF/WOFF2 的导出测试。审查 head sha:
a63a477a6b