Select the types of activity you want to include in your feed.
Further robustify trending news
- Convert back to RGB for max compat - Better variable names - Add fallback if there's no blurhash - Refactor color utils - Use alpha instead of light/dark colors
···1212import RelativeTime from '../components/relative-time';
1313import Timeline from '../components/timeline';
1414import { api } from '../utils/api';
1515+import { oklab2rgb, rgb2oklab } from '../utils/color-utils';
1516import { filteredItems } from '../utils/filters';
1617import pmem from '../utils/pmem';
1718import states from '../utils/states';
···161162 const domain = new URL(url).hostname
162163 .replace(/^www\./, '')
163164 .replace(/\/$/, '');
164164- const averageColor = getBlurHashAverageColor(blurhash);
165165- const labAverageColor = rgb2oklab(averageColor);
166166-167167- // const lightColor = averageColor.map((c) => {
168168- // const v = c + 120;
169169- // return v > 255 ? 255 : v;
170170- // });
171171- // const darkColor = averageColor.map((c) => {
172172- // const v = c - 100;
173173- // return v < 0 ? 0 : v;
174174- // });
175175- const accentColor = labAverageColor.map((c, i) => {
176176- if (i === 0) {
177177- return 0.65;
178178- }
179179- return c;
180180- });
181181- const lightColor = labAverageColor.map((c, i) => {
182182- if (i === 0) {
183183- return 0.9;
184184- }
185185- return c;
186186- });
187187- const darkColor = labAverageColor.map((c, i) => {
188188- if (i === 0) {
189189- return 0.4;
190190- }
191191- return c;
192192- });
165165+ let accentColor;
166166+ if (blurhash) {
167167+ const averageColor = getBlurHashAverageColor(blurhash);
168168+ const labAverageColor = rgb2oklab(averageColor);
169169+ accentColor = oklab2rgb([
170170+ 0.6,
171171+ labAverageColor[1],
172172+ labAverageColor[2],
173173+ ]);
174174+ }
193175194176 return (
195177 <a
···197179 href={url}
198180 target="_blank"
199181 rel="noopener noreferrer"
200200- style={{
201201- '--average-color': `rgb(${averageColor?.join(',')})`,
202202- // '--light-color': `rgb(${lightColor?.join(',')})`,
203203- // '--dark-color': `rgb(${darkColor?.join(',')})`,
204204- '--accent-color': `oklab(${accentColor?.join(' ')})`,
205205- '--light-color': `oklab(${lightColor?.join(' ')})`,
206206- '--dark-color': `oklab(${darkColor?.join(' ')})`,
207207- }}
182182+ style={
183183+ accentColor
184184+ ? {
185185+ '--accent-color': `rgb(${accentColor.join(',')})`,
186186+ '--accent-alpha-color': `rgba(${accentColor.join(
187187+ ',',
188188+ )}, 0.4)`,
189189+ }
190190+ : {}
191191+ }
208192 >
209193 <article>
210194 <figure>
···309293 }
310294 />
311295 );
312312-}
313313-314314-// https://gist.github.com/earthbound19/e7fe15fdf8ca3ef814750a61bc75b5ce
315315-const gammaToLinear = (c) =>
316316- c >= 0.04045 ? Math.pow((c + 0.055) / 1.055, 2.4) : c / 12.92;
317317-function rgb2oklab([r, g, b]) {
318318- r = gammaToLinear(r / 255);
319319- g = gammaToLinear(g / 255);
320320- b = gammaToLinear(b / 255);
321321- var l = 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b;
322322- var m = 0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b;
323323- var s = 0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b;
324324- l = Math.cbrt(l);
325325- m = Math.cbrt(m);
326326- s = Math.cbrt(s);
327327- return [
328328- l * +0.2104542553 + m * +0.793617785 + s * -0.0040720468,
329329- l * +1.9779984951 + m * -2.428592205 + s * +0.4505937099,
330330- l * +0.0259040371 + m * +0.7827717662 + s * -0.808675766,
331331- ];
332296}
333297334298export default Trending;
+52
src/utils/color-utils.js
···11+// https://gist.github.com/earthbound19/e7fe15fdf8ca3ef814750a61bc75b5ce
22+function clamp(value, min, max) {
33+ return Math.max(Math.min(value, max), min);
44+}
55+66+const gammaToLinear = (c) =>
77+ c >= 0.04045 ? Math.pow((c + 0.055) / 1.055, 2.4) : c / 12.92;
88+const linearToGamma = (c) =>
99+ c >= 0.0031308 ? 1.055 * Math.pow(c, 1 / 2.4) - 0.055 : 12.92 * c;
1010+1111+export function rgb2oklab([r, g, b]) {
1212+ r = gammaToLinear(r / 255);
1313+ g = gammaToLinear(g / 255);
1414+ b = gammaToLinear(b / 255);
1515+ var l = 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b;
1616+ var m = 0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b;
1717+ var s = 0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b;
1818+ l = Math.cbrt(l);
1919+ m = Math.cbrt(m);
2020+ s = Math.cbrt(s);
2121+ return [
2222+ l * +0.2104542553 + m * +0.793617785 + s * -0.0040720468,
2323+ l * +1.9779984951 + m * -2.428592205 + s * +0.4505937099,
2424+ l * +0.0259040371 + m * +0.7827717662 + s * -0.808675766,
2525+ ];
2626+}
2727+2828+export function oklab2rgb([L, a, b]) {
2929+ var l = L + a * +0.3963377774 + b * +0.2158037573;
3030+ var m = L + a * -0.1055613458 + b * -0.0638541728;
3131+ var s = L + a * -0.0894841775 + b * -1.291485548;
3232+ // The ** operator here cubes; same as l_*l_*l_ in the C++ example:
3333+ l = l ** 3;
3434+ m = m ** 3;
3535+ s = s ** 3;
3636+ var r = l * +4.0767416621 + m * -3.3077115913 + s * +0.2309699292;
3737+ var g = l * -1.2684380046 + m * +2.6097574011 + s * -0.3413193965;
3838+ var b = l * -0.0041960863 + m * -0.7034186147 + s * +1.707614701;
3939+ // Convert linear RGB values returned from oklab math to sRGB for our use before returning them:
4040+ r = 255 * linearToGamma(r);
4141+ g = 255 * linearToGamma(g);
4242+ b = 255 * linearToGamma(b);
4343+ // OPTION: clamp r g and b values to the range 0-255; but if you use the values immediately to draw, JavaScript clamps them on use:
4444+ r = clamp(r, 0, 255);
4545+ g = clamp(g, 0, 255);
4646+ b = clamp(b, 0, 255);
4747+ // OPTION: round the values. May not be necessary if you use them immediately for rendering in JavaScript, as JavaScript (also) discards decimals on render:
4848+ r = Math.round(r);
4949+ g = Math.round(g);
5050+ b = Math.round(b);
5151+ return [r, g, b];
5252+}