{"id":15310816,"url":"https://github.com/gsimone/things","last_synced_at":"2025-07-09T04:04:22.530Z","repository":{"id":37532165,"uuid":"477007760","full_name":"gsimone/things","owner":"gsimone","description":"Loose collection of *things*","archived":false,"fork":false,"pushed_at":"2022-06-21T17:27:14.000Z","size":3160,"stargazers_count":25,"open_issues_count":4,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-06T18:56:38.523Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","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/gsimone.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}},"created_at":"2022-04-02T09:27:40.000Z","updated_at":"2025-06-30T15:36:28.000Z","dependencies_parsed_at":"2022-08-19T06:41:03.420Z","dependency_job_id":null,"html_url":"https://github.com/gsimone/things","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/gsimone/things","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gsimone%2Fthings","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gsimone%2Fthings/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gsimone%2Fthings/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gsimone%2Fthings/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gsimone","download_url":"https://codeload.github.com/gsimone/things/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gsimone%2Fthings/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264390670,"owners_count":23600560,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-10-01T08:29:36.660Z","updated_at":"2025-07-09T04:04:22.508Z","avatar_url":"https://github.com/gsimone.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![NPM](https://badgen.net/npm/v/@gsimone/things)](https://www.npmjs.com/@gsimone/things) [![Node.js CI](https://github.com/gsimone/things/actions/workflows/node.js.yml/badge.svg)](https://github.com/gsimone/things/actions/workflows/node.js.yml)\n\n👉 You can install the packages individually or just grab the kitchensink version with everything - and leave it to treeshaking to remove unused code.\n\n```bash\nnpm i @gsimone/things\n```\n\n```js\nimport { CatenaryCurve, RaycasterHelper } from \"@gsimone/things\";\n```\n\n### Packages\n\n- [Three](#three)\n  * [RaycasterHelper](#raycasterhelper)\n  * [Catenary Curve](#catenary-curve)\n  * [Smoothdamp](#smoothdamp)\n- [React Three Fiber](#react-three-fiber)\n  * [Layers](#layers)\n- [Leva](#leva)\n  * [bitmask plugin](#bitmask-plugin)\n- [Vanilla](#vanilla)\n  * [Bitmask](#bitmask)\n\n# Three\n\n## RaycasterHelper\n\n[![NPM](https://badgen.net/npm/v/@gsimone/three-raycaster-helper)](https://www.npmjs.com/@gsimone/three-raycaster-helper) [![BundlePhobia](https://badgen.net/bundlephobia/minzip/@gsimone/three-raycaster-helper)](https://bundlephobia.com/package/@gsimone/three-raycaster-helper)\n\n\n\n```bash\nnpm i @gsimone/three-raycaster-helper\n```\n\n![](https://github.com/gsimone/things/blob/main/_images_/raycaster.png?raw=true)\n\nVisualize a Raycaster (ray and near/far) and, optionally, its hits.\n\n```js\nimport { RaycasterHelper } from \"@gsimone/three-raycaster-helper\";\n\nconst raycaster = new Raycaster(origin, direction, 0.5, 10);\nconst helper = new RaycasterHelper(raycaster);\n\nconst hits = raycaster.intersectObjects(scene.children);\nhelper.hits = hits;\n```\n\n## Catenary Curve\n\n\n[![NPM](https://badgen.net/npm/v/@gsimone/three-catenary)](https://www.npmjs.com/@gsimone/three-catenary) [![BundlePhobia](https://badgen.net/bundlephobia/minzip/@gsimone/three-catenary)](https://bundlephobia.com/package/@gsimone/three-catenary)\n\n```bash\nnpm i @gsimone/three-catenary\n```\n\n[![](https://github.com/gsimone/things/blob/main/_images_/catenary.gif?raw=true)](https://codesandbox.io/s/github/gsimone/things/tree/main/demo/src/demos/catenary)\n\n\u003csmall\u003e\u003ca href=\"https://codesandbox.io/s/github/gsimone/things/tree/main/demo/src/demos/catenary\"\u003e👉 Codesandbox\u003c/a\u003e\u003c/small\u003e\n\nAn hyperbole that passes through 2 points, used as a good enough approximation of ropes collapsing under their own weight between two points.\n\n```js\nimport { CatenaryCurve } from \"@gsimone/three-catenary\";\n\nconst catenary = new CatenaryCurve(p1, p2, 10);\nconst myGeometry = new TubeGeometry(catenary, 100, 0.1, 20, false);\n```\n\n@todo add credits \u0026 tiny explaination\n\n## Smoothdamp\n\n[![NPM](https://badgen.net/npm/v/@gsimone/smoothdamp)](https://www.npmjs.com/@gsimone/smoothdamp) [![BundlePhobia](https://badgen.net/bundlephobia/minzip/@gsimone/smoothdamp)](https://bundlephobia.com/package/@gsimone/smoothdamp)\n\n```bash\nnpm i @gsimone/smoothdamp\n```\n\nPort of Unity's SmoothDamp.\n\n```js\nimport { SmoothDamp } from \"@gsimone/smoothdamp\";\nimport { SmoothDampVectors } from \"@gsimone/smoothdamp/three\";\n\nconst smoothDamp = new SmoothDamp(0.5, 10);\nconst x = smoothDamp.get(10, deltaTime);\n\n// using with three.js Vectors\nconst mySmoothDampV = new SmoothDampVectors(0.5, 10);\nconst target = new Vector3(0, 0, 0);\nconst dest = new Vector3(10, 0, 0);\n\ntarget.copy(mySmoothDampV.get(target, dest, deltaTime));\n```\n\n# React Three Fiber\n\n## Layers\n\n\n[![NPM](https://badgen.net/npm/v/@gsimone/r3f-layers)](https://www.npmjs.com/@gsimone/r3f-layers) [![BundlePhobia](https://badgen.net/bundlephobia/minzip/@gsimone/r3f-layers)](https://bundlephobia.com/package/@gsimone/r3f-layers)\n\n```bash\nnpm i @gsimone/r3f-layers\n```\n\nSimple helper for three's Layers, lets you set an object's layers in a declarative manner:\n\n```js\n\u003cmesh\u003e\n  \u003cLayers layers={[0, 1, 3]} /\u003e {/* will set layers 0, 1 and 3 exclusively */}\n\u003c/mesh\u003e\n```\n\n# Leva\n\n## bitmask plugin\n\n[![NPM](https://badgen.net/npm/v/@gsimone/leva-plugin-bitmask)](https://www.npmjs.com/@gsimone/leva-plugin-bitmask) [![BundlePhobia](https://badgen.net/bundlephobia/minzip/@gsimone/leva-plugin-bitmask)](https://bundlephobia.com/package/@gsimone/leva-plugin-bitmask)\n\n```bash\nnpm i @gsimone/leva-plugin-bitmask\n```\n\n![](https://github.com/gsimone/things/blob/main/_images_/leva-bitmask.png?raw=true)\n\nPlugin to add a bitmask-type input. Returns a bitmask object from [bitmaskjs](https://www.npmjs.com/package/bitmaskjs) with an additional `layersArray` property to get an array compatible with the [🔗 Layers r3f component](https://github.com/gsimone/things#layers)\n\n```js\nconst { layers } = useControls({\n  layers: bitmask({\n    value: [1, 0, 1], // sets first bit to 1, second to 0, third to 1\n    size: 16,\n  }),\n  layers2: bitmask({\n    value: 3, // sets the integer of the bitmask to 3, equivalent to [1, 1]\n  }),\n});\n\nlayers.layersArray; // [0]\n```\n\n**TODO**\n\nAdd alternative APIs to set the initial value.\n\n# Vanilla\n\n## Bitmask\n\n[![NPM](https://badgen.net/npm/v/@gsimone/bitmask)](https://www.npmjs.com/@gsimone/bitmask) \n[![BundlePhobia](https://badgen.net/bundlephobia/minzip/@gsimone/bitmask)](https://bundlephobia.com/package/@gsimone/bitmask)\n\n```bash\nnpm i @gsimone/bitmask\n```\n\nTiny library for bitmasks.\n\n```js\nconst bitmask = new Bitmask([1, 0, 1], 16);\n\nbitmask.setBit(1, 1).clearBit(2).getBits();\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgsimone%2Fthings","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgsimone%2Fthings","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgsimone%2Fthings/lists"}