FabricJS 视频上的 clipPath 问题
FabricJS Problem with clipPath on a video
当 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()
哪个 return 和 true
,因为存在 this.clipPath
。
然后它调用 this.renderCache()
,它只更新缓存的 canvas if this.isCacheDirty()
returns true
.
要使其 return 为真,您可以利用对象的 statefullCache
and cacheProperties
设置自定义 videoTime
属性,其值为视频元素的 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>
当 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()
哪个 return 和 true
,因为存在 this.clipPath
。
然后它调用 this.renderCache()
,它只更新缓存的 canvas if this.isCacheDirty()
returns true
.
要使其 return 为真,您可以利用对象的 statefullCache
and cacheProperties
设置自定义 videoTime
属性,其值为视频元素的 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>