mifi/editly

Layer masking (AKA Clip) a video using canvas?

Ivanca opened this issue · 4 comments

Ivanca commented

I want to create a circle using canvas and clip a video so only it uses the canvas element as alpha channel, how can I do that with editly?

The equivalent in Photoshop (and similarly on other software) looks a like this:
image

Thank you very much for this library.

mifi commented

Hi. I think what youre asking for is «masking». Not sure if canvas can do that

Ivanca commented

Yes it can, see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/clip
But how can I do it with this library using a video?

Ivanca commented

I created a PR #222 that adds a new (optional) callback so users can use it to modify the generated image (Fabric.Image) before being rendered; so stuff like masking like this ticket is about can be done using the fabric API with this bit of code:

await editly({
  outPath: './output.mp4', 
  clips: [{
    duration: 4, layers: [
      { type: 'video', path: './assets/lofoten.mp4', cutFrom: 0, cutTo: 4 },
      { 
        type: 'video', 
        path: './assets/hiking.mp4',
        cutFrom: 0, cutTo: 4, 
        resizeMode: 'cover',
        originX: 'center', originY: 'center',
        left: 0.5, top: 0.5, width: 0.5, height: 0.5,
        fabricImagePostProcessing: async ({image, progress, canvas})=> {
          const circleArgs = {
            radius:  Math.min(image.width, image.height) * 0.4,
            originX: 'center',
            originY: 'center',
            stroke: 'white',
            strokeWidth: 22,
          };
          image.setOptions({
            clipPath: new fabric.Circle(circleArgs)
          });
          canvas.add(new fabric.Circle({
            ...circleArgs,
            left: image.getCenterPoint().x,
            top: image.getCenterPoint().y
          }));   
        }
      }
    ]}
  ]
});

Example result:

alpha.mp4
Ivanca commented

@mifi Any intention to merge this or a similar API in the near future? Thanks.