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} 
4
  • 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
    Commented Feb 16, 2018 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}; } Commented Feb 16, 2018 at 13:18
  • 1
    @percusse : Not quite, see below.
    – AlexG
    Commented Feb 16, 2018 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
    Commented Feb 20, 2018 at 17:06

2 Answers 2

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}
7
  • 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
    Commented Feb 17, 2018 at 0:43
  • I guess you can now also answer this question.
    – user121799
    Commented Feb 25, 2018 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
    Commented Feb 26, 2018 at 12:18
  • @AlexG The nodeparts also have anchors given in PGF Manual page 729 in case you want to check out.
    – percusse
    Commented Mar 11, 2018 at 15:25
  • 1
    @Manuel Ah yes, I deleted my public ShareLaTeX projects a while ago, after it became publicly known that too much personal information would be undisclosed via the public link and the project settings, most notably the project owner's e-mail address. Will edit my post.
    – AlexG
    Commented Apr 10, 2021 at 20:42
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.

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .