[HN Gopher] Faces.js, a JavaScript library for generating vector...
___________________________________________________________________
Faces.js, a JavaScript library for generating vector-based cartoon
faces
Author : starkparker
Score : 408 points
Date : 2024-04-06 18:37 UTC (1 days ago)
(HTM) web link (zengm.com)
(TXT) w3m dump (zengm.com)
| thatha7777 wrote:
| i love this
| gkoberger wrote:
| Very cool. Here's another style! https://getavataaars.com/
| throwaway35777 wrote:
| import { display, generate } from "facesjs"; //
| Generate a random face const face = generate();
| // Display in a div with id "my-div-id" display("my-div-
| id", face);
|
| Beautiful API.
| xg15 wrote:
| As beautiful as the faces.
| throwaway35777 wrote:
| The faces are amazing! I hope if he finds an artist they
| don't get changed too much.
|
| I absolutely am looking for an excuse to use faces.js
| somewhere.
| rkagerer wrote:
| It would be neat as a forum icon, if you got to pick one
| and tailor it.
| nox101 wrote:
| No, that's poor API. If it wants to generate HTML it should
| return it's root element.
|
| Let's say I want to add a random face to every div with class
| "face". With this API have to generate ids. With an API that
| returns a root element it's trivial and it's not duplicating
| work (inserting elements into the DOM) that already exists.
|
| Taking a selector would not be much better because it would
| again be duplicating work and make it harder to customize
| usage.
|
| Taking a parent element for it to insert into would also be a
| poor API because it makes it harder to insert next to a
| sibling.
|
| A good API would be one of const face =
| generate() someElem.appendChild(face);
|
| or const face = generate()
| someElem.appendChild(face.domElement);
|
| or const face = generate()
| someElem.appendChild(face.html()); // assumes it can render
| to something else too
| pc86 wrote:
| > Taking a parent element for it to insert into would also be
| a poor API because it makes it harder to insert next to a
| sibling.
|
| To extend the documentation example, wouldn't you just have
| "my-div-id-sibling" already and call
| display("my-div-id", face); display('my-div-id-
| sibling", someOtherFace);
|
| Like almost all discussions that use language like "good API"
| or "bad API" this seems to me entirely personal preference.
| Personally I find anything where I end up having to call
| appendChild() myself a bad API.
| nox101 wrote:
| No, that would not be better. Consider
| document.querySelectorAll('classIWantFacesIn').forEach(elem
| => { const face = generate(); elem.id
| = `face-${crypto.randomUUID()}`; // this line should not be
| needed display(elem.id, face); });
|
| With the current API I'm required to make ids and make sure
| they don't collide with other elements. Vs
| document.querySelectorAll('classIWantFacesIn').forEach(elem
| => { const face = generate();
| elem.appendChild(face.domElement); });
|
| Now, no id is needed. It's objectively a better API to not
| need the id.
| yoavm wrote:
| I agree the API could be better, but note that you don't have
| to use IDs - you can also pass the parent element to display
| directly: https://github.com/zengm-
| games/facesjs/blob/master/src/displ...
| nox101 wrote:
| As mentioned, that's still a poorer API than just returning
| a root element.
|
| Consider... // insert after every link
| document.querySelectorAll('a.funny').forEach(elem =>
| const face = generate(); const parentForFace =
| document.createElement('span');
| elem.appendChild(parentForFace);
| display(parentForFace); });
|
| vs // insert after every link
| document.querySelectorAll('a.funny').forEach(elem =>
| const face = generate();
| elem.after(face.domElement); });
|
| Taking a parent element is still a poor API
| xg15 wrote:
| Has a bit of a South Park and/or Futurama vibe to it, but why
| not?
| rasso wrote:
| Exactly, why not! Love it.
| krebby wrote:
| This would be fun to use with Chernoff Faces
| https://en.m.wikipedia.org/wiki/Chernoff_face
| winwang wrote:
| Thank you for evangelizing -- this is amazing and kinda
| hilarious. Does it count as biohacking? lol.
| pavel_lishin wrote:
| Ooh, ooh, I get to be the one to make the Peter Watts reference
| today! Chernoff Faces make an appearance in Blindsight, where
| the ship captain Sarasti uses them. The specific details would
| be a spoiler, though.
| 082349872349872 wrote:
| In this particular case, I think there are at least two nose
| shapes close enough to p/2 that Sarasti would find them
| disturbing.
| defrost wrote:
| Never saw such a nose in my life 'Tis a nose of
| parchment It is six times as big but 'tis a
| nose like my nose
|
| https://www.youtube.com/watch?v=bNQKYolhZkg
|
| https://en.wikipedia.org/wiki/The_Kiss_and_Other_Movements
| supportengineer wrote:
| Imagine these on SRE dashboards to determine system state
| itronitron wrote:
| Depending on the application that could provide some real
| benefit as human vision is predisposed to seeing/detecting
| faces.
| af3d wrote:
| Well, I didn't find the art very appealing. But I do love the
| idea behind it. Neat project!
| ramijames wrote:
| This is adorable.
| cmgriffing wrote:
| Really cool. I would love to see an api for just passing a
| numeric seed value. Then users of an app can click a "refresh"
| button to get one they like that could persist across page loads
| and devices without having to store the entire face object in the
| db.
| cypressious wrote:
| You could serialize the JS representation to Base64 or Base10
| if you want it to be numeric.
| wongarsu wrote:
| But that's a lot more data than just storing which of the
| ~2^50 possible faces was generated. You could serialize the
| entire face including the colors and scaling factors into a
| much smaller string, or just take one number that is used as
| a seed for a random number generator that sets the other
| parameters
| pests wrote:
| The seed version with random parameters doesn't allow you
| to or your users to design their own. Just random selection
| until you get one you like, no editing of details.
| two_handfuls wrote:
| The face object is small (it's the parameters). You can save
| that.
| itronitron wrote:
| I did the first part of this (not the API part) a while back to
| generate avatar faces for minecraft with a random sequence of
| numbers (one per pixel, gray scale, and the faces were
| symmetric). I got some fun results as a wide range of
| anatomical facial morphologies were produced.
| hacker_88 wrote:
| Back in the day out used to be called NFT
| toisanji wrote:
| very cool. Are there libraries like these that do whole
| characters with bodies? Would love to play with those!
| rented_mule wrote:
| Someone I know has done some work to parameterize facial
| expressions: https://www.redblobgames.com/x/1845-face-generator/
|
| He has a bunch of other interesting things like this, too:
| https://www.redblobgames.com/
| jlturner wrote:
| This is pretty common in 3D work. Blender has a feature called
| "blend shapes" that implements a similar interface, and is
| commonly used for complex facial animation and general model
| parameterization.
| Tijdreiziger wrote:
| Duolingo did a talk at their Duocon conference about how they
| use parametrization to animate the characters in their app.
|
| https://www.youtube.com/watch?v=fgOqvyPif3g
|
| (no affiliation)
| sabellito wrote:
| Their post on Polygonal Map Generation for Games [1], from
| 2010, got me into procedural generation in general.
|
| [1] http://www-cs-students.stanford.edu/~amitp/game-
| programming/...
| nmstoker wrote:
| That's cool - I had been thinking with the OP site that quite a
| number looked like they were scowling/angry so a way to vary
| that is interesting to explore.
| outime wrote:
| I liked it a lot, including the README. The author seems to be an
| indie dev who creates sport management sim games [1], all of
| which run entirely in the browser like the linked library (which
| is used in the games).
|
| [1] https://zengm.com/
| criley2 wrote:
| No wonder I instantly recognized these faces as Basketball GM's
| art! Dumbmatter has made some very cool things.
| Joel_Mckay wrote:
| Very fun little project. Nice =)
| SiempreViernes wrote:
| Aww, it's not making Chernoff faces :(
|
| (https://en.wikipedia.org/wiki/Chernoff_face)
| DyslexicAtheist wrote:
| they should have called it "4 non blondes" because there are no
| blonds
| Minor49er wrote:
| Using the "faces.js editor" link at the bottom of the page, it
| shows that you can use any color you want for the hair. Also,
| if it didn't allow blonds, it would probably just be called "no
| blonds" since there are more than 4 possible variants
| DyslexicAtheist wrote:
| sounds like you didn't get the joke. oh well.
| jszymborski wrote:
| When are the Faces.js NFTs going for sale? /s
| daltonlp wrote:
| If you like that, you may also like:
|
| https://pixelfaces.io/
| ezequiel-garzon wrote:
| Apologies for such a basic question. I have node installed on my
| machine, but clearly no idea how a JS library is included anymore
| (among other things...). I created an HTML file, included a div
| ``a div with id "my-div-id"`` as instructed, and even added
| type="module" in the script tag, but I get in Chrome ``Uncaught
| TypeError: Failed to resolve module specifier "facesjs". Relative
| references must start with either "/", "./", or "../".``
|
| Any pointers on all the steps to running this? Should I expect
| node to create a js file that could be served together with the
| HTML file? Or would my hosting server need to have node, and run
| it every time there is a request? Thanks in advance, I'm sorry
| for the confusion.
| tylerchilds wrote:
| not a basic question at all-- front end has jumped the shark.
|
| you can bypass node, npm install, etc for a prototype entirely
| in an html file leveraging an import map.
|
| this is the importmap i load for all my pages:
| https://github.com/tylerchilds/plan98/blob/6120e6a80a3d48438...
|
| to support faces, i'd add an entry: "facesjs":
| "https://esm.sh/facesjs@4.0.0"
|
| which should get rid of the import path issue, and to support
| legacy browsers that still might have that error:
|
| https://github.com/guybedford/es-module-shims
| Solvency wrote:
| That is 10x more complicated and unorthodox than simply
| running "$ npm install --save facesjs".
| fzzzy wrote:
| That's not enough to get it to load in a browser. Which
| bundler will you use? Shark jumped.
| Solvency wrote:
| One command: npx.
| tylerchilds wrote:
| yeah, i thought about asking if OP was using vite,
| webpack, snowpack or babel, but based on the context of
| the question, it seemed like vanilla web, so i answered
| vanilla web.
| ezequiel-garzon wrote:
| Thank you very much for your help, just upvoting feels
| rude! I have not quite gotten there, but thank you for
| pointing me in the right direction. Clearly I'm an
| enthusiast at best, but "back in my day" you could put
| all the needed libraries in the script tag and the CSS
| under link... sigh... The moment nodejs, supposedly a
| back end, started being used pervasively for the front
| end, I lost whatever conceptual map I had. Just as a
| personal challenge, I'm planning to _study_ [1], which I
| see referenced a lot, and see if I can "get it", albeit
| partially. Any other such references would be welcome.
|
| Thanks again! Great website and projects, by the way.
|
| [1] https://developer.mozilla.org/en-
| US/docs/Web/JavaScript/Guid...
| scubbo wrote:
| > jumped the shark
|
| Genuine question - what does that phrase mean to you?
|
| I've only ever heard it in the context of television shows
| (meaning "has been renewed for so many seasons that the
| writers have run out of ideas and have started forcing the
| characters into ever wackier situations to generate novelty")
| - and while it's intuitivve to map from that meaning to a
| more generic "has gone on for too long and thus become bad",
| the translation is fascinating. When you said this, were you
| intentionally using a term from another domain with a
| different meaning in the confidence that your audience could
| translate it appropriately, or does the phrase "jump the
| shark" really just mean "be old, and thus bad" to you?
|
| (Asking from a purely non-prescriptivist non-judgemental
| perspective! I'm interested in understanding your thought
| process, not in judging or correcting you)
| Retr0id wrote:
| While I'm aware of the phrase's origins, I've never heard
| it used to describe a TV show, only an unrelated field just
| like in this example.
| tylerchilds wrote:
| happy days was running out of ideas and wanted to continue
| to retain audience attention and had The Fonz water ski and
| jump over a shark.
|
| silicon valley was running out of ideas, but steve ballmer
| famously delivered the Developers, developers, developers
| speech paving the way for capturing developer market share,
| for a platform with platform developers is no platform at
| all.
|
| there's tooling that solves technical problems and tooling
| that business problems.
|
| a system has "jumped the shark" when there are at least
| five ways to accomplish the same thing and the audience was
| just trying to have some happy days on the tubes.
|
| my core hunch is that the ecosystem is a compile target
| versus a respected platform and that's where i believe the
| shark has been jumped.
|
| the web is cool, if only we stopped trying to jump it and
| befriend the shark already.
|
| the long answer is, i've got a bespoke markdown like syntax
| i'm using for both a web publishing and screenplay
| authoring. i feel no difference between telling stories in
| interactive web formats or printed pages.
|
| maybe i'm jumping the shark.
| tylerchilds wrote:
| i realize i'm making some claims here, so
|
| server side multi page demo:
| https://sillyz.computer/sagas/sillyz.computer/en-
| us/000-000....
|
| if you press esc in the top left, you can play with that
| in the repl.
|
| if you visit: https://sillyz.computer, that same text
| based adventure wizard journey as an embedded widget is
| the lower post it note.
|
| this is the folder i'm using for localizing that journey:
| https://github.com/tylerchilds/plan98/tree/plan98/client/
| pub...
|
| any of the short hand web components dynamically load
| from: https://github.com/tylerchilds/plan98/tree/plan98/c
| lient/pub...
|
| full circle-- i'm very much playing across domains with
| the jumping the shark reference
| icepat wrote:
| > Genuine question - what does that phrase mean to you?
|
| Jumped the shark means roughly the same thing as "lost the
| plot". In that, the current state of affairs has entered
| into absurd territories.
| philsnow wrote:
| I've never heard of importmaps before, thank you.
| nilslice wrote:
| Obviously this also needs to be a library in Zig, Rust, Go,
| Elixir, Haskell, Java, C#, F#, OCaml, PHP, Python, Ruby, Perl, C,
| C++ & Lean
|
| So, it now lives as an Extism[0] wasm plugin you can call from
| those languages:
| https://modsurfer.dylibso.com/module?hash=2050e7f7a129a48df0...
|
| [0]: https://github.com/extism/extism
| mnahkies wrote:
| Interesting, I hadn't come across extism before. How hard would
| it be to package https://github.com/biojppm/rapidyaml in this
| way? (And do you have a extism for dummies guide?)
| nilslice wrote:
| Extism can be really useful for packaging up and running
| cross-language libraries!
|
| The most clear information about it is at:
| https://extism.org, but its a bit focused on the primary use
| case for Extism, being a universal plugin system.
|
| There is a C PDK (https://github.com/extism/c-pdk) which
| you'd probably want to use in a new wrapper around your
| library in C++, and compile it to wasm32 freestanding or
| WASI, but without emscripten. Extism doesn't currently have
| an interop layer to emscripten.
| richardfey wrote:
| > Don't worry about what some plug-in code might do to your
| program. Extism is built with security as a core principle,
| and fully sandboxes the execution of all plug-in code.
|
| I find the wording a bit off here. Responsible security
| involves transparency along the supply chain and minimum
| trust, certainly not talking about worries and giving them
| up with ease.
| nilslice wrote:
| Would you suggest something more appropriate?
| foundart wrote:
| This is the first I've heard of Extism. I like their goal!
| "Extism's goal is to make all software programmable." [0]
|
| [0] https://extism.org/docs/overview
| b0bb0 wrote:
| I know many around here don't love scarce digital assets but here
| is my take on procedural faces: https://regular.world/
|
| My goal was to maximize variation across 10,000 faces and add
| warmth which is hard to do with cgi.
| tvink wrote:
| I thought "ah maybe they're saying scarce digital assets,
| because they don't wanna be conflated with NFT pyramid
| schemes".. clicked link, and found fullblown ponzinomics with
| "assets" paying out tokens.
|
| And people wonder why most of us are tired of this stuff.
| b0bb0 wrote:
| I don't know why you see it as any sort of ponzi.. it's just
| an experiment with digital assets, role-playing and world
| building. Involving money is a pyramid scheme? Perhaps not
| the thread to discuss. Guessing the reaction is because
| crypto is mainly grifters + money grabs.. and the cringey
| apes were the worst representatives.
| agys wrote:
| Those look like a total Fernando Botero rip-off!
| b0bb0 wrote:
| Yes his work was the inspiration, of course.
| jonwinstanley wrote:
| Are there any licensing restrictions to using this library and
| the images it creates?
| bitwize wrote:
| Spinnaker's Face Maker
| (https://www.youtube.com/watch?v=5K4ovkVLp8Y) for the modern era!
| monooso wrote:
| I built something similar a few months back [1][2].
|
| Among other things, it accepts an arbitrary key, and will always
| generate the same avatar for the same key. Very handy for apps
| which need to generate user-specific avatars.
|
| [1]: https://github.com/monooso/avataraas
|
| [2]: https://github.com/monooso/avatar
| snissn wrote:
| Here's a demo of my project shape faces https://shapefaces.com/
| red1reaper wrote:
| Aren't those like 2d version of nintendo's MIIs? I mean, the eyes
| noses and mouths are very much like those of MIIs
___________________________________________________________________
(page generated 2024-04-07 23:01 UTC)