File size: 15,839 Bytes
5671a81 b9f2bbe e922599 b9f2bbe e922599 b9f2bbe e922599 b9f2bbe e922599 b9f2bbe 04a7d02 b9f2bbe e922599 04a7d02 e922599 b9f2bbe 04a7d02 e922599 b9f2bbe e922599 04a7d02 e922599 04a7d02 e922599 b9f2bbe 5671a81 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | <!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Free Exercise Dataset — 400 Exercises, JSON + Images (EN/DE/ES) · RepDB</title>
<meta name="description" content="Browse RepDB's free exercise dataset: 400 exercises in JSON with flat illustrations, target muscles, equipment, MET, and EN/DE/ES instructions. Free for commercial in-app use with attribution. Full paid dataset at repdb.co." />
<link rel="canonical" href="https://repdb.co/free-exercise-dataset" />
<meta property="og:title" content="Free Exercise Dataset — 400 Exercises (RepDB)" />
<meta property="og:description" content="400 fitness exercises in JSON with illustrations, muscles, equipment and EN/DE/ES instructions. Free with attribution. The full paid dataset keeps growing at repdb.co." />
<meta property="og:type" content="website" />
<meta property="og:image" content="https://sergei-argutin.github.io/exercise-dataset/images/flat/squat-peak.webp" />
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Dataset",
"name": "RepDB Exercise Dataset (free tier)",
"description": "Free multilingual fitness exercise dataset: exercises in JSON with flat WebP illustrations, target muscles, equipment, MET values, and step-by-step instructions in English, German and Spanish. Free for personal and commercial in-app use with attribution.",
"url": "https://sergei-argutin.github.io/exercise-dataset/",
"license": "https://github.com/sergei-argutin/exercise-dataset/blob/main/LICENSE-DATA.md",
"isAccessibleForFree": true,
"inLanguage": ["en", "de", "es"],
"creator": {
"@type": "Organization",
"name": "RepDB",
"url": "https://repdb.co"
},
"distribution": {
"@type": "DataDownload",
"encodingFormat": "application/json",
"contentUrl": "https://raw.githubusercontent.com/sergei-argutin/exercise-dataset/main/exercises.json"
}
}
</script>
<style>
:root{--bg:#0b0c0f;--card:#15171c;--mut:#9aa3af;--fg:#f3f4f6;--acc:#22c55e;--line:#252830}
*{box-sizing:border-box}
body{margin:0;font:15px/1.5 system-ui,-apple-system,Segoe UI,Roboto,sans-serif;background:var(--bg);color:var(--fg)}
a{color:var(--acc)}
header{padding:28px 20px 14px;max-width:1100px;margin:0 auto}
h1{font-size:1.7rem;margin:0 0 6px}
.sub{color:var(--mut);margin:0 0 14px}
.cta{display:inline-block;background:var(--acc);color:#06210f;font-weight:700;text-decoration:none;padding:9px 16px;border-radius:9px}
.bar{display:flex;gap:10px;flex-wrap:wrap;align-items:center;max-width:1100px;margin:8px auto 0;padding:0 20px}
input,select{background:var(--card);border:1px solid var(--line);color:var(--fg);padding:9px 11px;border-radius:8px;font-size:14px}
input{flex:1;min-width:180px}
main{max-width:1100px;margin:18px auto 60px;padding:0 20px}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(170px,1fr));gap:14px}
.card{position:relative;background:var(--card);border:1px solid var(--line);border-radius:12px;overflow:hidden;cursor:pointer;transition:.12s}
.card:hover,.card:focus-visible{border-color:var(--acc);transform:translateY(-2px)}
.card:focus-visible{outline:2px solid var(--acc);outline-offset:2px}
.card .img{display:block;width:100%;aspect-ratio:1;object-fit:cover;background:#0f1115}
.card .meta{padding:9px 11px}
.card .meta b{display:block;font-size:.92rem}
.card .meta span{color:var(--mut);font-size:.78rem;text-transform:capitalize}
.count{color:var(--mut);font-size:.85rem;margin:14px 2px}
dialog{background:var(--card);color:var(--fg);border:1px solid var(--line);border-radius:14px;max-width:680px;width:92%;padding:0}
dialog::backdrop{background:rgba(0,0,0,.6)}
.modal{padding:20px}
.modal h2{margin:0 0 2px}
.poses{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin:14px 0}
.poses.single{grid-template-columns:minmax(0,340px)}
.poses figure{margin:0;background:#0f1115;border-radius:10px;padding:8px;text-align:center}
.poses img{width:100%;aspect-ratio:1;object-fit:contain}
.poses figcaption{color:var(--mut);font-size:.75rem;margin-top:4px}
.chips{display:flex;gap:6px;flex-wrap:wrap;margin:8px 0}
.chip{background:#0f1115;border:1px solid var(--line);border-radius:999px;padding:3px 10px;font-size:.75rem;color:var(--mut);text-transform:capitalize}
ol{padding-left:18px}
.foot{border-top:1px solid var(--line);margin-top:16px;padding-top:12px;color:var(--mut);font-size:.85rem}
.x{position:absolute;top:10px;right:14px;background:0;border:0;color:var(--mut);font-size:1.4rem;cursor:pointer}
.promo{background:linear-gradient(90deg,#0f2417,#14171c);border:1px solid var(--line);border-radius:12px;padding:14px 16px;margin:0 0 18px;display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap}
.upgrade{margin:48px 0 0;border-top:1px solid var(--line);padding-top:28px}
.upgrade h2{font-size:1.25rem;margin:0 0 4px}
.upgrade .note{color:var(--mut);font-size:.88rem;margin:0 0 16px}
.upgrade .note b{color:var(--fg)}
.samples{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:14px}
.samples figure{margin:0;border:1px solid var(--line);border-radius:12px;padding:8px;text-align:center;
background-image:conic-gradient(#1b1e25 90deg,#0f1217 0 180deg,#1b1e25 0 270deg,#0f1217 0);background-size:16px 16px}
.samples img{width:100%;aspect-ratio:1;object-fit:contain}
.samples figcaption{color:var(--mut);font-size:.75rem;margin-top:4px;background:var(--bg);border-radius:6px;padding:2px 4px}
.samples .tag{color:var(--acc);font-weight:700}
.dock{position:fixed;left:0;right:0;bottom:0;z-index:20;display:flex;gap:12px;align-items:center;
max-width:1100px;margin:0 auto;padding:10px 20px calc(10px + env(safe-area-inset-bottom));
background:rgba(15,17,22,.92);backdrop-filter:blur(10px);border:1px solid var(--line);border-bottom:0;
border-radius:14px 14px 0 0;box-shadow:0 -10px 30px rgba(0,0,0,.45);
animation:dock-in .55s .5s cubic-bezier(.2,.8,.2,1) both}
@keyframes dock-in{from{transform:translateY(130%)}to{transform:translateY(0)}}
.dock-open{display:flex;gap:12px;align-items:center;flex:1;min-width:0;
background:0;border:0;padding:0;color:inherit;font:inherit;text-align:left;cursor:pointer}
.dock-open img{width:80px;height:80px;flex:none;object-fit:contain;border-radius:10px;padding:3px;
background-image:conic-gradient(#1b1e25 90deg,#0f1217 0 180deg,#1b1e25 0 270deg,#0f1217 0);background-size:12px 12px}
.dock-open:hover img,.dock-open:focus-visible img{outline:1px solid var(--acc)}
.dock-open:focus-visible{outline:2px solid var(--acc);outline-offset:3px;border-radius:10px}
.dock-copy{min-width:0}
.dock-copy b{display:block;font-size:.92rem}
.dock-copy b .tag{color:var(--acc)}
.dock-copy>span{display:block;color:var(--mut);font-size:.78rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dock .cta{flex:none;padding:9px 14px}
@media (max-width:560px){
.dock{gap:10px;padding:9px 12px calc(9px + env(safe-area-inset-bottom))}
.dock-open img{width:68px;height:68px}
.dock-copy>span,.dock-copy b .tag{display:none}
.dock-copy b{font-size:.86rem;line-height:1.25}
.dock .cta{padding:8px 11px;font-size:.85rem}
}
@media (prefers-reduced-motion:reduce){.dock{animation:none}}
</style>
</head>
<body>
<header>
<h1>Free Exercise Dataset — JSON + Images</h1>
<p class="sub">The free tier of <b>RepDB</b>: <b class="jscount">400</b> fitness exercises with flat illustrations, target muscles, equipment, MET, and instructions in English, German & Spanish. Free for personal and commercial in-app use with attribution — see <a href="https://github.com/sergei-argutin/exercise-dataset/blob/main/LICENSE-DATA.md">LICENSE-DATA.md</a>. The full paid dataset keeps growing and adds high-res classic images, transparency and animations.</p>
<a class="cta" href="https://repdb.co/pricing?utm_source=huggingface">Get the full dataset →</a>
</header>
<div class="bar">
<input id="q" placeholder="Search exercises, muscles, equipment…" aria-label="Search exercises, muscles, equipment" />
<select id="body" aria-label="Filter by body part"><option value="">All body parts</option></select>
<select id="equip" aria-label="Filter by equipment"><option value="">All equipment</option></select>
</div>
<main>
<div class="promo">
<span>This is the <b>free tier</b> — <b><span class="jscount">400</span> exercises</b>, flat style, 512 px, EN/DE/ES, attribution license. The full paid dataset keeps growing and ships classic white-background 1024 px images, transparent backgrounds and looping animations.</span>
<a class="cta" href="https://repdb.co/pricing?utm_source=huggingface">See pricing →</a>
</div>
<div class="count" id="count"></div>
<div class="grid" id="grid"></div>
<section class="upgrade">
<h2>Upgrade samples — Standard tier preview</h2>
<p class="note"><b>Standard tier quality — evaluation only, see <a href="https://github.com/sergei-argutin/exercise-dataset/blob/main/LICENSE-DATA.md">LICENSE-DATA.md</a>.</b>
Looping, transparent-background exercise animations — the same clips shown on <a href="https://repdb.co/?utm_source=huggingface">repdb.co</a> (checkerboard shows the transparency). The Standard tier adds looping animations like these for most exercises → <a href="https://repdb.co/pricing?utm_source=huggingface">repdb.co/pricing</a>.</p>
<div class="samples">
<figure><img src="https://huggingface.co/datasets/RepDB/exercise-dataset/resolve/main/premium-samples/bent-over-db-row-start.webp" alt="Bent-over Dumbbell Row — classic start pose" loading="lazy"><figcaption>Bent-over DB Row · <span class="tag">start</span></figcaption></figure>
<figure><img src="https://huggingface.co/datasets/RepDB/exercise-dataset/resolve/main/premium-samples/bent-over-db-row-peak.webp" alt="Bent-over Dumbbell Row — classic peak pose" loading="lazy"><figcaption>Bent-over DB Row · <span class="tag">peak</span></figcaption></figure>
<figure><img src="https://huggingface.co/datasets/RepDB/exercise-dataset/resolve/main/premium-samples/bent-over-db-row.webp" alt="Bent-over Dumbbell Row — looping transparent animation" loading="lazy"><figcaption>Bent-over DB Row · <span class="tag">animation</span></figcaption></figure>
</div>
</section>
</main>
<aside class="dock" aria-label="Standard tier preview">
<button class="dock-open" id="premiumDock">
<img src="https://huggingface.co/datasets/RepDB/exercise-dataset/resolve/main/premium-samples/bent-over-db-row.webp" alt="Bent-over Dumbbell Row — looping transparent animation" />
<span class="dock-copy">
<b>Standard tier preview <span class="tag">— see the sample</span></b>
<span>Transparent looping animations and classic 1024 px images.</span>
</span>
</button>
<a class="cta" href="https://repdb.co/pricing?utm_source=huggingface">See pricing →</a>
</aside>
<dialog id="dlg"><button class="x" aria-label="Close" onclick="dlg.close()">×</button><div class="modal" id="modal"></div></dialog>
<script>
let DATA=[];
const ASSET_BASE='https://huggingface.co/datasets/RepDB/exercise-dataset/resolve/main/';
const PRICING_URL='https://repdb.co/pricing?utm_source=huggingface';
const grid=document.getElementById('grid'), q=document.getElementById('q'),
bodySel=document.getElementById('body'), equipSel=document.getElementById('equip'),
countEl=document.getElementById('count'), dlg=document.getElementById('dlg'), modal=document.getElementById('modal');
const cap=s=>(s||'').replace(/[-_]/g,' ');
fetch(ASSET_BASE+'exercises.json').then(r=>r.json()).then(d=>{
DATA=d.exercises;
document.querySelectorAll('.jscount').forEach(el=>el.textContent=DATA.length);
[...new Set(DATA.map(e=>e.body_part).filter(Boolean))].sort().forEach(v=>bodySel.add(new Option(cap(v),v)));
[...new Set(DATA.map(e=>e.equipment).filter(Boolean))].sort().forEach(v=>equipSel.add(new Option(cap(v),v)));
render();
}).catch(()=>{
grid.innerHTML='<p class="count">Could not load exercises.json — try reloading, or browse the <a href="https://github.com/sergei-argutin/exercise-dataset">repository files</a> directly.</p>';
});
dlg.onclick=ev=>{ if(ev.target===dlg) dlg.close(); };
document.getElementById('premiumDock').onclick=()=>{
const samples = [
['bent-over-db-row','Bent-over Dumbbell Row']
];
modal.innerHTML=`<section class="upgrade" style="margin:0;border:0;padding:0">
<h2>Premium samples - Standard tier preview</h2>
<p class="note"><b>Standard tier quality.</b> Transparent-background looping animations - the same kind of clips shipped in the paid Standard tier. The checkerboard shows the transparency.</p>
<div class="samples">${samples.map(([slug,name])=>`<figure><img src="${ASSET_BASE}premium-samples/${slug}.webp" alt="${name} - looping transparent animation"><figcaption>${name} · <span class="tag">animation</span></figcaption></figure>`).join('')}</div>
<div class="foot">The full paid dataset keeps growing - classic 1024 px images, transparency & animations at <a href="${PRICING_URL}">repdb.co/pricing</a></div>
</section>`;
dlg.showModal();
};
function filtered(){
const t=q.value.toLowerCase(), b=bodySel.value, eq=equipSel.value;
return DATA.filter(e=>{
if(b&&e.body_part!==b) return false;
if(eq&&e.equipment!==eq) return false;
if(!t) return true;
return (e.name_en+' '+(e.body_part||'')+' '+(e.equipment||'')+' '+(e.primary_muscles||[]).join(' ')).toLowerCase().includes(t);
});
}
function flat(e){ return (e.images||{}).flat||{}; }
function asset(path){ return path ? ASSET_BASE+path : ''; }
function cardImg(e){ const f=flat(e); return asset(f.peak||f.main||f.start||''); }
function render(){
const list=filtered();
countEl.textContent=list.length+' of '+DATA.length+' exercises';
grid.innerHTML='';
list.forEach(e=>{
const c=document.createElement('div'); c.className='card';
c.tabIndex=0; c.setAttribute('role','button');
c.setAttribute('aria-label','Show details for '+e.name_en);
c.innerHTML=`<img class="img" loading="lazy" src="${cardImg(e)}" alt="">
<div class="meta"><b>${e.name_en}</b><span>${[e.body_part,e.equipment].filter(Boolean).map(cap).join(' · ')}</span></div>`;
c.onclick=()=>open_(e);
c.onkeydown=ev=>{ if(ev.key==='Enter'||ev.key===' '){ ev.preventDefault(); open_(e); } };
grid.appendChild(c);
});
}
function poses(e){
const f=flat(e);
if(f.start&&f.peak) return `<div class="poses">
<figure><img src="${asset(f.start)}" alt="${e.name_en} start"><figcaption>Start</figcaption></figure>
<figure><img src="${asset(f.peak)}" alt="${e.name_en} peak"><figcaption>Peak</figcaption></figure>
</div>`;
const u=f.main||f.start||f.peak;
return u?`<div class="poses single">
<figure><img src="${asset(u)}" alt="${e.name_en}"></figure>
</div>`:'';
}
function open_(e){
const chips=[...(e.primary_muscles||[]),...(e.tags||[])].map(m=>`<span class="chip">${cap(m)}</span>`).join('');
const steps=(e.instructions_en||[]).map(s=>`<li>${s}</li>`).join('');
modal.innerHTML=`<h2>${e.name_en}</h2>
<div style="color:var(--mut)">${cap(e.difficulty)} · ${cap(e.mechanic)} · ${cap(e.category)}${e.met?' · MET '+e.met:''}</div>
${poses(e)}
<p>${e.description_en||''}</p>
<div class="chips">${chips}</div>
${steps?`<ol>${steps}</ol>`:''}
<div class="foot">German & Spanish translations are in the JSON. The full paid dataset keeps growing — classic 1024 px images, transparency & animations at <a href="https://repdb.co">repdb.co →</a></div>`;
dlg.showModal();
}
q.oninput=bodySel.onchange=equipSel.onchange=render;
</script>
</body>
</html>
|