Particle Wave
Turn a static image into an interactive, physics-driven particle cloud in the browser.
The work splits cleanly in two, and so does the distribution:
| Package | Registry | What it does |
|---|---|---|
particle-wave |
PyPI | Offline CLI. Image -> edge/feature map -> sampled point cloud -> .pwcloud |
@npmring/particle-wave |
npm | Browser ES module. Loads a .pwcloud, simulates spring physics, renders to canvas |
The halves are decoupled by the .pwcloud format, not by a shared runtime: the
engine never sees your image, and the tool never sees a canvas. Either one can
be swapped as long as the format contract in
docs/particle_wave_design.md is honoured.
Repository layout
.
├── pyproject.toml # particle-wave (PyPI)
├── LICENSE CHANGELOG.md
├── docs/ # design spec, parameter reference, module map
├── scripts/bump_version.py # keeps both package versions in step
├── sample/ # sample inputs
└── src/particle_wave/
├── __init__.py # single source of truth for the version
├── tool/ # Python: CLI, pipeline, stages, exporters
└── FE/ # @npmring/particle-wave (npm package root)
├── package.json
├── particle-wave.js # public entry
├── particle-wave.d.ts # hand-maintained type surface
├── engine_fields.json # config schema for host UIs
├── core/ interaction/ utils/ style/
└── demo/index.html # live demo with sliders (not published)
src/particle_wave/FE/ is deliberately both a subdirectory of the Python
package and the root of the npm package. That is what lets the wheel ship the
exact engine build that matches its exporter, so a pip install alone gives you
a working pair without vendoring JS separately and keeping the two in step by
hand.
Quick start
Convert an image
pip install "particle-wave[cv2]"
particle-wave convert logo.png -o logo.pwcloud
particle-wave inspect logo.pwcloud
Render it
npm install @npmring/particle-wave
<canvas id="pw" style="width:600px;height:400px"></canvas>
<script type="module">
import ParticleWave from '@npmring/particle-wave';
const pw = await ParticleWave.init(document.getElementById('pw'), {
src: '/assets/logo.pwcloud',
mouseMode: 'repel',
particleColor: '#7b93ff',
leftClickMode: 'outward_wave',
});
</script>
Full API, CLI flags, and the complete config schema live in
src/particle_wave/README.md and
docs/.
Development
# Python
uv sync --extra dev
uv run pytest
uv run ruff check .
# Frontend (no build step; the published files are the sources)
cd src/particle_wave/FE
npm run check # syntax-check every module
npm run demo # serve demo/index.html
Releasing
Both packages share one version number, kept in src/particle_wave/__init__.py.
Neither registry lets a version be reused, so the version, the changelog entry,
and the tag are all checked before anything is uploaded.
python scripts/bump_version.py 1.4.0 # rewrites __init__.py + FE/package.json
# add the CHANGELOG.md entry, commit, then:
git tag v1.4.0 && git push --tags # CI builds and publishes both
The tagged workflow needs PYPI_TOKEN and NPM_TOKEN as repository secrets.
To publish from a local checkout instead — for the first release, or to recover when one registry accepted a version and the other did not:
cp .env.example .env && $EDITOR .env # PYPI_TOKEN, NPM_TOKEN
python scripts/publish.py # dry run: build + validate, no upload
python scripts/publish.py --publish
python scripts/publish.py --publish --only npm
.env is gitignored and the tokens are never echoed or written into the tree.
License
MIT — see LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file particle_wave-1.4.0.tar.gz.
File metadata
- Download URL: particle_wave-1.4.0.tar.gz
- Upload date:
- Size: 102.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1431cc2ca0deb70cf54aa08babfe84f1f070d87f895b6d0dfd7394bded9c369c
|
|
| MD5 |
9b6fbcb7cb4e2bdf1dd7165e94949f03
|
|
| BLAKE2b-256 |
132e3230fb286be94649f7f95c3f9778502d764ad9ff85e2fbbdd50b9b9356e6
|
File details
Details for the file particle_wave-1.4.0-py3-none-any.whl.
File metadata
- Download URL: particle_wave-1.4.0-py3-none-any.whl
- Upload date:
- Size: 86.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aaa855d83e26d8e16105ed0a86a985304664b174f729dfb2c0e8a0b12b4b6a7b
|
|
| MD5 |
a9159772ba951c957c8cc43b3917b967
|
|
| BLAKE2b-256 |
9a8888af5834ccb34926b58941c3beab06537e56e0d39898b5f801839a20738a
|