3

I modified the MWE from Making TikZ nodes hyperlinkable and got the following result when I rotated the sample node by 60 degrees:

enter image description here


My desire would be for the hyperlink to rotate along with the box. As indicated here, it is possible to use \rotatebox{...} within the node, but this doesn't give nice results: it rotates the text inside the node, but not the boundary (or the link).

Modified MWE showing both of these less-than-perfect outcomes is below.

\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} 
Joe Corneli
  • 4,340

2 Answers2

5

Oblique / inclined / rotated / slanted hyperlinks are possible!

The PDF specification defines the /QuadPoints entry in the /Link annotation dictionary, which defines the corner coordinates of any number of quadrangles that only need be entirely inscribed within the usual, horizontal link rectangle and which further determine the mouse sensitive area of the hyperlink.

In principle, arbitrarly shaped regions in a document page may be turned into hyperlinks using this method, simply by superposition of multiple quadrangles. Individual quadrangles do not need be rectangular nor be horizontally aligned.

Alas, as usual, such advanced PDF features require Acrobat Reader.


Example (NB: for 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}

AlexG
  • 54,894
1

Given the limitations mentioned by percusse (and acknowledging Jasper Habicht's comment, which was posted while I completed testing this), here is an "improved" version which computes the rotation angle.

\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} 

The output is different for xelatex and other compilers. This version is "optimized" for xelatex.