Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
653a9f9
stroke dash array type
softmarshmallow Oct 29, 2025
f3283a4
type dec
softmarshmallow Oct 29, 2025
a8ebfc5
dasharray control
softmarshmallow Oct 29, 2025
b2a4c66
add stroke cap type
softmarshmallow Oct 29, 2025
71b9a56
stroke style
softmarshmallow Oct 29, 2025
faefea1
dasharray preserve zero
softmarshmallow Oct 29, 2025
c98ebaf
use prelude
softmarshmallow Oct 29, 2025
4af862e
Refactor StrokeDashArray normalization logic to enhance SVG complianc…
softmarshmallow Oct 29, 2025
66c4bfb
stroke class select control
softmarshmallow Oct 29, 2025
357233c
wasm 0.0.81-canary.0
softmarshmallow Oct 29, 2025
973d7df
fix doctest
softmarshmallow Oct 29, 2025
010a8d2
stroke width type
softmarshmallow Oct 30, 2025
d7d0afa
Enhance stroke width handling by introducing `SingularStrokeWidth` fo…
softmarshmallow Oct 30, 2025
8e4fc38
update examples spec
softmarshmallow Oct 30, 2025
2e94d89
cascading width
softmarshmallow Oct 30, 2025
96fd9d4
ui: stroke width 4 control
softmarshmallow Oct 30, 2025
2e96ff7
wg docs: stroke rect
softmarshmallow Oct 30, 2025
6dd07a7
stroke rect model
softmarshmallow Oct 31, 2025
8c790ac
wasm 0.0.81-canary.1 - stroke rect
softmarshmallow Oct 31, 2025
43fdca8
Refactor stroke options to include dash array support across vector n…
softmarshmallow Nov 2, 2025
63295dd
stroke join type
softmarshmallow Nov 2, 2025
5154b3a
ts strokeJoin
softmarshmallow Nov 2, 2025
4a3abd8
stroke join control
softmarshmallow Nov 2, 2025
44840e7
impl stroke join
softmarshmallow Nov 2, 2025
0498083
Add stroke miter limit support
softmarshmallow Nov 2, 2025
c03015d
cmath.miter
softmarshmallow Nov 2, 2025
bd681da
miter limit control
softmarshmallow Nov 2, 2025
35ee7a3
wasm 0.0.81-canary.2 - stroke join
softmarshmallow Nov 2, 2025
464f513
chore
softmarshmallow Nov 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/grida-canvas-wasm/lib/bin/grida-canvas-wasm.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions crates/grida-canvas-wasm/lib/bin/grida_canvas_wasm.wasm
Git LFS file not shown
2 changes: 1 addition & 1 deletion crates/grida-canvas-wasm/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@grida/canvas-wasm",
"description": "WASM bindings for Grida Canvas",
"version": "0.0.80-canary.3",
"version": "0.0.81-canary.2",
"keywords": [
"grida",
"canvas",
Expand Down
11 changes: 8 additions & 3 deletions crates/grida-canvas/benches/bench_rectangles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,14 @@ fn create_rectangles(count: usize, with_effects: bool) -> Scene {
corner_smoothing: CornerSmoothing::default(),
fills: Paints::new([Paint::from(CGColor(255, 0, 0, 255))]),
strokes: Paints::default(),
stroke_width: 1.0,
stroke_align: StrokeAlign::Inside,
stroke_dash_array: None,
stroke_style: StrokeStyle {
stroke_align: StrokeAlign::Inside,
stroke_cap: StrokeCap::default(),
stroke_join: StrokeJoin::default(),
stroke_miter_limit: StrokeMiterLimit::default(),
stroke_dash_array: None,
},
stroke_width: 1.0.into(),
effects: if with_effects {
LayerEffects::from_array(vec![FilterEffect::DropShadow(FeShadow {
dx: 2.0,
Expand Down
4 changes: 2 additions & 2 deletions crates/grida-canvas/examples/golden_container_stroke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ async fn scene() -> Scene {
let mut container = nf.create_container_node();
container.layout_dimensions.width = Some(400.0);
container.layout_dimensions.height = Some(400.0);
container.stroke_width = 10.0;
container.stroke_align = StrokeAlign::Outside;
container.stroke_width = 10.0.into();
container.stroke_style.stroke_align = StrokeAlign::Outside;
container.strokes = Paints::new([Paint::from(CGColor(255, 0, 0, 255))]);
container.set_fill(Paint::from(CGColor(255, 255, 255, 255)));
// Center the container in the 800x800 canvas
Expand Down
8 changes: 4 additions & 4 deletions crates/grida-canvas/examples/golden_corner_smoothing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ async fn create_scene() -> Scene {
rect_circular.corner_smoothing = CornerSmoothing::new(0.0); // Circular
rect_circular.fills = Paints::default(); // No fill
rect_circular.strokes = Paints::new([Paint::from(CGColor::from_rgb(255, 50, 50))]);
rect_circular.stroke_width = 3.0;
rect_circular.stroke_align = StrokeAlign::Center;
rect_circular.stroke_width = 3.0.into();
rect_circular.stroke_style.stroke_align = StrokeAlign::Center;

graph.append_child(Node::Rectangle(rect_circular), Parent::Root);

Expand All @@ -53,8 +53,8 @@ async fn create_scene() -> Scene {
rect_smoothed.corner_smoothing = CornerSmoothing::new(1.0); // Maximum smoothing
rect_smoothed.fills = Paints::default(); // No fill
rect_smoothed.strokes = Paints::new([Paint::from(CGColor::from_rgb(50, 150, 255))]);
rect_smoothed.stroke_width = 3.0;
rect_smoothed.stroke_align = StrokeAlign::Center;
rect_smoothed.stroke_width = 3.0.into();
rect_smoothed.stroke_style.stroke_align = StrokeAlign::Center;

graph.append_child(Node::Rectangle(rect_smoothed), Parent::Root);

Expand Down
13 changes: 9 additions & 4 deletions crates/grida-canvas/examples/golden_layout_flex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use cg::layout::ComputedLayout;
use cg::node::factory::NodeFactory;
use cg::node::scene_graph::{Parent, SceneGraph};
use cg::node::schema::{
ContainerNodeRec, LayoutContainerStyle, LayoutDimensionStyle, Node, Scene, Size,
ContainerNodeRec, LayoutContainerStyle, LayoutDimensionStyle, Node, Scene, Size, StrokeStyle,
};
use skia_safe::{surfaces, Color, Font, FontMgr, Paint, Rect};

Expand All @@ -31,9 +31,14 @@ fn create_container_with_gap(id: &str, width: f32, height: f32, gap: f32) -> Con
corner_smoothing: Default::default(),
fills: Default::default(),
strokes: Default::default(),
stroke_width: 0.0,
stroke_align: StrokeAlign::Center,
stroke_dash_array: None,
stroke_style: StrokeStyle {
stroke_align: StrokeAlign::Center,
stroke_cap: StrokeCap::default(),
stroke_join: StrokeJoin::default(),
stroke_miter_limit: StrokeMiterLimit::default(),
stroke_dash_array: None,
},
stroke_width: Default::default(),
effects: Default::default(),
clip: Default::default(),
layout_container: LayoutContainerStyle {
Expand Down
13 changes: 9 additions & 4 deletions crates/grida-canvas/examples/golden_layout_flex_alignment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use cg::layout::ComputedLayout;
use cg::node::factory::NodeFactory;
use cg::node::scene_graph::{Parent, SceneGraph};
use cg::node::schema::{
ContainerNodeRec, LayoutContainerStyle, LayoutDimensionStyle, Node, Scene, Size,
ContainerNodeRec, LayoutContainerStyle, LayoutDimensionStyle, Node, Scene, Size, StrokeStyle,
};
use skia_safe::{surfaces, Color, Font, FontMgr, Paint, Rect};

Expand All @@ -27,9 +27,14 @@ fn create_child_container(id: &str, width: f32, height: f32) -> ContainerNodeRec
corner_smoothing: Default::default(),
fills: Default::default(),
strokes: Default::default(),
stroke_width: 0.0,
stroke_align: StrokeAlign::Center,
stroke_dash_array: None,
stroke_style: StrokeStyle {
stroke_align: StrokeAlign::Center,
stroke_cap: StrokeCap::default(),
stroke_join: StrokeJoin::default(),
stroke_miter_limit: StrokeMiterLimit::default(),
stroke_dash_array: None,
},
stroke_width: Default::default(),
effects: Default::default(),
clip: Default::default(),
layout_container: LayoutContainerStyle {
Expand Down
11 changes: 8 additions & 3 deletions crates/grida-canvas/examples/golden_layout_flex_padding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,14 @@ fn create_child_container(id: &str, width: f32, height: f32) -> ContainerNodeRec
corner_smoothing: Default::default(),
fills: Default::default(),
strokes: Default::default(),
stroke_width: 0.0,
stroke_align: StrokeAlign::Center,
stroke_dash_array: None,
stroke_style: StrokeStyle {
stroke_align: StrokeAlign::Center,
stroke_cap: StrokeCap::default(),
stroke_join: StrokeJoin::default(),
stroke_miter_limit: StrokeMiterLimit::default(),
stroke_dash_array: None,
},
stroke_width: Default::default(),
effects: Default::default(),
clip: Default::default(),
layout_container: LayoutContainerStyle {
Expand Down
11 changes: 8 additions & 3 deletions crates/grida-canvas/examples/golden_layout_padding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,14 @@ fn create_container_with_padding(
corner_smoothing: Default::default(),
fills: Default::default(),
strokes: Default::default(),
stroke_width: 0.0,
stroke_align: StrokeAlign::Center,
stroke_dash_array: None,
stroke_style: StrokeStyle {
stroke_align: StrokeAlign::Center,
stroke_cap: StrokeCap::default(),
stroke_join: StrokeJoin::default(),
stroke_miter_limit: StrokeMiterLimit::default(),
stroke_dash_array: None,
},
stroke_width: Default::default(),
effects: Default::default(),
clip: Default::default(),
layout_container: LayoutContainerStyle {
Expand Down
12 changes: 6 additions & 6 deletions crates/grida-canvas/examples/golden_pdf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ async fn demo_scene() -> Scene {
blend_mode: BlendMode::Normal,
active: true,
}));
rect_gradient.stroke_width = 3.0;
rect_gradient.stroke_width = 3.0.into();
rect_gradient.strokes = Paints::new([Paint::from(CGColor(0, 0, 0, 255))]);
rect_gradient.effects = LayerEffects::from_array(vec![FilterEffect::DropShadow(FeShadow {
dx: 5.0,
Expand Down Expand Up @@ -133,7 +133,7 @@ async fn demo_scene() -> Scene {
blend_mode: BlendMode::Normal,
active: true,
})]);
ellipse_radial.stroke_width = 4.0;
ellipse_radial.stroke_width = 4.0.into();
ellipse_radial.strokes = Paints::new([Paint::from(CGColor(0, 0, 0, 255))]);

// Polygon (hexagon)
Expand All @@ -151,7 +151,7 @@ async fn demo_scene() -> Scene {
hexagon.transform = AffineTransform::new(550.0, 200.0, 0.0);
hexagon.points = hexagon_points;
hexagon.fills = Paints::new([Paint::from(CGColor(128, 0, 255, 255))]);
hexagon.stroke_width = 3.0;
hexagon.stroke_width = 3.0.into();
hexagon.strokes = Paints::new([Paint::from(CGColor(255, 255, 255, 255))]);
hexagon.effects = LayerEffects::from_array(vec![FilterEffect::DropShadow(FeShadow {
dx: 3.0,
Expand All @@ -171,15 +171,15 @@ async fn demo_scene() -> Scene {
star.point_count = 5;
star.inner_radius = 0.4;
star.fills = Paints::new([Paint::from(CGColor(255, 215, 0, 255))]);
star.stroke_width = 2.0;
star.stroke_width = 2.0.into();
star.strokes = Paints::new([Paint::from(CGColor(139, 69, 19, 255))]);

// Path (complex shape)
let mut path = nf.create_path_node();
path.transform = AffineTransform::new(220.0, 400.0, 0.0);
path.data = "M50,0 L61,35 L98,35 L68,57 L79,91 L50,71 L21,91 L32,57 L2,35 L39,35 Z".to_string();
path.fills = Paints::new([Paint::from(CGColor(255, 20, 147, 255))]);
path.stroke_width = 2.0;
path.stroke_width = 2.0.into();
path.strokes = Paints::new([Paint::from(CGColor(0, 0, 0, 255))]);

// Line with gradient stroke
Expand Down Expand Up @@ -220,7 +220,7 @@ async fn demo_scene() -> Scene {
};
octagon.point_count = 8;
octagon.fills = Paints::new([Paint::from(CGColor(0, 255, 255, 255))]);
octagon.stroke_width = 3.0;
octagon.stroke_width = 3.0.into();
octagon.strokes = Paints::new([Paint::from(CGColor(0, 0, 0, 255))]);

// Description text
Expand Down
38 changes: 26 additions & 12 deletions crates/grida-canvas/examples/golden_sk_paragraph_path_vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@
//! - Vector network integration with fills and strokes
//! - Typography showcase with rich content

use cg::{
cg::types::*,
vectornetwork::{StrokeOptions, VNPainter, VectorNetwork},
};
use cg::cg::prelude::*;
use cg::vectornetwork::{StrokeOptions, VNPainter, VectorNetwork};
use skia_safe::{
self as sk,
font_style::{Slant, Weight, Width},
Expand Down Expand Up @@ -205,10 +203,14 @@ fn scenario_geist(canvas: &sk::Canvas, y_offset: f32) -> f32 {
let painter = VNPainter::new(canvas);
let fill = Paint::from(color);
let stroke = StrokeOptions {
width: 1.5,
align: StrokeAlign::Center,
stroke_width: 1.5,
stroke_align: StrokeAlign::Center,
stroke_cap: StrokeCap::default(),
stroke_join: StrokeJoin::default(),
stroke_miter_limit: StrokeMiterLimit::default(),
paints: Paints::new([Paint::from(CGColor::from_rgba(0, 0, 0, 100))]),
width_profile: None,
stroke_dash_array: None,
};
painter.draw(&vn, &[fill], Some(&stroke), 0.0);
}
Expand Down Expand Up @@ -292,10 +294,14 @@ fn scenario_roboto_flex(canvas: &sk::Canvas, y_offset: f32) -> f32 {
let painter = VNPainter::new(canvas);
let fill = Paint::from(color);
let stroke = StrokeOptions {
width: 1.5,
align: StrokeAlign::Center,
stroke_width: 1.5,
stroke_align: StrokeAlign::Center,
stroke_cap: StrokeCap::default(),
stroke_join: StrokeJoin::default(),
stroke_miter_limit: StrokeMiterLimit::default(),
paints: Paints::new([Paint::from(CGColor::from_rgba(0, 0, 0, 100))]),
width_profile: None,
stroke_dash_array: None,
};
painter.draw(&vn, &[fill], Some(&stroke), 0.0);
}
Expand Down Expand Up @@ -396,10 +402,14 @@ fn scenario_multiscript(canvas: &sk::Canvas, y_offset: f32) -> f32 {
let painter = VNPainter::new(canvas);
let fill = Paint::from(color);
let stroke = StrokeOptions {
width: 1.0,
align: StrokeAlign::Center,
stroke_width: 1.0,
stroke_align: StrokeAlign::Center,
stroke_cap: StrokeCap::default(),
stroke_join: StrokeJoin::default(),
stroke_miter_limit: StrokeMiterLimit::default(),
paints: Paints::new([Paint::from(CGColor::from_rgba(0, 0, 0, 80))]),
width_profile: None,
stroke_dash_array: None,
};
painter.draw(&vn, &[fill], Some(&stroke), 0.0);
}
Expand Down Expand Up @@ -472,10 +482,14 @@ fn scenario_variable_fonts(canvas: &sk::Canvas, y_offset: f32) -> f32 {
let painter = VNPainter::new(canvas);
let fill = Paint::from(color);
let stroke = StrokeOptions {
width: 1.2,
align: StrokeAlign::Center,
stroke_width: 1.2,
stroke_align: StrokeAlign::Center,
stroke_cap: StrokeCap::default(),
stroke_join: StrokeJoin::default(),
stroke_miter_limit: StrokeMiterLimit::default(),
paints: Paints::new([Paint::from(CGColor::from_rgba(0, 0, 0, 120))]),
width_profile: None,
stroke_dash_array: None,
};
painter.draw(&vn, &[fill], Some(&stroke), 0.0);
}
Expand Down
Loading