Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hide: Hide elements #376

Merged
merged 1 commit into from
Dec 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ CeTZ 0.2.0 requires Typst 0.10.0
- Added element `arc-through` to draw an arc through three points
- Added Hobby curves (`hobby`) in addition to catmull (thanks to @Enivex)
- Added `radius` style to `rect` for drawing rounded rects
- Added `hide` function for hiding elements

### Plot
- Added `plot.add-contour(..)` for plotting contour plots
Expand Down
3 changes: 3 additions & 0 deletions src/canvas.typ
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@
return []
}

// Filter hidden drawables
drawables = drawables.filter(d => not d.hidden)

// Order draw commands by z-index
drawables = drawables.sorted(key: (cmd) => {
return cmd.at("z-index", default: 0)
Expand Down
2 changes: 1 addition & 1 deletion src/draw.typ
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#import "draw/grouping.typ": intersections, group, anchor, copy-anchors, place-anchors, set-ctx, get-ctx, for-each-anchor, on-layer, place-marks
#import "draw/grouping.typ": intersections, group, anchor, copy-anchors, place-anchors, set-ctx, get-ctx, for-each-anchor, on-layer, place-marks, hide
#import "draw/transformations.typ": set-transform, rotate, translate, scale, set-origin, move-to, set-viewport
#import "draw/styling.typ": set-style, fill, stroke
#import "draw/shapes.typ": circle, circle-through, arc, arc-through, mark, line, grid, content, rect, bezier, bezier-through, catmull, hobby, merge-path
38 changes: 38 additions & 0 deletions src/draw/grouping.typ
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,42 @@

#import "transformations.typ": move-to

/// Hides an element.
///
/// Hidden elements are not drawn to the canvas,
/// are ignored when calculating bounding boxes and discarded by `merge-path`. All
/// other behaviours remain the same as a non-hidden element.
///
/// #example(```
/// set-style(radius: .5)
/// intersections("i", {
/// circle((0,0), name: "a")
/// circle((1,2), name: "b")
/// // Use a hidden line to find the border intersections
/// hide(line("a.center", "b.center"))
/// })
/// line("i.0", "i.1")
/// ```)
///
/// - body (element): One or more elements to hide
#let hide(body) = {
if type(body) == array {
return body.map(f => {
(ctx) => {
let element = f(ctx)
if "drawables" in element {
element.drawables = element.drawables.map(d => {
d.hidden = true
return d
})
}
return element
}
})
}
return body
}

/// Calculates the intersections between multiple paths and creates one anchor
/// per intersection point.
///
Expand Down Expand Up @@ -44,6 +80,8 @@
/// })
/// ```)
///
/// You can calculate intersections with hidden elements by using @@hide().
///
/// - name (string): Name to prepend to the generated anchors.
/// - ..elements (elements,string): Elements and/or element names to calculate intersections with.
/// Elements referred to by name are (unlike elements passed) not drawn by the intersections function!
Expand Down
4 changes: 4 additions & 0 deletions src/draw/shapes.typ
Original file line number Diff line number Diff line change
Expand Up @@ -1528,6 +1528,9 @@
/// bezier((), (0, 0), (1,1), (0,1))
/// })
/// ```)
///
/// Elements hidden via `hide()` are ignored.
///
/// = parameters
///
/// = Anchors
Expand Down Expand Up @@ -1564,6 +1567,7 @@
}
}
for drawable in r.drawables {
if drawable.hidden { continue }
assert.eq(drawable.type, "path")
segments += drawable.segments
}
Expand Down
4 changes: 3 additions & 1 deletion src/drawable.typ
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
close: close,
segments: segments,
fill: fill,
stroke: stroke
stroke: stroke,
hidden: false
)
}

Expand All @@ -52,6 +53,7 @@
width: width,
height: height,
body: body,
hidden: false,
)
}

Expand Down
20 changes: 11 additions & 9 deletions src/process.typ
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,17 @@
element.drawables = (element.drawables,)
}
for drawable in element.drawables {
bounds = aabb.aabb(
if drawable.type == "path" {
path-util.bounds(drawable.segments)
} else if drawable.type == "content" {
let (x, y, _, w, h,) = drawable.pos + (drawable.width, drawable.height)
((x + w / 2, y - h / 2, 0), (x - w / 2, y + h / 2, 0))
},
init: bounds
)
if not drawable.hidden {
bounds = aabb.aabb(
if drawable.type == "path" {
path-util.bounds(drawable.segments)
} else if drawable.type == "content" {
let (x, y, _, w, h,) = drawable.pos + (drawable.width, drawable.height)
((x + w / 2, y - h / 2, 0), (x - w / 2, y + h / 2, 0))
},
init: bounds
)
}
}
}
if "name" in element and type(element.name) == "string" and "anchors" in element {
Expand Down
Binary file added tests/hide/ref.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 37 additions & 0 deletions tests/hide/test.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#set page(width: auto, height: auto)
#import "/src/lib.typ": *

#box(stroke: 2pt + red, canvas({
import draw: *
rect((0,0), (5,5))

// Hide a circle
hide(circle((6,6)))

// Hide content
hide(content((-6,-6), [Hidden]))

// Hide multiple elements
hide({
rect((0,0), (1,1))
rect((1,1), (2,2))
rect((2,2), (3,3))
})

// Use hidden anchor
hide(line((0,0), (2.5, 2.5), name: "line"))
content("line.end", [Hidden anchor])
}))

#box(stroke: 2pt + red, canvas({
import draw: *

merge-path({
arc((0,0), start: 0deg, stop: 180deg)
hide({
// This gets ignored
line((), (rel: (-5,0), update: false))
})
line((), (rel: (1, -1)))
}, close: true)
}))