{"id":15638761,"url":"https://github.com/transitive-bullshit/primitive","last_synced_at":"2026-03-10T02:33:12.898Z","repository":{"id":38857030,"uuid":"135392690","full_name":"transitive-bullshit/primitive","owner":"transitive-bullshit","description":"Reproduce images from geometric primitives.","archived":false,"fork":false,"pushed_at":"2023-10-10T04:12:49.000Z","size":13305,"stargazers_count":91,"open_issues_count":4,"forks_count":8,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-20T00:45:58.048Z","etag":null,"topics":["art","generative-art","graphics","primitive","primitives"],"latest_commit_sha":null,"homepage":"https://transitive-bullshit.github.io/primitive-web/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/transitive-bullshit.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-05-30T05:33:26.000Z","updated_at":"2025-05-02T14:13:57.000Z","dependencies_parsed_at":"2024-06-18T22:51:33.087Z","dependency_job_id":"c2b93517-17de-4c2f-8556-3ab479b05e19","html_url":"https://github.com/transitive-bullshit/primitive","commit_stats":{"total_commits":79,"total_committers":1,"mean_commits":79.0,"dds":0.0,"last_synced_commit":"d9bd79866b7f754303fc7b2539aa85acfb8fb1d5"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/transitive-bullshit/primitive","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/transitive-bullshit%2Fprimitive","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/transitive-bullshit%2Fprimitive/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/transitive-bullshit%2Fprimitive/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/transitive-bullshit%2Fprimitive/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/transitive-bullshit","download_url":"https://codeload.github.com/transitive-bullshit/primitive/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/transitive-bullshit%2Fprimitive/sbom","scorecard":{"id":897036,"data":{"date":"2025-08-11","repo":{"name":"github.com/transitive-bullshit/primitive","commit":"d9bd79866b7f754303fc7b2539aa85acfb8fb1d5"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.3,"checks":[{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Vulnerabilities","score":0,"reason":"102 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-6chw-6frg-f759","Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-whgm-jr23-g3j9","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-pp7h-53gx-mx7r","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-cwfw-4gq5-mrqx","Warn: Project is vulnerable to: GHSA-g95f-p29q-9xw4","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-c6rq-rjc2-86v2","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-h6ch-v84p-w6p9","Warn: Project is vulnerable to: GHSA-ff7x-qrg7-qggm","Warn: Project is vulnerable to: GHSA-qx4v-6gc5-f2vv","Warn: Project is vulnerable to: GHSA-qrmc-fj45-qfc2","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-8r6j-v8pm-fqw3","Warn: Project is vulnerable to: MAL-2023-462","Warn: Project is vulnerable to: GHSA-xf7w-r453-m56c","Warn: Project is vulnerable to: GHSA-4q6p-r6v2-jvc5","Warn: Project is vulnerable to: GHSA-pfrx-2q88-qq97","Warn: Project is vulnerable to: GHSA-44pw-h2cw-w3vq","Warn: Project is vulnerable to: GHSA-vfrc-7r7c-w9mx","Warn: Project is vulnerable to: GHSA-7wwv-vh3v-89cq","Warn: Project is vulnerable to: GHSA-jp4x-w63m-7wgm","Warn: Project is vulnerable to: GHSA-c429-5p7v-vgjp","Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj","Warn: Project is vulnerable to: GHSA-rc47-6667-2j5j","Warn: Project is vulnerable to: GHSA-pc5p-h8pf-mvwp","Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37","Warn: Project is vulnerable to: GHSA-78xj-cgh5-2h22","Warn: Project is vulnerable to: GHSA-2p57-rm9w-gvfp","Warn: Project is vulnerable to: GHSA-w7q9-p3jq-fmhm","Warn: Project is vulnerable to: GHSA-xvf7-4v9q-58w6","Warn: Project is vulnerable to: GHSA-2pr6-76vf-7546","Warn: Project is vulnerable to: GHSA-8j8c-7jfh-h6hx","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-6c8f-qphg-qjgp","Warn: Project is vulnerable to: GHSA-4xc9-xhrj-v574","Warn: Project is vulnerable to: GHSA-x5rq-j2xg-h7qm","Warn: Project is vulnerable to: GHSA-jf85-cpcp-j695","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-h726-x36v-rx45","Warn: Project is vulnerable to: GHSA-4xcv-9jjx-gfj3","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-fhjf-83wg-r2j9","Warn: Project is vulnerable to: GHSA-r683-j2x4-v87g","Warn: Project is vulnerable to: GHSA-ph34-pc88-72gc","Warn: Project is vulnerable to: GHSA-m6cx-g6qm-p2cx","Warn: Project is vulnerable to: GHSA-x8qc-rrcw-4r46","Warn: Project is vulnerable to: GHSA-4328-8hgf-7wjr","Warn: Project is vulnerable to: GHSA-93f3-23rq-pjfp","Warn: Project is vulnerable to: GHSA-pw54-mh39-w3hc","Warn: Project is vulnerable to: GHSA-xgh6-85xh-479p","Warn: Project is vulnerable to: GHSA-8g77-54rh-46hx","Warn: Project is vulnerable to: GHSA-4p35-cfcx-8653","Warn: Project is vulnerable to: GHSA-7f3x-x4pr-wqhj","Warn: Project is vulnerable to: GHSA-jpp7-7chh-cf67","Warn: Project is vulnerable to: GHSA-q6wq-5p59-983w","Warn: Project is vulnerable to: GHSA-j9fq-vwqv-2fm2","Warn: Project is vulnerable to: GHSA-pqw5-jmp5-px4v","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-g6ww-v8xp-vmwg","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-9q5w-79cv-947m","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-4g88-fppr-53pp","Warn: Project is vulnerable to: GHSA-4jqc-8m5r-9rpr","Warn: Project is vulnerable to: GHSA-325j-24f4-qv5x","Warn: Project is vulnerable to: GHSA-vx3p-948g-6vhq","Warn: Project is vulnerable to: GHSA-j44m-qm6p-hp7m","Warn: Project is vulnerable to: GHSA-3jfq-g458-7qm9","Warn: Project is vulnerable to: GHSA-5955-9wpr-37jh","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-r628-mhmh-qjhw","Warn: Project is vulnerable to: GHSA-9r2w-394v-53qc","Warn: Project is vulnerable to: GHSA-qq89-hq3f-393p","Warn: Project is vulnerable to: GHSA-pq67-2wwv-3xjx","Warn: Project is vulnerable to: GHSA-8cj5-5rvv-wf4v","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-w5p7-h5w8-2hfq","Warn: Project is vulnerable to: GHSA-7p7h-4mm5-852v","Warn: Project is vulnerable to: GHSA-38fc-wpqx-33j7","Warn: Project is vulnerable to: GHSA-662x-fhqg-9p8v","Warn: Project is vulnerable to: GHSA-394c-5j6w-4xmx","Warn: Project is vulnerable to: GHSA-78cj-fxph-m83p","Warn: Project is vulnerable to: GHSA-fhg7-m89q-25r3","Warn: Project is vulnerable to: GHSA-g3ch-rx76-35fx","Warn: Project is vulnerable to: GHSA-g78m-2chm-r7qv","Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh","Warn: Project is vulnerable to: GHSA-p9pc-299p-vxgp"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-24T14:06:38.406Z","repository_id":38857030,"created_at":"2025-08-24T14:06:38.406Z","updated_at":"2025-08-24T14:06:38.406Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30322645,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-10T01:36:58.598Z","status":"online","status_checked_at":"2026-03-10T02:00:06.579Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["art","generative-art","graphics","primitive","primitives"],"created_at":"2024-10-03T11:23:01.636Z","updated_at":"2026-03-10T02:33:12.877Z","avatar_url":"https://github.com/transitive-bullshit.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# primitive ([demo](https://transitive-bullshit.github.io/primitive-web/))\n\n\u003e Reproduce images from geometric primitives (Node.js + browser port of [primitive](https://github.com/fogleman/primitive)).\n\n[![NPM](https://img.shields.io/npm/v/primitive.svg)](https://www.npmjs.com/package/primitive) [![Build Status](https://travis-ci.com/transitive-bullshit/primitive.svg?branch=master)](https://travis-ci.com/transitive-bullshit/primitive) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)\n\nThis library is also available as a [CLI](https://github.com/transitive-bullshit/primitive-cli).\n\n[![Demo](https://storage.googleapis.com/transitive-bullshit-primitive/artem-bali-578205-unsplash-triangle-500.png)](https://transitive-bullshit.github.io/primitive-web/)\n\n#### Table of Contents\n\n- [Install](#install)\n- [Usage](#usage)\n- [How It Works](#how-it-works)\n- [Node API](#node-api)\n  * [primitive](#primitive)\n- [Browser API](#browser-api)\n  * [primitive](#primitive-1)\n- [Related](#related)\n- [Examples](#examples)\n- [License](#license)\n\n## Install\n\n```bash\nnpm install --save primitive\n```\n\n## Usage\n\nPrimitive is usable from both Node.js and browser environments. Most of the API options between the two are the same, with minor differences in input and output configurations.\n\nA good place to start is by checking out the [web demo](https://transitive-bullshit.github.io/primitive-web/).\n\nAvailable shape types:\n\n-   triangle\n-   ellipse\n-   rotated-ellipse\n-   rectangle\n-   rotated-rectangle\n-   random (will use all the shape types)\n\n## How It Works\n\nA target image is provided as input. The algorithm tries to find the single most optimal shape that can be drawn to minimize the error between the target image and the drawn image. It repeats this process, adding one shape at a time. Around 50 to 200 shapes are needed to reach a result that is recognizable yet artistic and abstract.\n\nThis GIF demonstrates the iterative nature of the algorithm, attempting to minimize the mean squared error by adding one shape at a time (use a \".gif\" output file to generate one yourself).\n\n[![Demo](https://raw.githubusercontent.com/transitive-bullshit/primitive/master/media/caleb-woods-248879-unsplash-rotated-ellipse-500.gif)](https://transitive-bullshit.github.io/primitive-web/)\n\n## Node API\n\n\u003c!-- Generated by documentation.js. Update this documentation by updating the source code. --\u003e\n\n### [primitive](https://github.com/transitive-bullshit/primitive/blob/b242853b0f4634b85b788b8c4d81d4d480d7f617/index.js#L48-L98)\n\nReproduces the given input image using geometric primitives.\n\nReturns a Promise for the generated model.\n\nAvailable output formats:\n\n-   png\n-   jpg\n-   svg\n-   gif\n\nType: `function (opts): Promise`\n\n-   `opts` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** Configuration options\n    -   `opts.input` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Input image to process (can be a local path, http url, or data url)\n    -   `opts.output` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** Path to generate output image\n    -   `opts.numSteps` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** Number of steps to process [1, 1000] \\(optional, default `200`)\n    -   `opts.minEnergy` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Minimum energy to stop processing early [0, 1]\n    -   `opts.shapeAlpha` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** Alpha opacity of shapes [0, 255] \\(optional, default `128`)\n    -   `opts.shapeType` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Type of shapes to use (optional, default `traingle`)\n    -   `opts.numCandidates` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** Number of top-level candidates per step [1, 32] \\(optional, default `1`)\n    -   `opts.numCandidateShapes` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** Number of random candidate shapes per step [10, 1000] \\(optional, default `50`)\n    -   `opts.numCandidateMutations` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** Number of candidate mutations per step [10, 500] \\(optional, default `100`)\n    -   `opts.numCandidateExtras` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** Number of extra candidate shapes per step [0, 16] \\(optional, default `0`)\n    -   `opts.onStep` **[function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)?** Optional async function taking in the model and step index\n    -   `opts.log` **[function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** Optional logging function (console.log to enable logging) (optional, default `noop`)\n\n## Browser API\n\n\u003c!-- Generated by documentation.js. Update this documentation by updating the source code. --\u003e\n\n### [primitive](https://github.com/transitive-bullshit/primitive/blob/b242853b0f4634b85b788b8c4d81d4d480d7f617/browser.js#L34-L83)\n\nReproduces the given input image using geometric primitives.\n\nOptionally draws the results to an HTML canvas.\n\nReturns a Promise for the generated model.\n\nType: `function (opts): Promise`\n\n-   `opts` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** Configuration options\n    -   `opts.input` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \\| [Image](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/Image) | ImageData)** URL, Image, or ImageData of input image to process\n    -   `opts.output` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \\| [HTMLCanvasElement](https://developer.mozilla.org/docs/Web/API/HTMLCanvasElement))?** Selector or DOM Element of HTMLCanvas to draw results\n    -   `opts.numSteps` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** Number of steps to process [1, 1000] (optional, default `200`)\n    -   `opts.minEnergy` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Minimum energy to stop processing early [0, 1]\n    -   `opts.shapeAlpha` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** Alpha opacity of shapes [0, 255] (optional, default `128`)\n    -   `opts.shapeType` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Type of shapes to use (optional, default `traingle`)\n    -   `opts.numCandidates` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** Number of top-level candidates per step [1, 32] (optional, default `1`)\n    -   `opts.numCandidateShapes` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** Number of random candidate shapes per step [10, 1000] (optional, default `50`)\n    -   `opts.numCandidateMutations` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** Number of candidate mutations per step [10, 500] (optional, default `100`)\n    -   `opts.numCandidateExtras` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** Number of extra candidate shapes per step [0, 16] (optional, default `0`)\n    -   `opts.onStep` **[function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)?** Optional async function taking in the model and step index\n    -   `opts.log` **[function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** Optional logging function (console.log to enable logging) (optional, default `noop`)\n\n## Related\n\nThere are several other ports of the primitive algorithm, including at least two JavaScript ports that I'm aware of. This module isn't necessarily better; I created it out of pure fascination.\n\n-   [primitive-cli](https://github.com/transitive-bullshit/primitive-cli) - CLI for this module.\n-   [primitive](https://github.com/fogleman/primitive) - Original Go version by [Michael Fogleman](https://www.michaelfogleman.com/).\n-   [primitive.js](https://github.com/ondras/primitive.js) - JavaScript (browser) port by [Ondřej Žára](https://github.com/ondras).\n-   [geometrize](http://www.geometrize.co.uk/) - Haxe and C++ ports by [Sam Twidale](https://samcodes.co.uk/).\n-   [node-primitive](https://github.com/vincentdesmares/node-primitive) - Node.js port by [Vincent Desmares](https://github.com/vincentdesmares).\n-   [sqip](https://github.com/technopagan/sqip) - An SVG-based LQIP library built on top of the [original primitive](https://github.com/fogleman/primitive).\n\n## Examples\n\n![alekzan-powell](https://storage.googleapis.com/transitive-bullshit-primitive/alekzan-powell-408990-unsplash-triangle-500.png \"500 triangles\")\n\n![atikh-bana](https://storage.googleapis.com/transitive-bullshit-primitive/atikh-bana-125761-unsplash-rotated-ellipse-500.png \"500 rotated ellipses\")\n\n![caleb-woods](https://storage.googleapis.com/transitive-bullshit-primitive/caleb-woods-248879-unsplash-triangle-500.png \"500 triangles\")\n\n![glauco-zuccaccia](https://storage.googleapis.com/transitive-bullshit-primitive/glauco-zuccaccia-132831-unsplash-rotated-ellipse-500.png \"500 rotated ellipses\")\n\n![jessica-weiller](https://storage.googleapis.com/transitive-bullshit-primitive/jessica-weiller-60884-unsplash-triangle-500.png \"500 triangles\")\n\n![nicolas-picard](https://storage.googleapis.com/transitive-bullshit-primitive/nicolas-picard-450042-unsplash-random-500.png \"500 random shapes\")\n\n![stefanus-martanto](https://storage.googleapis.com/transitive-bullshit-primitive/stefanus-martanto-setyo-husodo-14699-unsplash-random-500.png \"500 random shapes\")\n\n![timothy-paul-smith](https://storage.googleapis.com/transitive-bullshit-primitive/timothy-paul-smith-405497-unsplash-rotated-rectangle-500.png \"500 rectangles\")\n\n![umanoide](https://storage.googleapis.com/transitive-bullshit-primitive/umanoide-112489-unsplash-rotated-ellipse-500.png \"500 ellipses\")\n\n## License\n\nMIT © [Travis Fischer](https://github.com/transitive-bullshit)\n\nAll images are provided by [Unsplash](https://unsplash.com/) via a [CC0](https://creativecommons.org/publicdomain/zero/1.0/) license.\n\nSupport my OSS work by \u003ca href=\"https://twitter.com/transitive_bs\"\u003efollowing me on twitter \u003cimg src=\"https://storage.googleapis.com/saasify-assets/twitter-logo.svg\" alt=\"twitter\" height=\"24px\" align=\"center\"\u003e\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftransitive-bullshit%2Fprimitive","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftransitive-bullshit%2Fprimitive","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftransitive-bullshit%2Fprimitive/lists"}