TuxCore Skillset

OBS / StreamElements Overlay Skill

skill obs Guld

skills/obs-overlay/SKILL.md

OBS / StreamElements Overlay Skill

Formål

Denne skill bruges når TuxCore hjælper Thomas med OBS overlays, StreamElements widgets, browser sources, chat overlays, countdowns, DJ-rotationer, billedevisning og livestream UI.

Den er relevant for:

Standardprincipper

Standard HTML struktur

Et OBS overlay bør typisk bygges sådan:

<!DOCTYPE html>
<html lang="da">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>OBS Overlay</title>
  <style>
    html, body {
      margin: 0;
      padding: 0;
      width: 100%;
      height: 100%;
      overflow: hidden;
      background: transparent;
    }
  </style>
</head>
<body>
  <div id="overlay"></div>

  <script>
    // Config øverst
  </script>
</body>
</html>

OBS Browser Source anbefaling

Typiske OBS-indstillinger:

Width: 1920
Height: 1080
FPS: 30
Custom CSS: tom
Shutdown source when not visible: efter behov
Refresh browser when scene becomes active: efter behov

Ved overlays til sociale medier/posters kan størrelser også være:

1080x1920
1080x1350
1280x720
1920x1080

StreamElements widgets

Når der laves StreamElements custom widgets, skal TuxCore være opmærksom på:

Config-standard

JavaScript bør have config øverst:

const CONFIG = {
  title: "DjGulvBasS",
  intervalMs: 10000,
  autoRotate: true,
  debug: false
};

CSS bør have CSS variables:

:root {
  --main-color: #facc15;
  --bg-color: rgba(0, 0, 0, 0.0);
  --text-color: #ffffff;
  --glow-color: rgba(250, 204, 21, 0.9);
}

Chat commands

Ved chat command overlays bør TuxCore dokumentere:

Eksempel:

!next  - springer til næste DJ
!auto  - slår automatisk rotation til igen
!pause - pauser rotation

DJ rotation overlay

Ved DJ-navn rotation bør overlayet understøtte:

Countdown overlay

Countdown overlays bør understøtte:

Eksempel config:

const CONFIG = {
  eventTitle: "SommerFest 2026",
  targetDate: "2026-09-12T09:00:00+02:00",
  finishedText: "SommerFest er i gang!"
};

Billed-overlay

Ved upload/moderation/billedvisning bør TuxCore tænke i dette flow:

upload
→ database/fil
→ moderator godkender
→ overlay henter næste godkendte billede
→ OBS viser billedet
→ billede markeres som vist eller roterer videre

Overlay bør hente data via endpoint:

/next-image.php
/overlay-data.php
/api/overlay/next

Standard fetch-loop

Brug et kontrolleret fetch-loop:

async function fetchData() {
  try {
    const res = await fetch(CONFIG.endpoint, { cache: "no-store" });
    if (!res.ok) throw new Error("HTTP " + res.status);
    const data = await res.json();
    updateOverlay(data);
  } catch (err) {
    if (CONFIG.debug) console.error(err);
  }
}

setInterval(fetchData, CONFIG.refreshMs);
fetchData();

Animationer

Brug CSS animationer fremfor tunge JS-loops når muligt.

Eksempel:

