Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

In the spirit of How can we draw a Christmas tree with decorations, using TikZ?

Can you draw a 3D Christmas gift box with as many details as possible(bow tie, elevated lid/bow, patterned wrapping paper)?

Bonus points (500 rep bounty) for animating the box as it opens.

MWE (Addition by HK)

\documentclass[varwidth,tikz]{standalone}
\begin{document}

\begin{tikzpicture}
\draw[fill=red] (0,0) rectangle (1,1);
\draw[fill=red] (1,0) -- ++(50:0.75cm) -- ++(90:1cm) -- (1,1) -- cycle;
\draw[fill=magenta] (0,1) -- ++(50:0.75cm) -- ++(0:1cm) -- (1,1) --  cycle;
\draw (0,0.8) -- (1,0.8) -- +(50:0.75cm);
\end{tikzpicture}
\end{document}

enter image description here

share|improve this question
2  
Can you give a MWE? ;-) –  Przemysław Scherwentke Dec 19 '13 at 6:04
    
@PrzemysławScherwentke Sorry, I'm not that good at TikZ :/ Feel free to edit a simplistic one in if you have one :) Apologies if this is off topic without an MWE –  Manishearth Dec 19 '13 at 6:05
    
@tex For animation: 500 bounty :) Otherwise I don't know, I may give a 100-200 bounty for a really good non animated one. –  Manishearth Dec 19 '13 at 7:35
2  
I will offer a bounty of 500 someday for this question! –  stalking is prohibited Dec 19 '13 at 7:42
1  
@StiffJokes Order taken sir ;-) –  Harish Kumar Dec 19 '13 at 8:50

1 Answer 1

up vote 78 down vote
+1000

Just to get things going...

\documentclass[border=0.125cm]{standalone}
\usepackage{tikz}


\tikzset{gift box/.cd,
  x/.store in=\gbx,
  y/.store in=\gby,
  z/.store in=\gbz,
  x=0,y=0,z=0
}
\tikzdeclarecoordinatesystem{gift box}{%
  \tikzset{x=(-20:1cm),y=(200:1cm),z=(90:1cm)}%
  \tikzset{gift box/.cd, #1}%
  \pgfpointxyz{\gbx*(.9+\gbz/20)}{\gby*(.9+\gbz/20)}{\gbz*(1+\gbx/10+\gby/10)}%
}

\tikzset{wrapping paper/.style={
    bottom color=red!75!black, top color=red!50!black,
  },
  ribbon/.style={
    bottom color=yellow!75!orange, top color=yellow!50!orange,
  },
  sheen/.style={
    left color=black, right color=white, opacity=0.25
  },
  highlight/.style={
    draw=white,
    opacity=1/100,
    line width=#1,
    line cap=round
  },
  lowlight/.style={
    draw=black,
    opacity=1/80,
    line width=#1,
    line cap=round,
    line join=round
  }
}



\begin{document}

\begin{tikzpicture}

\foreach \l in {1,...,20}
  \path [lowlight=\l/3] 
       (gift box cs:x=-1, y= 1, z=-1) 
    -- (gift box cs:x= 1, y= 1, z=-1) 
    -- (gift box cs:x= 1, y=-1, z=-1) 
    -- (gift box cs:x= 1, y=-1, z=-1)
    -- cycle;



\path [wrapping paper]
     (gift box cs:x=-1, y= 1, z=-1)
  -- (gift box cs:x=-1, y= 1, z=1)
  -- (gift box cs:x= 1, y= 1, z=1)
  -- (gift box cs:x= 1, y=-1, z=1)
  -- (gift box cs:x= 1, y=-1, z=-1)
  -- (gift box cs:x= 1, y= 1, z=-1)
  -- cycle;


\foreach \n/\o in {.25/1, .33/.5}
  \path [ribbon, opacity=\o] 
       (gift box cs:x=1, y=-\n, z=-1)
    -- (gift box cs:x=1, y=-\n, z=1)
    -- (gift box cs:x=1, y= \n, z=1)
    -- (gift box cs:x=1, y= \n, z=-1)
    -- cycle
       (gift box cs:x=-\n, y=1, z=-1)
    -- (gift box cs:x=-\n, y=1, z=1)
    -- (gift box cs:x= \n, y=1, z=1)
    -- (gift box cs:x= \n, y=1, z=-1)
    -- cycle;

\path [sheen]
     (gift box cs:x=1,y=-1,z=-1)
  -- (gift box cs:x=1,y=-1,z=1)
  -- (gift box cs:x=1, y=1,z=1)
  -- (gift box cs:x=1, y=1,z=-1)
  -- cycle;

\path  [sheen]
     (gift box cs:x=-1,y=1,z=-1)
  -- (gift box cs:x=-1,y=1,z=1)
  -- (gift box cs:x=1, y=1,z=1)
  -- (gift box cs:x=1, y=1,z=-1)
  -- cycle;

\begin{scope}

\path [clip]
     (gift box cs:x=-1, y= 1, z=-1)
  -- (gift box cs:x=-1, y= 1, z= 1)
  -- (gift box cs:x= 1, y= 1, z= 1)
  -- (gift box cs:x= 1, y=-1, z= 1)
  -- (gift box cs:x= 1, y=-1, z=-1)
  -- (gift box cs:x= 1, y= 1, z=-1)
  -- cycle;

\foreach \l in {1,...,10}{
  \path [lowlight=\l/3] 
       (gift box cs:x=-1, y= 1, z=1) 
    -- (gift box cs:x=-1, y= 1, z=-1) 
    -- (gift box cs:x= 1, y= 1, z=-1) 
    -- (gift box cs:x= 1, y=-1, z=-1) 
    -- (gift box cs:x= 1, y=-1, z=1)
       (gift box cs:x=1, y=1,z=-1) 
    -- (gift box cs:x=1, y=1,z= 1);

  \path [lowlight=\l/2]
       (gift box cs:x=-1.05, y= 1.05, z=1) 
    -- (gift box cs:x=-1.05, y= 1.05, z=.5)
    -- (gift box cs:x= 1.05, y= 1.05, z=.5)
    -- (gift box cs:x= 1.05, y=-1.05, z=.5)
    -- (gift box cs:x= 1.05, y=-1.05, z=1);
}
\end{scope}


\path [wrapping paper]
     (gift box cs:x=-1.05, y=-1.05, z=1)
  -- (gift box cs:x=-1.05, y= 1.05, z=1)
  -- (gift box cs:x=-1.05, y= 1.05, z=.5)
  -- (gift box cs:x= 1.05, y= 1.05, z=.5)
  -- (gift box cs:x= 1.05, y=-1.05, z=.5)
  -- (gift box cs:x= 1.05, y=-1.05, z=1)
  -- cycle;



\foreach \n/\o in {.33/.5, .25/1}{
  \path [ribbon, opacity=\o]
       (gift box cs:x= 1.05, y=-\n, z=0.5)
    -- (gift box cs:x= 1.05, y=-\n, z=1)
    -- (gift box cs:x=-1.05, y=-\n, z=1)
    -- (gift box cs:x=-1.05, y= \n, z=1)
    -- (gift box cs:x= 1.05, y= \n, z=1)
    -- (gift box cs:x= 1.05, y= \n, z=.5)
    -- cycle;

  \path [ribbon, opacity=\o]
       (gift box cs:y= 1.05, x=-\n, z=0.5)
    -- (gift box cs:y= 1.05, x=-\n, z=1)
    -- (gift box cs:y=-1.05, x=-\n, z=1)
    -- (gift box cs:y=-1.05, x= \n,  z=1)
    -- (gift box cs:y= 1.05, x= \n, z=1)
    -- (gift box cs:y= 1.05, x= \n, z=.5)
    -- cycle;
}


\path [sheen]
     (gift box cs:x=-1.05, y=1.05, z=1)
  -- (gift box cs:x=-1.05, y=1.05, z=0.5)
  -- (gift box cs:x= 1.05, y=1.05, z=0.5)
  -- (gift box cs:x= 1.05, y=1.05, z=1)
  -- cycle;

\path [sheen]
     (gift box cs:x=1.05, y=-1.05, z=1)
  -- (gift box cs:x=1.05, y=-1.05, z=0.5)
  -- (gift box cs:x=1.05, y= 1.05, z=0.5)
  -- (gift box cs:x=1.05, y= 1.05, z=1)
  -- cycle;

\path [sheen]
     (gift box cs:x=-1.05, y=-1.05, z=1)
  -- (gift box cs:x=-1.05, y= 1.05, z=1)
  -- (gift box cs:x= 1.05, y= 1.05, z=1)
  -- (gift box cs:x= 1.05, y=-1.05, z=1)
  -- cycle;

\begin{scope}
\path [clip]
     (gift box cs:x=-1.05, y=-1.05, z=1)
  -- (gift box cs:x=-1.05, y= 1.05, z=1)
  -- (gift box cs:x=-1.05, y= 1.05, z=.5)
  -- (gift box cs:x= 1.05, y= 1.05, z=.5)
  -- (gift box cs:x= 1.05, y=-1.05, z=.5)
  -- (gift box cs:x= 1.05, y=-1.05, z=1)
  -- cycle;

\foreach \l in {1,...,10}{
  \path [highlight=\l/3] 
       (gift box cs:x= 1.05, y= 1.05, z=1) 
    -- (gift box cs:x= 1.05, y=-1.05, z=1) 
    -- (gift box cs:x=-1.05, y=-1.05, z=1) 
    -- (gift box cs:x=-1.05, y= 1.05, z=1)
    -- cycle 
       (gift box cs:x=1.05, y=1.05, z=1) 
    -- (gift box cs:x=1.05, y=1.05, z=0.5);

  \path [lowlight=\l/3]
       (gift box cs:x=-1.05, y= 1.05, z=1) 
    -- (gift box cs:x=-1.05, y= 1.05, z=.5)
    -- (gift box cs:x= 1.05, y= 1.05, z=.5)
    -- (gift box cs:x= 1.05, y=-1.05, z=.5)
    -- (gift box cs:x= 1.05, y=-1.05, z=1);
}
\end{scope}
\end{tikzpicture}

\end{document}

enter image description here

And, with surprisingly little extra work:

enter image description here

Unfortunately, this gift box is empty. Sad faces all round.

(Unless it contains something small that cannot yet be seen).

The (rather pleasing) "texture" that the wrapping seems to have is a result of reducing the size and optimizing the color space of the gif for uploading.

The code (which takes some time to compile) is shown below. The resulting pdf is then processed with gimp to produce the image above:

\documentclass[tikz,border=0.125cm]{standalone}

\tikzset{gift box/.cd,
  x/.store in=\gbx,
  y/.store in=\gby,
  z/.store in=\gbz,
  rotate around z axis/.store in=\gbzaxisrotate,
  x=0,y=0,z=0,  
  rotate around z axis=0
}
\tikzdeclarecoordinatesystem{gift box}{%
  \tikzset{x=(-20:1cm),y=(200:1cm),z=(90:1cm)}%
  \tikzset{gift box/.cd, #1}%
  \pgfmathsin{\gbzaxisrotate}\let\gbsin=\pgfmathresult%
  \pgfmathcos{\gbzaxisrotate}\let\gbcos=\pgfmathresult%
  \pgfmathparse{cos(\gbzaxisrotate)*(\gbx)-sin(\gbzaxisrotate)*(\gby)}\let\gbxa=\pgfmathresult%
  \pgfmathparse{sin(\gbzaxisrotate)*(\gbx)+cos(\gbzaxisrotate)*(\gby)}\let\gbya=\pgfmathresult%
  \pgfpointxyz{\gbxa*(.9+(\gbz)/20)}{\gbya*(.9+(\gbz)/20)}{(\gbz)*(1+\gbxa/10+\gbya/10)}%
}

\tikzset{wrapping paper/.style={
    bottom color=red!75!black, top color=red!50!black,
  },
  ribbon/.style={
    bottom color=yellow!75!orange, top color=yellow!50!orange,
  },
  sheen/.style={
    left color=black, right color=white, opacity=0.25
  },
  sheen inside/.style={
    left color=black, right color=black!50, opacity=0.25
  },
  highlight/.style={
    draw=white,
    opacity=1/100,
    line width=#1,
    line cap=round
  },
  lowlight/.style={
    draw=black,
    opacity=1/80,
    line width=#1,
    line cap=round,
    line join=round
  }
}



\begin{document}


\foreach \i [evaluate={\zangle=-45+mod(\i,18)*5; \lidz=1.25+min(\i,18)*.1;}] in {0,...,35}{
\begin{tikzpicture}[gift box/rotate around z axis=\zangle]

\useasboundingbox [gift box/rotate around z axis=0] 
     (gift box cs:x= 1, y= 1, z=-1)
  -- (gift box cs:x=-1, y= 1, z=-1)
  -- (gift box cs:x=-1, y= 1, z=3)
  -- (gift box cs:x=-1, y=-1, z=3)
  -- (gift box cs:x= 1, y=-1, z=3)
  -- (gift box cs:x= 1, y=-1, z=-1)
  -- cycle;

\foreach \l in {1,...,20}
  \path [lowlight=\l/3] 
       (gift box cs:x=-1, y= 1, z=-1) 
    -- (gift box cs:x= 1, y= 1, z=-1) 
    -- (gift box cs:x= 1, y=-1, z=-1) 
    -- (gift box cs:x= 1, y=-1, z=-1)
    -- cycle;

\path [wrapping paper]
     (gift box cs:x= 1, y= 1, z=-1)
  -- (gift box cs:x=-1, y= 1, z=-1)
  -- (gift box cs:x=-1, y= 1, z=1)
  -- (gift box cs:x=-1, y=-1, z=1)
  -- (gift box cs:x= 1, y=-1, z=1)
  -- (gift box cs:x= 1, y=-1, z=-1)
  -- cycle;


\path [sheen inside]
     (gift box cs:x= 1, y=-1, z=-1)
  -- (gift box cs:x= 1, y=-1, z=1)
  -- (gift box cs:x=-1, y=-1, z=1)
  -- (gift box cs:x=-1, y=-1, z=-1)
  -- cycle;

\path  [sheen inside]
     (gift box cs:x=-1, y= 1, z=-1)
  -- (gift box cs:x=-1, y= 1, z=1)
  -- (gift box cs:x=-1, y=-1, z=1)
  -- (gift box cs:x=-1, y=-1, z=-1)
  -- cycle;

\begin{scope}

\path [clip]
     (gift box cs:x= 1, y= 1, z=-1)
  -- (gift box cs:x=-1, y= 1, z=-1)
  -- (gift box cs:x=-1, y= 1, z=1)
  -- (gift box cs:x=-1, y=-1, z=1)
  -- (gift box cs:x= 1, y=-1, z=1)
  -- (gift box cs:x= 1, y=-1, z=-1)
  -- cycle;

\foreach \l in {1,...,20}
  \path [lowlight=\l/3] 
       (gift box cs:x=-1, y= 1, z=1) 
    -- (gift box cs:x=-1, y=-1, z=1) 
    -- (gift box cs:x= 1, y=-1, z=1);
\end{scope}

\path [wrapping paper]
     (gift box cs:x=-1, y= 1, z=-1)
  -- (gift box cs:x=-1, y= 1, z=1)
  -- (gift box cs:x= 1, y= 1, z=1)
  -- (gift box cs:x= 1, y=-1, z=1)
  -- (gift box cs:x= 1, y=-1, z=-1)
  -- (gift box cs:x= 1, y= 1, z=-1)
  -- cycle;


\foreach \n/\o in {.25/1, .33/.5}
  \path [ribbon, opacity=\o] 
       (gift box cs:x=1, y=-\n, z=-1)
    -- (gift box cs:x=1, y=-\n, z=1)
    -- (gift box cs:x=1, y= \n, z=1)
    -- (gift box cs:x=1, y= \n, z=-1)
    -- cycle
       (gift box cs:x=-\n, y=1, z=-1)
    -- (gift box cs:x=-\n, y=1, z=1)
    -- (gift box cs:x= \n, y=1, z=1)
    -- (gift box cs:x= \n, y=1, z=-1)
    -- cycle;

\path [sheen]
     (gift box cs:x=1, y=-1, z=-1)
  -- (gift box cs:x=1, y=-1, z=1)
  -- (gift box cs:x=1, y= 1, z=1)
  -- (gift box cs:x=1, y= 1, z=-1)
  -- cycle;

\path  [sheen]
     (gift box cs:x=-1,y=1,z=-1)
  -- (gift box cs:x=-1,y=1,z=1)
  -- (gift box cs:x=1, y=1,z=1)
  -- (gift box cs:x=1, y=1,z=-1)
  -- cycle;

\begin{scope}

\path [clip]
     (gift box cs:x=-1, y= 1, z=-1)
  -- (gift box cs:x=-1, y= 1, z= 1)
  -- (gift box cs:x= 1, y= 1, z= 1)
  -- (gift box cs:x= 1, y=-1, z= 1)
  -- (gift box cs:x= 1, y=-1, z=-1)
  -- (gift box cs:x= 1, y= 1, z=-1)
  -- cycle;

\foreach \l in {1,...,10}{
  \path [lowlight=\l/3] 
       (gift box cs:x=-1, y= 1, z=1) 
    -- (gift box cs:x=-1, y= 1, z=-1) 
    -- (gift box cs:x= 1, y= 1, z=-1) 
    -- (gift box cs:x= 1, y=-1, z=-1) 
    -- (gift box cs:x= 1, y=-1, z=1)
       (gift box cs:x=1, y=1,z=-1) 
    -- (gift box cs:x=1, y=1,z= 1);

   \path [highlight=\l/3]
        (gift box cs:x=-1, y= 1, z=1) 
     -- (gift box cs:x= 1, y= 1, z=1)
     -- (gift box cs:x= 1, y=-1, z=1);

    \path [lowlight=\l/2]
        (gift box cs:x=-1.05, y= 1.05, z=\lidz-.5) 
     -- (gift box cs:x= 1.05, y= 1.05, z=\lidz-.5)
     -- (gift box cs:x= 1.05, y=-1.05, z=\lidz-.5);
}
\end{scope}

\path [wrapping paper]
     (gift box cs:x=-1.05, y=-1.05, z=\lidz)
  -- (gift box cs:x=-1.05, y= 1.05, z=\lidz)
  -- (gift box cs:x=-1.05, y= 1.05, z=\lidz-.5)
  -- (gift box cs:x= 1.05, y= 1.05, z=\lidz-.5)
  -- (gift box cs:x= 1.05, y=-1.05, z=\lidz-.5)
  -- (gift box cs:x= 1.05, y=-1.05, z=\lidz)
  -- cycle;



\foreach \n/\o in {.33/.5, .25/1}{
  \path [ribbon, opacity=\o]
       (gift box cs:x= 1.05, y=-\n, z=\lidz-.5)
    -- (gift box cs:x= 1.05, y=-\n, z=\lidz)
    -- (gift box cs:x=-1.05, y=-\n, z=\lidz)
    -- (gift box cs:x=-1.05, y= \n, z=\lidz)
    -- (gift box cs:x= 1.05, y= \n, z=\lidz)
    -- (gift box cs:x= 1.05, y= \n, z=\lidz-.5)
    -- cycle;

  \path [ribbon, opacity=\o]
       (gift box cs:y= 1.05, x=-\n, z=\lidz-.5)
    -- (gift box cs:y= 1.05, x=-\n, z=\lidz)
    -- (gift box cs:y=-1.05, x=-\n, z=\lidz)
    -- (gift box cs:y=-1.05, x= \n,  z=\lidz)
    -- (gift box cs:y= 1.05, x= \n, z=\lidz)
    -- (gift box cs:y= 1.05, x= \n, z=\lidz-.5)
    -- cycle;
}


\path [sheen]
     (gift box cs:x=-1.05, y=1.05, z=\lidz)
  -- (gift box cs:x=-1.05, y=1.05, z=\lidz-.5)
  -- (gift box cs:x= 1.05, y=1.05, z=\lidz-.5)
  -- (gift box cs:x= 1.05, y=1.05, z=\lidz)
  -- cycle;

\path [sheen]
     (gift box cs:x=1.05, y=-1.05, z=\lidz)
  -- (gift box cs:x=1.05, y=-1.05, z=\lidz-.5)
  -- (gift box cs:x=1.05, y= 1.05, z=\lidz-.5)
  -- (gift box cs:x=1.05, y= 1.05, z=\lidz)
  -- cycle;

\path [sheen]
     (gift box cs:x=-1.05, y=-1.05, z=\lidz)
  -- (gift box cs:x=-1.05, y= 1.05, z=\lidz)
  -- (gift box cs:x= 1.05, y= 1.05, z=\lidz)
  -- (gift box cs:x= 1.05, y=-1.05, z=\lidz)
  -- cycle;

\begin{scope}
\path [clip]
     (gift box cs:x=-1.05, y=-1.05, z=\lidz)
  -- (gift box cs:x=-1.05, y= 1.05, z=\lidz)
  -- (gift box cs:x=-1.05, y= 1.05, z=\lidz-.5)
  -- (gift box cs:x= 1.05, y= 1.05, z=\lidz-.5)
  -- (gift box cs:x= 1.05, y=-1.05, z=\lidz-.5)
  -- (gift box cs:x= 1.05, y=-1.05, z=\lidz)
  -- cycle;

\foreach \l in {1,...,10}{
  \path [highlight=\l/3] 
       (gift box cs:x= 1.05, y= 1.05, z=\lidz) 
    -- (gift box cs:x= 1.05, y=-1.05, z=\lidz) 
    -- (gift box cs:x=-1.05, y=-1.05, z=\lidz) 
    -- (gift box cs:x=-1.05, y= 1.05, z=\lidz)
    -- cycle 
       (gift box cs:x=1.05, y=1.05, z=\lidz) 
    -- (gift box cs:x=1.05, y=1.05, z=\lidz-.5);

  \path [lowlight=\l/3]
       (gift box cs:x=-1.05, y= 1.05, z=\lidz) 
    -- (gift box cs:x=-1.05, y= 1.05, z=\lidz-.5)
    -- (gift box cs:x= 1.05, y= 1.05, z=\lidz-.5)
    -- (gift box cs:x= 1.05, y=-1.05, z=\lidz-.5)
    -- (gift box cs:x= 1.05, y=-1.05, z=\lidz);
}
\end{scope}
\ifnum\i>17
\path [fill=white,opacity=(\i-17)/7]
     (gift box cs:x=-1.1, y=-1.1, z=\lidz)
  -- (gift box cs:x=-1.1, y= 1.1, z=\lidz)
  -- (gift box cs:x=-1.1, y= 1.1, z=\lidz-.5)
  -- (gift box cs:x= 1.1, y= 1.1, z=\lidz-.5)
  -- (gift box cs:x= 1.1, y=-1.1, z=\lidz-.5)
  -- (gift box cs:x= 1.1, y=-1.1, z=\lidz)
  -- cycle;
\fi
\end{tikzpicture}
}
\end{document}
share|improve this answer
6  
Absolutely stunning! –  maetra Dec 19 '13 at 11:04
    
Wow, that stands out pretty nicely :D –  Manishearth Dec 19 '13 at 11:24
1  
Holy moly that's awesome! –  Pouya Dec 19 '13 at 12:04
6  
Sweet guacamole! This is insanely fantastic! :) –  Paulo Cereda Dec 19 '13 at 12:43
    
Incredibly amazing! –  OSjerick Dec 19 '13 at 23:05

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.