当我沿着平面将文本放置在 3D 图形中时,hyperref
框不会调整。图片中的问题文本被放置为
\node [yz slant style, anchor=west, black] at (0,1,3)
{\href{http://tex.stackexchange.com}{TeX.SE}};
如果我删除它,yz slant style
那么一切就会像第一个链接显示的那样正常工作,但是文本并没有按照我想要的平面对齐。
有办法解决这个问题吗?
参考:
- 倾斜的文本基于:如何计算 xslant 和 yslant
笔记:
- 下面的代码看起来比实际更吓人——大部分代码都在设置倾斜度,因此可以忽略不计。但这对于说明问题是必不可少的。
代码:
\documentclass{article}
\usepackage{xcolor}
\usepackage{tikz}
\usepackage[colorlinks=false, pdfborder={0 0 1}, allbordercolors=cyan]{hyperref}
\begin{document}
%% https://tex.stackexchange.com/a/51388/4301
\newcommand*\elevation{14}
\newcommand*\anglerot{-50}
\pgfmathsetmacro\xc{cos(\anglerot)}
\pgfmathsetmacro\xs{sin(\anglerot)}
\pgfmathsetmacro\yc{cos(\elevation)}
\pgfmathsetmacro\ys{sin(\elevation)}
\newcommand*\axexthreed{\xs*1cm,-\xc*1cm}
\newcommand*\axeythreed{\yc*1cm,-\ys*1cm}
\newcommand*\axezthreed{0cm,1cm}
\newcommand*{\CoordX}{3}%
\newcommand*{\CoordY}{4}%
\newcommand*{\CoordZ}{5}%
%% https://tex.stackexchange.com/a/170255/4301
\tikzset{yz slant style/.style={red, yslant=-tan(\elevation), xscale=cos(\elevation)}}
%\tikzset{xy slant style/.style={blue, xslant=-tan(\elevation+\anglerot), rotate=-\elevation, yscale=cos(\anglerot)}}
%\tikzset{xz slant style/.style={orange, yslant=-cot(\anglerot), xscale=sin(-\anglerot)}}
\begin{tikzpicture}[x = {(\axexthreed)},
y = {(\axeythreed)},
z = {(\axezthreed)},
]
%% Draw Axes:
\draw[gray, thick, -latex] (-1,0,0) -- (\CoordX,0,0) node[black, left=6pt ] {$x$};
\draw[gray, thick, -latex] (0,-1,0) -- (0,\CoordY,0) node[black, right=6pt] {$y$};
\draw[gray, thick, -latex] (0,0,-1) -- (0,0,\CoordZ) node[black, above=6pt] {$z$};
%% Place text in yz plane
\node [anchor=west] at (0,1,4)
{\href{http://tex.stackexchange.com}{TeX.SE (no slant)}};
\node [yz slant style, anchor=west, black] at (0,1,3) % ??? How get this border to work ???
{\href{http://tex.stackexchange.com}{TeX.SE (slant)}};
\end{tikzpicture}
\end{document}
答案1
关于 pdfTeX:这是 TikZ 的一个限制。转换是使用原始命令而不是 pdfTeX 原语完成的\pdftransformmatrix
。后者不包括翻译,因为它可以通过移动框来实现。但是,Tikz 的基本系统层命令需要包括翻译在内的整个矩阵,因此修复意味着至少在较低层进行重新设计。
内部结构:
pdfTeX 提供:
\pdfsetmatrix{<a> <b> <c> <d>}
pdfTeX 将其转换为等效的
\pdfliteral{<a> <b> <c> <d> 0 0 cm}
通知 pdfTeX 有关转换的信息,从而可以纠正链接和锚点位置。
TikZ在系统层定义\pgf@transformcm
:
\def\pgfsys@transformcm#1#2#3#4#5#6{%
\pgfsysprotocol@literalbuffered{#1 #2 #3 #4}%
\pgf@sys@bp{#5}% <x>: horizontal translation in bp
\pgf@sys@bp{#6}% <y>: vertical translation in bp
\pgfsysprotocol@literal{cm}%
}
这相当于(<x>
并<y>
作为转换为 bp 的结果):
\pdfliteral{#1 #2 #3 #4 <x> <y> cm}
但内容\pdfliteral
是不是由 pdfTeX 解析,因此 pdfTeX 不知道该转换。
翻译组件<x
破坏<y>
了乐趣,因为 pdfTeX\pdftransformmatrix
只能处理零值。
无论如何,pdfTeX 不直接支持任意链接形状。
答案2
倾斜、歪斜、剪切、旋转的超链接是没有问题的,至少如果使用 Acrobat Reader 来显示的话:
为此,我们定义了一个href={<url>}
选项,将任何四边形的 TikZ 节点转换为超链接。
我们还将hyperref
条目添加/QuadPoints [...]
到Link
PDF 注释中。根据 PDF 规范,/QuadPoints [...]
定义任意数量的四边形的角坐标,这些四边形只需完全内接在通常的水平链接矩形内,并进一步确定超链接的鼠标敏感区域。即使任意形状区域可以变成超链接这样,只需将多个四边形叠加即可。
(跑pdflatex
/lualatex
两次。)
\documentclass{article}
\usepackage{luatex85} %for LuaLaTeX compatibility
\usepackage{xcolor}
\usepackage{tikz}
\usepackage[colorlinks=false, pdfborder={0 0 1}, allbordercolors=cyan]{hyperref}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% href={<URL>} for TikZ nodes
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usetikzlibrary{calc}
\tikzset{
href/.style={
alias=hrefnode,
append after command={
let \p1 = (hrefnode.south west),
\p2 = (hrefnode.south east),
\p3 = (hrefnode.north east),
\p4 = (hrefnode.north west)
in
node [inner sep=0pt, outer sep=0pt,at=(\p1)] {\pdfsavepos%
\writeAux{}{%
\string\expandafter\string\xdef\string\csname\space hrefnd\thehrefnd.x1\string\endcsname{%
\noexpand\hypercalcbp{\noexpand\number\pdflastxpos sp}}%
\string\expandafter\string\xdef\string\csname\space hrefnd\thehrefnd.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 hrefnd\thehrefnd.x2\string\endcsname{%
\noexpand\hypercalcbp{\noexpand\number\pdflastxpos sp}}%
\string\expandafter\string\xdef\string\csname\space hrefnd\thehrefnd.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 hrefnd\thehrefnd.x3\string\endcsname{%
\noexpand\hypercalcbp{\noexpand\number\pdflastxpos sp}}%
\string\expandafter\string\xdef\string\csname\space hrefnd\thehrefnd.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 hrefnd\thehrefnd.x4\string\endcsname{%
\noexpand\hypercalcbp{\noexpand\number\pdflastxpos sp}}%
\string\expandafter\string\xdef\string\csname\space hrefnd\thehrefnd.y4\string\endcsname{%
\noexpand\hypercalcbp{\noexpand\number\pdflastypos sp}}}%
}
{[local bounding box=link rect] (\p1)--(\p2)--(\p3)--(\p4)--cycle}
node [inner sep=0pt, outer sep=0pt,anchor=center,at=(link rect.center)] {%
{\edef\QuadPoints{/QuadPoints [%
\csname hrefnd\thehrefnd.x1\endcsname\space\csname hrefnd\thehrefnd.y1\endcsname\space
\csname hrefnd\thehrefnd.x2\endcsname\space\csname hrefnd\thehrefnd.y2\endcsname\space
\csname hrefnd\thehrefnd.x3\endcsname\space\csname hrefnd\thehrefnd.y3\endcsname\space
\csname hrefnd\thehrefnd.x4\endcsname\space\csname hrefnd\thehrefnd.y4\endcsname%
]}%
\href{#1}{%
% upscale a bit to ensure /QuadPoints lie within /Rect (link bounding box)
\tikz[scale=1.01] \useasboundingbox (\p1)--(\p2)--(\p3)--(\p4)--cycle;%
}}%
\stepcounter{hrefnd}%
}
}
}
}
\makeatletter
%patch hyperref
\let\Hy@setpdfborderOrig\Hy@setpdfborder
\def\Hy@setpdfborder{
\QuadPoints
\Hy@setpdfborderOrig
}
\def\writeAux{\protected@write\@mainaux}
\def\QuadPoints{}
\makeatother
\newcounter{hrefnd}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
%% https://tex.stackexchange.com/a/51388/4301
\newcommand*\elevation{14}
\newcommand*\anglerot{-50}
\pgfmathsetmacro\xc{cos(\anglerot)}
\pgfmathsetmacro\xs{sin(\anglerot)}
\pgfmathsetmacro\yc{cos(\elevation)}
\pgfmathsetmacro\ys{sin(\elevation)}
\newcommand*\axexthreed{\xs*1cm,-\xc*1cm}
\newcommand*\axeythreed{\yc*1cm,-\ys*1cm}
\newcommand*\axezthreed{0cm,1cm}
\newcommand*{\CoordX}{3}%
\newcommand*{\CoordY}{4}%
\newcommand*{\CoordZ}{5}%
%% https://tex.stackexchange.com/a/170255/4301
\tikzset{yz slant style/.style={red, yslant=-tan(\elevation), xscale=cos(\elevation)}}
\tikzset{xy slant style/.style={blue, xslant=-tan(\elevation+\anglerot), rotate=-\elevation, yscale=cos(\anglerot)}}
\tikzset{xz slant style/.style={orange, yslant=-cot(\anglerot), xscale=sin(-\anglerot)}}
\begin{tikzpicture}[x = {(\axexthreed)},
y = {(\axeythreed)},
z = {(\axezthreed)},
]
%% Draw Axes:
\draw[gray, thick, -latex] (-1,0,0) -- (\CoordX,0,0) node[black, left=6pt ] {$x$};
\draw[gray, thick, -latex] (0,-1,0) -- (0,\CoordY,0) node[black, right=6pt] {$y$};
\draw[gray, thick, -latex] (0,0,-1) -- (0,0,\CoordZ) node[black, above=6pt] {$z$};
%% Place text in various planes
\node [yz slant style,anchor=west,black,href={http://tex.stackexchange.com}] at (0,1,3) {TeX.SE (slant)};
\node [xy slant style,anchor=north west,black,href={http://tex.stackexchange.com}] at (1.5,1,0) {TeX.SE (slant)};
\node [xz slant style,anchor=south west,rotate=90,black,href={http://tex.stackexchange.com}] at (1.5,0,1) {TeX.SE (slant)};
\end{tikzpicture}
\end{document}