ScrollyVideo.js
一个基于滚动(或其他外部控制)的播放组件。完整的使用示例请参见 /demos
。
🚀 Web
在页面中添加 HTML 容器:
<div id="scrolly-video"></div>
在页面中引入 JavaScript 并创建对象(在 </body>
之前):
<script src="https://cdn.jsdelivr.net/npm/scrolly-video@latest/dist/scrolly-video.js"></script>
<script type="text/javascript">
new ScrollyVideo({
scrollyVideoContainer: "scrolly-video",
src: "https://scrollyvideo.js.org/goldengate.mp4"
});
</script>
你可以将 @latest
替换为特定版本,例如 @0.0.2
。
🔵 React
通过 npm install scrolly-video --save
安装 npm 模块:
在应用中导入组件:
import ScrollyVideo from 'scrolly-video/dist/ScrollyVideo.cjs.jsx';
或
import ScrollyVideo from 'scrolly-video/dist/ScrollyVideo.esm.jsx';
在需要的地方添加组件:
<ScrollyVideo src="https://scrollyvideo.js.org/goldengate.mp4" />
🟠 Svelte
通过 npm install scrolly-video --save
安装 npm 模块:
在应用中导入组件:
import ScrollyVideo from 'scrolly-video/dist/ScrollyVideo.svelte';
将 ScrollyVideo 组件添加到应用中:
<ScrollyVideo src="https://scrollyvideo.js.org/goldengate.mp4" />
🟢 Vue
通过 npm install scrolly-video --save
安装 npm 模块:
在 src/App.vue
中导入模块并配置:
import ScrollyVideo from 'scrolly-video/dist/ScrollyVideo.vue';
在 HTML 组件中添加以下代码:
<ScrollyVideo src="https://scrollyvideo.js.org/goldengate.mp4" />
🧰 选项 / 属性
参数 | 描述 | 值 | 默认值 |
---|---|---|---|
src | 视频的 URL(必填) | URL | |
scrollyVideoContainer | 容器的 DOM 元素,仅用于纯 JavaScript | 字符串 / 元素 | |
transitionSpeed | 设置此视频的最大播放速率 | 数字 | 8 |
frameThreshold | 何时停止视频动画,以秒为单位 | 数字 | 0.1 |
cover | 强制视频覆盖其容器 | 布尔值 | true |
sticky | 视频是否应具有 position: sticky | 布尔值 | true |
full | 视频是否应占据整个视口 | 布尔值 | true |
trackScroll | 此对象是否应自动响应滚动 | 布尔值 | true |
lockScroll | 在启用 trackScroll 的情况下运行 setVideoPercentage 时是否忽略人为滚动 | 布尔值 | true |
useWebCodecs | 库是否应使用 webcodecs 方法,见下文 | 布尔值 | true |
videoPercentage | 手动指定视频在 0..1 之间的位置,仅用于 React、Vue 和 Svelte 组件 | 数字 | |
onReady | 准备好滚动时的回调 | 空函数 | |
onChange | 视频百分比变化的回调 | 空函数 | |
debug | 是否记录调试信息 | 布尔值 | false |
额外回调
setVideoPercentage
描述:手动设置 currentTime 的方法。传递一个 0 到 1 之间的进度,指定视频的百分比位置。如果启用了 trackScroll
,则自动执行滚动。
签名:(percentage: number, options: { transitionSpeed: number, (progress: number) => number }) => void
示例:scrollyVideo.setVideoPercentage(0.5, { transitionSpeed: 12, easing: d3.easeLinear })
技术细节和跨浏览器差异
为了使这个库在所有浏览器中都能最优化地运行,采用了三种不同的方法来制作视频动画。
方法 1:WebCodecs 和 Canvas
使用新的 WebCodecs API,我们能够获取视频中的所有帧并准备好绘制到 canvas 上。这种方法性能最佳,但有两个缺点:首先,根据设备和视频大小的不同,使用 WebCodecs API 处理所有帧需要一些时间,因此动画在页面加载后不会立即可用。其次,WebCodecs API 目前仅在 Chrome 上可用,而 WebCodecs polyfill 不适用于此应用。
如果浏览器不支持 WebCodecs 或尚未完成所有帧的处理,则会退回到方法 2:
方法 2:HTML5 视频和 playbackRate
这种方法只是用 HTML <video>
标签嵌入视频,并在需要制作动画时播放视频。为了适应滚动速度,这种方法会调节视频的 playbackRate
属性,以动态模仿更快或更慢的滚动速度。当滚动方向使视频向前移动时,这种方法非常流畅,但不幸的是,由于 playbackRate
不能是负值,所以反向不起作用。
因此,如果需要反向制作视频动画,这个库会退回到方法 3。
方法 3:HTML5 视频和 currentTime
这种方法是传统的滚动讲述视频的制作方式,使用 HTML <video>
标签并通过 currentTime 直接跳转到帧。然而,这种方法要求视频以关键帧 = 1 的方式编码,这会导致视频体积变大或质量下降。不幸的是,在方法 1 和方法 2 不受支持的情况下,或在移动版 Safari 浏览器上(不知何故,这种方法比方法 2 表现更好),这是唯一的选择。因此,为了在所有情况下都能获得最佳性能,如果可能的话,仍建议将视频编码为关键帧 = 1。
已知问题
- 在 iOS 上,如果开启省电模式,ScrollyVideo 将无法工作。由于 iOS 处理视频和省电功能的方式,这个问题目前没有解决方法。
作者:Daniel Kao