首页 > 解决方案 > 视频上的 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);
});

标签: fabricjsclip-path

解决方案


当 Image 对象具有 clipPath 时,fabric.js 看起来非常依赖缓存。

在渲染调用期间,它检查this.needsItsOwnCache()哪个返回true,因为this.clipPath存在。然后它调用this.renderCache(),它只在this.isCacheDirty()返回时更新缓存的画布true

要让它返回 true,您可以利用该对象statefullCachecacheProperties设置一个自定义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>


推荐阅读