fabricjs - 视频上的 ClipPath 的 FabricJS 问题
问题描述
将 clipPath 附加到对象时,视频无法正确播放。
仅当您调整对象大小时,视频才会更新帧。
var canvas = new fabric.Canvas('canvas');
var videoEl = document.getElementById('video');
var clipText = new fabric.Text('My Custom Text', {
left: 'center',
top: 'center',
fontSize: 40,
});
var video = new fabric.Image(videoEl, {
left: 10,
top: 10,
angle: 0,
originX: 0,
originY: 0,
objectCaching: false,
clipPath: clipText,
backgroundColor: '#ff0000'
});
canvas.add(video);
video.getElement().play();
fabric.util.requestAnimFrame(function render() {
canvas.renderAll();
fabric.util.requestAnimFrame(render);
});
解决方案
当 Image 对象具有 clipPath 时,fabric.js 看起来非常依赖缓存。
在渲染调用期间,它检查this.needsItsOwnCache()
哪个返回true
,因为this.clipPath
存在。然后它调用this.renderCache()
,它只在this.isCacheDirty()
返回时更新缓存的画布true
。
要让它返回 true,您可以利用该对象statefullCache
并cacheProperties
设置一个自定义videoTime
属性,其值为 video element's currentTime
。然后,您只需确保更新videoTime
每个动画帧。
const canvas = new fabric.Canvas("c");
const clipText = new fabric.Text("My Custom Text", {
left: "center",
top: "center",
fontSize: 36
});
const videoEl = document.querySelector("#video");
const video = new fabric.Image(videoEl, {
left: 10,
top: 10,
angle: 0,
originX: 0,
originY: 0,
objectCaching: true,
statefullCache: true,
cacheProperties: ['videoTime'],
clipPath: clipText,
backgroundColor: "#ff0000"
});
canvas.add(video);
video.getElement().play();
fabric.util.requestAnimFrame(function render() {
canvas.renderAll();
video.videoTime = videoEl.currentTime;
fabric.util.requestAnimFrame(render);
});
document.querySelector("#button").onclick = () => {
video.clipPath = video.clipPath == null ? clipText : null;
};
body {
background: ivory;
}
.row {
display: flex;
flex-direction: row;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.5.0/fabric.js"></script>
<div class="row">
<canvas id="c" width="300" height="200"></canvas>
<video id="video" width="240" height="180" autoplay loop muted >
<source src="https://html5demos.com/assets/dizzy.mp4">
</video>
</div>
<button id="button">toggle</button>
推荐阅读
- sql - Redshift:如果存在则截断表
- vba - 循环遍历单元格,直到找到相同的字符串
- rpa - RPA-自动化无处不在
- sql - SQL如何使用不同的列和连接连接两个查询
- javascript - 如何在 Function.Prototype 上调用调用函数
- mysql - sql server中mysql的from_days()相当于什么?
- apache - Apache - 只允许通过 URL 打开位于特定文件夹中的文件
- python - 如何关闭/退出从 multiprocessing.Pool 生成的 Selenium Chrome 驱动程序?
- excel - 将文本文件导入单个 Excel 电子表格的 VBA 脚本
- javascript - 文本框上的 Jquery 更改事件