Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

blank: fix face winding (try both), per-key z-sort, pastel face tints

- addFaces tries both winding orders, keeps front-facing one
- Each keyboard key gets its own z-depth for proper sorting
- Each face gets a subtle pastel tint (pink, green, lavender, warm, cool, mauve)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+27 -12
+27 -12
system/public/aesthetic.computer/disks/blank.mjs
··· 217 217 const drawList = []; 218 218 219 219 // Base + lid faces 220 - const addFaces = (proj, color, tag, flipWinding) => { 221 - for (let [a, b, c, d] of faceQuads) { 222 - if (flipWinding) { [a, b, c, d] = [d, c, b, a]; } 220 + // Pastel tints per face — subtle color shifts 221 + const pastelTints = [ 222 + [1.0, 0.92, 0.95], [0.92, 1.0, 0.95], [0.95, 0.92, 1.0], 223 + [1.0, 0.97, 0.9], [0.9, 0.97, 1.0], [0.97, 0.9, 0.97], 224 + ]; 225 + let faceIdx = 0; 226 + const addFaces = (proj, color, tag) => { 227 + for (const [a, b, c, d] of faceQuads) { 228 + const fi = faceIdx++; 223 229 const e1x = proj[b][0] - proj[a][0], e1y = proj[b][1] - proj[a][1]; 224 230 const e2x = proj[d][0] - proj[a][0], e2y = proj[d][1] - proj[a][1]; 225 - if (e1x * e2y - e1y * e2x >= 0) continue; 226 - const z = (proj[a][2] + proj[b][2] + proj[c][2] + proj[d][2]) / 4; 227 - drawList.push({ z, type: "face", proj, verts: [a, b, c, d], color, tag }); 231 + const cross = e1x * e2y - e1y * e2x; 232 + if (cross < 0) { 233 + const z = (proj[a][2] + proj[b][2] + proj[c][2] + proj[d][2]) / 4; 234 + drawList.push({ z, type: "face", proj, verts: [a, b, c, d], color, tag, fi }); 235 + } else if (cross > 0) { 236 + const z = (proj[a][2] + proj[b][2] + proj[c][2] + proj[d][2]) / 4; 237 + drawList.push({ z, type: "face", proj, verts: [d, c, b, a], color, tag, fi }); 238 + } 228 239 } 229 240 }; 230 - addFaces(projBase, baseColor, "base", false); 231 - addFaces(projLid, lidColor, "lid", true); 241 + addFaces(projBase, baseColor, "base"); 242 + addFaces(projLid, lidColor, "lid"); 232 243 233 244 // Hinge barrels 234 245 const hingeColor = isDark ? [40, 40, 45] : [140, 140, 148]; ··· 246 257 const ke1x = kbTR[0] - kbTL[0], ke1y = kbTR[1] - kbTL[1]; 247 258 const ke2x = kbBL[0] - kbTL[0], ke2y = kbBL[1] - kbTL[1]; 248 259 if (ke1x * ke2y - ke1y * ke2x < 0) { 249 - const kbZ = (kbTL[2] + kbTR[2] + kbBL[2] + kbBR[2]) / 4; 250 260 const rows = ["QWERTYUIOP", "ASDFGHJKL", "ZXCVBNM"]; 251 261 const lerp = (a, b, t) => a + (b - a) * t; 252 262 for (let r = 0; r < rows.length; r++) { ··· 256 266 for (let k = 0; k < row.length; k++) { 257 267 const u0 = indent + (k + 0.15) / row.length * (1 - indent * 2); 258 268 const u1 = indent + (k + 0.85) / row.length * (1 - indent * 2); 269 + // Per-key z from interpolated depth 270 + const keyMidT = (t0 + t1) / 2; 271 + const keyMidU = (u0 + u1) / 2; 272 + const keyZ = lerp(lerp(kbTL[2], kbTR[2], keyMidU), lerp(kbBL[2], kbBR[2], keyMidU), keyMidT); 259 273 drawList.push({ 260 - z: kbZ - 0.05, // draw on top of base face 274 + z: keyZ - 0.05, // slightly in front of base face 261 275 type: "key", 262 276 pts: [ 263 277 [lerp(lerp(kbTL[0], kbTR[0], u0), lerp(kbBL[0], kbBR[0], u0), t0), ··· 305 319 // Draw everything in sorted order 306 320 for (const item of drawList) { 307 321 if (item.type === "face") { 308 - const { proj, verts: [a, b, c, d], color } = item; 322 + const { proj, verts: [a, b, c, d], color, fi } = item; 309 323 const shade = max(0.5, min(1, 0.8 - item.z * 0.15)); 310 - ink(floor(color[0] * shade), floor(color[1] * shade), floor(color[2] * shade)); 324 + const tint = pastelTints[fi % pastelTints.length]; 325 + ink(floor(color[0] * shade * tint[0]), floor(color[1] * shade * tint[1]), floor(color[2] * shade * tint[2])); 311 326 tri(proj[a][0], proj[a][1], proj[b][0], proj[b][1], proj[c][0], proj[c][1]); 312 327 tri(proj[a][0], proj[a][1], proj[c][0], proj[c][1], proj[d][0], proj[d][1]); 313 328 } else if (item.type === "key") {