-
Notifications
You must be signed in to change notification settings - Fork 16
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
Refactor to simplify supporting new CSS props; add support for variable character width & letter-spacing #36
base: development
Are you sure you want to change the base?
Conversation
`font-weight` works just like `font-variation-settings: "wght"`, but unlike the latter it doesn't override the CSS cascade (which happens in Chrome and Safari when the `@font-face` declaration includes a `font-weight` range). (See note on https://developer.mozilla.org/en-US/docs/Web/CSS/font-variation-settings: 'font characteristics set using `font-variation-settings` will always override those set using the corresponding basic font properties, e.g. `font-weight`, no matter where they appear in the cascade.') So, if some text within a Textblock block has a specified weight (e.g. for `<strong>` tags), that won't be overridden by the script like it would previously have been. - Add bold text to demos to show cascade now honored.
More accurately conveys the actual property / variation axis being manipulated. Also, replace 'grades' with 'weights' in demo.html and README (but leave reference to 'simulating grades').
Move description from bottom of Parameters section to top intro.
Make explicit the relationship between container width and the type-related parameters.
- Use a top-level `config` var to contain all defaults and list all supported type-related properties to make it easier to add support for additional CSS properties. - Allow for units to be specified per-property (e.g. `fontSizeUnits`, though `units` is still respected and applied only to `fontSize`). - Apply defaults and calculate all CSS property values programmatically instead of handling each property manually. This makes supporting new CSS properties trivial. - Refactor `run()` & `calc()` to be more modular: -- Simplify `run()` function. -- Change `calc()` into `calcCurrentPropValue()` to calculate a single property at time. -- Separate width-ratio calculation into its own `calcCurrentWidthRatio()` method.
Also: - Update demos with var. width (font-stretch) & letter-spacing. Include new font (AmstelvarAlpha), which supports variable width. Also add legacy `units` param to the legacy test. - Update README.
- Replace date with version number in banner. (Prevents meaningless version control changes from being indicated when script is re-minified but nothing has changed other than the date.) - Update `grunt-contrib-uglify` to 4.0.0 to enable better 'mangling' (i.e. shortened from longer human-friendly names to single characters). - Remove demo files from watch task. (No need for the JS file to be minified every time the demo files update.) - Rebuild minified script.
@tinymachine — whoa, this is amazing! I only skimmed but really looks like the way to approach it. I won't be able to take a proper look for a while. I'll request @traviskochel and @jessevdp in case they’re available to pop in and see. Thanks Mihira! |
My pleasure, @theorosendorf! |
Haven't tested it, but it looks good to me. nice work @tinymachine! |
Thanks, @traviskochel — you and @theorosendorf both do really beautiful and inspiring work. I'm frankly humbled to be able to contribute to this project. |
@tinymachine — This PR also takes care of #34 since formatting becomes customizable, right? I was able to change min/maxWidth to min/maxWidth_ without breaking the demo. Hope you don't mind, I commited that test... :) |
I ran Chrome’s performance monitor and was able to ramp up the CPU usage to 100%, although to do that I had to frantically resize the viewport like a crazed meth addict. |
Humbled to have you here @tinymachine. |
I don't mind at all — please feel free to make changes as you see fit! I hadn't considered this PR to close #34 since it didn't actually change the param formatting, but your commit does the trick.
Ha — yeah, not sure if it's warranted but I wonder if it might make sense to throttle, or maybe throttle and debounce, the script and see if it would bring that CPU usage down. (I set up a test on jsPerf but haven't figured out how to get reliable results. I switched up the ordering of which version of the script to test first, and the first script always performed much better than the others, and with a huge margin of error.)
🙏 |
@theorosendorf, I just tried some crude benchmarking by changing the var reps = 10000;
var startTime = Date.now();
for (var i = 0; i < reps; i++) {
run();
}
var endTime = Date.now();
console.log(reps + ' executions took ' + (endTime - startTime) / 1000 + ' seconds'); Somewhat consistently I'm seeing a time of ~3.4s for this PR, and ~0.8s for 0.10.0 when I try multiple runs in Safari and Chrome. So though this PR makes it much easier to make changes to the params, etc., it might result in ~4x slower performance 😬. I'll look into this further but wanted to give a heads-up... |
I really love the idea of this PR. Are there any tools we can use to better understand the performance hit? |
You know, because this would squash a ton of current and future features... |
Okay, here's a cleaner PR than my last attempt. Again, this PR is pretty far-reaching, so I totally understand if you can't accept it. Just thought you might be interested in some aspects of how I approached these changes.
Major change: apply defaults, calculate and adjust property values programmatically
The biggest update here is in 887d31d, which refactors how CSS properties are handled by the script. Instead of 'manually' handling all calculations (with separate lines of code for applying defaults for each property, and calculating and applying each property value), all supported properties and their defaults are defined in a
config
var. Then defaults are applied for all properties included in theconfig
, and all calculations are made and style changes are applied programmatically.This way when you want to support additional CSS properties, you just update the
config
, without having to worry about making additional per-property updates throughout the script. For example, adding letter-spacing support to the script is now as simple as adding the following toconfig.supportedProps
:Adding per-property defaults for
minWidth
andmaxWidth
is supported as well. Here's the entire config for all five props supported in the PR:Limitations
Parameter naming restriction: each supported property must have a
propName
that matches the JS equivalents for CSS properties. The script assumes thepropName
is what's used by the API params, so the letter-spacing params would (as currently coded) have to bemin/maxWidthLetterSpacing
(the script is aware of the initial cap on the property name) andletterSpacingUnits
. Params for changing character width would (as currently coded) have to bemin/maxWidthFontStretch
andfontStretchUnits
. This could be changed pretty easily to handle param names that don't necessarily map directly to their respective CSS properties, but it might be a good thing to enforce a standard style on the params and to make explicit exactly what the params control.No support for special CSS properties: properties like
font-variation-settings
, which can control multiple properties at once, aren't currently supported. This is probably fine, though, since the VF variation axes users will probably generally want to control (and the ones more variable fonts support) would be more standardized variation axes likeweight
and sometimeswidth
, which honor their own respective CSS properties (e.g.font-weight
andfont-stretch
).Other updates
min/maxWidthVariableGrade
in favor ofmin/maxWidthFontWeight
(closes Though params refer to variable font grade, script changes font weight #29) (also related to limitation 1 above)font-variation-settings
for weight withfont-weight
so the cascade is better respected (see 661cf6c's commit message for details) (also related to limitation 2 above)units
withfontSizeUnits
(but plainunits
is still honored) (closes Renameunits
param tofontSizeUnits
? #23)Backward compatibility
This PR is backward-compatible with previous versions with the exception of dropping support for
min/maxWidthVariableGrade
(andmin/maxVariableGrade
) in favor ofmin/maxWidthFontWeight
(though supporting it could be added fairly easily).Questions