6

In the following two questions

@AlexG demonstrates how to construct a click to zoom in button using javascript.

Can this be done without using javascript?

There are reasons to ask for this:

  • Some PDF viewer simply disables javascript.
  • according to the PDF specification, one can assign the destination of a hyperlink as follows

    [page /XYZ left top zoom]

    (However, seems to disable this when using pdftex/lualatex/xelatex.)

PS.

  • A pdftex answer would be fine.
  • I only care about the click to zoom in part. The click to zoom out part is unnecessary as it can be done by keyboard shortcut.

Here is a sandbox

\documentclass{beamer}

\usepackage{mwe}

\makeatletter
    % something?
\makeatother

\begin{document}
    \begin{frame}
        \includegraphics[width=1cm]{example-image-a}\par
        \includegraphics[width=1cm]{example-image-b}\par
        \includegraphics[width=1cm]{example-image-c}\par
        \includegraphics[height=1cm]{example-image-golden}\par
        \includegraphics[width=1cm]{example-image-golden-upright}\par
    \end{frame}
\end{document}
Symbol 1
  • 36,855

1 Answers1

8

This is a JavaScript free version of a click-to-zoom box. (For pdfLaTeX, LuaLaTeX, XeLaTeX, LaTeX+Dvips.)

\zoombox[dotted box line width in px, default: 1]{<contents>}

It makes use of the "mouse-button-down" and "mouse-button-up" events in order to zoom in and out. In a lecture situation, this works quite reliably and should be sufficient for giving short explanations about a detail on the slide.

This was successfully tested with Acrobat Reader and PDF-XChange. Foxit Reader does not zoom-in correctly, which should be reported to the developers, in Evince it does not work at all.

The first code example targets beamer class documents and should be used in Full Screen/Presentation mode. The zoom target is centred on screen upon mouse button press. On button release, it zooms out to whole-page view. (This is more robust than returning to the previous view, used in the second code example.) For best performance, the document's aspect ratio (beamer option aspectratio) should match the target video projector or monitor.


For beamer class document:

\documentclass[
  aspectratio=169,% must match the target video projector/monitor, default: 43
  hyperref={pdfpagemode=FullScreen}
]{beamer}
\usepackage{graphicx}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  usage: \zoombox[<dotted border width in pix, default: 1>]{<content>}
%
%  * optimized version for BEAMER class:
%     - zoom target centred on screen upon zoom-in   (mouse btn press)
%     - whole-page-view upon zoom-out                (mouse btn release)
%                                       
%  * !! to be used in FULL-SCREEN mode !!
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage{pdfbase,calc}

\ExplSyntaxOn
\let\pbsPdfDest\pbs_pdfdest:nnnn
\let\pbsPdfAnnot\pbs_pdfannot:nnnn
\ExplSyntaxOff
\newsavebox\zbox
\newcounter{zoom}
\newdimen\zAr\newdimen\pAr %aspect ratios of zoom target and document page
\newdimen\zwd\newdimen\zht\newdimen\zdp %intermediate and final zoom target dims

