[{"data":1,"prerenderedAt":247},["ShallowReactive",2],{"project-43583478":3},{"id":4,"name":5,"line":6,"line_source":7,"title":8,"url":9,"domain":10,"maker":11,"posted_at":12,"year":13,"points":14,"comments":15,"rank_in_year":16,"shown_in_year":17,"top":18,"tier":19,"category":20,"subcategory":21,"format":22,"keywords":23,"reception":29,"sentiment":30,"stance_mix":31,"scored_comments":35,"aspects":36,"strip":42,"post_text":44,"what":45,"said":79,"maker_in_thread":154,"shape":161,"grid":166,"attempts":210,"same_week":211,"maker_shows":33,"maker_hidden":239,"reader_version":240,"card":241},"43583478","uWrap.js","A faster and more accurate text wrapping util in \u003C 2KB","title","Show HN: uWrap.js – A faster and more accurate text wrapping util in \u003C 2KB","https:\u002F\u002Fgithub.com\u002Fleeoniya\u002FuWrap","github.com","leeoniya",1743778984,2025,121,21,622,3837,17,"notable","languages","text layout library","library",[24,25,26,27,28],"text wrapping","canvas text","virtualization","row height","javascript library","curious",0.286,{"positive":32,"neutral":33,"mixed":34,"critical":34},3,7,0,10,{"idea":37,"performance":39,"execution":41},{"positive":38,"critical":34},2,{"positive":40,"critical":34},1,{"positive":34,"critical":34},[34,34,34,34,43,34,32,32,32,32,43,34,43,32,34,34,34,32,34,32,34],5,null,{"problem":46,"audience":57,"pricing":44,"motivation":66,"time_to_build":44,"stack":70,"openness":77,"stage":78,"team_size":78},{"value":47,"source":48,"evidence":49},"Canvas and virtual lists lack text wrapping, so predicting wrapped text height or wrap points is hard","maker",[50,53],{"id":51,"by":11,"text":52},"43589586","it's where you need to know the wrap points of some text given a width of the container. since Canvas does not offer text wrapping, that is one use case, because you have to wrap…",{"id":54,"by":55,"text":56},"43589186","sroussey","From the introduction: uWrap exists to efficiently predict varying row heights for list and grid virtualization[1], a technique for UI performance optimization when rendering…",{"value":58,"source":59,"evidence":60},"Developers building virtualized lists, tables and canvas-rendered text","inferred",[61,62,63],{"id":54,"by":55,"text":56},{"id":51,"by":11,"text":52},{"id":64,"by":11,"text":65},"43593552","we needed something like this for virtualization of the Table panel, data-heavy dropdowns, and long list views in Grafana. so i guess that's a three-in-one? i looked for the…",{"value":67,"source":48,"evidence":68},"Needed fast, accurate wrapping for virtualized Grafana table panels and dropdowns; existing options were inaccurate or wasteful",[69],{"id":64,"by":11,"text":65},[71],{"value":72,"source":59,"evidence":73},"JavaScript",[74],{"id":75,"by":11,"text":76},"43589412","let me know if you find one: https:\u002F\u002Fgithub.com\u002Fleeoniya\u002FuWrap\u002Fblob\u002Fmain\u002Fpackage.json","open_source","unknown",{"praise":80,"objections":101,"requests":116,"questions":124,"alternatives":139},[81,93],{"value":82,"source":83,"evidence":84},"Useful for virtualization and canvas text layout","commenter",[85,89],{"id":86,"by":87,"text":88},"43590328","somishere","I can count on one hand the number of times I've needed something like this in the last decade. But I'd also need to count the same number of times I've implemented a less than…",{"id":90,"by":91,"text":92},"43594999","nhatcher","Hmmm, I might have a brilliant usecase for it: https:\u002F\u002Fgithub.com\u002Fironcalc\u002FIronCalc\u002Fblob\u002Fmain\u002Fwebapp\u002FIronCalc\u002Fsrc\u002Fcomponents\u002FWorksheetCanvas\u002FworksheetCanvas.ts#L88 Thanks!",{"value":94,"source":83,"evidence":95},"Accuracy and performance improvements over existing approaches",[96,97],{"id":64,"by":11,"text":65},{"id":98,"by":99,"text":100},"43592560","RadiozRadioz","Nice. I plan to use this tool to pre-calculate the letter size ratios for all my fonts, then bake those into my non-JS server code as constants and use a similar wrapping…",[102,109],{"value":103,"source":83,"evidence":104},"Unclear why canvas rendering is needed when HTML subsets work",[105],{"id":106,"by":107,"text":108},"43589173","Jaxkr","Hi OP! Thanks for sharing. I don’t totally understand the point of this. Why would you want to use a Canvas renderer for this use case? If you want to render a massive table,…",{"value":110,"source":83,"evidence":111},"Kerning and ligatures complicate accuracy",[112],{"id":113,"by":114,"text":115},"43593947","tln","You'd need more than just letter widths because of kerning and ligatures, for 100% accuracy. Anyway, fontkit can work on the server and can get individual glyph metrics as well…",[117],{"value":118,"source":83,"evidence":119},"Support for WebGL environments",[120],{"id":121,"by":122,"text":123},"43589979","bufferoverflow","What if you have to display it in a webgl environment?",[125,132],{"value":126,"source":83,"evidence":127},"What underlying dependencies does it have",[128],{"id":129,"by":130,"text":131},"43589405","ForOldHack","Any underlying dependencies we need to know about?",{"value":133,"source":83,"evidence":134},"Does it handle kerning and character pairs",[135,136],{"id":113,"by":114,"text":115},{"id":137,"by":11,"text":138},"43594030","yep, uWrap internally builds a lookup table for char pairs that differ significantly in width together from just adding their raw widths.",[140,144,148],{"value":141,"source":48,"evidence":142},"canvas-hypertxt",[143],{"id":64,"by":11,"text":65},{"value":145,"source":83,"evidence":146},"fontkit",[147],{"id":113,"by":114,"text":115},{"value":149,"source":83,"evidence":150},"CSS columns",[151],{"id":152,"by":11,"text":153},"43593188","> As an old school print designer, I would love to see a return to a web with multi-column text on desktop, that reformatted to single column on mobile, and graphics runarounds…",{"comments":33,"answered":32,"key":155},[156,157,160],{"id":152,"text":153},{"id":158,"text":159},"43594017","> Now what is there to prevent me from scrolling up and down on a 16:9 display to read the left column of a 10k letter text and then the right column? if the author decided on…",{"id":64,"text":65},{"commenters":162,"max_depth":163,"maker_replies":33,"first_comment_mins":164,"lifespan_hours":165},14,4,566,29,[167,171,173,176,177,179,181,183,184,187,188,189,192,194,196,199,200,203,205,206,209],[168,34,34,169,170,34],"43590713","other\u002Fneutral\u002Fnone","noduerme",[152,34,34,172,11,40],"commenter\u002Fcritical\u002Fnone",[174,34,34,172,175,34],"43593915","PinkSheep",[158,34,34,172,11,40],[86,40,43,178,87,34],"project\u002Fpositive\u002Fidea",[64,40,34,180,11,40],"maker\u002Fpositive\u002Fperformance",[106,38,32,182,107,34],"project\u002Fneutral\u002Fidea",[54,38,32,182,55,34],[185,38,32,182,186,34],"43589216","kevlened",[121,38,32,182,122,34],[90,32,43,178,91,34],[190,32,34,191,11,40],"43596297","maker\u002Fpositive\u002Fnone",[98,163,43,193,99,34],"project\u002Fpositive\u002Fperformance",[113,163,32,195,114,34],"project\u002Fneutral\u002Fexecution",[197,163,34,198,99,34],"43594023","commenter\u002Fneutral\u002Fnone",[137,163,34,195,11,40],[201,43,34,169,202,34],"43594046","dawnerd",[129,204,32,195,130,34],6,[75,204,34,195,11,40],[207,204,32,182,208,34],"43589541","jonahx",[51,204,34,182,11,40],[],[212,217,222,227,231,235],{"id":213,"name":214,"points":215,"category":216},"43613194","Browser MCP",616,"dev_tools",{"id":218,"name":219,"points":220,"category":221},"43593789","Whatsit",513,"games",{"id":223,"name":224,"points":225,"category":226},"43569190","OpenNutrition",311,"data",{"id":228,"name":229,"points":230,"category":216},"43614285","Lux",268,{"id":232,"name":233,"points":234,"category":216},"43627758","DrawDB",263,{"id":236,"name":237,"points":238,"category":216},"43573539","GitMCP",185,false,"v2",{"id":242,"name":5,"line":6,"ai":239,"cat":20,"year":13,"points":14,"comments":15,"rec":29,"s":243,"top":18,"kw":244,"maker":11,"domain":10,"tier":19,"attempts":34,"strip":245,"url":9,"mix":246,"praise":82,"objection":103,"sub":21},43583478,0.29,[24,25,26,27,28],"000050333350530003030",[32,33,34,34],1793991116713]