Tikz Picture Behind Text on Page

overlayspgflayerstikz-pgf

I thought I'd seen an answer to this a while ago, but I can't find it now.

I have a document with some variable text that I want to draw a TikZ picture behind based somewhat on a dimensions of the text.

I know I can use TikZ's opacity parameter to achieve the effect I want, but I really don't like this approach.

So, here's my attempt using layers. I thought I understood this, but obviously I'm getting something wrong.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{backgrounds}
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}
\begin{document}

\begin{minipage}{2in}
\tikz[remember picture] \coordinate (A);%%
  Hello world
\tikz[remember picture] \coordinate (B);%%

\begin{tikzpicture}[remember picture,overlay]
  \begin{pgfonlayer}{background}
    \coordinate (nA) at ([yshift=14pt]A)  ;
    \coordinate (sB) at ([yshift=-14pt]B);
    \draw (nA) -- (sB);
    \draw[fill=orange!80] (nA) rectangle (sB);
    %% ----------------------------------------------------
    %% I know this next line kind of achieves what I want.  
    %% I just prefer not to do it this way.                 
    %% ----------------------------------------------------
    % \draw[fill=orange,opacity=0.80] (nA) rectangle (sB);  
  \end{pgfonlayer}
\end{tikzpicture}
\end{minipage}

\end{document}

The result:

enter image description here

I tried moving the tikzpicture to the top of the document, but then the coordinates A and B haven't been defined yet. I thought that should work on a second run. I figured the remember picture aspect would record the nodes. But this just failed.

Best Answer

blend mode=darken and blend mode=multiply actually do the trick

\documentclass{article}
\usepackage{tikz}
\begin{document}

Hello world
\tikz[remember picture] \coordinate (A);%
Hello world
\tikz[remember picture] \coordinate (B);%
Hello world

\begin{tikzpicture}[remember picture,overlay]
    \coordinate (nA) at ([yshift=14pt]A);
    \coordinate (sB) at ([yshift=-14pt]B);
    \draw[fill=orange,blend mode=darken] (nA) rectangle (sB);
\end{tikzpicture}

\end{document}

Another approach using tikzmark

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{tikzmark}
\begin{document}

\begin{tikzpicture}[remember picture,overlay]
    \coordinate (nA) at ([yshift=14pt]pic cs:A);
    \coordinate (sB) at ([yshift=-14pt]pic cs:B);
    \draw[fill=orange] (nA) rectangle (sB);
\end{tikzpicture}

Hello world
\tikzmark{A}
Hello world
\tikzmark{B}
Hello world

\end{document}

Why tikzmark is (sort-of) necessary in this case?

remember picture is implemented by remembering in the aux file the position of the current tikzpicture relative to the current page. Each tikzpicture will correspond to a line that looks like

\pgfsyspdfmark {pgfid29}{21177794}{4593314}

where pgfid29 means this is the 29th remember picture. The next two numbers are x, y coordinates in sp.

Whenever you try to access a node (A), TikZ needs three information

  • the coordinate of (A)
  • the position of the picture that contains (A)
  • the position of the current picture

Without tikzmark the aux file only knows the last two bullet points. And tikzmark puts the first bullet point into the aux file.

BTW: I don't like the interface of tikzmark. And for those who wants to reimplement, suggestion is to look at the aux file to see what's going on there. And copy the idea.