如何使用 TikZ 创建交互式图表

如何使用 TikZ 创建交互式图表

我正在尝试创建一个交互的图表,与 EPUB 中使用的图表非常相似去书店

Go Books 图解 - 初始位置

Go Books 图解 - 第 1 步

我所说的“互动”是指用户控制触发事件的时间。例如,动画不是我所说的互动性,因为无论用户做什么,动画都会发生。(当然,在每个动作之间,我们可以有一个动画。)

坦白说,我不知道 TikZ 是否可以做到这一点。是吗?也许有办法将 HTML 和 JS 注入 TikZ?

下面是一个具有 3 步走棋的围棋棋盘的简单示例,我们的想法是让 TikZ 添加某种 UI 用于来回移动,然后相应地显示每一步走棋 — — 不需要播放按钮 — —:

\documentclass{article}

\usepackage{tikz}

\newlength{\step}

\begin{document}
  \begin{tikzpicture}
    \setlength{\step}{\dimexpr 10cm / 18 \relax}

    \draw[step=\step] (0, 0) grid (10, 10);

    \draw[draw = white, fill = black, line width = 0.1mm]
      (2 * 10cm / 18, 3 * 10cm / 18)
      circle [radius = 0.2575cm]
      node[color = white] {1};
    \draw[draw = black, fill = white, line width = 0.1mm]
      (3 * 10cm / 18, 3 * 10cm / 18)
      circle [radius = 0.2575cm]
      node[color = black] {2};
    \draw[draw = white, fill = black, line width = 0.1mm]
      (4 * 10cm / 18, 3 * 10cm / 18)
      circle [radius = 0.2575cm]
      node[color = white] {3};
  \end{tikzpicture}
\end{document}

答案1

还应该归功于亚历克斯。感谢他的出色animate软件包。这个\playgo命令也是出自他的想法邮政\uncover命令)。

animateinline下面是使用包的示例animate。它可以在 Adob​​e Reader 和 Foxit Reader 中使用(它似乎无法在 VS Code 的 PDF Viewer 上使用):

\documentclass{article}

\usepackage{tikz}
\usepackage{animate}

\newlength{\step}
\setlength{\step}{\dimexpr 10cm / 18 \relax}

