Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issue with size and positioning of canvas (not expected and inconsistent behavior) #16

Open
pietroppeter opened this issue Dec 7, 2021 · 3 comments
Labels
documentation Improvements or additions to documentation will investigate more

Comments

@pietroppeter
Copy link

hi, nanim looks great, thanks for making this!

I am having trouble understanding the size and positioning of the canvas and it seems to me it is not what I would expect and inconsistent between what is shown in the rendering video and the final result in mp4. I might be missing something.

as an ad hoc example that allows me to understand better the issue (the issue presents itself for me also on the examples in repo), here is what I am running:

import nanim

let
  colors = colorsFromCoolors("https://coolors.co/202b38-009900-ffff66-dea584-b5453a")
  dark = colors[0]
  green = colors[1]
  yellow = colors[2]
  rust = colors[3]
  crab = colors[4]

let scene = newScene() # a ref object, let would be also fine
scene.setBackgroundColor(dark)
scene.width = 500
scene.height = 500

var circle = newCircle(radius=100)
circle.fill(yellow)
scene.add(circle)

scene.wait 500
scene.showAllEntities()
scene.wait 500
scene.play circle.move(500, 0)
scene.wait 500
scene.play circle.move(0, 500)
scene.wait 500
scene.play circle.move(-500, 0)
scene.wait 500
scene.play circle.move(0, -500)
scene.wait 500

render(scene)
  • I expect a yellow circle on dark background only partially visible with its center that runs on the border of a 500x500 square canvas area.

I run with nim c -r example.nim --video --debug:false and output in terminal is:

[Info]: Width: 500, Height: 500 (ratio: 1.00:1.00), FPS: 60.0
[Info]: Launching FFmpeg subprocess with: ffmpeg -y -f rawvideo -pix_fmt rgba -s 500x500 -r 60.0 -i - -vf vflip -an -c:v libx264 -preset medium -profile:v high -crf 17 -coder 1 -tune animation -pix_fmt yuv420p -movflags +faststart -g 30 -bf 2 <mypath>/renders/final_17_46_28.mp4

here are two screenshots that I take when the circle has moved in the bottom right corner. Note that in both screenshots the behavior is not as expected above:

when rendering plays in a window:

rendering

  • it seems the canvas is 1000x1000 instead of 500x500

when reproducing the mp4 file:

final_video

  • it seems like we are seeing the bottom left quadrant of a canvas sized 1000x1000

this is on a recent Mac Air M1 with Nim 1.6 and latest nanim

@pietroppeter
Copy link
Author

I went looking in the code and found that if in this line:

scene.window.getWindowSize(width.addr, height.addr)

I substitute scene.window.getWindowSize(width.addr, height.addr) with the call to getFramebufferSize (I google stuff to find this gflw reference), then at least get consistent behavior between final video and rendering (the canvas is still sized 1000x1000 instead of 500x500). I see those two functions appear in many places, so it is possible that this is not the correct place to make the fix.

@EriKWDev
Copy link
Owner

EriKWDev commented Dec 11, 2021

Hi! Thanks for taking interest in nanim! :)

I looked at your PR quickly and love the RenderingOptions, make much more sense than what I was doing. Will take a closer look later and might merge :)

It is deffinately a bug if the rendered video is different from the window animation. I only have access to test on an intel mac, so thanks for reporting behaviour on the M1!

When I render your example with the command you provided, I get the same expected result in both the live window and the video:

image

I'll boot up in MacOS later and see what the behaviour is like over there. In the meantime, here is some info about the coordinate system:

The Coordinate System of Nanim

The coordinate system of Nanim is a bit "weird", but it is intentional and has its logic. I have not yet documented it, so here's a start:

No matter what size of canvas you use, coordinates will always map from 0 to 1000 in a square with 500, 500 in the center. If the canvas is not a perfect square, (500, 500) will still remain the center of the canvas, and unit "1000" will represent pixel position min(width, height) + offset as in the picture below:

image

The reason I did this was that I usually render videos at many different resolutions and want them all to "look the same" - even if the ratio changes!

Here is an example:

import nanim

proc myScene(): Scene =
  let
    scene = newScene()
    square = newSquare(1000) # Fills the height/width of the inner square, no matter canvas size

  square.moveTo(500, 500) # Puts square in center, no matter the canvas  size

  square.stroke(newColor("#db235d"), 10)
  square.fill(newColor("#00000000"))

  scene.add(square)

  return scene

when isMainModule:
  render(myScene)

Notice now, when I resize the canvas (either by dragging the window or by passing --height:XX, --width:XX and/or --ratio:XX), the square will always fill the smallest of the width and the height and remain in the center:

Coordinates

This all stems from the fact that I scale the canvas using this function:

proc scaleToUnit(scene: Scene, fraction: float = 1000f, compensate: bool = true) =

I should probably both document this behaviour and also add an option to use exact pixels as unit instead.

BTW: Sorry for the circles looking a bit weird with dots and artefacts.. I'm working on fixing that. You can fix it in the meantime by using newDot() instead of newCircle() since Dots are perfect circles.

@EriKWDev EriKWDev mentioned this issue Dec 11, 2021
5 tasks
@EriKWDev EriKWDev added documentation Improvements or additions to documentation will investigate more labels Dec 11, 2021
@EriKWDev
Copy link
Owner

EriKWDev commented Dec 21, 2021

Screenshot 2021-12-21 at 10 44 30

Here is the video rendered using your command next to the live rendering on my mac.

Sadly, I don't get the same behaviour on my Intel Macbook Air from 2016 in Big Sur (11.1) :/

That being said, I tried your "Wrong Fix", and it doesn't change anything for me, so I would be OK with applying it to the rendering procs in rendering.nim

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation will investigate more
Projects
None yet
Development

No branches or pull requests

2 participants