将动画转换为单独的 Beamer 幻灯片

将动画转换为单独的 Beamer 幻灯片

animateinline我正在编写一个 Beamer 演示文稿,其中包含一个通过包内的环境创建的动画animate。当我创建幻灯片的讲义(通过设置选项handout)时,我希望将动画的每一帧显示为单独的幻灯片,最好不显示动画控件。有没有一种简单的方法可以做到这一点,而不需要重复动画代码?

显示我想要实现的目标的一个简单的例子是:

\documentclass{beamer}
\usepackage{animate}
\usepackage{boolexpr}

\begin{document}

\begin{frame}
    \begin{center}
        \begin{animateinline}[controls]{1}
            \multiframe{2}{iStep=1+1}
            {
            \ifthenelse{\iStep=1}{Frame 1}{Frame 2}
            }
        \end{animateinline}
    \end{center}
\end{frame}

\end{document}

这会产生一个包含两个帧的动画。我想要的是,当我将源更改为包含文档类handout的选项beamer时,动画的每个帧都对应讲义中的一张新幻灯片(因此讲义将有两张幻灯片)。

答案1

在此处输入图片描述

这将禁用animateinline环境,并修改\multiframe循环,以便它

\only<2|handout:2>{.....}

使用循环计数器,<...>因此 beamer 可以执行其正常操作,并制作与迭代的每一帧相对应的幻灯片。(仅XXX修改了标记的两行。)

需要规范handout来强制其在讲义模式下使用多张幻灯片。

\documentclass
%[handout]
{beamer}


\usepackage{animate}
\usepackage{boolexpr}

\makeatletter
\def\animateinline[#1]#2{%
\@anim@insidetrue
}
\def\endanimateinline{}


