Spatial Audio Dir
A 🎵 note at the center of four rings that keep widening and fading (2 s, 0.3 s apart), and a violet dot circling at 90 px in 5 s to stand for a moving sound source: a visual indicator of sound direction. The page plays no sound and uses no spatial audio — CSS only, zero JavaScript, frozen rings and source set on the left when the user reduces motion.
Updated
This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. 3D has 50 effects, including 8 free. Explore the category →
3 usage examples



How it works
Despite its name, Spatial Audio Dir produces no sound: no audio file, no Web Audio API, no JavaScript. It is an animated pictogram that shows a direction, useful precisely when the sound is not heard (deaf player, page without audio, explaining a sound installation). If your page has real spatial audio, this effect can be its display; your script will have to feed it the direction (see the FAQ).
The .fx-0046-root root (background #0a0a0f, at least 300 px tall) holds .xr-audio-dir, which centers everything. Four .xr-audio-wave elements are 40, 80, 120 and 160 px circles, 2 px indigo edge at 30%, stacked on the same center; each plays xrAudioPulse over 2 s (ease-out): it goes from scale 0.8 and 60% opacity to 1.2 and 0%, with delays of 0, 0.3, 0.6 and 0.9 s. You see rings leaving the center and fading in waves. On top, .xr-audio-center, a 40 px indigo disc, holds the 🎵 character.
The 12 px #a855f7 .xr-audio-indicator dot also sits at the center; its xrAudioMove animation chains rotate() from 0 to 360° then translateX(90px): the rotation turns the coordinate system, the translation moves the dot 90 px away in it, so it draws a 90 px radius circle in 5 s, at constant speed. The rings come from the center (the listener), the dot shows where the sound comes from: that split is what makes the indicator readable.
Accessibility
- Reduced motion: under
prefers-reduced-motion: reduce, a block scoped to.fx-0046-rootstops everything: the four rings become still rings, paler and paler (50, 50, 35 and 20%), and the dot rests on the left of the center. The direction stays readable. Measured: 0% of pixels change over 0.8 s in Chromium, Firefox and WebKit, versus 1.4 to 1.8% in normal mode. - Screen readers: the 🎵 note is a real character that screen readers read out ("musical notes" or similar). If the indicator is decorative, add
aria-hidden="true"to.xr-audio-center; if it carries information ("footsteps on the left"), write it as text next to it: a circling dot is not read. - Contrast: the violet dot measures 5.0:1 on the dark background; the rings, at 30%, are deliberately subtle. For an accessibility use (deaf players), give the dot a strong color and a glow, as in the first example.
- Rhythm: rings about every 0.3 s, a full turn in 5 s, no flashing.
Browser compatibility
CSS only: transform (scale, rotate, translateX) and opacity animations, no JavaScript, no audio API, no dependency. Measured in Chromium 151, Firefox 153 and WebKit 26 (Safari's engine): same rendering, same stop under reduced motion. The look of the 🎵 note depends on the system's emoji font. Not checked on a real Safari.
No recent property: every current browser shows the rings and the circling dot. Without an emoji font, the note may show in black and white or as an empty box: replace it with a small svg then.
The code
HTML structure to paste into your page (the CSS + JS come with your purchase):
<div class="fx-0046-root">
<div class="xr-audio-dir">
<div class="xr-audio-wave"></div> … (4 rings, 40 to 160 px)
<div class="xr-audio-center">🎵</div>
<div class="xr-audio-indicator"></div>
</div>
</div>
One-time payment, no subscription — the code is yours forever
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
Center pictogram (HTML — .xr-audio-center) |
🎵 character on a 40 px indigo disc | Replace the note with an svg (character, ear, speaker) for the same look on every system, as in the examples. |
Colors (CSS — .xr-audio-wave, .xr-audio-center, .xr-audio-indicator) |
Indigo rings at 30%, #a855f7 dot | Give the dot a color that stands out from the rings: it carries the direction. |
Dot distance (CSS — translateX(90px) in xrAudioMove) |
90 px | Change both keyframe values together. Keep it larger than half the biggest ring (80 px) so the dot stays outside the rings. |
Speed (CSS — 2s for the rings, 5s for the dot) |
2 s and 5 s | Slower rings (3 s) calm things down; a faster dot (2 s) suggests a sound whizzing around the listener. |
| Fixed direction (CSS) | The dot circles continuously | To show a specific direction, stop the rotation: animation: none; transform: rotate(180deg) translateX(90px) puts the dot on the left, 0deg on the right, -90deg at the top. |
Background (CSS — .fx-0046-root) |
#0a0a0f | Change or remove the background; on a light background, darken the rings and outline the center disc. |
FAQ
PannerNode, a game engine), this indicator can go with it, but your code has to feed it the direction..xr-audio-indicator { animation: none; transform: rotate(var(--angle, 0deg)) translateX(90px) }, then, from your script, el.style.setProperty('--angle', angle + 'deg'), with the angle counted from the right, clockwise. The sold code does not include that script: it keeps the source circling.