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} 
  • 5
    even if you can rotate it the hyperlink box will be the bounding box. This is a PDF issue and TikZ has no way to fix that. – percusse Feb 16 '18 at 13:09
  • 1
    The closest you can get is possibly \hyperlink{pagetwo}{ \tikz \node [draw, inner sep=2ex, rotate=60] {Go to Page Two}; } – Jasper Habicht Feb 16 '18 at 13:18
  • 1
    @percusse : Not quite, see below. – AlexG Feb 16 '18 at 23:13
  • @AlexG ahah so it is an PDF issue after all :) That's what I meant by it but really nice anyways. – percusse Feb 20 '18 at 17:06
3

Oblique / inclined / rotated 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, open on ↗ShareLaTeX (download and open the PDF in 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}
  • Really cool! +1. BTW, you did not really use my solution, all I did in addition to the original post was to compute the rotation angle. – user121799 Feb 17 '18 at 0:43
  • I guess you can now also answer this question. – user121799 Feb 25 '18 at 0:12
  • @marmot : To me it looks like a different problem. To turn a nodepart into a hyperlink, we must know its corner coordinates. These are not accessible, I think. – AlexG Feb 26 '18 at 12:18
  • @AlexG The nodeparts also have anchors given in PGF Manual page 729 in case you want to check out. – percusse Mar 11 '18 at 15:25
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.