A real QR code, drawn as a living maze.
People wander the corridors, a monster hunts them, a forest grows round it by day and a city by night, and it is built to stay readable while it moves. Type anything and scan.
People wander the corridors, a monster hunts them, a forest grows round it by day and a city by night, and it is built to stay readable while it moves. Type anything and scan.
One script, one function. No server, no dependencies, no build step.
mazeqr.min.js from jsDelivr (below), npm (npm i @phoseinq/mazeqr) or the latest release.@1 always gets the latest 1.x; a breaking 2.0 never arrives on its own.renderArtisticQr(text, size) returns a live canvas.<div id="qr"></div>
<script src="https://cdn.jsdelivr.net/npm/@phoseinq/mazeqr@1/dist/mazeqr.min.js"></script>
<script>
var canvas = renderArtisticQr("https://example.com/", 1000);
canvas.style.width = "100%";
document.getElementById("qr").appendChild(canvas);
</script>TypeScript types are included.
npm install @phoseinq/mazeqrimport { renderArtisticQr, mazeCheer } from "@phoseinq/mazeqr";
const canvas = renderArtisticQr("https://example.com/", 1000);
document.getElementById("qr").appendChild(canvas);Leave night out and the maze follows <html data-theme="dark">, cross-fading when it changes:
document.documentElement.setAttribute("data-theme", "dark"); // the maze turns to night by itselfvar still = renderArtisticQr("https://example.com/", 1200, {still: true, night: false});
var png = still.toDataURL("image/png");navigator.clipboard.writeText(url).then(function () { mazeCheer(url); });mazeqr.min.js را از jsDelivr (پایین)، npm (npm i @phoseinq/mazeqr) یا آخرین Release بردارید.@1 همیشه آخرین نسخهی 1.x را میگیرد؛ نسخهی 2 که ممکن است ناسازگار باشد هیچوقت خودکار نمیآید.renderArtisticQr(text, size) یک canvas زنده برمیگرداند.<div id="qr"></div>
<script src="https://cdn.jsdelivr.net/npm/@phoseinq/mazeqr@1/dist/mazeqr.min.js"></script>
<script>
var canvas = renderArtisticQr("https://example.com/", 1000);
canvas.style.width = "100%";
document.getElementById("qr").appendChild(canvas);
</script>تایپهای TypeScript هم همراهش هست.
npm install @phoseinq/mazeqrimport { renderArtisticQr, mazeCheer } from "@phoseinq/mazeqr";
const canvas = renderArtisticQr("https://example.com/", 1000);
document.getElementById("qr").appendChild(canvas);اگر night را ندهید، هزارتو از <html data-theme="dark"> پیروی میکند و وقتی عوض شود، آرام به شب میرود:
document.documentElement.setAttribute("data-theme", "dark"); // the maze turns to night by itselfvar still = renderArtisticQr("https://example.com/", 1200, {still: true, night: false});
var png = still.toDataURL("image/png");navigator.clipboard.writeText(url).then(function () { mazeCheer(url); });renderArtisticQr(text, size, options)Returns a <canvas> of size × size pixels, or null if the text is too long for a QR code.
| Option | Default | What it does |
|---|---|---|
night | follows the page | true / false fixes the theme; leave it out to follow data-theme. |
still | false | Draw one frame and stop. |
motion | false | Animate even when the system asks for reduced motion. |
fps | 30 | Frame rate of the animation. |
time | — | Start the simulation this many seconds in (repeatable stills). |
characters / props | true | false removes the people / the trees and benches. |
thumb + lens | — | A small live view that follows the monster: {thumb: true, lens: {mods: 13, size: 132}}. |
debug | — | {showReservedModules, showSafeCores, showConnectivity, showModuleGrid, hideArtwork} |
mazeCheer(text) | Plays the reaction: people jump, cars crash or pirates fight. |
canvas.__stop() / __start() | Pause and resume the animation. |
verifyCores(canvas) | Checks that every module's centre is within its bit's tone: {bad, worst}. |
MAZE | All tunables: error correction, quiet zone, colours, people count, speeds… |
renderArtisticQr(text, size, options)یک <canvas> به اندازهی size × size پیکسل برمیگرداند، یا اگر متن برای یک کد QR خیلی طولانی باشد null.
| گزینه | پیشفرض | کارکرد |
|---|---|---|
night | از صفحه پیروی میکند | true / false تم را ثابت میکند؛ اگر ندهید از data-theme پیروی میکند. |
still | false | یک فریم میکشد و متوقف میشود. |
motion | false | حتی وقتی سیستم «کاهش حرکت» خواسته، انیمیشن را اجرا میکند. |
fps | 30 | نرخ فریم انیمیشن. |
time | — | شبیهسازی را از این ثانیه شروع میکند (برای تصویر ثابتِ تکرارپذیر). |
characters / props | true | با false آدمها / درختها و نیمکتها حذف میشوند. |
thumb + lens | — | یک نمای کوچک زنده که دنبال هیولا میرود: {thumb: true, lens: {mods: 13, size: 132}}. |
debug | — | {showReservedModules, showSafeCores, showConnectivity, showModuleGrid, hideArtwork} |
mazeCheer(text) | واکنش را اجرا میکند: آدمها میپرند، ماشینها تصادف میکنند یا دزدان دریایی میجنگند. |
canvas.__stop() / __start() | توقف و ادامهی انیمیشن. |
verifyCores(canvas) | بررسی میکند مرکز هر ماژول در محدودهی رنگ بیتش باشد: {bad, worst}. |
MAZE | همهی تنظیمات: تصحیح خطا، حاشیهی خالی، رنگها، تعداد آدمها، سرعتها… |
The bits come from qrcode-generator; the drawing never decides them. The art is a skin over a valid code:
Every push is tested with three decoders (ZXing, ZBar, quirc) on plain, degraded and camera-like images, and the crowd's behaviour is simulated for regressions.
بیتها از qrcode-generator میآیند و نقاشی هیچوقت آنها را تعیین نمیکند. نقاشی پوستهای روی یک کد معتبر است:
هر push با سه دیکودر (ZXing، ZBar و quirc) روی تصاویر عادی، خرابشده و شبیه دوربین تست میشود و رفتار جمعیت هم شبیهسازی و بررسی میشود.
still PNG at high resolution and test it with a phone before printing.fps, call __stop() when it is off screen, or use still for many codes on one page.fps را کم کنید، وقتی دیده نمیشود __stop() را صدا بزنید یا برای چند کد در یک صفحه از still استفاده کنید.