npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

shapesnap

v1.2.1

Published

Transform images to SVG using primitive shapes

Downloads

65

Readme

🃏 Shapesnap 🃏

Transform images to SVG using primitive shapes.

This library renders raster images to SVG images The algorithm repeatedly generates and mutates shapes, keeping only those that closely match the original bitmap.

Effectively it plays the card game "snap" with shapes until it finds a good match.

The code has largely been ported from the last known good fork of cutout which itself is derived from Primitive.

As per original, this has

  • No native, non-javascript dependencies (so no node-canvas, as that relies on Cairo)
  • No browser specific APIs (even though it can be bundled for the browser without any problems)
  • Modular and not tied to a single implementation, so it can fit in any project

New features

  • Ported to Typescript and ES6
  • Replaced d3 randomNormal with a faster random algorithm (gteat) for shape generation that has a greater central bell curve (anecdotally better fitting in fewer iterations).
  • Fixed a race condition causing NaNs in randomNormal only seen after a 5K+ iterations caused by a bug in the original d3 randomNormal implementation.
  • Replaced missing "dainty" utility lib npm dependency with a small function to do the same thing (thanks go to swanie21's svg info page svg-shapes for the crash course).
  • Provided a direct runner.ts using Jimp to use with your own images. (Original used direct ndarrays or the cutout-cli project which is now unavailable).
  • Added open licenced pexels.com example images.
  • Cleaned up/modernised the code (an ongoing thing),

Additionally, I'm investigating further performance improvements using webworkers to split the variants work over multiple threads.

Examples with Increasing Detail

| Raster input | Svg result | |:----------------------------------------------|:----------------------------------------------| | | | | | | | | |

Usage

Note that this is only a quickly created script with a hardcoded config for my own testing but felt it would be useful for others to try it out before using the API.

Usage with tsx installed globally

npm install -g tsx
tsx runner.ts images/robot.png ./robot.svg

Usage with transpile and node

npm run build
node ./dist/runner.js images/robot.png ./robot.svg

API

Usage

Auto stepping with [options.steps]

return new ShapeSnap( target, [options] ).autostep().svg

Within a for loop

for (let i = 0; i < steps; i++) {
    shapesnap.step(); // number of rendered shapes
}
return shapesnap.svg;

Constructor

new ShapeSnap( target, [options] )

Options

| Param | Type | Default | Description | |----------------------------|-----------------------------------|---------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | target | NdArray | | The image to render to svg | | [options] | Object | All of the below | Configuration options | | [options.alpha] | number | 192 | The opacity of the shapes (0-255) | | [options.amountOfShapes] | number | 40 | The number of shapes to try per step | | [options.amountOfAttempts] | number | 2 | The number of times to mutate each candidate shape | | [options.background] | Array.<number> | Auto calculated blend | Optional background color, expressed as an array of four numbers between 0 - 255 for respectively red, green, blue and transparency | | [options.maxSize] | number | 24 | The maximum size of any shape in SVG pixels e.g. for radius it is 1x, for width 2x. | | [options.shapeTypes] | Array.<string> | 'Circle', 'Cubic', 'Ellipse', 'Line', 'Quadratic', 'Rect', 'Square', 'Triangle' | The types of shapes to use when generating the image, available are: Circle, Cubic, RotatedEllipse, Ellipse, Line, Quadratic, Rect, RotatedRect, Square and Triangle | | [options.steps] | number | 2400 | The number of steps to attempt, this is directly relational to the number of final shapes in the image |

shapesnap.image ⇒ NdArray

Get the current image

shapesnap.svg ⇒ string

Get the current svg

shapesnap.shapes ⇒ ShapeColor[]

Get the current internal model of shapes

shapesnap.difference ⇒ number

Get the current difference

shapesnap.step() ⇒ Shapesnap

Add a single new shape

shapesnap.autostep( [callback: (progress:String) => void] ) ⇒ Shapesnap

Adds the option.steps number of steps with each 10% progression passed to the (optional) callback. If no callback is specified it outputs to the console.

Credits

License

MIT