Animated SVG gemstones — every cut, every colour, lit from a single moving light source. No canvas, no WebGL, no dependencies. Just SVG and a little maths.
Move your cursor to roll the light around the stone.
Swipe or use the arrows. Toggle the optical effects and watch the same stone come alive.
Pick a colour to see every cut, or a cut to see every stone. Or open the complete grid.
Colour
Cut
Every choice below maps to one Gem.create() call. The code updates as you go — copy it into any page.
Cut
Stone
Effects
Custom colour ramp (lightest → darkest, overrides the stone)
Size — pure CSS, same call at any scale
Jewellers name the ways a stone plays with light. gem.js reproduces each — toggle them off and on to see the difference.
The light follows your cursor on desktop and device tilt on mobile — one shared source across every gem on the page. The feel is set by a handful of global knobs on Gem.config. Drag them; every stone here responds live.
gem.js is a single dependency-free script. Load it, and any element becomes a gem.
<!-- 1. Load the library --> <script src="gem.js" defer></script> <!-- 2a. Declarative: any [data-gem] element --> <div data-gem="pear" data-stone="sapphire" data-effects="highlight sheen scintillation fire" style="width:200px;height:200px"></div> <!-- 2b. Programmatic --> <script> const g = Gem.create('#hero', { shape: 'marquise', stone: 'amethyst', effects: { highlight:true, sheen:true, scintillation:true } }); g.toggle('fire'); g.set({ stone:'ruby' }); </script>
MIT-licensed. Attribution welcome, not required.
Download gem.js
View source
| Method | What it does |
|---|---|
Gem.create(t, o) | Render a gem into an element or selector. |
Gem.scan(root?) | Hydrate every [data-gem] (auto-runs once). |
Gem.enableTilt() | Request device-motion permission (iOS) and light up. |
Gem.setParallax(on) | Enable/disable motion for all gems. |
Gem.motionLive() | Is the light drivable right now? |
Gem.light() | Live light vector {x, y, move} to drive your own UI. |
Gem.shapes / Gem.stones | The lists of available cuts and stones. |
Gem.config | Global tuning knobs (drift, tilt, contrast…). |
g.set(opts) | Re-render with a new shape / stone / ramp / effects. |
g.setEffects(obj) | Merge effect booleans, e.g. {fire:true}. |
g.toggle(name) | Flip one effect; returns its new state. |
g.destroy() | Stop animating and remove the SVG. |