\newcommand{\zoombox}[2][1]{% [#1] (optional) sets border line width, default: 1 pixel
                            % {#2} box context
  \sbox\zbox{#2}%
  \setlength\zAr{1pt*\ratio{\wd\zbox}{\ht\zbox+\dp\zbox}}%
  \setlength\pAr{1pt*\ratio{\paperwidth}{\paperheight}}%
  \ifdim\zAr>\pAr\relax%
    \setlength\zwd{\wd\zbox}\setlength\zht{\zwd*\ratio{\paperheight}{\paperwidth}}%
    \setlength\zdp{(\zht-\ht\zbox-\dp\zbox)*\real{0.5}+\dp\zbox}%
    \setlength\zht{\zht-\zdp}%
  \else%
    \setlength\zht{\ht\zbox+\dp\zbox}%
    \setlength\zwd{\zht*\ratio{\paperwidth}{\paperheight}}%
    \setlength\zht{\ht\zbox}\setlength\zdp{\dp\zbox}%
  \fi%
  \pbsPdfDest{zb\thezoom.out}{fit}{1}{}% full-slide view for zoom-out
  \makebox[0pt][l]{\makebox[\wd\zbox][c]{% zoom-in target
    \pbsPdfDest{zb\thezoom.in}{fitr}{1}{\phantom{\vrule
      width \zwd\space height\space \zht\space depth \zdp
  }}}}%
  \makebox[0pt][l]{{\fboxsep=0.5\fboxsep\hskip-\fboxsep%
    \pbsPdfAnnot{\dimexpr\wd\zbox+2\fboxsep\relax}{%
      \dimexpr\ht\zbox+\fboxsep\relax}{%
      \dimexpr\dp\zbox+\fboxsep\relax}{%
      /Subtype/Link/Border [0 0 #1[#1]]%
      }%
    \pbsPdfAnnot{\dimexpr\wd\zbox+2\fboxsep\relax}{%
      \dimexpr\ht\zbox+\fboxsep\relax}{%
      \dimexpr\dp\zbox+\fboxsep\relax}{%
      /Subtype/Widget/FT/Btn/Ff 65536/H/N
      /T (zb\thezoom)
      /AA <<
        /D <</S/GoTo /D (zb\thezoom.in)>>
        /U <</S/GoTo /D (zb\thezoom.out)>>
        /X <</S/GoTo /D (zb\thezoom.out)>>
      >>
      }%
  }}%
  \usebox{\zbox}%
  \stepcounter{zoom}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}

\begin{frame}
  1-px-border (default): \zoombox{\includegraphics[width=1cm]{example-image-a}}\quad
                         \zoombox{Hello World!}\\[2ex]
  2-px-border: \zoombox[2]{\includegraphics[width=1cm]{example-image-b}}\\[2ex]
  zero-width-border: \zoombox[0]{\includegraphics[width=1cm]{example-image-golden-upright}}\quad
  \zoombox[0]{\includegraphics[width=1cm]{example-image-golden}}
\end{frame}

\end{document}

The second code example executes the GoBack action (return to the previous view) upon mouse button release.

Note, that the GoBack action used for zooming-out was broken and non-functional in A-Readers X and XI, but came back in AR-DC.

Usable with any document class, but less robust. (The stack of saved views in the PDF viewer may become messed up sometimes.)

\documentclass{article}
\usepackage{graphicx}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% usage: \zoombox[<dotted border width in pix, default: 1>]{<content>}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage{pdfbase,calc}

\ExplSyntaxOn
\let\pbsPdfDest\pbs_pdfdest:nnnn
\let\pbsPdfAnnot\pbs_pdfannot:nnnn
\ExplSyntaxOff
\newsavebox\zbox
\newcounter{zoom}

\newcommand{\zoombox}[2][1]{% [#1] (optional) sets border line width, default: 1 pixel
  \leavevmode%                {#2} box context
  \sbox\zbox{#2}%
  \makebox[0pt][l]{{\fboxsep=0.5\fboxsep\hskip-\fboxsep%
    \pbsPdfAnnot{\dimexpr\wd\zbox+2\fboxsep\relax}{%
      \dimexpr\ht\zbox+\fboxsep\relax}{%
      \dimexpr\dp\zbox+\fboxsep\relax}{%
      /Subtype/Link/A <</S/GoTo /D (zb\thezoom)>>/Border [0 0 #1[#1]]%
      }%
    \pbsPdfAnnot{\dimexpr\wd\zbox+2\fboxsep\relax}{%
      \dimexpr\ht\zbox+\fboxsep\relax}{%
      \dimexpr\dp\zbox+\fboxsep\relax}{%
      /Subtype/Widget/FT/Btn/Ff 65536/H/N
      /T (zb\thezoom)/TU (Press mouse button to zoom in.)
      /AA <<
        /D <</S/GoTo /D (zb\thezoom)>>
        /U <</S/Named /N/GoBack>>
        /X <</S/Named /N/GoBack>>
      >>
      }%
  }}%
  \pbsPdfDest{zb\thezoom}{fitr}{1}{\usebox{\zbox}}%
  \stepcounter{zoom}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}\parindent=0pt

1-px-border (default): \zoombox{\includegraphics[width=1cm]{example-image-a}}\quad
2-px-border: \zoombox[2]{\includegraphics[width=1cm]{example-image-b}}\\[2ex]
zero-width-border: \zoombox[0]{\includegraphics[width=1cm]{example-image-golden-upright}}
\zoombox[0]{\strut Hello World!}

\end{document}
AlexG
  • 54,894
  • This is magic! By the way, how did you know /Bl=blur as the official description is "An action that shall be performed when the annotation loses the input focus". – Symbol 1 Apr 04 '17 at 13:33
  • Actually, /Bl is the trigger event ("blur") and <<...>> is the action dictionary associated with it. The name "blur" for the event of losing focus is used in other page description languages, such as HTML (https://www.w3schools.com/jsref/event_onblur.asp), too. – AlexG Apr 04 '17 at 13:41
  • @Symbol : This is documented in the PDF Spec. – AlexG Apr 04 '17 at 13:54
  • Interesting, because I cannot find "blur" in PDF32000_2008.pdf (dated 2008); but I found it in pdf_reference_1-7.pdf (dated 2006). – Symbol 1 Apr 04 '17 at 14:56
  • @Symbol1 What about using the mouse-down & mouse-up events for zooming in and out? – AlexG Apr 06 '17 at 11:47
  • Even better :) (Learning user interface is a long way to go.) – Symbol 1 Apr 06 '17 at 12:04
  • @Dr.ManuelKuehner I changed the Subtype of the annotation. Does it work in a recent AR? – AlexG Apr 06 '17 at 14:46
  • @AlexG I added -- temporarily -- an "answer" with screenshots. Now it works. – Dr. Manuel Kuehner Apr 06 '17 at 14:49
  • 1
    To see the neighbouring image is normal, since the viewer zooms in to the maximum magnification of the target image such that it still fits into the view area and aligns its top-left corner with the same corner of the view area. If it does not fill the area completely, you will see the neighbourhood on the page – AlexG Apr 06 '17 at 14:54
  • 1
    @Dr.ManuelKuehner Some kind of "animated" zooming would be nice, but AR doesn't provide such a thing for the /GoTo action used here. – AlexG Apr 06 '17 at 15:08
  • 1
    @AlexG You already make so much possible. Really appreciate it. – Dr. Manuel Kuehner Apr 06 '17 at 15:13
  • 1
    For the mac users out there: works with acrobat, but not with preview. – samcarter_is_at_topanswers.xyz Apr 12 '17 at 20:45
  • @AlexG This is awesome! I stumbled upon this post by accident and you solved a problem I have not even begun to tackle yet =) I am barely a novice at latex, so I don't really understand what does what in the code. Is it possible to make it so it zooms in on mouse-down and holds until mouse-down again? To clarify, I would like to click to zoom and release the button and it is still zoomed in until I click again. Is this possible? – Mathphyte May 08 '21 at 18:20