A MoonBit port of rough.js 4.6.6: hand-drawn, sketchy shapes rendered to backend-agnostic op sets and SVG.
fn main {
let gen = @moon_rough.generator()
let rect = gen.rectangle(
10.0, 10.0, 200.0, 100.0,
options=@moon_rough.Options::new(
seed=42,
fill="#e66",
fill_style=CrossHatch,
roughness=1.5,
),
)
// 和后端无关的数据:OpSet 列表,每个 op 是 Move / LineTo / BCurveTo
for set in rect.sets {
println("\{set.kind.name()}: \{set.ops.length()} ops")
}
// 转成 SVG:每个 OpSet 一个 <path>,整个 Drawable 一个 <g>
println(@moon_rough.svg_document(220.0, 120.0, @moon_rough.drawable_to_svg(rect)))
}| 包 | 内容 | 移植来源 |
|---|---|---|
| sayoi7799/moon_rough | 门面:generator()、常用类型、drawable_to_svg | — |
| .../core | Generator、Options、Drawable / OpSet / Op、renderer、7 种填充 | roughjs generator.ts、renderer.ts、fillers/* |
| .../svg | drawable_to_svg、svg_document | roughjs svg.ts(输出字符串,不操作 DOM) |
| .../random | Random(Park–Miller)、RandomSource | roughjs math.ts |
| .../path_data | parse_path、absolutize、normalize(含弧线转贝塞尔)、serialize | path-data-parser 0.1.0 |
| .../curve | points_on_bezier_curves、simplify、curve_to_bezier、points_on_path | points-on-curve 0.2.0、points-on-path 0.2.1 |
| .../hachure | hachure_lines(扫描线填充) | hachure-fill 0.5.2 |
| .../geometry | 可变的 Point | roughjs geometry.ts |
| .../jsmath | 和 V8 逐位一致的 sin / cos / tan / asin / atan、Math.round、toFixed、Number#toString、parseFloat、Math.min/max | — |
| rough.js | moon_rough |
|---|---|
| rough.generator({ options }) | @moon_rough.generator(options=…, source=…) |
| gen.line(x1, y1, x2, y2, o) | gen.line(x1, y1, x2, y2, options=o) |
| gen.rectangle / ellipse / circle | 同名方法 |
| gen.linearPath(points, o) / gen.polygon(points, o) | gen.linear_path(points) / gen.polygon(points),points : Array[(Double, Double)] |
| gen.arc(x, y, w, h, start, stop, closed, o) | gen.arc(x, y, w, h, start, stop, closed=true) |
| gen.curve(Point[]) / gen.curve(Point[][]) | gen.curve(points) / gen.curves(points_list) |
| gen.path(d, o) | gen.path(d),非法路径 raise PathError |
| gen.opsToPath(set, digits) / gen.toPaths(d) | ops_to_path(set, fixed_decimals=…) / gen.to_paths(d) |
| RoughSVG.draw(drawable) | drawable_to_svg(drawable)(属性及顺序与 setAttribute 一致) |
| { roughness: 2, fillStyle: 'zigzag' } | Options::new(roughness=2.0, fill_style=Zigzag) |
| 功能 | 状态 |
|---|---|
| 图形:line、rectangle、ellipse、circle、linearPath、polygon、arc(开 / 闭)、curve(单条 / 多条)、path | ✅ 全部 |
| 填充:hachure、solid、zigzag、cross-hatch、dots、dashed、zigzag-line | ✅ 全部 |
| 选项:maxRandomnessOffset、roughness、bowing、stroke、strokeWidth、curveFitting、curveTightness、curveStepCount、fill、fillStyle、fillWeight、hachureAngle、hachureGap、simplification、dashOffset、dashGap、zigzagOffset、seed、strokeLineDash、strokeLineDashOffset、fillLineDash、fillLineDashOffset、disableMultiStroke、disableMultiStrokeFill、preserveVertices、fixedDecimalPlaceDigits、fillShapeRoughnessGain | ✅ 全部(默认值照 generator.ts) |
| SVG 路径:M L H V C S Q T A Z 及其相对形式、隐式重复、紧凑数字写法、弧线转三次贝塞尔 | ✅ |
| 输出:Drawable(OpSet 列表)、SVG 字符串、opsToPath、toPaths | ✅ |
| Canvas 后端、浏览器演示页、与 diago 对接、动画 | ⏳ 后续阶段 |
moon test --target jsmoon test --target wasm-gcmoon test --target native| 类别 | 内容 |
|---|---|
| 底层 | Random 13 个 seed(含 −2³¹、2³¹−1、cloneOptionsAlterSeed 产生的非 int32 的 2³¹)各前 1000 个输出、seed 0 的回退;约 2.9 万条数学 / toFixed / toString / parseFloat 用例;456 条路径的 parse / absolutize / normalize / serialize;Bézier 采样、简化、curveToBezier、pointsOnPath(含点对象的身份);600 组 hachure-fill(含旋转回来后的多边形坐标) |
| 图形 × 填充 | 642 个用例:所有图形 × 描边 / solid / hachure × 多组选项;415 个用例:8 种可填充图形 × 7 种填充 × 多组选项 |
| 随机组合 | 600 组随机图形 + 随机选项(roughness、bowing、角度、间距、preserveVertices、disableMultiStroke(Fill)、曲线参数、虚线 / 锯齿参数、simplification、各种 fill 值和填充样式) |
| 边界情况 | 宽高为 0、长度为 0、roughness 0、单点 / 两点 / 空的 polygon、linearPath 和 curve、空路径、只有 M 的路径、带相对命令和弧线的复杂路径、非法路径(返回错误)、无穷坐标、curveStepCount 1 和 2 等 321 个用例;同一生成器连续调用的序列;以及 rough.js 会死循环或抛异常的输入(只检查能正常结束) |
| suite | values | js | wasm-gc | native |
|---|---|---|---|---|
| core edge cases | 69890 | 0 (0 inexact) | 0 (0 inexact) | 0 (0 inexact) |
| core fills | 309900 | 0 (0 inexact) | 0 (0 inexact) | 0 (0 inexact) |
| core random | 249504 | 0 (0 inexact) | 0 (0 inexact) | 0 (0 inexact) |
| core sequences | 3248 | 0 (0 inexact) | 0 (0 inexact) | 0 (0 inexact) |
| core shapes | 196962 | 0 (0 inexact) | 0 (0 inexact) | 0 (0 inexact) |
| curve curve_to_bezier | 10614 | 0 (0 inexact) | 0 (0 inexact) | 0 (0 inexact) |
| curve points_on_bezier_curves | 51712 | 0 (0 inexact) | 0 (0 inexact) | 0 (0 inexact) |
| curve points_on_path | 67786 | 0 (0 inexact) | 0 (0 inexact) | 0 (0 inexact) |
| curve simplify | 7796 | 0 (0 inexact) | 0 (0 inexact) | 0 (0 inexact) |
| hachure | 994388 | 0 (0 inexact) | 0 (0 inexact) | 0 (0 inexact) |
| jsmath trig | 28085 | 0 (0 inexact) | 0 (0 inexact) | 0 (0 inexact) |
| jsmath trig edge cases | 12200 | 0 (0 inexact) | 0 (0 inexact) | 0 (0 inexact) |
| path_data | 43038 | 0 (0 inexact) | 0 (0 inexact) | 0 (0 inexact) |
| random | 13000 | 0 (0 inexact) | 0 (0 inexact) | 0 (0 inexact) |
cd scripts && npm ci && npm run gen| 项目 | 版本 | 许可证 | 作者 |
|---|---|---|---|
| roughjs | 4.6.6 | MIT | Preet Shihn |
| hachure-fill | 0.5.2 | MIT | Preet Shihn |
| path-data-parser | 0.1.0 | MIT | Preet Shihn |
| points-on-curve | 0.2.0 | MIT | Preet Shihn |
| points-on-path | 0.2.1 | MIT | Preet Shihn |
fn svg_document(width : Double, height : Double, content : String, background? : String) -> StringInstall
Download zipA MoonBit port of rough.js 4.6.6: hand-drawn, sketchy shapes rendered to backend-agnostic op sets and SVG.