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 dot i is at column i % cols, row Math.floor(i / cols).
  • If someone's browser has matchMedia("(prefers-reduced-motion: reduce)").matches set, 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

  1. Have a Tangled account.
  2. Clone/fork the Tangled core repository.
  3. Add your file at appview/pages/profile-fx/<your-username>.js.
  4. Get your DID, so that you can add one line to profileScripts in appview/state/profile.go: "<your-did>": "/static/profile-fx/<your-username>.js".
  5. Open a PR to Tangled core repository. It will be reviewed thoroughly by us, since it'll run in any arbitrary browser!
  6. Once merged and deployed, your punchcard will run your effect for everyone who views your profile. Ta da!