
Imagine que eu queira desenhar uma forma preenchida atrás de algo já escrito na página. A abordagem usual é definir um \tikzmark
comando que simplesmente lembre uma coordenada usando as opções remember picture
e overlay
, e depois use essa coordenada para desenhar coisas tikz usando transparência.
Por exemplo:
\documentclass{article}
\usepackage{tikz}
\usepackage{lipsum}
\usetikzlibrary{backgrounds}
\def\tikzmark#1{\tikz[remember picture,overlay]\coordinate(#1);}
\begin{document}
\noindent\tikzmark{A}\lipsum[11]
\begin{tikzpicture}[remember picture, overlay]
\fill[yellow, opacity=.3] (A) circle(2em);
\end{tikzpicture}
\end{document}
O que produz:
Mas agora suponha que eu queira umsólidoamarelo. A ideia óbvia é usar pgfonlayer
e desenhar no fundo. No entanto, o conceito de plano de fundo/primeiro plano aparentemente só existe dentro de ambientes tikz. Como o texto principal da página já estava escrito, ele está atrás do plano de fundo do tikz:
\documentclass{article}
\usepackage{tikz}
\usepackage{lipsum}
\usetikzlibrary{backgrounds}
\def\tikzmark#1{\tikz[remember picture,overlay]\coordinate(#1);}
\begin{document}
\noindent\tikzmark{A}\lipsum[11]
\begin{tikzpicture}[remember picture, overlay]
\begin{pgfonlayer}{background}
\fill[yellow] (A) circle(2em);
\end{pgfonlayer}
\end{tikzpicture}
\end{document}
Isso pode ser feito?
Responder1
Obrigado a Andrew Stacey por me indicar onovo melhoradotikzmkark
. Eu não estava ciente disso. Esta versão \tikzmark
permite usar as coordenadas definidasanteso ponto de sua definição. O uso de \tikzmark{foo}
uma nova coordenada chamada (pic cs:foo)
está disponível e pode ser usado em qualquer lugar da página.
Usando o new \tikzmark
, retirado do preâmbulo dehttps://tex.stackexchange.com/a/50054/12571o problema pode ser resolvido assim:
\begin{document}
\noindent\begin{tikzpicture}[remember picture, overlay]
\fill[yellow] (pic cs:A) circle(2em);
\end{tikzpicture}%
\tikzmark{A}\lipsum[11]
\end{document}
Com o resultado desejado:
Apêndice
Para completar, o código de todo o documento, incluindo o preâmbulo em que o novo \tikzmark
aparece, está incluído aqui:
\documentclass{article}
\usepackage{tikz}
\usepackage{lipsum}
\makeatletter
\tikzset{%
remember picture with id/.style={%
remember picture,
overlay,
save picture id=#1,
},
save picture id/.code={%
\edef\pgf@temp{#1}%
\immediate\write\pgfutil@auxout{%
\noexpand\savepointas{\pgf@temp}{\pgfpictureid}}%
},
if picture id/.code args={#1#2#3}{%
\@ifundefined{save@pt@#1}{%
\pgfkeysalso{#3}%
}{
\pgfkeysalso{#2}%
}
}
}
\def\savepointas#1#2{%
\expandafter\gdef\csname save@pt@#1\endcsname{#2}%
}
\def\tmk@labeldef#1,#2\@nil{%
\def\tmk@label{#1}%
\def\tmk@def{#2}%
}
\tikzdeclarecoordinatesystem{pic}{%
\pgfutil@in@,{#1}%
\ifpgfutil@in@%
\tmk@labeldef#1\@nil
\else
\tmk@labeldef#1,(0pt,0pt)\@nil
\fi
\@ifundefined{save@pt@\tmk@label}{%
\tikz@scan@one@point\pgfutil@firstofone\tmk@def
}{%
\pgfsys@getposition{\csname save@pt@\tmk@label\endcsname}\save@orig@pic%
\pgfsys@getposition{\pgfpictureid}\save@this@pic%
\pgf@process{\pgfpointorigin\save@this@pic}%
\pgf@xa=\pgf@x
\pgf@ya=\pgf@y
\pgf@process{\pgfpointorigin\save@orig@pic}%
\advance\pgf@x by -\pgf@xa
\advance\pgf@y by -\pgf@ya
}%
}
\newcommand\tikzmark[2][]{%
\tikz[remember picture with id=#2] #1;}
\makeatother
\begin{document}
\noindent\begin{tikzpicture}[remember picture, overlay]
\fill[yellow] (pic cs:A) circle(2em);
\end{tikzpicture}%
\tikzmark{A}\lipsum[11]
\end{document}
OBSERVAÇÃO: Qualquer pessoa disposta a votar nesta auto-resposta deve votarhttps://tex.stackexchange.com/a/50054/12571em vez de :-)
Atualizar
Conforme observado por Ulrike Fischer em um comentário, colocar o tikzpicture
que desenha o fundo muito próximo do parágrafo decorado pode ter efeitos colaterais no parágrafo anterior:
\begin{document}
\lipsum[5] % <------ Added a previous paragraph
\medskip
\noindent\begin{tikzpicture}[remember picture, overlay]
\fill[yellow] (pic cs:A) circle(2em);
\end{tikzpicture}%
\tikzmark{A}\lipsum[11]
\end{document}
Porém, separando muito o tikzpicture
do, \tikzmark
corremos o risco de acabar com aqueles em páginas separadas e, assim, o fundo aparecerá na página errada.
A melhor solução é então usar alguma solução que "armazene" a imagem necessária e "ative" sua saída como plano de fundo ao mesmo tempo que colocamos o \tikzmark
, como por exemplo a solução proposta por Ulrike no comentário.
Explorei outra opção, que é usar o maravilhosopacote de plano de fundoporGonzalo Medina(obrigado ao Andrew por sugerir isso no chat!). Usando este pacote configuramos a imagem de fundo em qualquer lugar do documento, e a "ativamos" ao \BgThispage
mesmo tempo em que colocamos o arquivo \tikzmark
. Usando esta abordagem, não há necessidade denovo melhoradotikzmark
e em vez disso oantigo minimalistatikzmark
pode ser usado.
É importante também atribuir valores apropriados às opções placement
e scale
, para obter o desenho nas coordenadas apropriadas. Existe o MWE:
\documentclass{article}
\usepackage{tikz}
\usepackage[pages=some]{background}
\usepackage{lipsum}
\def\tikzmark#1{\tikz[remember picture, overlay]\coordinate(#1);}
\begin{document}
\backgroundsetup{scale=1,placement=bottom,contents={%
\noindent\begin{tikzpicture}[remember picture,overlay]
\fill[yellow] (A) circle(2em);
\end{tikzpicture}%
}}
\lipsum[5]
\medskip
\noindent\tikzmark{A}\BgThispage\lipsum[11]
\end{document}
E depois de três (por que três?) compilações eu recebo: