Open-source project
imsai-sh/zhuzhiliao avatar
imsai-sh/zhuzhiliao

zhuzhiliao: a single HTML file that rebuilds the bamboo cicada toy

竹知了 —— 一转就哇哇叫的传统玩具,Web 模拟版。零依赖单文件,真实录音采样,移动端优先。

2,880 stars342 forksHTMLNOASSERTION

At a glance

What is it?
zhuzhiliao is a browser recreation of the bamboo cicada, the spinning folk toy that buzzes like a cicada. It ships as one dependency-free index.html with an embedded real recording, and its licence forbids redistribution and public deployment.
Who is it for?
Read the source, run it locally, and tune the physics or the sound for your own use. Do not fork it into a public site: the README states that redistribution, deployment to third-party-accessible locations, and commercial use are not authorized, and that only https://imsai.top is official.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 34 days ago.
What is it written in?
Mainly HTML, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 16, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What zhuzhiliao reproduces, and for whom

The bamboo cicada (竹知了) is a street-stall toy: a bamboo tube with a membrane stretched over one end, a rosin-coated string running from the membrane's centre to a small stick. Spin it and the string alternately sticks and slips on the rosin, pulses travel along the string to the membrane, and the tube's cavity amplifies the result into a waa-waa drone. zhuzhiliao is a browser version of that object.

The README frames the audience plainly: people who played with the physical toy, plus anyone curious about squeezing a real audio sample and a rope-and-mass simulation into one file. It is not a game, not a library, and not a component you drop into an app. It is a page you open. The README also notes the physical toy is getting harder to find, which is the stated motivation for keeping a copy that still makes the noise.

The project describes itself as zero-dependency and single-file, and the repository layout agrees: index.html sits at the root next to icons, robots.txt, sitemap.xml, sw.js and a 3d/ directory, with no package.json, no bundler config and no build step anywhere in the listing.

Rope physics, angular velocity, and the fallback synth chain

The simulation treats the bamboo tube as a particle on a string: gravity, an elastic rope that pulls but never pushes, and air resistance, integrated at a fixed 1/240 s step. The variable that drives sound is the angular velocity of the rope's direction. Spin faster and the rope tightens, and the sound gets louder and brighter. The README states that below roughly 1.1 revolutions per second, or when the rope is slack, no sound is produced at all, and that after you let go the tone decays on inertia.

Audio has two paths. The primary source is a real recording of a bamboo cicada, cut to 1.72 seconds from video footage, which the README says is exactly four waa cycles with the envelope boundaries found automatically. The tail 50 ms is crossfaded into the head with an equal-power fade to make a seamless loop, and the result is embedded as AAC inside the HTML to keep the file self-contained. Playback rate follows spin speed (the recording was made at about 2.33 revolutions per second), with a per-revolution pitch wobble layered on top.

If decoding that sample fails, the page falls back to a fully synthesised chain, which the README documents as a table mapping each physical element to its stand-in. Rosin stick-slip becomes a sawtooth oscillator whose frequency rises with spin speed between 55 and 195 Hz, roughened by tanh soft clipping. The graininess of a cicada becomes a 24 to 45 Hz sine amplitude modulation plus a band-passed friction noise floor. Membrane and cavity resonance become three parallel band-pass formants at 1050, 2150 and 3350 Hz. The waa-waa cycle becomes a band-pass centre frequency swept by rotation phase.

That table is the most interesting part of the repository. It is a written account of what the author decided each physical mechanism sounds like, which is more than most audio demos offer.

Running zhuzhiliao locally and getting the first waa

There is nothing to install. The README says to open index.html directly in a browser: no build, no network needed. Because the file is self-contained, saving it and opening it offline works the same way.

If you want to try it on a phone, the README gives a static-server recipe. Run this in the project directory and open http://<your-computer-IP>:8123 from a phone on the same Wi-Fi:

bash
python3 -m http.server 8123

On the page, the documented interaction is to press and drag in a circle, as if swinging the real toy. Spin faster and it calls louder. On touch screens the anchor point lifts above your fingertip so your hand does not cover the cicada. The README also describes an automatic swing mode, triggered by tapping the toy or pressing the space bar, and a phone-shaking mode that reads devicemotion and drives the swing from the gravity direction in device coordinates. That last mode needs HTTPS or a local file: iOS asks for motion-sensor permission on first use, and on a plain http LAN address the browser does not deliver sensor events, so the button hides itself.

Audio initialises on the first touch or click, and the README notes that touch unlock is also retried on lift to satisfy user-activation rules. A counter at the bottom of the page shows only your own waa count, one per manually swung revolution, stored in localStorage. The README is explicit that it is never uploaded, there is no backend, and the page makes no further requests after load. An earlier Cloudflare Worker and Durable Object counter for online users, visits and a global waa total was taken offline and removed from the repository; the README points to git history for it.

The licence is the real constraint, not the code

This is the part that decides whether you can use zhuzhiliao at all. The README states in bold that the project is not open source in the OSI sense, and repeats the point in English: redistribution and public deployment are not permitted. What is allowed, per the README's summary of LICENSE, is reading and studying the source, running it locally on devices you own or control, and modifying it for learning or personal use. What is not authorized: redistribution including modified versions, deployment anywhere third parties can reach, offering it as a service in any form, any commercial use, and removing or altering copyright notices.

