
Представьте, что я хочу нарисовать заполненную фигуру позади чего-то, уже набранного на странице. Обычный подход заключается в определении \tikzmark
команды, которая просто запоминает координату, используя remember picture
и overlay
опции, а затем использовать эту координату для рисования 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]
\fill[yellow, opacity=.3] (A) circle(2em);
\end{tikzpicture}
\end{document}
Что производит:
Но теперь предположим, что я хочутвердыйжелтый. Очевидная идея — использовать pgfonlayer
и рисовать его на фоне. Однако, концепция фона/переднего плана, по-видимому, существует только внутри сред tikz. Поскольку основной текст на странице уже был набран, он находится за фоном 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}
Можно ли это сделать?
решение1
Спасибо Эндрю Стейси за то, что указал мне нановый улучшенныйtikzmkark
. Я не знал об этом. Эта версия \tikzmark
позволяет использовать определенные координатыдоточка его определения. Использование \tikzmark{foo}
новой координаты с именем (pic cs:foo)
доступно и может быть использовано в любом месте страницы.
Используя новый \tikzmark
, взятый из преамбулыhttps://tex.stackexchange.com/a/50054/12571Эту проблему можно решить следующим образом:
\begin{document}
\noindent\begin{tikzpicture}[remember picture, overlay]
\fill[yellow] (pic cs:A) circle(2em);
\end{tikzpicture}%
\tikzmark{A}\lipsum[11]
\end{document}
С желаемым результатом:
Приложение
\tikzmark
Для полноты изложения ниже приводится код всего документа, включая преамбулу, в которой появляется новое :
\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}
ПРИМЕЧАНИЕ: Любой, кто склонен голосовать за этот ответ, должен голосовать заhttps://tex.stackexchange.com/a/50054/12571вместо :-)
Обновлять
Как отметила Ульрике Фишер в своем комментарии, размещение , tikzpicture
которое рисует фон слишком близко к оформленному абзацу, может иметь побочные эффекты для предыдущего абзаца:
\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}
Однако, если слишком сильно отделить « » tikzpicture
от « », \tikzmark
мы рискуем оказаться на разных страницах, и, таким образом, фон появится не на той странице.
Лучшим решением будет использовать какое-либо решение, которое «сохраняет» требуемую картинку и «активирует» ее вывод в качестве фона в то же время, когда мы размещаем \tikzmark
, как, например, решение, предложенное Ульрике в комментарии.
Я рассмотрел другой вариант, а именно использование замечательногофоновый пакеткГонсало Медина(спасибо Эндрю за предложение в чате!). Используя этот пакет, мы устанавливаем фоновое изображение в любом месте документа и «активируем» его \BgThispage
одновременно с размещением \tikzmark
. При использовании этого подхода нет необходимости вновый улучшенныйtikzmark
и вместо этогостарый минималистичныйtikzmark
может быть использован.
Важно также задать соответствующие значения параметрам placement
и scale
, чтобы получить чертеж в соответствующих координатах. Есть 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}
И после трёх (почему три?) компиляций я получаю: