-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Colour handling improvements #8702
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
base: master
Are you sure you want to change the base?
Conversation
The replacement library from https://colorjs.io/ is much, much larger but I think we can develop a custom build that uses treeshaking to whittle the code down to the bits that we need. @linonetwo does that sound feasible? I intend the explore further improvements but I wanted to start by establishing a library that can do modern P3 and OKLCH colour calculations.
Really just syntactic sugar for the wikify widget
Using the new wikify operator. Currently has a bug whereby redirected colours (like "tiddler-background") do not work. Direct colours like "background" do work. Note the hacks needed to makeFakeWidgetWithVariables work
Confirmed: Jermolene has already signed the Contributor License Agreement (see contributing.md) |
Is there a demo to test colour handling improvement? |
Hi @kookma I've posted a preview to tiddlyhost |
These are mostly RGB entries that were previously missing, filled in with values from Vanilla. The goal is still not to have any direct RGB colours in the palette, just computed colours derived from the base colours
Makes debugging easier, and works in CSS and as a style.prop assignment
button-border: | ||
button-background: | ||
button-border: | ||
button-foreground: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need spaces here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I intend to fill in those entries later.
@@ -76,7 +78,7 @@ dropdown-background: [tf.colour[background]] | |||
dropdown-border: [tf.colour[muted-foreground]] | |||
dropdown-tab-background-selected: [tf.colour[background]] | |||
dropdown-tab-background: [tf.interpolate-colours[base-paper],[base-ink],[0.9]] | |||
dropzone-background: rgba(0,200,0,0.7) | |||
dropzone-background: [tf.colour[base-secondary]colour-set-alpha[0.7]] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do like this possibility: [tf.colour[base-secondary]colour-set-alpha[0.7]]
but once the "alpha" values are settled, would it be possible to have eg: colour-set-alpha<lighter>
, colour-set-alpha<lighter>
colour-set-alpha<lightest>
and eg: dark, darker, darkest -- What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the same realm. I know colour-set-alpha
is the right technical term, but our users would probably prefer darken-colour<percent>
Question Does "alpha" set transparency or does it calculate a lighter or darker colour?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @pmario to darken a colour one would use colour-set-oklch:l[0.5]
to set the lightness.
We don't yet have operators to extract the components of a colour in a particular colour space, but once we have those then it would be possible to make macros for setting the alpha or brightness in relative steps.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question Does "alpha" set transparency or does it calculate a lighter or darker colour?
Apologies, to be clear it sets transparency
core/modules/background-actions.js
Outdated
(function(){ | ||
|
||
/*jslint node: true, browser: true */ | ||
/*global $tw: false */ | ||
"use strict"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function wrappers should be removed now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @Leilei332 I've removed them in a4c84d7 – I think they still need to be removed from a number of my other open PRs.
core/modules/background-actions.js
Outdated
return id; | ||
}; | ||
|
||
BackgroundActionDispatcher.prototype.untrackFilter = function(enterValue) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since ES2017 is the baseline now, I think we are ready to migrate to class
(since refactoring to class is easy in VSCode). We should also use function argument default value and use const
in some occasions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, which again applies to my other PRs.
We need to discuss the considerable increase in size of the core incurred by this PR. Nearly 300KB is a considerable impact; I think it's 11% of the current size of empty.html.
My original thinking was that we could conceal the size impact by adopting compression for the core, but it would be reasonable to expect that the percentage increase in size would be roughly similar. I wondered if it might be possible to reduce the size of the library through tree shaking. I don't have experience of the tooling but perhaps others might be able to comment. However, we are using some substantial subsystems from the library (such as parsing CSS colours, which I would imagine might be a hefty chunk of code), and so the impact might not be enormous. |
Introduction
This PR brings several new features for end users:
There are also new capabilities for palette authors:
To make all of these new features possible, this PR also includes some useful new general purpose mechanisms and features:
$:/info/...
tiddlerchangecount
filter operator:apply
filter run prefixTry the Demo
A preview build is available at https://deploy-preview-8702--tiddlywiki-previews.netlify.app/
Changes to Palettes
Palette entries are now defined as filters that must be evaluated, rather than wikitext that must be wikified.
This makes it possible to create palettes that reference and modify other colours. For example:
Retrospectively re-interpreting palettes entries as filters would normally mean that
<<colour background>>
would no longer work. Instead these entries are automatically converted to the updated form[function[colour],[background]]
.Palette Compilation
The key idea underpinning these changes is a fundamental change to the way that TiddlyWiki handles palettes. At the moment, palette entries are named items that can contain either a CSS colour string, a CSS colour token like "inherit", or can use the
<<colour>>
macro to reference another colour palette entry. Thus, palette entries have to be wikified before they can be used. This has turned out to be very limiting and doesn't provide a viable path to the complex colour manipulations shown above. Switching to filters might make things worse, by encouraging authors to use complex expressions within palettes.The fix is compiled palettes: at the point of switching to a new palette, the colours within it are "compiled" to raw CSS colour values (typically but not necessarily in
#rrggbbaa
format). This allows palette entries to be used directly, without the requirement to wikify them.The static palette is created in a new system tiddler
$:/temp/palette-colours
by an action procedure that is invoked at startup and when switching to a new palette.There should not be any backwards compatibility issues because the use of background actions means that any code that changes
$:/palette
will automatically trigger the recompilation of the palette.This change also allows us to change the
<<colour>>
procedure to be a function, which allows it to be used as the value for a style attribute:Automatic Palette Readability Tests
Palettes can opt to include readability tests as special palette entries. The results of these tests are shown at the bottom of the palette chooser. For example:
The test framework looks for palette entries starting with a question mark and runs the associated filters. The filter should return nothing if there are no errors, or a textual error message if the conditions are violated. Sample output:
Colour Manipulation
We need a colour manipulation library that can calculate variants of colours. Only color.js met the requirements of being able to work with P3 colours and the OKLCH colour space. It also includes a CSS colour string parser which can replace the simple one that TiddlyWiki has always incorporated.
Media Query Tracker
The CSS media query tracker allows a media query to be bound to an info tiddler so that the current state of the query is reflected in the value of the tiddler. The value is updated dynamically.
The use of the info mechanism for the CSS media query tracker means that these tiddlers are dynamically created as shadow tiddlers within the
$:/temp/info
plugin, and so do not appear in tiddler lists.The mechanism is used to implement the existing dark mode tiddler with the following configuration:
Note the use of
info-tiddler-alt
to specify a redundant secondary info tiddler. This is used by the dark mode tracker to maintain compatibility while changing the info tiddler title for consistency.Background Actions
The new background actions mechanism allows action strings to be invoked automatically in the background whenever the results of a filter change.
The preview includes a demonstration background action that displays an alert with a list of tiddlers in the story river whenever the story river changes:
apply
Filter Run PrefixAn experimental new filter run prefix that makes it possible to use computed values as variables within a filter run. For example:
Backwards Compatibility
$:/PaletteManager
is moved into$:/PaletteEditor
, and$:/PaletteManager
repurposed as the control panel palette switcher$:/config/DefaultColourMappings/
now only supports CSS colours, and not indirections via<<colour X>>
or[function[colour],[X]]
References
Progress
changecount
operatorcolour-interpolate
operatorcolour-lighten
operatorcolour-darken
operatorcolour-get-oklch
operatorcolour-set-oklch
operatorcolour-contrast
operatorcolour-best-contrast
operator