There is a content clause as well: you may not use the project or a modified version to create or spread material that infringes others' rights, including using a real person's name, likeness or voice without permission, and the licence terminates automatically for violators. The README's caution block describes a specific incident: someone modified the code and deployed it publicly, replacing the author's hand-drawn cicada with a real person's image, and the author states those derivatives are unaffiliated, unauthorized and the responsibility of their makers.

I am not a lawyer and this is not legal advice. The practical reading for an engineer is that zhuzhiliao is source-available, not open source, so the usual assumption that you can fork it and host it does not hold. The repository's LICENSE file is the document that matters, and it is listed at the root.

Where zhuzhiliao is the wrong tool

If you need a reusable audio or physics library, this is the wrong project. Everything lives in one index.html, so there is no module to import, no npm package, no API surface, and no versioned release to pin. The README's own framing is a page you open, not a dependency you add.

If you want to host a copy, the licence rules it out. Deployment to any location third parties can access is not authorized, and the README states that only https://imsai.top is official. A fork on your own domain is exactly the case the caution block describes as unauthorized, regardless of whether you changed anything.

The licence also blocks the common reason a demo gets forked in the first place: putting it in front of an audience. Classroom use, a portfolio site, a conference kiosk, a client prototype. Each of those is a deployment to a third-party-accessible location under the README's wording.

There are technical limits too. The devicemotion mode depends on HTTPS or a local file, so a plain http LAN address silently loses that button. The README does not document rollback for the counter, and it does not describe a way to disable the local waa counter or reset it beyond clearing browser storage. There is no server component to configure, which also means there is nothing to scale and nothing to monitor.

How it differs from a generic Web Audio demo

The obvious alternative is a synthesised instrument demo built on the Web Audio API, where every sound is generated from oscillators, filters and envelopes. That approach is fully controllable, tiny, and has no sample-licensing question attached. It is also the path zhuzhiliao deliberately did not take as its primary voice. Its fallback chain is exactly that kind of synthesis, and the README presents it as the backup, not the main event. The project's stated choice is a real recording, cut and looped, with playback rate tied to simulated spin speed.

That difference matters if you care about how it sounds. A synthesised cicada is a model of the noise; a recording is the noise. The trade-off is that the recording is fixed at 1.72 seconds and four waa cycles, so the variation you hear comes from playback rate and the per-revolution pitch wobble rather than from synthesis parameters. The README documents both paths, which means you can read the fallback table and decide for yourself which one is more convincing.

The second difference is the physics coupling. A generic demo maps a slider to a filter. zhuzhiliao maps a rope simulation's angular velocity to both loudness and pitch, and gates sound entirely below about 1.1 revolutions per second or when the rope is slack. The silence when you stop swinging is part of the design, not an oversight.

Maintenance, upgrade cost, and what the repository actually ships

The last push to the default branch was on 2026-08-14. The repository is not archived. There are no releases retrieved, so there is no version number to track and no changelog to read before upgrading. Upgrading means replacing index.html, and because there is no build step, that is the whole operation.

That also means there is no dependency graph to audit and no supply-chain surface. What you do inherit is the embedded AAC recording inside the HTML, which is not separable from the file without editing it. If your reason for looking at this project is the audio, the recording is the thing you cannot swap out without touching the source.

The repository root also holds sw.js, manifest.webmanifest, icon-192.png, icon-512.png, apple-touch-icon.png, og-image.jpg, robots.txt, sitemap.xml and 404.html. The README explains the last one: on Cloudflare Pages, a 404.html is what makes unknown paths return a real 404 instead of a 200 serving the homepage. It also notes that the head carries OG and Twitter cards plus JSON-LD (WebSite and WebApplication/VideoGame), and that a noscript block holds a static description readable by non-JS environments including crawlers that do not execute JavaScript.

The maintenance cost for a reader is therefore close to zero, and the upgrade cost is one file. The constraint that does not go away is the licence: any hosted derivative needs written permission from the author first, per the README's closing note.

Editorial conclusion

Read the source, run it locally, and tune the physics or the sound for your own use. Do not fork it into a public site: the README states that redistribution, deployment to third-party-accessible locations, and commercial use are not authorized, and that only https://imsai.top is official. Before building on it, open LICENSE and read the permitted and non-permitted lists in full, and check whether the recording inside index.html carries terms separate from the code.

Frequently asked questions

Is zhuzhiliao open source?

No. The README states the project is not open source in the OSI sense and that source is published for technical sharing. Redistribution, deployment to third-party-accessible locations, offering it as a service, and commercial use are not authorized.

How do I run zhuzhiliao locally?

Open index.html directly in a browser, with no build and no network required. For phone testing, the README suggests starting a static server in the project directory and visiting http://<your-computer-IP>:8123 on the same Wi-Fi.

Why does zhuzhiliao make no sound when I spin slowly?

The README states that no sound is produced below roughly 1.1 revolutions per second, or when the rope is not taut. Sound is driven by the angular velocity of the rope direction, so it rises with spin speed and decays on inertia after you let go.

Does zhuzhiliao send my waa count anywhere?

No. The README says the counter at the bottom of the page stores only your own manually swung revolutions in localStorage, is never uploaded, and that the page makes no requests after loading. An earlier Cloudflare Worker counter was taken offline and removed from the repository.

Official sources

  1. imsai-sh/zhuzhiliao on GitHub
  2. Issues
  3. Project website
  4. README
Community notes

Community notes