-
Notifications
You must be signed in to change notification settings - Fork 747
Description
border-shape
allows a single-path variant, which is an arbitrary shaped border.
It's not resolved exactly where this path gets its stroke width from.
Option 1: uniform border-width
Take the top border width and ignore the rest, perhaps allowing a more granular way to provide a stroke later on
Option 2: Cutoff points with interpolations
See comment by @fserb in #6997_
The cutoff points can be based on the point in the path, or based on a diagonal between the border box and the padding box.
One proposal for
border-width
interaction.Break it down in two steps.
Step 1. Assume a
width(t)
function that returns the width of the border parametrized over its length (t=0
begin of the path,,t=1
end of a continuous path). For each path, thewidth(t)
function can be applied to create an outer shape by moving the path outside in the direction of the normal of the path.Step 2. How to build
width(t)
. One option is to allow the user to specify a function or 1d gradient directly for each continuous path. But let's ignore that for now. Can we build a reasonable function givenborder-width
? I think so. We can define "control points" (similar to what we have today):0 - 0.25 - 0.5 - 0.75 - 1.0
. Each interval gets one width. And then we specify a transition range: so, something like:width(t) = border-top-width [0.05, 0.2], lerp(top, right) [0.2, 0.3], right [0.3, 0.45] ... etc
. We can decide how much control/flexibility to give. This function would be applied to every continuous path on the shape.Would something like this work?
Option 3: Use point-by-point tangents:
See this comment , not sure if I chose the right name for it. Quoting the direction:
Conceptually, the general idea was: for each point along the path, you find the tangent, and draw a vector perpendicular to the tangent with a length calculated as follows:
- If the angle is a multiple of 90deg, then it directly maps to one of the four border widths.
- Otherwise, you compute its proximity to the two adjacent angles that are multiples of 90deg and do a weighed average of the two border widths.
I don’t have access to our sketches as I write this, but it seemed to us that this would produce a very nice result for many common cases, and a not-terrible result for edge cases.
Ideally, the single shape syntax should allow specifying either the border edge (and draw the border on the inside of it) or the padding edge (and draw the border on the outside of it). We'd still need to decide how to do line joins and miter limits.
Option 4: interpolate each path segment based on nearest border to its end points
The idea is inspired by option 3, but is perhaps simpler as it works with whole segments and not point by point:
For each target point in the path:
- find the straight line that's perpendicular to the segment between that point and the point before it (for the first "move to", use the point after it)
- find the side that intersects with the perpendicular, and has an even number of other segments in between. There should be one
- use that border width
- emit two points that are perpendicular to the segment at the target point, each half width away
- For the control points, interpolate the width based on the position of the line perpendicular to the control point that intersects with the segment's straight line
- The options are a bit hard to read as quotes from comments, will try to edit them before we discuss this.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Status