pgf-tikz / pgf

A Portable Graphic Format for TeX
https://pgf-tikz.github.io/
1.14k stars 108 forks source link

Two animations affecting the same objects result in a different bounding box as if only one animation is used. #1016

Open esteban-stafford opened 3 years ago

esteban-stafford commented 3 years ago

The document I am working in (for reasons with which I don't want to bloat this report) requires that a certain animation is done in two steps. For this reason, I have two scopes so I can write two different animation statements that affect essentially the same objects. This has the expected behaviour in terms of the animation, but the problem is that the bounding box of the resulting document is larger than necessary. To demonstrate this issue, I wrote a MWE with simple objects. The circle is supposed to move right to the middle of the line, stop and then go back to the origin. Comented in the MWE is the equivalent animation with a single statement that gives the correct bounding box.

\documentclass[dvisvgm]{minimal}
\usepackage{tikz}
\usetikzlibrary{animations}

\begin{document}
   \begin{tikzpicture}[very thick, animate = {
         first:shift={ along= {(0,0) -- (4,0.0)} upright, 0s="0", 1s later="1", freeze },
         second:shift={ along= {(0,0) -- (-4,-0.0)} upright, 2s="0", 1s later="1", freeze },
         % This is the single animation statement equivalent to the previous two
         %first:position={ along= {(0,0) -- ++(4,0.0) -- ++(-4,-0.0)} upright, 0s="0", 1s later=".5", 1s later=".5", 1s later="1", freeze }
      } ]
      \draw (-4,0) -- (4,0);
      \begin{scope}[name=second]
         \begin{scope}[name=first]
            \draw  (-4,0) circle[radius=1cm];
         \end{scope}
      \end{scope}
   \end{tikzpicture}
\end{document}

This is the resulting document with the two animation statements. Note that the objects are not centered in the document.

image

This is the document comenting the two statements and uncomenting the equivalent animation statement, where it can be seen that the document is properly framed around the objects.

image

These tests were made in a Ubuntu 20.04 machine. The version of tikz is v3.1.5b from 2020/01/08. The commands used were:

latex along.tex
dvisvgm --font-format=woff2 --zoom=-1 --page=- --output=%f-%p.svg along.dvi
hmenke commented 3 years ago

That looks very tricky, however, note that the two step first + second is not equivalent to the single step first. You can easily check this by adding another circle to the second scope (also using the overlay option to make sure it doesn't affect the bounding box.

\documentclass[dvisvgm]{article}
\pagestlye{empty}
\usepackage{tikz}
\usetikzlibrary{animations}
\begin{document}
   \begin{tikzpicture}[very thick, animate = {
         first:shift={ along= {(0,0) -- (4,0)} upright, 0s="0", 1s later="1", freeze },
         second:shift={ along= {(0,0) -- (-4,0)} upright, 2s="0", 1s later="1", freeze },
         % This is the single animation statement equivalent to the previous two
         %first:position={ along= {(0,0) -- ++(4,0.0) -- ++(-4,-0.0)} upright, 0s="0", 1s later=".5", 1s later=".5", 1s later="1", freeze }
      } ]
      \draw (-4,0) -- (4,0);
      \begin{scope}[name=second]
        \draw[overlay] (-4,0) circle[radius=1cm];
         \begin{scope}[name=first]
           \draw (-4,0) circle[radius=1cm];
         \end{scope}
      \end{scope}
   \end{tikzpicture}
\end{document}

first + second

first+second

first

first

esteban-stafford commented 3 years ago

Thanks for the fast response. The overlay circle helped me understand how the bounding box is calculated.

One of the attempts I made to overcome this problem was using a manual bounding box, but it did not seem to have any effect.

\documentclass[dvisvgm]{article}
\pagestlye{empty}
\usepackage{tikz}
\usetikzlibrary{animations}
\begin{document}
   \begin{tikzpicture}[very thick, animate = {
         first:shift={ along= {(0,0) -- (4,0)} upright, 0s="0", 1s later="1", freeze },
         second:shift={ along= {(0,0) -- (-4,0)} upright, 2s="0", 1s later="1", freeze },
         % This is the single animation statement equivalent to the previous two
         %first:position={ along= {(0,0) -- ++(4,0.0) -- ++(-4,-0.0)} upright, 0s="0", 1s later=".5", 1s later=".5", 1s later="1", freeze }
      } ]
      \draw[use as bounding box] (-5,-1) rectangle (4,1);
      \draw (-4,0) -- (4,0);
      \begin{scope}[name=second]
        \draw[overlay] (-4,0) circle[radius=1cm];
         \begin{scope}[name=first]
           \draw (-4,0) circle[radius=1cm];
         \end{scope}
      \end{scope}
   \end{tikzpicture}
\end{document}

By the way. I would love to know how you created those gif animations.

hmenke commented 3 years ago

The manual bounding box worked for me (but you have to take the linewidth of drawing the circle into account)

\documentclass[dvisvgm]{article}
\pagestyle{empty}
\usepackage{tikz}
\usetikzlibrary{animations}
\begin{document}
   \begin{tikzpicture}[very thick, animate = {
         first:shift={ along= {(0,0) -- (4,0)} upright, 0s="0", 1s later="1", freeze },
         second:shift={ along= {(0,0) -- (-4,0)} upright, 2s="0", 1s later="1", freeze },
         % This is the single animation statement equivalent to the previous two
         %first:position={ along= {(0,0) -- ++(4,0.0) -- ++(-4,-0.0)} upright, 0s="0", 1s later=".5", 1s later=".5", 1s later="1", freeze }
      } ]
      \useasboundingbox (-5cm-.5\pgflinewidth,-1cm-.5\pgflinewidth) rectangle (4cm,1cm+.5\pgflinewidth);
      \draw (-4,0) -- (4,0);
      \begin{scope}[name=first]
        \begin{scope}[name=second]
          \draw (-4,0) circle[radius=1cm];
        \end{scope}
      \end{scope}
   \end{tikzpicture}
\end{document}

Since the animations mechanism is relatively new, has only very few users and I didn't write it, I had to check the manual several times and found this:

Screenshot from 2021-05-20 11-43-11

So it looks like what you are experiencing is an inherent limitation of the current mechanism.

By the way. I would love to know how you created those gif animations.

I just recorded my screen and used FFMpeg to crop the output and convert it to GIF:

ffmpeg -i "Screencast from 05-20-2021 09:21:33 AM.webm" -filter:v "crop=700:80:7:110" out.gif
esteban-stafford commented 3 years ago

I assume you are using the latest version of TikZ. So guess that in my older version of tikz, the animation bounding box overrides the user bounding box. I'm up to date with the Ubuntu repositories; I'll look into upgrading manually.

I did not know about \pgflinewidth, I'll keep it in mind for the future.

Thank you very much for your help.

Esteban


De: Henri Menke @.***> Enviado: jueves, 20 de mayo de 2021 11:54:25 Para: pgf-tikz/pgf Cc: Stafford Fernandez, Esteban; Author Asunto: Re: [pgf-tikz/pgf] Two animations affecting the same objects result in a different bounding box as if only one animation is used. (#1016)

The manual bounding box worked for me (but you have to take the linewidth of drawing the circle into account)

\documentclass[dvisvgm]{article} \pagestyle{empty} \usepackage{tikz} \usetikzlibrary{animations} \begin{document} \begin{tikzpicture}[very thick, animate = { first:shift={ along= {(0,0) -- (4,0)} upright, 0s="0", 1s later="1", freeze }, second:shift={ along= {(0,0) -- (-4,0)} upright, 2s="0", 1s later="1", freeze }, % This is the single animation statement equivalent to the previous two %first:position={ along= {(0,0) -- ++(4,0.0) -- ++(-4,-0.0)} upright, 0s="0", 1s later=".5", 1s later=".5", 1s later="1", freeze } } ] \useasboundingbox (-5cm-.5\pgflinewidth,-1cm-.5\pgflinewidth) rectangle (4cm,1cm+.5\pgflinewidth); \draw (-4,0) -- (4,0); \begin{scope}[name=first] \begin{scope}[name=second] \draw (-4,0) circle[radius=1cm]; \end{scope} \end{scope} \end{tikzpicture} \end{document}

Since the animations mechanism is relatively new, has only very few users and I didn't write it, I had to check the manual several times and found this:

[Screenshot from 2021-05-20 11-43-11]https://user-images.githubusercontent.com/1903556/118958042-55f4b980-b961-11eb-9a89-f2821294b70b.png

So it looks like what you are experiencing is an inherent limitation of the current mechanism.

By the way. I would love to know how you created those gif animations.

I just recorded my screen and used FFMpeg to crop the output and convert it to GIF:

ffmpeg -i "Screencast from 05-20-2021 09:21:33 AM.webm" -filter:v "crop=700:80:7:110" out.gif

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/pgf-tikz/pgf/issues/1016#issuecomment-844933153, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AFGPXCWW37WG6AXMAEJ6MILTOTL5DANCNFSM45GEYA2Q.

hmenke commented 3 years ago

Let's leave this open. Even though it's a known limitation, they underlying issue has not been fixed yet.

esteban-stafford commented 3 years ago

OK. Just confirming that version 3.1.8b, available with Ubuntu 21.04, works.