.overlay-item {
  animation: fadeInUp 600ms ease both;
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(24px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

Sikkerhedsregler

Når TuxCore laver $obs $full

Lever som udgangspunkt:

  1. Komplet HTML-fil.
  2. CSS inkluderet eller separat efter behov.
  3. JavaScript inkluderet eller separat efter behov.
  4. Config øverst.
  5. OBS Browser Source indstillinger.
  6. Testtrin.
  7. Eventuelle endpoint-eksempler.
  8. Noter om StreamElements, hvis relevant.

Når TuxCore laver $obs $patch

Lever kun:

  1. Den konkrete fejl/ændring.
  2. CSS/JS/HTML patch.
  3. Hvor patchen skal placeres.
  4. Kort test i OBS.
  5. Eventuelle cache-refresh råd.

Typiske fejl

Overlay vises ikke

Mulige årsager:

Fix:

Animation hakker

Mulige årsager:

Fix:

Fetch virker i browser men ikke OBS

Mulige årsager:

Fix:

Testtrin

Et overlay er klar når:

Tags

obs, streamelements, overlay, html, css, javascript, twitch, djgulvbass, tuxcore, livestream
obs streamelements overlay html css javascript
\n\n\n```\n\n## OBS Browser Source anbefaling\n\nTypiske OBS-indstillinger:\n\n```text\nWidth: 1920\nHeight: 1080\nFPS: 30\nCustom CSS: tom\nShutdown source when not visible: efter behov\nRefresh browser when scene becomes active: efter behov\n```\n\nVed overlays til sociale medier/posters kan størrelser også være:\n\n```text\n1080x1920\n1080x1350\n1280x720\n1920x1080\n```\n\n## StreamElements widgets\n\nNår der laves StreamElements custom widgets, skal TuxCore være opmærksom på:\n\n- HTML, CSS og JS ligger i separate felter.\n- `FIELDS` bruges til bruger-konfigurerbare værdier.\n- `DATA` kan bruges til events, overlays og dynamisk data.\n- Config bør være let at finde.\n- Undgå kode der kræver lokal filadgang.\n- Brug sikre fallback-værdier.\n\n## Config-standard\n\nJavaScript bør have config øverst:\n\n```js\nconst CONFIG = {\n title: \"DjGulvBasS\",\n intervalMs: 10000,\n autoRotate: true,\n debug: false\n};\n```\n\nCSS bør have CSS variables:\n\n```css\n:root {\n --main-color: #facc15;\n --bg-color: rgba(0, 0, 0, 0.0);\n --text-color: #ffffff;\n --glow-color: rgba(250, 204, 21, 0.9);\n}\n```\n\n## Chat commands\n\nVed chat command overlays bør TuxCore dokumentere:\n\n- Kommando\n- Hvem må bruge den\n- Hvad den gør\n- Cooldown hvis relevant\n- Fallback hvis kommando ikke virker\n\nEksempel:\n\n```text\n!next - springer til næste DJ\n!auto - slår automatisk rotation til igen\n!pause - pauser rotation\n```\n\n## DJ rotation overlay\n\nVed DJ-navn rotation bør overlayet understøtte:\n\n- Liste over navne\n- Automatisk rotation\n- Manuel next-knap eller chat command\n- Justerbart interval\n- Animation ind/ud\n- Fallback hvis listen er tom\n\n## Countdown overlay\n\nCountdown overlays bør understøtte:\n\n- Fast slutdato\n- Dansk tekst\n- Dage/timer/minutter/sekunder\n- Eventnavn\n- Når countdown er slut, vis en slutbesked\n- Nem ændring af dato øverst i config\n\nEksempel config:\n\n```js\nconst CONFIG = {\n eventTitle: \"SommerFest 2026\",\n targetDate: \"2026-09-12T09:00:00+02:00\",\n finishedText: \"SommerFest er i gang!\"\n};\n```\n\n## Billed-overlay\n\nVed upload/moderation/billedvisning bør TuxCore tænke i dette flow:\n\n```text\nupload\n→ database/fil\n→ moderator godkender\n→ overlay henter næste godkendte billede\n→ OBS viser billedet\n→ billede markeres som vist eller roterer videre\n```\n\nOverlay bør hente data via endpoint:\n\n```text\n/next-image.php\n/overlay-data.php\n/api/overlay/next\n```\n\n## Standard fetch-loop\n\nBrug et kontrolleret fetch-loop:\n\n```js\nasync function fetchData() {\n try {\n const res = await fetch(CONFIG.endpoint, { cache: \"no-store\" });\n if (!res.ok) throw new Error(\"HTTP \" + res.status);\n const data = await res.json();\n updateOverlay(data);\n } catch (err) {\n if (CONFIG.debug) console.error(err);\n }\n}\n\nsetInterval(fetchData, CONFIG.refreshMs);\nfetchData();\n```\n\n## Animationer\n\nBrug CSS animationer fremfor tunge JS-loops når muligt.\n\nEksempel:\n\n```css\n.overlay-item {\n animation: fadeInUp 600ms ease both;\n}\n\n@keyframes fadeInUp {\n from {\n opacity: 0;\n transform: translateY(24px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n```\n\n## Sikkerhedsregler\n\n- Brug ikke hemmelige tokens i frontend-overlay.\n- Lad ikke OBS Browser Source kalde admin endpoints.\n- Public overlay endpoints bør kun returnere nødvendige data.\n- Uploads skal modereres før visning.\n- Billeder skal valideres på filtype og størrelse.\n- Brug cache-busting eller `cache: \"no-store\"` ved live data.\n- Undgå at vise brugerens IP, mail eller private data i overlay.\n\n## Når TuxCore laver `$obs $full`\n\nLever som udgangspunkt:\n\n1. Komplet HTML-fil.\n2. CSS inkluderet eller separat efter behov.\n3. JavaScript inkluderet eller separat efter behov.\n4. Config øverst.\n5. OBS Browser Source indstillinger.\n6. Testtrin.\n7. Eventuelle endpoint-eksempler.\n8. Noter om StreamElements, hvis relevant.\n\n## Når TuxCore laver `$obs $patch`\n\nLever kun:\n\n1. Den konkrete fejl/ændring.\n2. CSS/JS/HTML patch.\n3. Hvor patchen skal placeres.\n4. Kort test i OBS.\n5. Eventuelle cache-refresh råd.\n\n## Typiske fejl\n\n### Overlay vises ikke\n\nMulige årsager:\n\n- Forkert Browser Source URL\n- Filen åbnes via forkert sti\n- HTML har syntax-fejl\n- Elementet er uden størrelse\n- Farven er samme som baggrund\n- OBS cache viser gammel version\n\nFix:\n\n- Reload Browser Source\n- Tjek console via browser\n- Test filen i Chrome\n- Brug tydelig testtekst\n\n### Animation hakker\n\nMulige årsager:\n\n- For mange JS animationer\n- Store billeder\n- For hyppig polling\n- CSS filter/glow er for tung\n\nFix:\n\n- Brug CSS transform/opacity\n- Komprimer billeder\n- Øg refresh interval\n- Reducer blur/glow\n\n### Fetch virker i browser men ikke OBS\n\nMulige årsager:\n\n- CORS\n- HTTPS/mixed content\n- Forkert lokal URL\n- Endpoint returnerer HTML-fejl i stedet for JSON\n\nFix:\n\n- Brug samme protokol\n- Returnér korrekt JSON header\n- Test endpoint direkte\n- Tjek OBS log/browser console\n\n## Testtrin\n\nEt overlay er klar når:\n\n- Det åbner korrekt i almindelig browser.\n- Det åbner korrekt i OBS Browser Source.\n- Baggrunden er transparent hvis ønsket.\n- Tekst/billeder skalerer korrekt.\n- Animationer kører uden hak.\n- Config kan ændres nemt.\n- Eventuelle endpoints returnerer korrekt data.\n\n## Tags\n\n```text\nobs, streamelements, overlay, html, css, javascript, twitch, djgulvbass, tuxcore, livestream\n```\n"; const copyButton = document.getElementById('copyMarkdownButton'); if (copyButton) { copyButton.addEventListener('click', async () => { try { await navigator.clipboard.writeText(window.TUXCORE_MARKDOWN || ''); const originalText = copyButton.textContent; copyButton.textContent = 'Kopieret!'; setTimeout(() => { copyButton.textContent = originalText; }, 1400); } catch (error) { copyButton.textContent = 'Kunne ikke kopiere'; setTimeout(() => { copyButton.textContent = 'Kopiér Markdown'; }, 1800); } }); }