\renewcommand{\multiframe}[3]{% #1: #repetitions, #2: vars, #3: frame content
  \unskip%
  \if@anim@inside\else%
    \PackageError{animate}{%
      \protect\multiframe\space cannot be used outside `animateinline'%
      \MessageBreak environment%
    }{}%
  \fi%
  \if@anim@insidemulti%
    \PackageError{animate}{\protect\multiframe\space cannot be nested}{}%
  \fi%
  \setboolean{@anim@insidemulti}{true}%
  %reset macro for updating variables
  \gdef\@anim@updatevars{}%
  %reset loop counter
  \global\@anim@mulframecnt=\z@%
  %remove spaces from variable declaration list (2nd arg)
  \xdef\@anim@vardecls{#2\space}%
  \xdef\@anim@vardecls{\expandafter\zap@space\@anim@vardecls\@empty}%
  \ifnum#1<\z@%
    \PackageError{animate}{%
      \protect\multiframe: first argument must be greater than zero%
    }{}%
  \fi%
  %parse list of variable declarations and build macro for updating them
  \expandafter\@anim@parsevars\@anim@vardecls,\@nil%
  \whiledo{\@anim@mulframecnt<#1}{%
    \ifnum\@anim@mulframecnt>\z@%
    % \newframe% don't do this XXX
      \@anim@updatevars% update variables
    \fi%
    \global\advance\@anim@mulframecnt by \@ne%
    \ignorespaces%
    \only<\the\@anim@mulframecnt|handout:\the\@anim@mulframecnt>{#3}% execute loop body( using \only<>) XXX
    \unskip%
  }%
  \setboolean{@anim@insidemulti}{false}%
  \ignorespaces%
}


\makeatother
\begin{document}


\begin{frame}
    \begin{center}
        \begin{animateinline}[controls]{1}
            \multiframe{2}{iStep=1+1}
            {
            \ifthenelse{\iStep=1}{Frame 1}{Frame 2}
            }
        \end{animateinline}
    \end{center}
\end{frame}

\end{document}

答案2

这是一个更普遍使用的解决方案(来自内部人员),因为它适用于嵌入式\newframes、缩放选项\animategraphics、时间线等......

animate仅当类选项 optionhandout实际设置后,才会修补内部宏(感谢\@ifclasswith{beamer}{handout}{.... }{}David Carlisle):

\documentclass
[handout]
{beamer}

\usepackage{animate}

\makeatletter
\newcount\@currentframe

\@ifclasswith{beamer}{handout}{
  %non-interactive Widget annotation, representing one frame of the animation
  \ifpdf
    \def\@anim@makeframe#1#2{% #1:@anim@num, #2:@anim@curframe@zb
      %container XObject for all transparencies that compose the frame
      \begingroup%
      \setlength{\unitlength}{1pt}%
        \global\setbox\@anim@box=\hbox{%
          \pdfliteral{q}%
          \begin{picture}(\@anim@framewidth,\@anim@frametotalheight)%
          \end{picture}%
          \pdfliteral{Q\@anim@getkeyval{frmcontent@#2}}%
        }%
      \endgroup%
      \immediate\pdfxform resources {%
        /XObject <<\@anim@getkeyval{frmxobject@#2}>>}\@anim@box%
      \if@anim@useocg%
        \@anim@newocg{#1}{#2}%
        \ifx\@anim@poster\@anim@posterlast%
          \@anim@keytoaux{a#1.poster}{#2}%
          \ifthenelse{\equal{\@anim@getkeyval{a#1.poster}}{#2}}{}{%
            \xdef\@anim@offocgs{\@anim@offocgs\space\@anim@curocg}%
          }%
        \else%
          \ifnum#2=\z@%
            \ifx\@anim@poster\@anim@posternone%
              \xdef\@anim@offocgs{\@anim@offocgs\space\@anim@curocg}%
            \fi%
          \else%
            \xdef\@anim@offocgs{\@anim@offocgs\space\@anim@curocg}%
          \fi%
        \fi%
        \def\@anim@annotflag{/F 4}%, print, visibility set by OCG
      \else%
        %widget visibility state
        \def\@anim@annotflag{/F 4}%, print, visibility set by OCG
        \ifx\@anim@poster\@anim@posternone\else%
          \ifnum#2=\z@%
            \ifx\@anim@poster\@anim@posterfirst%
              \def\@anim@annotflag{/F 4}% visible, print
            \fi%
          \fi%
          \ifx\@anim@poster\@anim@posterlast%
            \@anim@keytoaux{a#1.poster}{#2}%
            \ifthenelse{\equal{\@anim@getkeyval{a#1.poster}}{#2}}{%
              \def\@anim@annotflag{/F 4}%
            }{}%
          \fi%
        \fi%
      \fi%
      %frame widget, using the container XObject as its Appearance
      \pdfannot
        width \@anim@animwidth\p@ height \@anim@animheight\p@
        depth \@anim@animdepth\p@
      {%
        /Subtype/Widget%
        \@anim@annotflag
        \if@anim@useocg%
          /OC \@anim@curocg %associate widget with the just created OCG
        \fi%
        /FT/Btn/Ff 65537% non-interactive push button
        /BS <</W 0>>%
        /AP <</N \the\pdflastxform\space 0 R>>%
        /T (#1.#2)%
      }%
      %\xdef\@anim@fields{\@anim@fields\space\the\pdflastannot\space 0 R}%
    }
  \else
    \if@anim@@dvipdfmx
      \def\@anim@makeframe#1#2{%
        %container XObject
        \global\setbox\@anim@box=\hbox{%
          \special{pdf:content \@anim@getkeyval{frmcontent@#2}}%
        }%
        \special{pdf:bxobj @anim@anmfrm@#1@#2 width \@anim@framewidth pt
          height \@anim@frameheight pt depth \@anim@framedepth pt}%
        \begin{picture}(0,0)\put(0,0){\box\@anim@box}\end{picture}%
        \special{pdf:put @resources <<
          /XObject <<\@anim@getkeyval{frmxobject@#2}>>%
        >>}%
        \special{pdf:exobj}%
        \if@anim@useocg%
          \@anim@newocg{#1}{#2}%
          \ifx\@anim@poster\@anim@posterlast%
            \@anim@keytoaux{a#1.poster}{#2}%
            \ifthenelse{\equal{\@anim@getkeyval{a#1.poster}}{#2}}{}{%
              \special{pdf:put @anim@offocgs @anim@ocg@#1@#2}%
            }%
          \else%
            \ifnum#2=\z@%
              \ifx\@anim@poster\@anim@posternone%
                \special{pdf:put @anim@offocgs @anim@ocg@#1@#2}%
              \fi%
            \else%
              \special{pdf:put @anim@offocgs @anim@ocg@#1@#2}%
            \fi%
          \fi%
          \def\@anim@annotflag{/F 4}%
        \else%
          \def\@anim@annotflag{/F 4}%
          \ifx\@anim@poster\@anim@posternone\else%
            \ifnum#2=\z@%
              \ifx\@anim@poster\@anim@posterfirst%
                \def\@anim@annotflag{/F 4}%
              \fi%
            \fi%
            \ifx\@anim@poster\@anim@posterlast%
              \@anim@keytoaux{a#1.poster}{#2}%
              \ifthenelse{\equal{\@anim@getkeyval{a#1.poster}}{#2}}{%
                \def\@anim@annotflag{/F 4}%
              }{}%
            \fi%
          \fi%
        \fi%
        %frame widget
        \special{pdf:annot @annot@\the\@anim@fieldnum\space
          width \@anim@animwidth pt height \@anim@animheight pt
          depth \@anim@animdepth pt <<%
            /Subtype/Widget%
            \@anim@annotflag
            \if@anim@useocg/OC @anim@ocg@#1@#2\fi%
            /FT/Btn/Ff 65537%
            /BS <</W 0>>%
            /AP <</N @anim@anmfrm@#1@#2>>%
            /T (#1.#2)%
          >>%
        }%
        %\special{pdf:put @anim@fields @annot@\the\@anim@fieldnum}%
        \global\advance\@anim@fieldnum by \@ne%
      }
    \else
      \def\@anim@makeframe#1#2{%
        %container XObject
        \special{ps:
          mark  /_objdef {@anim@anmfrm@#1@#2} /type/stream /OBJ pdfmark
          mark {@anim@anmfrm@#1@#2} (\@anim@getkeyval{frmcontent@#2}) /PUT
            pdfmark
          mark {@anim@anmfrm@#1@#2} <<
            /Type/XObject/Subtype/Form/FormType 1
            /BBox [frame@llx frame@lly frame@urx frame@ury]
            /Resources <</XObject <<\@anim@getkeyval{frmxobject@#2}>>>>
          >> /PUT pdfmark
        }%
        \if@anim@useocg%
          \@anim@newocg{#1}{#2}%
          \ifx\@anim@poster\@anim@posterlast%
            \@anim@keytoaux{a#1.poster}{#2}%
            \ifthenelse{\equal{\@anim@getkeyval{a#1.poster}}{#2}}{}{%
              \special{ps: mark {@anim@offocgs} {@anim@ocg@#1@#2} /APPEND pdfmark}%
            }%
          \else%
            \ifnum#2=\z@%
              \ifx\@anim@poster\@anim@posternone%
                \special{ps: mark {@anim@offocgs} {@anim@ocg@#1@#2} /APPEND pdfmark}%
              \fi%
            \else%
              \special{ps: mark {@anim@offocgs} {@anim@ocg@#1@#2} /APPEND pdfmark}%
            \fi%
          \fi%
          \def\@anim@annotflag{/F 4}%
        \else%
          \def\@anim@annotflag{/F 4}%
          \ifx\@anim@poster\@anim@posternone\else%
            \ifnum#2=\z@%
              \ifx\@anim@poster\@anim@posterfirst%
                \def\@anim@annotflag{/F 4}%
              \fi%
            \fi%
            \ifx\@anim@poster\@anim@posterlast%
              \@anim@keytoaux{a#1.poster}{#2}%
              \ifthenelse{\equal{\@anim@getkeyval{a#1.poster}}{#2}}{%
                \def\@anim@annotflag{/F 4}%
              }{}%
            \fi%
          \fi%
        \fi%
        %frame widget
        \begingroup%
          \setlength{\unitlength}{1pt}%
          \begin{picture}(0,0)% mark annotation rectangle
            \put(0,-\@anim@animdepth){%
            \special{ps:
              currentpoint /wid@lly exch def /wid@llx exch def
            }%
          }%
          \put(\@anim@animwidth,\@anim@animheight){%
            \special{ps:
              currentpoint /wid@ury exch def /wid@urx exch def
            }%
          }%
          \end{picture}%
        \endgroup%
        \special{ps:
          mark
            /_objdef {annot@\the\@anim@fieldnum}%
            /Rect [wid@llx wid@lly wid@urx wid@ury]%
            /Subtype/Widget%
            \@anim@annotflag
            \if@anim@useocg/OC {@anim@ocg@#1@#2}\fi%
            /FT/Btn/Ff 65537
            /BS <</W 0>>%
            /AP <</N {@anim@anmfrm@#1@#2}>>%
            /T (#1.#2)%
          /ANN pdfmark
          %mark {\@anim@fields} {annot@\the\@anim@fieldnum} /APPEND pdfmark
        }%
        \global\advance\@anim@fieldnum by \@ne%
      }
    \fi
  \fi
  \let\@anim@makeframe@orig\@anim@makeframe
  \def\@anim@makeframe#1#2{% #1:@anim@num, #2:@anim@curframe@zb
    \@currentframe=#2\relax%
    \advance\@currentframe by \@ne%
    \only<\@currentframe|handout:\@currentframe>{\@anim@makeframe@orig{#1}{#2}}%
  }
  \def\@anim@animwidget#1{%
    \hbox to \@anim@animwidth\p@ {%
      \vrule width 0pt height \@anim@animheight\p@ depth \@anim@animdepth\p@%
      \hss%
    }%
  }%
  \def\@anim@insertwidgets#1#2{%#1:@anim@num, #2 existing btn colour combination
    \vtop{%
      \offinterlineskip%
      \hbox{\@anim@animwidget{#1}}%
      \if@anim@controls%
        \setlength{\@anim@tmpdima}{\@anim@btnsize}%
        \vskip 0.1\@anim@tmpdima%
        \hbox to \@anim@animwidth\p@ {%
          \hss\vrule width 0pt height \@anim@tmpdima depth 0pt\hss%
        }%
      \fi%
    }%
  }
}{}
\makeatother

\begin{document}

\begin{frame}
  \begin{center}
      \begin{animateinline}[controls,scale=2]{1}
          Frame 1
      \newframe
          Frame 2
      \newframe
      \multiframe{2}{iStep=3+1}{Frame \iStep}
      \newframe
          Frame 5
      \end{animateinline}
  \end{center}
\end{frame}
\end{document}

相关内容