- From: Brian Birtles <bbirtles@mozilla.com>
- Date: Fri, 10 May 2013 14:43:05 +0900
- To: www-svg <www-svg@w3.org>
Dear all,
I've put together a strawman proposal for the syntax for variable-width
stroke incorporating many of the suggestions raised in the recent telcon.
I warned you you'll hate it but I hope it gets the ball rolling. I'm
sure you can make it great!
Initial observation: Combining percentage-based offsets with
length-based offsets doesn't make much sense
e.g. '50%: 1.2, 13em: 1.1'
This is because depending on the length of the path, '50%' may occur
before or after '13em'.
Therefore I've split the 'type' of the offset out into a separate
property; a little bit like "patternContentUnits" etc.
Proposed properties at a glance:
stroke-width: <percentage> | <length>
stroke-widths-array:
[ [ [<percentage>|<length>|<number>] S* ":" S* ]? <number> ]#
(Or maybe: [ [ <number> S* ":" S* ]? <number> ]#)
stroke-widths-position: percent | length | point
stroke-widths-repeat: no-repeat | repeat
stroke-widths: [ <position> || repeat> ]? <array>
Proposed properties in detail:
stroke-width - As currently defined, specifies the _base_stroke_width_.
stroke-widths-array:
[ [ [<percentage>|<length>|<number>] S* ":" S* ]? <number> ]#
The optional number/length/percentage before the ':' represents the
offset.
The application of the offset depends on the value of
'stroke-widths-position' (defined below) as follows:
'percent': percentage of the path length (<percentage> or
<number> where 0.2 -> 20%)
'length': absolute length along the path in user units (<length>
or <number> where <number> is user units)
'point': integer part of the <number> is the index of the point
in the path, fractional part is a percentage between that point and the
end of the segment (as per Inkscape). e.g. '3.2' is a point 20% along
the 4th segment in the path (the index is 0-based).
Note that <number> can be used in all three cases so it's possible
to change the stroke-widths-position property without changing
stroke-widths-array.
If we introduce support for asymmetric stroke widths the format
would be:
[ [ [<percentage>|<length>|<number>] S* ":" S* ]?
<number>(/<number>)? ]#
[ Sorry about the line-wrapping there, the only part that changes is
the last part becomes: <number>(/<number>)? ]
In this case the last two numbers represent the width on the
left-side of the stroke (/) and the right-side of the stroke respectively.
The offsets must be in ascending order. If not we process up to the
last item that is ascending order and only apply that far. (For lengths
we'd have to specify when they are resolved.)
When an offset is omitted, it is filled in based on the value of
stroke-widths-position as follows:
'percent' and 'length': evenly space between values which have an
offset. If the first value has no offset use '0'. If the last value has
no offset make it match the end of the path.
'point': If the first value has no offset, make it '0.0' (the
first point). For every other value, take the previous offset, increment
by 1.0 and then apply floor(). i.e. <no-offset>, 2.3, <no-offset>,
<no-offset> becomes 0.0, 2.3, 3.0, 4.0
The final <number> is the magnification factor on the
_base_stroke_width_ (specified by 'stroke-width'), e.g. 1.1 for 1.1x the
stroke width. We could also make this [ <number> | <percentage> ].
Issue: For length-based offsets, if you have an offset of '3em' and
'12px' the order can change if you set the font-size on an ancestor.
Alternative proposal, just always use <number> for the offset, i.e.:
stroke-widths-array ::= [ [ <number> S* ":" S* ]? <number> ]#
(<number> can still be used to describe a percentage as a fraction
or a length using user units as defined above).
stroke-widths-position: percent | length | point
Initial: 'percent'
Specifies how the offsets in stroke-widths-array are applied as
specified above.
stroke-widths-repeat: no-repeat | repeat
Initial: 'no-repeat'
(The 'no-repeat' keyword matches the value for CSS'
background-repeat property)
For stroke-widths-array lists that don't fill up to the end of the
path, 'repeat' makes it repeat the pattern.
Possible future value: 'reflect' which alternates the pattern
I'm not quite sure how to avoid sudden jumps when using 'percent' or
'length' here. Maybe you need 'reflect' for this case?
stroke-widths: [ <position> || repeat> ]? <array>
Shorthand for the above (forgive the abbreviated syntax).
Examples:
a) A hair stroke pattern
.hair {
stroke-width: 10px;
stroke-widths: 0.1, 70%: 1.1, 0.3;
stroke-linecap: round;
}
b) A bulging pattern like a snake that has eaten a lot of eggs.
.snake {
stroke-width: 30px;
stroke-widths: length repeat 0.5, 30px: 1, 60px: 0.5
}
c) A box where the alternate corners are thicker
rect.sharpBox {
stroke: black;
stroke-width: 5px;
stroke-widths: point 1, 1.5, 1, 1.5;
fill: white;
paint-order: stroke;
}
d) An n-pointed star where the outside points and inside points differ
in stroke width
star.sharp {
stroke-widths: point repeat 1, 1.5;
}
e) A path created using touch input
<path d="M123 345C...." stroke-widths-position="points"
stroke-widths-array="1, 1.1, 1.15..." />
I look forward to your suggestions!
Best regards,
Brian
Received on Friday, 10 May 2013 05:43:41 UTC