tungs / timecut

Node.js program to record smooth movies of web pages with JavaScript animations
BSD 3-Clause "New" or "Revised" License
623 stars 72 forks source link

Canvas Rendering creates black background when frames are white #41

Open baljeetrathi opened 3 years ago

baljeetrathi commented 3 years ago

I am recording an animation rendered on the canvas using Timecut. The screenshots (frames or temporary images) of the canvas show a white background but when the animation is combined to form the video, the backgorund turns black. How can I keep the background white in the video as well.

Here is the command that I run from the terminal:

timecut "path/to/file.html" --viewport=1920,1080 --duration=30 --canvas-capture-mode=true --output=bounce.mp4

Thanks.

tungs commented 3 years ago

From your description, it sounds like your canvas actually has a transparent background, which ffmpeg replaces with a black background by default. If you add a white background for you canvas (painting a white rectangle over everything before anything else), that should give you a white background on your video. There are also ways of adding a background color in ffmpeg, but I'm not too familiar with how to do that.

baljeetrathi commented 3 years ago

Thanks @tungs, I used CSS to set the background of the canvas to white. I am also setting the background to white using a function provided by the library I am using (matter.js).

Will the background of screenshots still be white if the canvas is actually transparent?

tungs commented 3 years ago

Hi @baljeetrathi, CSS rules don't affect canvas data, which is what timesnap/timecut uses when in canvas capture mode. I took a quick look at matter.js and it looks like it also uses CSS to set the background color. I think you have a few options off the top of my head:

  1. You could use the regular capture mode which takes screenshots of what's actually rendered, instead of canvas capture mode which just copies canvas data.
  2. You could fork matter.js and change this line: https://github.com/liabru/matter-js/blob/5a0079df1b0a10b4ec5ef5e645d18b3e3910565c/src/render/Render.js#L317 from context.fillStyle = "transparent"; to context.fillStyle = background;.
  3. You could have ffmpeg use a background color-- though as I mentioned, I don't have much experience doing this, so I wouldn't be able to help.
baljeetrathi commented 3 years ago

Thanks @tungs 👍

I was previously using the following code to change the color to white:

var render = Render.create({
  element: document.body,
  engine: engine,
  options: {
    width: 1920,
    height: 1080,
    wireframes: false,
    background: 'white',
  }
});

This did not change anything so I used the method specified by you. That also does not work as expected and only creates white background where the objects travel and not the whole canvas. I will create an issue on Matter.js to ask them what's going on.