[TeX][TikZ] TikZ でカード作成
2021年12月24日 (金) 12:25
この記事は TeX & LaTeX Advent Calendar 2021 の 16 日目の記事です。 15 日目は mod_poppo さんの Standard ML on LuaTeXしてみる でした。 17 日目は mattskala さんの MakeでLaTeX言語のビルドしましょう です。
非常に遅れて申し訳有りません。
さて、TeX を使っているならば、「TeX (LaTeX) でカードゲームのカードを作成したい」 という要求が出てくるのは自然であると考えられます。 実際、カードゲームのカードは、同じテンプレートに違うテキストを流し込んである場合が多く、 TeX のマクロを活用して自動化することができるのではないかと考えられます。
今回は、簡単なカードを 2 枚作成することを考えます。 LuaLaTeX を使うことにしましょう。
まず、マクロ定義をするファイルを作成するのですが、これはクラスファイル (waku.cls) とします。 なぜパッケージファイル (*.sty) にしないかというと、ここで定義するコマンドは 任意のクラスで使用するわけではないからです。
waku.cls にマクロ定義をするという方針が定まったので、ひとまず作ってゆきます。 まず、クラスファイルの中で、jlreq.cls を読み込みます。 jlreq は余白や紙面サイズを簡単に設定できるので重宝します。 紙面の大きさがそのままカードの大きさになるので、紙面の大きさをポーカーサイズ 63 mm × 88 mm にします。余白は邪魔なのですべて 0 pt にします。 一行の長さも 63 mm にします。 また、tikz で文字を配置するので tikz を読み込み、calc ライブラリも読み込みます (座標の計算用です)。 トンボを出力するために gentombow を読み込みます。ヌリタシは 3 mm にしました。 また、コマンド定義用に xparse パッケージも読み込みます。
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{waku}[2021/12/23]
\LoadClass[
jafontsize=2.5mm,
baselineskip=1.1zh,
line_length=63mm,
paper={63mm,88mm},
gutter=0pt,
head_space=0pt,
foot_space=0pt,
fore-edge=0pt,
]{jlreq}
\RequirePackage{luatexja,xparse,xcolor,graphicx,luatexja-fontspec}
\RequirePackage{tikz}
\usetikzlibrary{calc}
\RequirePackage[export]{adjustbox}
\RequirePackage[pdfbox]{gentombow}
\settombowbleed{3mm}
\setlength{\parindent}{0pt}
ここで、\Card{⟨名前⟩}{⟨イラストのファイル名⟩}{⟨文章欄⟩}
というコマンドを定義して、
*.tex ファイル内で \Card コマンドを使うとカードが出力されるようにします。
レイアウトを決めるために、方眼を出力します。 \Card コマンドに方眼を出力するように定義します。
\NewDocumentCommand\Card{m m m}{%
\begin{tikzpicture}[x=1mm,y=1mm]
\coordinate(OL1)at(0,0);\coordinate(OL3)at(63,88);
\coordinate(OO1)at(-3,-3);\coordinate(OO3)at(66,91);
\useasboundingbox(OL1)rectangle(OL3);
\draw[very thin,cyan,nearly transparent](OO1)grid[step=1](OO3);
\draw[thin,cyan,nearly transparent](OL1)grid[step=10](OL3);
\draw[thin,cyan,nearly transparent](OL1)rectangle(OL3);
\end{tikzpicture}%
}
ここでのテクニックとして、カードの印刷領域だけをバウンディングボックスとして使い、 バンディングボックスを 3 mm はみ出して方眼を書くことで、 ヌリタシ部分にも方眼を書きつつ、トンボの裁ち落としラインがカードの外側に一致するようにしています。
方眼を出力したら、それを印刷し、レイアウトを決めます。 このとき、TikZ で描画するのに必要そうな点の座標を確認します。
— 幼穂の太陽帝 ヒトミ(ゲーム開始時から 10 VP を持っている)💉⓵7/23⓶8/22 転 1 (@CareleSmith9) December 24, 2021
レイアウトを決めたら、TikZ で描画します。 入れる文字はとりあえず決め打ちしておき、あとで #1 などに置き換えます。
\NewDocumentCommand\Card{m m m}{%
\begin{tikzpicture}[x=1mm,y=1mm]
\coordinate(OL1)at(0,0);\coordinate(OL3)at(63,88);
\coordinate(OO1)at(-3,-3);\coordinate(OO3)at(66,91);
\coordinate(N3)at(3,75);\coordinate(N1)at(66,85);
\coordinate(A3)at(5,40);\coordinate(A1)at(58,75);
\coordinate(T3)at(5,3);\coordinate(T1)at(58,40);
\useasboundingbox(OL1)rectangle(OL3);
%% 枠
\fill[black](OO1)rectangle(OO3);
\fill[white](A3)rectangle(A1);
\fill[white](T3)rectangle(T1);
\filldraw[fill=white](N3)rectangle(N1);
%% 絵
%%%% min size オプションは adjustbox パッケージが提供。
%%%% 枠内いっぱいに縦横比維持して表示するためのトリック。
%%%% (min size を指定しないと、枠内に余白ができる)
\draw[path picture={\node at (path picture bounding box.center)
{\includegraphics[width=53mm,height=35mm,keepaspectratio,min size={53mm}{35mm},clip]
{kuma.pdf}};}](A1)-|(A3)-|cycle;
%% 文字 (VisualTikz 17.8, 17.9 あたりを参照)
\path(N3)[anchor=south west,font=\fontsize{6mm}{0pt}\selectfont]node{くま};
\path(T1)--(T3)node[midway,anchor=center,text width=50mm,align=flush center]{くまです。};
%% 方眼
\draw[very thin,cyan,nearly transparent]($(OL1)-(3,3)$)grid[step=1]($(OL3)+(3,3)$);
\draw[thin,cyan,nearly transparent](OL1)grid[step=10](OL3);
\draw[thin,cyan,nearly transparent](OL1)rectangle(OL3);
\endif
\end{tikzpicture}%
}
レイアウトが決まり、TikZ で描画ができたら、方眼は不要なので消します。
再度レイアウトを調整する可能性を考えて、クラスオプションで方眼をオンオフできるようにします。
waku.cls の頭に以下を追記して、方眼を書くコードを
\ifgrid
と \fi
で囲みます。
\newif\ifgrid\gridfalse
\DeclareOption{grid}{\gridtrue}
\ProcessOptions\relax
— 幼穂の太陽帝 ヒトミ(ゲーム開始時から 10 VP を持っている)💉⓵7/23⓶8/22 転 1 (@CareleSmith9) December 24, 2021
そして、コマンド定義文中の必要な部分を #1 などに置き換えます。
最終的に出来上がったものは GitHub にあげてあります。
以上、TikZ でカード画像を作ってみる話でした。