\newcommand\playgo[3]{\ifnum#1<#2\phantom{#3}\else#3\fi}

\begin{document}
  \begin{animateinline}[step,controls=step]{1}
    \multiframe{4}{i=0+1}{
      \begin{tikzpicture}[x=\step,y=\step]
        %create the board 
        \draw[step=1] (0, 0) grid (18, 18);

        %setup black
        \foreach \bloc in {{2,4},{3,4},{4,4},{5,4},{6,5},{7,6}}{
          \filldraw[line width = 0.1mm] (\bloc) circle [radius = 0.2575cm];
        }

        %setup white
        \foreach \wloc in {{2,6},{3,6},{4,6},{5,6},{6,6},{7,7}}{
          \filldraw[fill=white,line width = 0.1mm] (\wloc) circle [radius = 0.2575cm];
        }

        %play the go-game start from black
        \foreach \stepnum/\loc in {1/{8,7},2/{8,8},3/{9,8}}{
          \playgo{\i}{\stepnum}{\filldraw[fill={\ifodd\stepnum black\else white\fi},line width = 0.1mm] (\loc) circle [radius = 0.2575cm] node [color = \ifodd\stepnum white\else black\fi] {\stepnum};}
        }
      \end{tikzpicture}
    }
  \end{animateinline}
\end{document}

一步步动画

这个动画是这样控制的:

动画控制

更新:增加显示进度条及颜色。

\documentclass{article}

\usepackage{tikz}
\usepackage{animate}

\newlength{\step}
\setlength{\step}{\dimexpr 10cm / 18 \relax}

\newcommand\playgo[3]{\ifnum#1<#2\phantom{#3}\else#3\fi}
\newcounter{totalsteps}
\setcounter{totalsteps}{3}

\begin{document}
{\centering
  \begin{animateinline}[step,controls=step]{1}
    \multiframe{\numexpr\value{totalsteps}+1}{i=0+1}{
      \begin{tikzpicture}[x=\step,y=\step]
        %create the board 
        \fill [brown!30] (-0.5,-0.5) rectangle (18.5,18.5);
        \draw[step=1] (0, 0) grid (18, 18);
        \draw [line width=2pt] (0,0) rectangle (18,18);
        \foreach \sloc in 
 {{3,3},{3,9},{3,15},{9,3},{9,9},{9,15},{15,3},{15,9},{15,15}}{\filldraw (\sloc) circle [radius=1.5pt];}
        %add progress bar
        \draw [rounded corners=3pt,blue!20] (5,-0.85) rectangle (13,-1.15);
        \fill [rounded corners=3pt,blue] (5,-0.85) rectangle ++(\i*13/\value{totalsteps}-\i*5/\value{totalsteps} ,-0.3);
        \filldraw [blue] (5,-0.85) ++ (\i*13/\value{totalsteps}-\i*5/\value{totalsteps} ,-0.15) circle [radius=5pt];
        %setup black
        \foreach \bloc in {{2,4},{3,4},{4,4},{5,4},{6,5},{7,6}}{
          \filldraw[line width = 0.1mm] (\bloc) circle [radius = 0.2575cm];
        }

        %setup white
        \foreach \wloc in {{2,6},{3,6},{4,6},{5,6},{6,6},{7,7}}{
          \filldraw[fill=white,line width = 0.1mm] (\wloc) circle [radius = 0.2575cm];
        }

        %play the go-game start from black
        \foreach \stepnum/\loc in {1/{8,7},2/{8,8},3/{9,8}}{
          \playgo{\i}{\stepnum}{\filldraw[fill={\ifodd\stepnum black\else white\fi},line width = 0.1mm] (\loc) circle [radius = 0.2575cm] node [color = \ifodd\stepnum white\else black\fi] {\stepnum};}
        }
      \end{tikzpicture}
    }
  \end{animateinline}\par}
\end{document}

在此处输入图片描述

答案2

我使用 TikZ 和动画包制作了以下动画:

在此处输入图片描述

经典的方法是将逐帧图片制作成一个.tex文件,对于基于某种算法的数学或图形,你可以使用循环,这是完美的,但在这种情况下,我制作了一个逐帧文件,我将其命名为Go-game.tex

\documentclass[tikz, border=30mm]{standalone}
\usetikzlibrary{fadings}
\definecolor{backcol}{HTML}{8b5a16}
\definecolor{wood}{HTML}{5d2f03}
\definecolor{gwhite}{HTML}{ecefe9}
\definecolor{gblack}{HTML}{221d1d}


\newcommand{\white}[1]{
\begin{scope}[shift={#1}]
\shade[top color=gwhite, bottom color=white] (0,0)circle(0.95);
\end{scope}
}

\newcommand{\black}[1]{
\begin{scope}[shift={#1}]
\shade[top color=gblack, bottom color=black] (0,0)circle(0.95);
\end{scope}
}

\begin{document}
\pagecolor{backcol}
\color{wood}
\foreach\i in {0, 10, 20, ..., 100}{
\begin{tikzpicture}
\draw[line width=0.5mm, step=2] (0,0)grid(16,16);
\white{(4,4)}
\white{(4,6)}

\node[opacity=\i/100, scale=3, text width=4cm, align =center, preaction={fill, wood}] at (8,14) {\color{white}In order to take over the white goishi we need};

\end{tikzpicture}
}
\foreach\i in {90, 80,..., 0}{
\begin{tikzpicture}
\draw[line width=0.5mm, step=2] (0,0)grid(16,16);
\white{(4,4)}
\white{(4,6)}

\node[opacity=\i/100, scale=3, text width=4cm, align =center, preaction={fill, wood}] at (8,14) {\color{white}In order to take over the white goishi we need};

\end{tikzpicture}
}

\foreach\i in {0, 10, 20, ..., 100}{
\begin{tikzpicture}
\draw[line width=0.5mm, step=2] (0,0)grid(16,16);
\white{(4,4)}
\white{(4,6)}

\node[opacity=\i/100, scale=3, text width=4cm, align =center, preaction={fill, wood}] at (8,14) {\color{white}To surround them using the black goishi};
\end{tikzpicture}
}
\foreach\i in {90, 80, 70, ..., 0}{
\begin{tikzpicture}
\draw[line width=0.5mm, step=2] (0,0)grid(16,16);
\white{(4,4)}
\white{(4,6)}

\node[opacity=\i/100, scale=3, text width=4cm, align =center, preaction={fill, wood}] at (8,14) {\color{white}To surround them using the black goishi};
\end{tikzpicture}
}


\begin{tikzpicture}
\draw[line width=0.5mm, step=2] (0,0)grid(16,16);
\white{(4,4)}
\white{(4,6)}
\black{(2,4)}
\end{tikzpicture}

\begin{tikzpicture}
\draw[line width=0.5mm, step=2] (0,0)grid(16,16);
\white{(4,4)}
\white{(4,6)}
\black{(2,4)}
\black{(4,2)}

\end{tikzpicture}

\begin{tikzpicture}
\draw[line width=0.5mm, step=2] (0,0)grid(16,16);
\white{(4,4)}
\white{(4,6)}
\black{(2,4)}
\black{(4,2)}
\black{(6,4)}
\end{tikzpicture}

\begin{tikzpicture}
\draw[line width=0.5mm, step=2] (0,0)grid(16,16);
\white{(4,4)}
\white{(4,6)}
\black{(2,4)}
\black{(4,2)}
\black{(6,4)}
\black{(6,6)}
\end{tikzpicture}

\begin{tikzpicture}
\draw[line width=0.5mm, step=2] (0,0)grid(16,16);
\white{(4,4)}
\white{(4,6)}
\black{(2,4)}
\black{(4,2)}
\black{(6,4)}
\black{(6,6)}
\black{(4,8)}
\end{tikzpicture}

\begin{tikzpicture}
\draw[line width=0.5mm, step=2] (0,0)grid(16,16);
\white{(4,4)}
\white{(4,6)}
\black{(2,4)}
\black{(4,2)}
\black{(6,4)}
\black{(6,6)}
\black{(4,8)}
\black{(2,6)}
\end{tikzpicture}

\foreach\i in {90, 80, 70, ...,0}{
\begin{tikzpicture}
\draw[line width=0.5mm, step=2] (0,0)grid(16,16);
\begin{scope}[opacity=\i/100]
\white{(4,4)}
\white{(4,6)}
\end{scope}
\black{(2,4)}
\black{(4,2)}
\black{(6,4)}
\black{(6,6)}
\black{(4,8)}
\black{(2,6)}
\end{tikzpicture}

}

\end{document}

编译您的文件生成Go-game.pdf我们将使用它来为我们的帧制作动画:

\documentclass[tikz, border=40mm]{standalone}
\usepackage{animate}
\begin{document}
\animategraphics[controls=all, loop]{15}{Go-game}{}{}
\end{document}

是的,之后你应该就可以得到动画了。

相关内容