diff --git a/src/control.html b/src/control.html index d1cec78..25c66de 100644 --- a/src/control.html +++ b/src/control.html @@ -252,6 +252,12 @@ + + diff --git a/src/control.js b/src/control.js index c6a5773..eddcf1e 100644 --- a/src/control.js +++ b/src/control.js @@ -525,6 +525,7 @@ $('#video-blend').addEventListener('change', (e) => send({ type: 'videoBlend', v $('#ticker-text').addEventListener('input', (e) => send({ type: 'tickerText', text: e.target.value.replace(/\s*\n\s*/g, ' · ') })); $('#ticker-on').addEventListener('change', (e) => send({ type: 'tickerOn', on: e.target.checked })); $('#ticker-pos').addEventListener('change', (e) => send({ type: 'tickerPos', pos: e.target.value })); +$('#ticker-dir').addEventListener('change', (e) => send({ type: 'tickerDir', value: e.target.value })); $('#ticker-speed').addEventListener('input', (e) => { const m = parseFloat(e.target.value); $('#ticker-speed-val').textContent = m.toFixed(1) + '×'; diff --git a/src/output.js b/src/output.js index c40d3d7..5e0ad94 100644 --- a/src/output.js +++ b/src/output.js @@ -247,6 +247,7 @@ function setTickerText(t) { const h = buildLetters(t); tickCopies.forEach(c => c function setTickerSpeed(m) { tickerTrack.style.setProperty('--ticker-dur', (18 / m) + 's'); } function tickerLetters() { return tickerTrack.querySelectorAll('.tl'); } ticker.classList.add('pos-bottom'); +ticker.classList.add('dir-h'); setTickerSpeed(1); function hideHint() { $('#drop-hint').classList.add('hidden'); } @@ -382,6 +383,10 @@ djv.onControl(async (m) => { ticker.classList.add('pos-' + m.pos); break; case 'tickerSpeed': setTickerSpeed(m.mult); break; + case 'tickerDir': + ticker.classList.remove('dir-h', 'dir-vup', 'dir-vdown'); + ticker.classList.add('dir-' + m.value); + break; case 'tickerFont': tickerTrack.style.fontFamily = m.value; break; case 'tickerSize': tickerTrack.style.fontSize = m.value + 'vh'; break; case 'tickerWeight': tickerTrack.style.fontWeight = m.on ? '800' : '400'; break; diff --git a/src/style.css b/src/style.css index 6d4bc57..4d35eab 100644 --- a/src/style.css +++ b/src/style.css @@ -484,9 +484,38 @@ body.output { cursor: none; background: #000; } font-weight: 800; color: #fff; text-transform: uppercase; - animation: ticker-scroll var(--ticker-dur, 18s) linear infinite; } .tick-copy { display: inline-flex; padding: 0 2vw; } + +/* Horizontal scroll (default) */ +#ticker.dir-h #ticker-track { + animation: ticker-scroll var(--ticker-dur, 18s) linear infinite; +} + +/* Vertical scroll: full-height column, the two copies stacked and scrolling */ +#ticker.dir-vup, #ticker.dir-vdown { + top: 0 !important; + bottom: 0 !important; + height: 100vh; + padding: 0; + background: none; + transform: none !important; +} +#ticker.dir-vup.show, #ticker.dir-vdown.show { + display: flex; + align-items: flex-start; + justify-content: center; +} +#ticker.dir-vup #ticker-track, #ticker.dir-vdown #ticker-track { + flex-direction: column; + align-items: center; + white-space: nowrap; +} +#ticker.dir-vup .tick-copy, #ticker.dir-vdown .tick-copy { padding: 32vh 0; } +#ticker.dir-vup #ticker-track { animation: ticker-scroll-vup var(--ticker-dur, 18s) linear infinite; } +#ticker.dir-vdown #ticker-track { animation: ticker-scroll-vdown var(--ticker-dur, 18s) linear infinite; } +@keyframes ticker-scroll-vup { from { transform: translateY(0); } to { transform: translateY(-50%); } } +@keyframes ticker-scroll-vdown { from { transform: translateY(-50%); } to { transform: translateY(0); } } .tl { display: inline-block; white-space: pre;