Skip to content

Commit 5ef8fea

Browse files
committed
Dobument crazy sprite setup
1 parent 1d61979 commit 5ef8fea

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

packages/webamp/js/hooks.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,54 @@ type SpriteConfig = {
181181
size?: SpriteName;
182182
};
183183

184+
/**
185+
* You can set CSS variables on an HTML element via it's style attribute.
186+
* We use special (hacky) CSS selectors in `webamp.css` which match elements
187+
* that have these special variables set and then use the value of that
188+
* variable as the background image.
189+
*
190+
* ```css
191+
* #webamp [style*="--base-background"] {
192+
* background-image: var(--base-background);
193+
* }
194+
* ```
195+
*
196+
* Sprite images are extracted and assigned to CSS variables of their own.
197+
* By giving an HTML element a style attribute defining one of these CSS
198+
* variables as one of the sprite images's CSS variables we can set the
199+
* background of an HTML element to one of the skin's sprites.
200+
*
201+
* ## This is super conveluted. So why are we doing it?
202+
*
203+
* A simple approach would be to just get the sprite as an object URL and
204+
* assign it to the HTML element's `backgroundImage` style attribute.
205+
*
206+
* The first problem with this approach is that we want the default skin to act
207+
* as a fallback and the simplest way to achive that is via CSS. We have the
208+
* parsed skin shadow the CSS variables defined by the default skin. If the
209+
* parsed skin is missing any sprites, anyone referencing the sprite's CSS
210+
* variable will get the default skin's sprite.
211+
*
212+
* Secondly, I suspect (but have not tested) that it's not performant to use
213+
* large data URIs as style attributes when the element (and it's attributes)
214+
* might be leaving the DOM, since the browser might need to re-parse the image
215+
* every time it's added.
216+
*
217+
* Thirdly, we would like to be able to use the `:active` pseudo selector, and
218+
* `::-webkit-slider-thumb` pseudo elements which cannot be directly set using
219+
* the style attribute.
220+
*
221+
* Using this method (where we assign a CSS variable to a magic CSS variable)
222+
* solves all three of these:
223+
*
224+
* 1. We can encode the default skin as a CSS sheet defining a bunch of CSS
225+
* variables, and these will act as fallbacks for any sprites the pased skin is
226+
* missing.
227+
* 2. The sprite data URIs are added to the style sheet and should never have
228+
* to be re-parsed.
229+
* 3. Since the actual styling is done in a real CSS rule, it can take
230+
* advantage of pseudo selectors and pseudo elements.
231+
*/
184232
export function useSprite(options: SpriteConfig): React.CSSProperties {
185233
const style: React.CSSProperties = {};
186234
(["base", "active", "thumb", "activeThumb"] as const).forEach((name) => {

0 commit comments

Comments
 (0)