live preview
⌘/Ctrl + Enter
Console
How it works
An effect is a little JavaScript file that runs whenever someone opens your profile. It reaches into your punchcard, that grid of dots on top left, and does whatever you like with them. It must be plain browser JavaScript with no imports/libraries, build step (like TypeScript needs), etc, no nothing. Gotta be plain 'n simple!
Here's what you're working with:
- You get this grid with
document.querySelector("[data-punchcard]"). - Each direct child is a cell, and the dot you actually want to poke at is that cell's
firstElementChild. - To change a dot, set its inline style:
dot.style.backgroundColor,dot.style.transform = "scale(2)", just as some examples. - There are 28 columns on a narrow screen and 14 on a wide one. Get the count with
const cols = matchMedia("(min-width: 768px)").matches ? 14 : 28, and then dotiis at columni % cols, rowMath.floor(i / cols). - If someone's browser has
matchMedia("(prefers-reduced-motion: reduce)").matchesset, don't animate, be respectful to user wishes.
If you're not a programmer, no problem, you can also copy the prompt below into whichever LLM you like, say what you want on the last line, and paste what it spits back out at you back into the editor up top.
I'm making a visual effect for the "punchcard" on Tangled, a dev platform. The punchcard is a grid of small circular dots, like a GitHub contribution graph. I want you to write the animation.
Write *one* self-contained vanilla JavaScript ES module.
There's a real one running on a live profile that you can read for reference: https://tangled.org/tangled.org/core/blob/master/appview/pages/profile-fx/orrery.js . If you can open it, treat it as a reference. If you can't, the notes below tell you everything you need:
How the grid works:
- Get it with: document.querySelector("[data-punchcard]")
- Its direct children are cell wrappers. Each wrapper's firstElementChild is the dot <div> you animate.
- There's one dot per day of the current year, so 365 of them, or 366 in a leap year. Read the actual count off the elements you select rather than hardcoding it.
- Animate a dot by setting its inline style, for example dot.style.backgroundColor and dot.style.transform = "scale(2)".
- The grid is 28 columns on narrow screens and 14 on wide ones: const cols = matchMedia("(min-width: 768px)").matches ? 14 : 28. The dot at index i is at column i % cols, row Math.floor(i / cols).
Rules:
- If matchMedia("(prefers-reduced-motion: reduce)").matches, do not animate.
- One file, vanilla JS only. Absolutely no imports, no libraries, and no build step.
Make it: <DESCRIBE YOUR IDEA HERE, such as "a slow aurora of greens and blues", "dots that chase my mouse", "rain falling down the grid">
Submitting it
- Have a Tangled account.
- Clone/fork the Tangled core repository.
- Add your file at
appview/pages/profile-fx/<your-username>.js. - Get your DID, so that you can add one line to
profileScriptsinappview/state/profile.go:"<your-did>": "/static/profile-fx/<your-username>.js". - Open a PR to Tangled core repository. It will be reviewed thoroughly by us, since it'll run in any arbitrary browser!
- Once merged and deployed, your punchcard will run your effect for everyone who views your profile. Ta da!