Small library for generating claude-code like unicde block mascots, and providing animations when they do stuff
0
fork

Configure Feed

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

refactor: smarter leg positioning with inset/full/outset cascade

Legs now prefer being inset 1 col from body edges for a cleaner look.
Falls back to full body width if inset would be too cramped (adjacent
legs touching), then outset by 1 if even full width isn't enough.
Threshold: need span >= 2N-1 for N legs to have gaps between them.

+30 -11
+30 -11
src/main.rs
··· 161 161 format!("\x1b[38;2;{};{};{}m\u{2588}\x1b[0m", r, g, b) 162 162 } 163 163 164 - fn leg_mask(width: usize, numlegs: usize) -> (Vec<bool>, usize) { 165 - let overhang = if numlegs > width / 2 { 1 } else { 0 }; 166 - let total = width + 2 * overhang; 167 - let mut mask = vec![false; total]; 164 + /// Build a leg row mask. Chooses the best span for the legs: 165 + /// 1. Inset by 1 from each edge (preferred, looks smoother) 166 + /// 2. Full body width (if inset is too cramped) 167 + /// 3. Outset by 1 beyond each edge (if full width is still too cramped) 168 + /// "Too cramped" = adjacent legs would touch (need at least 1 gap between each). 169 + /// Returns (mask vec, inset amount). Positive inset = legs narrower than body, 170 + /// negative inset (stored as 0 with wider mask) = legs wider than body. 171 + fn leg_mask(width: usize, numlegs: usize) -> (Vec<bool>, i32) { 168 172 if numlegs == 0 { 169 - return (mask, overhang); 173 + return (vec![false; width], 0); 170 174 } 171 175 172 - let span = total; 176 + // Minimum span to have at least 1 gap between each adjacent leg: 177 + // N legs need span >= 2N - 1 (each leg + gap except after last) 178 + let min_span = if numlegs <= 1 { 1 } else { 2 * numlegs - 1 }; 179 + 180 + // Try inset first (1 col in from each side), then full width, then outset 181 + let (span, inset): (usize, i32) = if width >= 4 && width - 2 >= min_span { 182 + (width - 2, 1) // inset by 1 183 + } else if width >= min_span { 184 + (width, 0) // full body width 185 + } else { 186 + (width + 2, -1) // outset by 1 187 + }; 188 + 189 + let mut mask = vec![false; span]; 173 190 174 191 if numlegs == 1 { 175 192 mask[span / 2] = true; 176 - return (mask, overhang); 193 + return (mask, inset); 177 194 } 178 195 179 196 for i in 0..numlegs { 180 197 let col = (i * (span - 1)) / (numlegs - 1); 181 - if col < total { 198 + if col < span { 182 199 mask[col] = true; 183 200 } 184 201 } 185 202 186 - (mask, overhang) 203 + (mask, inset) 187 204 } 188 205 189 206 fn render(p: &CloodParams) -> String { ··· 270 287 output.push('\n'); 271 288 } 272 289 273 - let (legs, overhang) = leg_mask(width, p.numlegs); 290 + let (legs, inset) = leg_mask(width, p.numlegs); 274 291 let effective_legsize = if p.numlegs == 0 { 0 } else { p.legsize }; 275 292 276 293 for _row in 0..effective_legsize { 277 - let leg_pad = if arm_pad >= overhang { arm_pad - overhang } else { 0 }; 294 + // inset > 0: legs narrower than body, add extra padding 295 + // inset < 0: legs wider than body, reduce padding 296 + let leg_pad = (arm_pad as i32 + inset).max(0) as usize; 278 297 for _ in 0..leg_pad { 279 298 output.push_str(space); 280 299 }