“星球大战”文字效果

“星球大战”文字效果

我想对一些文本应用转换,使其按照梯形倾斜,例如《星球大战》系列著名的开场白:

在此处输入图片描述

这似乎很难做到,因为它不是仿射变换。我试过在谷歌上搜索,但没有成功。

空的 MWE:

\documentclass{article}
\newcommand{\starwarsbox}[1]{\fbox{#1}}

\begin{document}
\begin{center}
\starwarsbox{
    \parbox{0.8\linewidth}
    {
    Star wars effect demo.
    \begin{itemize}
        \item Lots of text here
        \item And environments such as \texttt{itemize}, too!
    \end{itemize}
    }
}
\end{center}
\end{document}

有什么想法吗?谢谢!

答案1

这一切都始于布鲁诺的\slantbox剪切变换一个“盒子”) 并逐个字母地应用它。作为参考,提供给 Bruno 程序的倾斜值是倾斜角的正切。

我正在编辑以更好地解释我在这里所做的事情。关键是定义一个消失点和一个坐标系,并了解您相对于它的当前位置。

昨晚写完代码后,我累了,愚蠢地定义了一个左手系统,其中X是相对于消失点的当前水平位置,并且向下页面上与消失点之间的距离。因此,三角计算中需要一些额外的负数来消除左手系的影响。

\xvpref透视图的左边距由连接消失点和坐标 ( , )的线定义\ypvref,坐标相对于消失点指定。因此,更改 的值会\xvpref改变文本的宽度,而更改\yvpref会改变地平线的垂直位置。在我原来的方法(前景中的第一行文本)中,这也是第一行文本的开始位置。在更正的方法(前景中的最后一行文本)中,起点位于 ( \xvp, \ypv)

输入通过和\nextline进行处理 ,以便一次处理一个字母,考虑到空格。一旦每个字母被隔离,就会在 内计算从其位置回到消失点的切线,并使用。该切线将确定倾斜度。\nextword\nextletter\nextletter\FPdiv

除了倾斜度之外,还需要确定字母的放大倍数。放大倍数在 中确定\setmagf,仅作为(且与)的函数-与消失点的距离(这样给定的线就都具有相同的放大倍数)。一旦知道了字母的倾斜度和放大倍数,这些参数就会\shslbox通过传递给\nextletter。宏\shslbox只是缩放字母并将其传递给 Bruno 的 \slantbox

随着每个字母的呈现,X值已更新(在\xvp),这将影响消失点的切线斜率,从而影响后续字母的倾斜度。

\nextline除了处理每行中的字母之外,宏还必须执行额外的簿记。调用\parallax宏以通过正确的 来注册消失左边距上的当前位置\hspace\setmagf调用宏来确定此行文本的 mag 因子。调用 A\vspace来将行向上移动(原始方法)或向下移动(校正方法),在此过程中考虑 mag 因子。修订后的 值当然,也会影响消失点的切线。

右侧没有进行边距调整,因此仍然参差不齐,必须手动调整以适应。这可以通过将整个单词移至相邻行来实现,或者通过填充单词来\,增加单词之间的间隙。

修正方法(前景中的最后一行文本)

\documentclass{article}
\usepackage{fp,amssymb,graphicx,xcolor}
\makeatletter
\def\strippt{\strip@pt}
\makeatother
\newsavebox\foobox
\newcommand\slbox[2]{%
  \slantbox[\result]{#2}%
}%
\newcommand{\slantbox}[2][30]{%
        \mbox{%
        \global\sbox{\foobox}{\textcolor{yellow}{#2}}%
        \hskip\wd\foobox
        \pdfsave
        \pdfsetmatrix{1 0 #1 1}%
        \llap{\usebox{\foobox}}%
        \pdfrestore
}}
\newcommand\shslbox[3]{\slbox{#1}{\scalebox{#3}{#2}}}
\newlength\yvp
\newlength\xvp
\newlength\yvpref
\newlength\xvpref
\yvpref 50pt\relax
\xvpref -75pt\relax
\xvp=\xvpref\relax
\yvp=.3\yvpref\relax
\newcommand\nextletter[1]{%
  \FPdiv{\result}{\strippt\xvp}{-\strippt\yvp}%
  \shslbox{\result}{#1}{\themagf}%
  \addtolength{\xvp}{\wd\foobox}%
}
\newcommand\nextword[1]{\nextwordhelp #1\relax}
\def\nextwordhelp#1#2\relax{%
  \nextletter{#1}%
  \ifx\relax#2\relax\sbox{\foobox}{\scalebox{\themagf}{~}}\addtolength{\xvp}{\wd\foobox}\usebox{\foobox}%
  \else\nextwordhelp#2\relax\fi%  
}
\newcommand\nextline[1]{%
  \parallax\setmagf\nextlinehelp #1 \relax \relax%
  \vspace{-\dimexpr\baselineskip-\themagf\baselineskip}\par%
  \addtolength\yvp{\themagf\baselineskip}\xvp\xvpref\relax%
  \ignorespaces%
}
\def\nextlinehelp#1 #2\relax{%
  \nextword{#1}%
  \ifx\relax#2\relax\else\nextlinehelp #2\relax\fi%
}
\newcommand\parallax{%
  \FPdiv{\result}{\strippt\yvp}{\strippt\yvpref}%
  \FPsub{\result}{1}{\result}%
  \hspace{-\result\xvpref}\addtolength{\xvp}{-\result\xvpref}%
}
\def\setmagf{\global\FPdiv{\themagf}{\strippt\yvp}{\strippt\yvpref}} 
\parindent 0pt

\begin{document}
\pagecolor{black}\sffamily\bfseries%

\nextline{In a galaxy, far, far away, the Empire}
\nextline{struck back.  Our hero, Luke Skywalker}
\nextline{nearly died, but didn't.  Meanwhile,}
\nextline{R2D2 and C3PO were stuck on the}
\nextline{planet Tatoine.}
\nextline{~}
\nextline{The evil Darth Vader was plotting}
\nextline{terrible deeds.}

\end{document}

在此处输入图片描述

原始方法(前景中的第一行文本)

\documentclass{article}
\usepackage{fp,amssymb,graphicx,xcolor}
\makeatletter
\def\strippt{\strip@pt}
\makeatother
\newsavebox\foobox
\newcommand\slbox[2]{%
  \slantbox[\result]{#2}%
}%
\newcommand{\slantbox}[2][30]{%
        \mbox{%
        \global\sbox{\foobox}{\textcolor{yellow!50}{#2}}%
        \hskip\wd\foobox
        \pdfsave
        \pdfsetmatrix{1 0 #1 1}%
        \llap{\usebox{\foobox}}%
        \pdfrestore
}}
\newcommand\shslbox[3]{\slbox{#1}{\scalebox{#3}{#2}}}
\newlength\yvp
\newlength\xvp
\newlength\yvpref
\newlength\xvpref
\yvpref 50pt\relax
\xvpref -50pt\relax
\xvp=\xvpref\relax
\yvp=\yvpref\relax
\newcommand\nextletter[1]{%
  \FPdiv{\result}{\strippt\xvp}{-\strippt\yvp}%
  \shslbox{\result}{#1}{\themagf}%
  \addtolength{\xvp}{\wd\foobox}%
}
\newcommand\nextword[1]{\nextwordhelp #1\relax}
\def\nextwordhelp#1#2\relax{%
  \nextletter{#1}%
  \ifx\relax#2\relax\sbox{\foobox}{\scalebox{\themagf}{~}}\addtolength{\xvp}{\wd\foobox}\usebox{\foobox}%
  \else\nextwordhelp#2\relax\fi%  
}
\newcommand\nextline[1]{\setmagf\nextlinehelp #1 \relax \relax%
  \vspace{-\dimexpr\baselineskip+\themagf\baselineskip}\par%
  \addtolength\yvp{-\themagf\baselineskip}\xvp\xvpref\relax%
  \parallax\ignorespaces%
}
\def\nextlinehelp#1 #2\relax{%
  \nextword{#1}%
  \ifx\relax#2\relax\else\nextlinehelp #2\relax\fi%
}
\newcommand\parallax{%
  \FPdiv{\result}{\strippt\yvp}{\strippt\yvpref}%
  \FPsub{\result}{1}{\result}%
  \hspace{-\result\xvpref}\addtolength{\xvp}{-\result\xvpref}%
}
\def\setmagf{\global\FPdiv{\themagf}{\strippt\yvp}{\strippt\yvpref}} 
\parindent 0pt

\begin{document}
\pagecolor{black}
\nextline{In a galaxy, far, far away}
\nextline{the Empire struck back.}
\nextline{Our hero Luke Skywalker}
\nextline{nearly died, but didn't}
\nextline{Meanwhile, R2D2 and}
\nextline{C3PO were stuck on}
\nextline{the planet Tatoine.}
\end{document}

在此处输入图片描述

只需将值\yvpref从 50pt 更改为 30pt 即可改变淡入淡出角度:

在此处输入图片描述

将负值\xvpref从 -50pt 增加到 -80pt 允许一行中包含更多文本。当然,需要调整文本规范,因为它是逐行输入的。此外,\yvpref设置为 50pt。

在此处输入图片描述

相关内容