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

stroke-linecap and markers #798

Open
GLRoylance opened this issue May 17, 2020 · 4 comments
Open

stroke-linecap and markers #798

GLRoylance opened this issue May 17, 2020 · 4 comments

Comments

@GLRoylance
Copy link
Contributor

The stroke-linecap attribute may be butt, round, or square.

It should have another value of something such as short. The property means the line starts and ends about a stroke width away from its starting and ending points. (We could even have a shortStart and shortEnd or shortMarker (line is shortened if a marker will be drawn.)

Consider the problem of drawing a dimension line with sharp arrows at the end. Say the dimension line should end at (100,0) with a sharp arrow. The arrow is defined as a marker and invoked with marker-end="url(#arrow)". Make the stroke width for the line 20px to emphasize the problem.

The the ending arrow point will not be sharp because the wide line will cover the arrow point; instead of a 0 width ending point, the ending width will be the 20px line width. To get around this problem, the user must make the dimension line shorter by about the stroke width. Instead of drawing the line to (100, 0), the user must draw the line to (80,0) and then fudge the marker to extend 20px past the end point.

There are some other uglies. if the marker scales by stroke width, then increasing the stroke width requires the endpoint of the line to be moved back.

It would be easier if setting stroke-linecap to short would just not draw the last stroke-width of the line.

Next consider orient="auto". If the endpoint of a line needs to be shortened to make a sharp arrow, then the direction of auto will be slightly off. Say we have a 90-degree circular arc starting at (0, -100) and bending upward to end at (100,0). The ending tangent points straight up. If I shorten the arc to get a sharp arrow point ending at (100,0), then auto will give a direction that is not parallel to the y-axis but rather pointed a little bit to the right.

Drawing short lines would give cleaner geometry because lines could start and end at their obvious positions.

@Doktorchen
Copy link

For your example-application you need a rule for the case, that the length of the path or initial or last subpath is smaller than the width.

This applies as well for a related cap shapes like a reduction of the stroke-width to zero within the length corresponding to the width of the stroke.
This may include schortened round or spike shapes as well, not only an arrow-like shape (affine reduction of the width to the end).

If you know the length of the path, you can use stroke-dasharray to shorten the visible part of a stroke as you need it.
Similar applies with mask or clip if you need only a part of the stroke perpendicular to the path direction.

@GLRoylance
Copy link
Contributor Author

I would be OK with the shortening applying only to the last segment of the path. I'm trying to avoid complicated SVG for simple cases such as straight dimension lines. Cases that have segments shorter than the width are not simple and probably need more thought placed into markers.

Calculating the length of the path doesn't really work if the width of the line is changes with the style. That means the dash-offset must also change. And what happens if the user wants to make a dashed line with a marker. Now the user must solve some simultaneous equations.

The user could also make a clip region that has cutouts where the markers go. Draw the line using the clip region. Then redraw the line with opacity 0 but with the markers rendered. But if I scale the line width, then I must also scale the cutouts.

The simple solution is have a line cap that doesn't quite make it to the end point. It would cover the common cases.

@BigBadaboom
Copy link
Contributor

I'm not sure that it is the specs job to cater for all the possible use cases that might occur. If you are trying to do something unique and special, then it is expected that the generator (either a person of a piece of software) is supposed to do some of the work.

Calculating the length of the path doesn't really work if the width of the line is changes with the style. That means the dash-offset must also change.

The calculated line length doesn't shange when you change the stroke width. And the dash lengths also remain the same if you change the width.

Are you using markerUnits="strokeWidth" markers? If so, that would require a recaculation of the dash pattern.

And what happens if the user wants to make a dashed line with a marker. Now the user must solve some simultaneous equations.

I don't think that is correct either.


It is quite simple to use a mask to carve out a chunk of the stroked path near the endpoints. I've seen other people do that. Have you tried that?

@Doktorchen
Copy link

I tried an example with declarative animation - the main problem seems to be limitations in rendering accuracy in viewers.
And there this no real need for calculation (at least if the path itself does not change, for a static path the pathLength can be simply estimated with some tries with stroke-dasharray).

Example see:
http://hoffmann.bplaced.net/svgueb/short-stroke.svg

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants