- From: Tab Atkins Jr. via GitHub <sysbot+gh@w3.org>
- Date: Thu, 08 Feb 2024 01:01:49 +0000
- To: public-css-archive@w3.org
So, let's talk about better circle commands, since SVG arcs are, indeed, terrible. * In SVG, you provide the size of the circle, and two points on the perimeter (your starting point and your ending point). The UA then figures out where it needs to place the circle to make that work (there are always two locations), and then you select between the four possible arcs thus defined (which location, and which half of the circle at that location). Total necessary information: one coord, one radius (or two radiuses + a rotation), and then two binary flags for the arc choice. Pros: no need to calculate the circle center yourself, which can be complicated trig. Fits into the SVG path model of every command providing an explicitly-stated endpoint for the next to pick up from (tho why that is necessary, I have no idea). Cons: you need to calculate the endpoint yourself, which can be complicated trig. It's very sensitive to small numerical errors if you try to draw nearly a whole circle; actually drawing a whole circle in on command is impossible, and you need to do two half-circles instead. The arc choices are pretty confusing. * Lea suggests a very simple command: you provide the center of the circle, and it automatically gets a radius sufficient to put the starting point on the perimeter. You then provide the angle sweep you want to make with the arc, either positive (clockwise) or negative (counter-clockwise); the endpoint is automatically calculated as the end of that arc. Total necessary information: one coord, one angle. Pros: Minimal data. If you know you want a quarter-circle or something, very easy. Can trivially do an entire circle. Cons: Need to calculate the center and angle, which can be complicated trig. Endpoint isn't obvious (if you want to know where it is, you have to do trig.) As described, Lea's command can't do ellipses, and since the radius is auto-calculated, there's not a clean way to slot that in anyway. Maybe if you provide the eccentricity, or the major/minor axis ratio? Plus a rotation. That would be a little awkward, but possible. * `<canvas>` defines [`arc()` and `ellipse()` commands](https://html.spec.whatwg.org/multipage/canvas.html#building-paths), which are basically more explicit variants of Lea's idea. You provide a center point, a radius (or two radiuses + a rotation), and both a starting and ending angle to sweep between. If your starting point isn't already at the indicated start of your arc, it draws a straight line to there, then sweeps the indicated arc. Total necessary information: one coord, one radius (or two radiuses + a rotation), and two angles. Pros: Can do ellipses as easily as circles. Can draw any arbitrary segment of a curve without having to calculate *either* endpoint. Can draw an entire circle. Cons: Need to calculate the center and angles, which can be complicated trig. Endpoint isn't obvious. Can draw more than just the desired circle, if your starting point isn't already on the arc. * `<canvas>` also has an [`arcTo()`](https://html.spec.whatwg.org/multipage/canvas.html#building-paths) command, which is better thought of as a "round corner" command. You provide two points (defining a line from your starting point to the first, and then from the first to the second), and a radius. The UA auto-calculates the position of a circle of the given radius that is tangent to the given lines, and draws the shorter arc from its two contact points with the lines (the arc closer to the corner). Total necessary information: two coords and a radius. Pros: Makes rounded corners of a given radius extraordinarily trivial, just need the coord of the corner you're rounding, and *some* point on the next side. Can draw an entire rounded rect with four commands, using only the four corners and the desired corner rounding; more complex shapes like a rounded star just require the star points, no need for trig to precisely place the arcs themselves. Cons: Can draw more than just the desired circle, if your starting point isn't already on the circle. As defined by HTML, can do a funky backwards line, since the radius isn't clamped. Endpoint isn't obvious (and the "endpoint" you provide for the line isn't necessarily relevant). Have to make sure your starting point is on the line *before* the curve connects, or you'll get a weird segment. Not a general-purpose arc-drawer. As written, doesn't allow ellipses, but it's fairly straightforward to allow two radius and a rotation. To match the ease-of-use, you probably want a few auto-rotate options, too - align first radius's axis with first line, with second line, or with corner bisector. -------- Okay, so I think all of these are pretty reasonable; three of them already exist on the web platform, so supporting them has a good consistency argument, and the variant proposed by Lea is a nice simplification of one of them. Let's talk grammars. We already have a grammar for the SVG arcs: ``` arc <by-to> <coordinate-pair> of <length-percentage>{1,2} [ [cw|ccw] || [small|large] || rotate <angle> ]? ``` Tho with the discussion here, we might want to fix it up a bit to: ``` arc <by-to> <coordinate-pair> of <length-percentage>{1,2} [ flip? || [small|large] || rotate <angle> ] ``` (Tho both of these allow specifying some ellipse-specific options when doing a circle. Maybe instead: ``` arc <by-to> <coordinate-pair> [ of <length-percentage> [ flip? || [small|large] ] | of <length-percentage>{2} [flip? || [small|large] || rotate <angle> ]] ``` ) Lea's simple arc is: ``` arc2 <by-to> <coordinate-pair> <angle> ``` HTML's arc()/ellipse() are: ``` circle <by-to> <coordinate-pair> of <length-percentage> <angle>{2} ellipse <by-to> <coordinate-pair> of <length-percentage>{2} [rotate <angle>]? <angle>{2} ``` HTML's arcTo() is: ``` corner <by-to> <coordinate-pair> via <coordinate-pair> <length-percentage> ``` And expanded to be elliptical: ``` corner <by-to> <coordinate-pair> via <coordinate-pair> <length-percentage>{2} [rotate [ <angle> | auto-first | auto-second | auto-center ]]? ``` Lea's suggested arc looks to be doable just as a subset of `circle`, aka a grammar like: ``` circle <by-to> <coordinate-pair> [ of <length-percentage> <angle>{2} | <angle> ] ``` We might want to make the "straight line to the start of the arc" for circle/ellipse/corner skippable, so you just get the arc itself. Like a `skip-line` keyword. -- GitHub Notification of comment by tabatkins Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/9889#issuecomment-1933199502 using your GitHub account -- Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Thursday, 8 February 2024 01:01:56 UTC