Changes to immersiveplayer.scroll.pub

root
root
25 days ago
Initial commit
body.html
Changed around line 1
+
+
+
+
+ Your browser does not support the video tag.
+
+
+
+
+
+
+
+
+
+
+
+
+

Rotate your device for different viewing modes!

+
+
+
+

How to Use

+
    +
  • 📱 Portrait Mode: Zoom and pan with pinch gestures
  • +
  • 🖥️ Landscape Mode: Full 16:9 view
  • +
  • 👆 Double tap to skip 10 seconds
  • +
  • 🔄 Swipe vertically to change videos
  • +
    +
    index.scroll
    Changed around line 1
    + buildHtml
    + baseUrl https://immersiveplayer.scroll.pub
    + metaTags
    + editButton /edit.html
    + title Immersive Video Player
    + style.css
    + body.html
    + script.js
    prompt.json
    Changed around line 1
    + {
    + "id": "ffee3901-ca54-4a73-9bdf-21699c370b0b",
    + "object": "chat.completion",
    + "created": 1735341292,
    + "model": "deepseek-chat",
    + "choices": [
    + {
    + "index": 0,
    + "message": {
    + "role": "assistant",
    + "content": "---domain---\nimmersiveplayer.scroll.pub\n---index.scroll---\nbuildHtml\nbaseUrl https://immersiveplayer.scroll.pub\nmetaTags\neditButton /edit.html\ntitle Immersive Video Player\nstyle.css\nbody.html\nscript.js\n---body.html---\n
    \n
    \n \n
    \n \n \n
    \n \n
    \n
    \n
    \n
    \n\n
    \n

    Rotate your device for different viewing modes!

    \n
    \n\n
    \n

    How to Use

    \n
      \n
    • 📱 Portrait Mode: Zoom and pan with pinch gestures
    • \n
    • 🖥️ Landscape Mode: Full 16:9 view
    • \n
    • 👆 Double tap to skip 10 seconds
    • \n
    • 🔄 Swipe vertically to change videos
    • \n
    \n
    \n---style.css---\n:root {\n --primary-color: #1e90ff;\n --control-bg: rgba(0, 0, 0, 0.7);\n --control-size: 40px;\n}\n\n* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: 'Segoe UI', sans-serif;\n background: #000;\n color: #fff;\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n}\n\n.video-container {\n width: 100%;\n max-width: 800px;\n position: relative;\n overflow: hidden;\n border-radius: 15px;\n box-shadow: 0 0 20px rgba(255, 255, 255, 0.1);\n}\n\n.video-wrapper {\n position: relative;\n padding-top: 56.25%;\n}\n\nvideo {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.controls {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background: var(--control-bg);\n padding: 10px;\n display: flex;\n align-items: center;\n gap: 10px;\n opacity: 0;\n transition: opacity 0.3s ease;\n}\n\n.video-container:hover .controls {\n opacity: 1;\n}\n\n.control-btn {\n background: none;\n border: none;\n color: #fff;\n font-size: 1.2rem;\n cursor: pointer;\n padding: 5px;\n transition: transform 0.2s ease;\n}\n\n.control-btn:hover {\n transform: scale(1.1);\n}\n\n.seek-bar {\n flex: 1;\n}\n\n#seek-slider {\n width: 100%;\n cursor: pointer;\n}\n\n.orientation-notice {\n margin-top: 20px;\n text-align: center;\n font-size: 1.1rem;\n color: #aaa;\n}\n\n.instructions {\n margin-top: 30px;\n padding: 20px;\n background: rgba(255, 255, 255, 0.05);\n border-radius: 10px;\n max-width: 800px;\n}\n\n.instructions h2 {\n margin-bottom: 15px;\n color: var(--primary-color);\n}\n\n.instructions ul {\n list-style: none;\n padding: 0;\n}\n\n.instructions li {\n margin: 10px 0;\n font-size: 1rem;\n color: #ddd;\n}\n\n@media (max-width: 768px) {\n .video-container {\n border-radius: 0;\n }\n \n .instructions {\n margin: 20px;\n }\n}\n---script.js---\nconst video = document.getElementById('main-video');\nconst playPauseBtn = document.getElementById('play-pause');\nconst fullscreenBtn = document.getElementById('fullscreen');\nconst seekSlider = document.getElementById('seek-slider');\n\nlet isZoomed = false;\nlet startX, startY, translateX = 0, translateY = 0;\n\n// Play/Pause functionality\nplayPauseBtn.addEventListener('click', () => {\n if (video.paused) {\n video.play();\n playPauseBtn.textContent = '⏸️';\n } else {\n video.pause();\n playPauseBtn.textContent = '▶️';\n }\n});\n\n// Fullscreen functionality\nfullscreenBtn.addEventListener('click', () => {\n if (!document.fullscreenElement) {\n video.requestFullscreen();\n } else {\n document.exitFullscreen();\n }\n});\n\n// Seek functionality\nseekSlider.addEventListener('input', () => {\n const seekTime = video.duration * (seekSlider.value / 100);\n video.currentTime = seekTime;\n});\n\nvideo.addEventListener('timeupdate', () => {\n const value = (100 / video.duration) * video.currentTime;\n seekSlider.value = value;\n});\n\n// Double tap to skip\nlet lastTap = 0;\nvideo.addEventListener('touchend', (e) => {\n const currentTime = new Date().getTime();\n const tapLength = currentTime - lastTap;\n \n if (tapLength < 300 && tapLength > 0) {\n const skipTime = e.touches[0].clientX < window.innerWidth / 2 ? -10 : 10;\n video.currentTime += skipTime;\n }\n \n lastTap = currentTime;\n});\n\n// Handle orientation changes\nwindow.addEventListener('orientationchange', () => {\n if (isZoomed) {\n resetZoom();\n }\n});\n\n// Zoom and pan functionality\nvideo.addEventListener('touchstart', (e) => {\n if (e.touches.length === 2) {\n isZoomed = true;\n startX = (e.touches[0].pageX + e.touches[1].pageX) / 2;\n startY = (e.touches[0].pageY + e.touches[1].pageY) / 2;\n }\n});\n\nvideo.addEventListener('touchmove', (e) => {\n if (isZoomed && e.touches.length === 2) {\n const scale = Math.hypot(\n e.touches[0].pageX - e.touches[1].pageX,\n e.touches[0].pageY - e.touches[1].pageY\n ) / Math.hypot(\n e.touches[0].pageX - e.touches[1].pageX,\n e.touches[0].pageY - e.touches[1].pageY\n );\n\n const currentX = (e.touches[0].pageX + e.touches[1].pageX) / 2;\n const currentY = (e.touches[0].pageY + e.touches[1].pageY) / 2;\n\n translateX += currentX - startX;\n translateY += currentY - startY;\n\n video.style.transform = `scale(${scale}) translate(${translateX}px, ${translateY}px)`;\n video.style.transformOrigin = 'center center';\n }\n});\n\nvideo.addEventListener('touchend', () => {\n if (isZoomed) {\n isZoomed = false;\n }\n});\n\nfunction resetZoom() {\n video.style.transform = 'none';\n translateX = 0;\n translateY = 0;\n}\n---end---"
    + },
    + "logprobs": null,
    + "finish_reason": "stop"
    + }
    + ],
    + "usage": {
    + "prompt_tokens": 1113,
    + "completion_tokens": 1767,
    + "total_tokens": 2880,
    + "prompt_cache_hit_tokens": 0,
    + "prompt_cache_miss_tokens": 1113
    + },
    + "system_fingerprint": "fp_f1afce2943"
    + }
    readme.scroll
    Changed around line 1
    + # immersiveplayer.scroll.pub
    + Website generated by DeepSeek from prompt: Descrizione del videoplayer: Modalità Portrait (Verticale): • Visualizzazione principale: • Quando un filmato è in formato 16:9, viene zoomato per riempire l’intero schermo in modalità portrait. Questo significa che il video mostra la parte centrale (sia orizzontale che verticale) del contenuto, sacrificando le porzioni laterali del video. • Interazione Zoom: • È possibile zoomare in ulteriormente tramite un gesto di pinch-to-zoom (allargando le dita), mantenendo però il video a schermo intero. Lo zoom non può essere ridotto al punto di lasciare bordi neri o spazi vuoti. • Una volta zoomato, l’utente può muoversi all’interno del video trascinando con il dito per spostare la porzione visibile. • Navigazione video: • L’interfaccia consente di scorrere i video in stile TikTok con uno swipe verso l’alto o il basso per passare al video successivo o precedente. Modalità Landscape (Orizzontale): • Visualizzazione principale: • Quando lo schermo viene girato in modalità landscape, il video si ridimensiona automaticamente per adattarsi al formato 16:9 e riempire l’intero schermo orizzontale. • Non ci sono ritagli o porzioni nascoste in questa modalità: il video viene visualizzato nella sua interezza. • Interazione Zoom: • Anche in modalità landscape, l’utente può effettuare il pinch-to-zoom per ingrandire il video. Come nella modalità portrait, il video rimane fullscreen e le aree ingrandite possono essere esplorate trascinando il dito. • Non è possibile zoomare out a un punto in cui ci siano bordi neri. Comportamenti comuni: 1. Transizione Portrait-Landscape: • Il passaggio tra portrait e landscape è fluido: in modalità portrait, il video torna automaticamente al livello di zoom iniziale (se c’era uno zoom) e centra il contenuto visibile. • In modalità landscape, il video viene adattato al formato 16:9 senza interruzioni o lag. 2. Gestione dei controlli: • Controlli minimalisti per play, pausa, avanti/indietro, volume e modalità schermo intero. • Possibilità di doppio tap per avanzare o riavvolgere di 10 secondi. 3. Funzione Drag-to-Pan: • In entrambe le modalità, quando il video è zoomato, si può trascinare con il dito per esplorare diverse parti della scena. Il movimento è fluido e limitato ai bordi del video, evitando aree nere. 4. Compatibilità video: • Supporta video con aspect ratio diversi (1:1, 9:16, ecc.) adattando lo zoom automaticamente per riempire lo schermo nella modalità corrente. UI e Animazioni: • UI minimalista: • I controlli sono semi-trasparenti e scompaiono automaticamente dopo pochi secondi di inattività, riapparendo con un tap sullo schermo. • Animazioni fluide: • Il passaggio tra zoom e pan è accompagnato da transizioni fluide per una sensazione di naturalezza durante l’interazione. Questo videoplayer è progettato per massimizzare l’esperienza immersiva indipendentemente dall’orientamento del dispositivo, offrendo una combinazione tra flessibilità di zoom e una visualizzazione sempre a schermo intero.
    script.js
    Changed around line 1
    + const video = document.getElementById('main-video');
    + const playPauseBtn = document.getElementById('play-pause');
    + const fullscreenBtn = document.getElementById('fullscreen');
    + const seekSlider = document.getElementById('seek-slider');
    +
    + let isZoomed = false;
    + let startX, startY, translateX = 0, translateY = 0;
    +
    + // Play/Pause functionality
    + playPauseBtn.addEventListener('click', () => {
    + if (video.paused) {
    + video.play();
    + playPauseBtn.textContent = '⏸️';
    + } else {
    + video.pause();
    + playPauseBtn.textContent = '▶️';
    + }
    + });
    +
    + // Fullscreen functionality
    + fullscreenBtn.addEventListener('click', () => {
    + if (!document.fullscreenElement) {
    + video.requestFullscreen();
    + } else {
    + document.exitFullscreen();
    + }
    + });
    +
    + // Seek functionality
    + seekSlider.addEventListener('input', () => {
    + const seekTime = video.duration * (seekSlider.value / 100);
    + video.currentTime = seekTime;
    + });
    +
    + video.addEventListener('timeupdate', () => {
    + const value = (100 / video.duration) * video.currentTime;
    + seekSlider.value = value;
    + });
    +
    + // Double tap to skip
    + let lastTap = 0;
    + video.addEventListener('touchend', (e) => {
    + const currentTime = new Date().getTime();
    + const tapLength = currentTime - lastTap;
    +
    + if (tapLength < 300 && tapLength > 0) {
    + const skipTime = e.touches[0].clientX < window.innerWidth / 2 ? -10 : 10;
    + video.currentTime += skipTime;
    + }
    +
    + lastTap = currentTime;
    + });
    +
    + // Handle orientation changes
    + window.addEventListener('orientationchange', () => {
    + if (isZoomed) {
    + resetZoom();
    + }
    + });
    +
    + // Zoom and pan functionality
    + video.addEventListener('touchstart', (e) => {
    + if (e.touches.length === 2) {
    + isZoomed = true;
    + startX = (e.touches[0].pageX + e.touches[1].pageX) / 2;
    + startY = (e.touches[0].pageY + e.touches[1].pageY) / 2;
    + }
    + });
    +
    + video.addEventListener('touchmove', (e) => {
    + if (isZoomed && e.touches.length === 2) {
    + const scale = Math.hypot(
    + e.touches[0].pageX - e.touches[1].pageX,
    + e.touches[0].pageY - e.touches[1].pageY
    + ) / Math.hypot(
    + e.touches[0].pageX - e.touches[1].pageX,
    + e.touches[0].pageY - e.touches[1].pageY
    + );
    +
    + const currentX = (e.touches[0].pageX + e.touches[1].pageX) / 2;
    + const currentY = (e.touches[0].pageY + e.touches[1].pageY) / 2;
    +
    + translateX += currentX - startX;
    + translateY += currentY - startY;
    +
    + video.style.transform = `scale(${scale}) translate(${translateX}px, ${translateY}px)`;
    + video.style.transformOrigin = 'center center';
    + }
    + });
    +
    + video.addEventListener('touchend', () => {
    + if (isZoomed) {
    + isZoomed = false;
    + }
    + });
    +
    + function resetZoom() {
    + video.style.transform = 'none';
    + translateX = 0;
    + translateY = 0;
    + }
    style.css
    Changed around line 1
    + :root {
    + --primary-color: #1e90ff;
    + --control-bg: rgba(0, 0, 0, 0.7);
    + --control-size: 40px;
    + }
    +
    + * {
    + margin: 0;
    + padding: 0;
    + box-sizing: border-box;
    + }
    +
    + body {
    + font-family: 'Segoe UI', sans-serif;
    + background: #000;
    + color: #fff;
    + min-height: 100vh;
    + display: flex;
    + flex-direction: column;
    + align-items: center;
    + justify-content: center;
    + }
    +
    + .video-container {
    + width: 100%;
    + max-width: 800px;
    + position: relative;
    + overflow: hidden;
    + border-radius: 15px;
    + box-shadow: 0 0 20px rgba(255, 255, 255, 0.1);
    + }
    +
    + .video-wrapper {
    + position: relative;
    + padding-top: 56.25%;
    + }
    +
    + video {
    + position: absolute;
    + top: 0;
    + left: 0;
    + width: 100%;
    + height: 100%;
    + object-fit: cover;
    + }
    +
    + .controls {
    + position: absolute;
    + bottom: 0;
    + left: 0;
    + right: 0;
    + background: var(--control-bg);
    + padding: 10px;
    + display: flex;
    + align-items: center;
    + gap: 10px;
    + opacity: 0;
    + transition: opacity 0.3s ease;
    + }
    +
    + .video-container:hover .controls {
    + opacity: 1;
    + }
    +
    + .control-btn {
    + background: none;
    + border: none;
    + color: #fff;
    + font-size: 1.2rem;
    + cursor: pointer;
    + padding: 5px;
    + transition: transform 0.2s ease;
    + }
    +
    + .control-btn:hover {
    + transform: scale(1.1);
    + }
    +
    + .seek-bar {
    + flex: 1;
    + }
    +
    + #seek-slider {
    + width: 100%;
    + cursor: pointer;
    + }
    +
    + .orientation-notice {
    + margin-top: 20px;
    + text-align: center;
    + font-size: 1.1rem;
    + color: #aaa;
    + }
    +
    + .instructions {
    + margin-top: 30px;
    + padding: 20px;
    + background: rgba(255, 255, 255, 0.05);
    + border-radius: 10px;
    + max-width: 800px;
    + }
    +
    + .instructions h2 {
    + margin-bottom: 15px;
    + color: var(--primary-color);
    + }
    +
    + .instructions ul {
    + list-style: none;
    + padding: 0;
    + }
    +
    + .instructions li {
    + margin: 10px 0;
    + font-size: 1rem;
    + color: #ddd;
    + }
    +
    + @media (max-width: 768px) {
    + .video-container {
    + border-radius: 0;
    + }
    +
    + .instructions {
    + margin: 20px;
    + }
    + }