this repo has no description
0
fork

Configure Feed

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

+77 -65
+4 -8
src/pages/trending.css
··· 54 54 } 55 55 56 56 a { 57 - --other-color: var(--light-color); 58 - @media (prefers-color-scheme: dark) { 59 - --other-color: var(--dark-color); 60 - } 61 57 min-width: 240px; 62 58 flex-grow: 1; 63 59 max-width: 320px; ··· 65 61 color: inherit; 66 62 border-radius: 16px; 67 63 overflow: hidden; 68 - background-color: var(--other-color); 64 + background-color: var(--accent-alpha-color); 69 65 border: 4px solid transparent; 70 66 box-shadow: 0 4px 8px -2px var(--drop-shadow-color); 71 67 transition: all 0.15s ease-out; 72 68 display: flex; 73 69 background-image: linear-gradient( 74 70 to bottom, 75 - var(--accent-color) -50%, 71 + var(--accent-color, var(--link-text-color)) -50%, 76 72 transparent 77 73 ); 78 74 background-clip: border-box; ··· 82 78 max-height: 50vh; 83 79 84 80 &:not(:active):is(:hover, :focus-visible) { 85 - border-color: var(--accent-color); 81 + border-color: var(--accent-color, var(--link-light-color)); 86 82 box-shadow: 0 4px 8px var(--drop-shadow-color), 87 83 0 8px 16px var(--drop-shadow-color); 88 84 transform-origin: center bottom; ··· 107 103 background-repeat: no-repeat; 108 104 background-image: linear-gradient( 109 105 to bottom, 110 - var(--other-color) 70%, 106 + var(--accent-alpha-color) 70%, 111 107 var(--bg-color) 100% 112 108 ); 113 109 transition: background-position-y 0.15s ease-out;
+21 -57
src/pages/trending.jsx
··· 12 12 import RelativeTime from '../components/relative-time'; 13 13 import Timeline from '../components/timeline'; 14 14 import { api } from '../utils/api'; 15 + import { oklab2rgb, rgb2oklab } from '../utils/color-utils'; 15 16 import { filteredItems } from '../utils/filters'; 16 17 import pmem from '../utils/pmem'; 17 18 import states from '../utils/states'; ··· 161 162 const domain = new URL(url).hostname 162 163 .replace(/^www\./, '') 163 164 .replace(/\/$/, ''); 164 - const averageColor = getBlurHashAverageColor(blurhash); 165 - const labAverageColor = rgb2oklab(averageColor); 166 - 167 - // const lightColor = averageColor.map((c) => { 168 - // const v = c + 120; 169 - // return v > 255 ? 255 : v; 170 - // }); 171 - // const darkColor = averageColor.map((c) => { 172 - // const v = c - 100; 173 - // return v < 0 ? 0 : v; 174 - // }); 175 - const accentColor = labAverageColor.map((c, i) => { 176 - if (i === 0) { 177 - return 0.65; 178 - } 179 - return c; 180 - }); 181 - const lightColor = labAverageColor.map((c, i) => { 182 - if (i === 0) { 183 - return 0.9; 184 - } 185 - return c; 186 - }); 187 - const darkColor = labAverageColor.map((c, i) => { 188 - if (i === 0) { 189 - return 0.4; 190 - } 191 - return c; 192 - }); 165 + let accentColor; 166 + if (blurhash) { 167 + const averageColor = getBlurHashAverageColor(blurhash); 168 + const labAverageColor = rgb2oklab(averageColor); 169 + accentColor = oklab2rgb([ 170 + 0.6, 171 + labAverageColor[1], 172 + labAverageColor[2], 173 + ]); 174 + } 193 175 194 176 return ( 195 177 <a ··· 197 179 href={url} 198 180 target="_blank" 199 181 rel="noopener noreferrer" 200 - style={{ 201 - '--average-color': `rgb(${averageColor?.join(',')})`, 202 - // '--light-color': `rgb(${lightColor?.join(',')})`, 203 - // '--dark-color': `rgb(${darkColor?.join(',')})`, 204 - '--accent-color': `oklab(${accentColor?.join(' ')})`, 205 - '--light-color': `oklab(${lightColor?.join(' ')})`, 206 - '--dark-color': `oklab(${darkColor?.join(' ')})`, 207 - }} 182 + style={ 183 + accentColor 184 + ? { 185 + '--accent-color': `rgb(${accentColor.join(',')})`, 186 + '--accent-alpha-color': `rgba(${accentColor.join( 187 + ',', 188 + )}, 0.4)`, 189 + } 190 + : {} 191 + } 208 192 > 209 193 <article> 210 194 <figure> ··· 309 293 } 310 294 /> 311 295 ); 312 - } 313 - 314 - // https://gist.github.com/earthbound19/e7fe15fdf8ca3ef814750a61bc75b5ce 315 - const gammaToLinear = (c) => 316 - c >= 0.04045 ? Math.pow((c + 0.055) / 1.055, 2.4) : c / 12.92; 317 - function rgb2oklab([r, g, b]) { 318 - r = gammaToLinear(r / 255); 319 - g = gammaToLinear(g / 255); 320 - b = gammaToLinear(b / 255); 321 - var l = 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b; 322 - var m = 0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b; 323 - var s = 0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b; 324 - l = Math.cbrt(l); 325 - m = Math.cbrt(m); 326 - s = Math.cbrt(s); 327 - return [ 328 - l * +0.2104542553 + m * +0.793617785 + s * -0.0040720468, 329 - l * +1.9779984951 + m * -2.428592205 + s * +0.4505937099, 330 - l * +0.0259040371 + m * +0.7827717662 + s * -0.808675766, 331 - ]; 332 296 } 333 297 334 298 export default Trending;
+52
src/utils/color-utils.js
··· 1 + // https://gist.github.com/earthbound19/e7fe15fdf8ca3ef814750a61bc75b5ce 2 + function clamp(value, min, max) { 3 + return Math.max(Math.min(value, max), min); 4 + } 5 + 6 + const gammaToLinear = (c) => 7 + c >= 0.04045 ? Math.pow((c + 0.055) / 1.055, 2.4) : c / 12.92; 8 + const linearToGamma = (c) => 9 + c >= 0.0031308 ? 1.055 * Math.pow(c, 1 / 2.4) - 0.055 : 12.92 * c; 10 + 11 + export function rgb2oklab([r, g, b]) { 12 + r = gammaToLinear(r / 255); 13 + g = gammaToLinear(g / 255); 14 + b = gammaToLinear(b / 255); 15 + var l = 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b; 16 + var m = 0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b; 17 + var s = 0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b; 18 + l = Math.cbrt(l); 19 + m = Math.cbrt(m); 20 + s = Math.cbrt(s); 21 + return [ 22 + l * +0.2104542553 + m * +0.793617785 + s * -0.0040720468, 23 + l * +1.9779984951 + m * -2.428592205 + s * +0.4505937099, 24 + l * +0.0259040371 + m * +0.7827717662 + s * -0.808675766, 25 + ]; 26 + } 27 + 28 + export function oklab2rgb([L, a, b]) { 29 + var l = L + a * +0.3963377774 + b * +0.2158037573; 30 + var m = L + a * -0.1055613458 + b * -0.0638541728; 31 + var s = L + a * -0.0894841775 + b * -1.291485548; 32 + // The ** operator here cubes; same as l_*l_*l_ in the C++ example: 33 + l = l ** 3; 34 + m = m ** 3; 35 + s = s ** 3; 36 + var r = l * +4.0767416621 + m * -3.3077115913 + s * +0.2309699292; 37 + var g = l * -1.2684380046 + m * +2.6097574011 + s * -0.3413193965; 38 + var b = l * -0.0041960863 + m * -0.7034186147 + s * +1.707614701; 39 + // Convert linear RGB values returned from oklab math to sRGB for our use before returning them: 40 + r = 255 * linearToGamma(r); 41 + g = 255 * linearToGamma(g); 42 + b = 255 * linearToGamma(b); 43 + // 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: 44 + r = clamp(r, 0, 255); 45 + g = clamp(g, 0, 255); 46 + b = clamp(b, 0, 255); 47 + // OPTION: round the values. May not be necessary if you use them immediately for rendering in JavaScript, as JavaScript (also) discards decimals on render: 48 + r = Math.round(r); 49 + g = Math.round(g); 50 + b = Math.round(b); 51 + return [r, g, b]; 52 + }