Skip to content

Commit

Permalink
WIP use border anchors
Browse files Browse the repository at this point in the history
  • Loading branch information
johannes-wolf committed Dec 8, 2023
1 parent 13ec259 commit 5aec01b
Show file tree
Hide file tree
Showing 3 changed files with 266 additions and 202 deletions.
62 changes: 55 additions & 7 deletions src/anchor.typ
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
south: 270deg,
south-east: 315deg,
)
#let compass-angle-names = compass-angle.keys()
#let compass-angle-names-with-center = compass-angle-names + ("center",)

/// Setup an anchor calculation and handling function for an element. Unifies anchor error checking and calculation of the offset transform.
///
Expand Down Expand Up @@ -59,13 +61,14 @@
assert.ne(default, none, message: strfmt("Element '{}' does not have a default anchor!", name))
anchor = default
}
assert(
anchor in anchor-names,
message: strfmt("Anchor '{}' not in anchors {} for element '{}'", anchor, repr(anchor-names), name)
// message: strfmt("Anchor '{}' not in anchors {}", anchor, repr(anchor-names)) + if name != none { strfmt(" for element '{}'", name) }
)

assert(type(anchor) != str or anchor in anchor-names,
message: strfmt("Anchor '{}' not in anchors {} for element '{}'", anchor, repr(anchor-names), name))

let out = callback(anchor)
assert(out != none,
message: "Anchor '" + repr(anchor) + "' does not exist for element '" + name + "'")

return if transform != none {
util.apply-transform(
transform,
Expand All @@ -89,7 +92,10 @@
/// - drawables (drawables): Drawables to test for an intersection against. Ideally should be of type path but all others are ignored.
/// - angle (angle): The angle to check for a border anchor at.
/// -> vector
#let border(center, x-dist, y-dist, drawables, angle) = {
#let border-intersection(center, x-dist, y-dist, drawables, angle) = {
x-dist += util.float-epsilon
y-dist += util.float-epsilon

if type(drawables) == dictionary {
drawables = (drawables,)
}
Expand All @@ -116,5 +122,47 @@
}

// Find the furthest intersection point from center
return util.sort-points-by-distance(center, pts).last()
return util.sort-points-by-distance(center, pts).at(-1, default: none)
}

/// Path anchor function providing:
/// - named "start", "mid" and "end" anchors
/// - distance border anchors
#let path(anchor, segments) = {
if anchor == "start" { anchor = 0% }
else if anchor == "mid" { anchor = 50% }
else if anchor == "end" { anchor = 100% }

if type(anchor) in (int, float, ratio) {
return path-util.point-on-path(segments, anchor)
}
}

/// Border anchor function providing:
/// - named compass anchors
/// - angle border anchors
/// - distance border anchors
/// Returns none if the anchor could not be handled
#let border(anchor, center, dx, dy, drawables, with-center: false) = {
assert(drawables != none,
message: "Shape must be set.")

// Compass name => angle
if type(anchor) == str {
if str in compass-angle-names {
anchor = compass-angle.at(anchor)
} else if with-center and anchor == "center" {
return center
} else {
return none
}
}

if type(anchor) == angle {
return border-intersection(center, dx, dy, drawables, anchor)
} else if type(anchor) in (int, float, ratio) {
let p = drawables.filter(d => d.type == "path").first()
return path(anchor, p.segments)
}
return none
}
Loading

0 comments on commit 5aec01b

Please sign in to comment.