@@ -181,6 +181,54 @@ type SpriteConfig = {
181
181
size ?: SpriteName ;
182
182
} ;
183
183
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
+ */
184
232
export function useSprite ( options : SpriteConfig ) : React . CSSProperties {
185
233
const style : React . CSSProperties = { } ;
186
234
( [ "base" , "active" , "thumb" , "activeThumb" ] as const ) . forEach ( ( name ) => {
0 commit comments