使旋转的 TikZ 节点可超链接

使旋转的 TikZ 节点可超链接

我修改了 MWE使 TikZ 节点可超链接当我将示例节点旋转 60 度时,得到以下结果:

在此处输入图片描述


我希望超链接能随着框一起旋转。如所示这里,可以\rotatebox{...}在节点内使用,但这不会产生很好的结果:它旋转节点内的文本,但不旋转边界(或链接)。

修改后的 MWE 显示了这两种不太完美的结果。

\documentclass{article}
\usepackage{hyperref}
\usepackage{tikz}
\usepackage{graphicx}
\usetikzlibrary{calc}
\begin{document}
\tikzset{
    hyperlink node/.style={
        alias=sourcenode,
        append after command={
            let     \p1 = (sourcenode.north west),
                \p2=(sourcenode.south east),
                \n1={\x2-\x1},
                \n2={\y1-\y2} in
            node [inner sep=0pt, outer sep=0pt,anchor=north west,at=(\p1)] {\hyperlink{#1}{\XeTeXLinkBox{\phantom{\rule{\n1}{\n2}}}}}
                    %xelatex needs \XeTeXLinkBox, won't create a link unless it
                    %finds text --- rules don't work without \XeTeXLinkBox.
                    %Still builds correctly with pdflatex and lualatex
        }
    }
}

\tikz \node [draw, inner sep=2ex,hyperlink node=pagetwo,rotate=60] {Go to Page Two};

\bigskip

\tikz \node [draw, inner sep=2ex,hyperlink node=pagetwo] {\rotatebox{30}{\hyperref[pagetwo]{I said, Page Two}}};

\clearpage
\hypertarget{pagetwo}{Page Two}
\end{document} 

答案1

斜向 / 倾斜 / 旋转 /倾斜的可以实现超链接!

PDF 规范定义了注释字典/QuadPoints中的条目/Link,该条目定义了任意数量的四边形的角坐标,这些四边形只需完全内接在通常的水平链接矩形内,并进一步确定超链接的鼠标敏感区域。

原则,任意形状文档页面中的区域可能会变成超链接使用这种方法,只需将多个四边形叠加即可。单个四边形不必是矩形,也不必水平对齐。

唉,像往常一样,这种高级 PDF 功能需要 Acrobat Reader。


例子(注:对于 Acrobat Reader):

\documentclass{article}
\usepackage{hyperref}
\usepackage{tikz}
\usepackage{graphicx}
\usetikzlibrary{calc}
    
\makeatletter
  % patch hyperref to also include the /QuadPoints array
  \let\Hy@setpdfborderOrig\Hy@setpdfborder
  \def\Hy@setpdfborder{
    \QuadPoints
    \Hy@setpdfborderOrig
  }
  \def\writeAux{\protected@write\@mainaux}
  \def\QuadPoints{}
\makeatother

\newcounter{srcnd}

\begin{document}
\tikzset{
    hyperlink node/.style={
        alias=sourcenode,
        append after command={
            let \p1 = (sourcenode.south west),
                \p2 = (sourcenode.south east),
                \p3 = (sourcenode.north east),
                \p4 = (sourcenode.north west),
                \p5 = (sourcenode.center)
                in
            node [inner sep=0pt, outer sep=0pt,at=(\p1)] {\pdfsavepos%
              \writeAux{}{%
                \string\expandafter\string\xdef\string\csname\space srcnd\thesrcnd.x1\string\endcsname{%
                  \noexpand\hypercalcbp{\noexpand\number\pdflastxpos sp}}%
                \string\expandafter\string\xdef\string\csname\space srcnd\thesrcnd.y1\string\endcsname{%
                  \noexpand\hypercalcbp{\noexpand\number\pdflastypos sp}}}%
            }
            node [inner sep=0pt, outer sep=0pt,at=(\p2)] {\pdfsavepos%
              \writeAux{}{%
                \string\expandafter\string\xdef\string\csname\space srcnd\thesrcnd.x2\string\endcsname{%
                  \noexpand\hypercalcbp{\noexpand\number\pdflastxpos sp}}%
                \string\expandafter\string\xdef\string\csname\space srcnd\thesrcnd.y2\string\endcsname{%
                  \noexpand\hypercalcbp{\noexpand\number\pdflastypos sp}}}%
            }
            node [inner sep=0pt, outer sep=0pt,at=(\p3)] {\pdfsavepos%
              \writeAux{}{%
                \string\expandafter\string\xdef\string\csname\space srcnd\thesrcnd.x3\string\endcsname{%
                  \noexpand\hypercalcbp{\noexpand\number\pdflastxpos sp}}%
                \string\expandafter\string\xdef\string\csname\space srcnd\thesrcnd.y3\string\endcsname{%
                  \noexpand\hypercalcbp{\noexpand\number\pdflastypos sp}}}%
            }
            node [inner sep=0pt, outer sep=0pt,at=(\p4)] {\pdfsavepos%
              \writeAux{}{%
                \string\expandafter\string\xdef\string\csname\space srcnd\thesrcnd.x4\string\endcsname{%
                  \noexpand\hypercalcbp{\noexpand\number\pdflastxpos sp}}%
                \string\expandafter\string\xdef\string\csname\space srcnd\thesrcnd.y4\string\endcsname{%
                  \noexpand\hypercalcbp{\noexpand\number\pdflastypos sp}}}%
            }
            node [inner sep=0pt, outer sep=0pt,at=(\p5)] {%
              \makebox[0pt][c]{{%
                \edef\QuadPoints{/QuadPoints [
                  \csname srcnd\thesrcnd.x1\endcsname\space\csname srcnd\thesrcnd.y1\endcsname\space
                  \csname srcnd\thesrcnd.x2\endcsname\space\csname srcnd\thesrcnd.y2\endcsname\space
                  \csname srcnd\thesrcnd.x3\endcsname\space\csname srcnd\thesrcnd.y3\endcsname\space
                  \csname srcnd\thesrcnd.x4\endcsname\space\csname srcnd\thesrcnd.y4\endcsname\space
                ]}%
                \hyperlink{#1}{%
                  \raisebox{-\height}{%
                    \tikz \useasboundingbox (\p1) -- (\p2) -- (\p3) -- (\p4) -- cycle;
                  }%
                }%
              }}%
              \stepcounter{srcnd}%
            }
        }
    }
}

\tikz \node [draw, inner sep=2ex,hyperlink node=pagetwo,rotate=0] {Go to Page Two};

\bigskip

\tikz \node [draw, inner sep=2ex,hyperlink node=pagetwo,rotate=60] {Go to Page Two};

\bigskip

\tikz \node [draw, inner sep=2ex,hyperlink node=pagetwo,rotate=40] {Go to Page Two};

\bigskip

\tikz \node [draw, inner sep=2ex,hyperlink node=pagetwo,rotate=135] {I said, Page Two};

\clearpage
\hypertarget{pagetwo}{Page Two}
\end{document}

答案2

考虑到 percusse 提到的局限性(并承认 Jasper Habicht 的评论,该评论是在我完成测试时发布的),这里有一个计算旋转角度的“改进”版本。

\documentclass{article}
\usepackage{hyperref}
\usepackage{tikz}
\usepackage{graphicx}
\usetikzlibrary{calc}
\begin{document}
\tikzset{
    hyperlink node/.style={
        alias=sourcenode,
        append after command={
            let             \p1 = (sourcenode.north west),
                \p2=(sourcenode.south east),
                \p3 = (sourcenode.south west),
                \n1={\x2-\x1},
                \n2={\y1-\y2},
                \n3={atan2(\y2-\y3,\x2-\x3)},
                \n4={veclen(\y2-\y3,\x2-\x3)},
                \n5={veclen(\y1-\y3,\x1-\x3)}
                 in
            node [inner sep=0pt, outer sep=0pt,anchor=south
            west,at=(\p3),rotate=\n3]
            {\hyperlink{#1}{\XeTeXLinkBox{\phantom{\rule{\n4}{\n5}}}}}
                    %xelatex needs \XeTeXLinkBox, won't create a link unless it
                    %finds text --- rules don't work without \XeTeXLinkBox.
                    %Still builds correctly with pdflatex and lualatex
        }
    }
}

\tikz \node [draw, inner sep=2ex,hyperlink node=pagetwo,rotate=0] {Go to Page Two};


\bigskip


\tikz \node [draw, inner sep=2ex,hyperlink node=pagetwo,rotate=60] {Go to Page Two};


\bigskip


\tikz \node [draw, inner sep=2ex,hyperlink node=pagetwo,rotate=40] {Go to Page Two};


\bigskip

\tikz \node [draw, inner sep=2ex,hyperlink node=pagetwo] {\rotatebox{30}{\hyperref[pagetwo]{I said, Page Two}}};

\clearpage
\hypertarget{pagetwo}{Page Two}
\end{document} 

xelatex 和其他编译器的输出有所不同。此版本针对 xelatex 进行了“优化”。

相关内容