animate(video) on scroll

在捲動頁面時加入動畫、動態效果,在 Apple 產品頁很常看見

實際上製作起來應該都是透過 video 的前進、後退完成

也就是設定影片的 play current time
頁面下捲時影片向前播放, 頁面上捲時影片後退完成這樣的視覺效果

javascript 在控制影片時,需要計算其影片的長度 (duration) 和 frames,讓頁面的效果有較好的體驗
ps: 需要配合影片的 framerate

簡單來說,
影片內容直接影響使用者在頁面上的視覺影驗
(影片過快或過慢)

設定頁面捲動與影片播放 frames, fps
利用 `requestAnimationFrame` 監聽頁面捲動位置並設定影片 currentTime

example:


    const playbackConst = 500; // lower numbers = faster playback

    .
    .
    .

    function scrollPlay() {
        video1.currentTime = getVideoScrollContainerY(dummy1) / playbackConst;

        window.requestAnimationFrame(scrollPlay);
    }
    window.requestAnimationFrame(scrollPlay);
                

參考連結:

影片
捲軸關係

注意影片長度與大小,截入速度造成使用者體驗不同
若一定要使用較大的影片,記得指定良好的 video poster(preview photo)

可以讓影片在載入前不破壞畫面(ux)

這個範例的 video tag 都使用 position sticky


    .pos-sticky {
        display: block;
        position: -webkit-sticky;
        position: sticky;
        will-change: transform;

        left: 0;
        top: 0;
    }
                    
                    

若有需要也可以加入 polyfill
polyfill position sticky: https://github.com/yowainwright/stickybits

影片
內容的完美平衝

this video from github (註1 codepen example)

影片與文字內容區塊兩者相依
文字區塊關系到影片出場時機(捲動出頁面)

如果文字區塊高度 (height) 不足
影片還沒播放到重點就出場了...

因此這類的效果,文字內容與影片長度會互相配合
影片較短或是文字行距較大
當然~ 選擇合適的影片是其中最重要因素

而影片的播放也速度(frame,fps)也有相對關係
這部份目前還在找正確的計算方式... (註2)

在這整個範例裡
使用 section tag 做為影片與文字區塊的容器
其中有兩個主要子容器,分別為 video 與 div (dummy)
取得 video 影片長度,設定文字區塊的高度也是一種技巧


    // set text container height
    textContainer.style.minHeight =
            Math.ceil(getVideoDuration(video))
            * playbackConst
            + getViewportHeight()
            + 'px';
    .
    .
    .

    // get custom video duration
    const getVideoDuration = elem => {
        return elem.dataset.duration || elem.duration || null;
    }
                

當然
也可以依需求,直接透過 css 指定文字區塊的高度

需注意事項

video tag at mobile browser
特別指定部份參數,確保各瀏覽(mobile)都能正常播放


    <video
        muted
        autoplay
        playsinline
        poster="./Pexels-Videos-2715.png">
        <source src="./Pexels-Videos-2715.mp4" type="video/mp4">
        Your browser does not support the video tag.
    </video>
    

mobile browser 隱藏播放鈕


    *::-webkit-media-controls-panel,
    *::-webkit-media-controls-play-button,
    *::-webkit-media-controls-start-playback-button {
        display: none!important;
        -webkit-appearance: none;
    }
                  

使用 requestAnimationFrame 監聽、設定 video.currentTime

效能優於 window on scroll, setTimeout 等且不會抖動的情況