2

I have created a newtcolorbox that has a unique shape defined by a path, and then filled as seen in the code below:

\documentclass[20pt, a4paper]{article}

\usepackage{tcolorbox}
\usepackage{lipsum}

\tcbuselibrary{skins}
\usetikzlibrary{calc}
\usetikzlibrary{shadows}
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}

\definecolor{BaseColor}{HTML}{8533FF}

\newlength{\boxCornerOfset}
\setlength{\boxCornerOfset}{12pt}
\newlength{\boxShadowOfset}
\setlength{\boxShadowOfset}{2mm}

\newtcolorbox{mybox}{
    left=\boxCornerOfset,
    top=\boxCornerOfset,
    bottom=\boxCornerOfset,
    right=\boxCornerOfset,
    skin=enhanced jigsaw,
    sharpish corners,
    drop fuzzy shadow southeast={BaseColor!20!white},
    %frame style={drop shadow},
    %fuzzy shadow={\boxShadowOfset}{-\boxShadowOfset}{0mm}{BaseColor!30!white},
    frame code={%
        \begin{pgfonlayer}{main}
            \draw[line width=4pt,color=BaseColor,fill=BaseColor]($(frame.north west) + (\boxCornerOfset, 0pt)$)
                -- (frame.north east)
                -- ($(frame.south east) + (0pt, \boxCornerOfset)$)
                -- ($(frame.south east) + (-\boxCornerOfset, 0pt)$)
                -- (frame.south west)
                -- ($(frame.north west) + (0pt, -\boxCornerOfset)$)
                -- cycle;

        \end{pgfonlayer}
    },
    interior code={%
        \draw[line width=4pt,color=BaseColor,fill=BaseColor]($(frame.north west) + (\boxCornerOfset, -0pt)$)
                -- ($(frame.north east) + (-0pt, -0pt)$)
                -- ($(frame.south east) + (-0pt, \boxCornerOfset)$)
                -- ($(frame.south east) + (-\boxCornerOfset, 0pt)$)
                -- ($(frame.south west) + (0pt, 0pt)$)
                -- ($(frame.north west) + (0pt, -\boxCornerOfset)$)
                -- cycle;
    }

}

\begin{document}

\begin{mybox}
\begin{center}
{\sffamily\huge\color{white} Testing textbox, bippity!}
\end{center}
\end{mybox}

\end{document}

My problem is that when I try and apply a shadow it doesn't follow the path that I have created and I was wondering if there was a way to correctly lay out the shadow to follow the shape created.

5
  • I see, you have used my advice ;-)
    – user31729
    Sep 5, 2016 at 12:40
  • Yup, it was very useful. I don't imagine this'll be my last post here regarding stuff like this, but I thought best to keep each new issue separate. Sep 5, 2016 at 12:52
  • Please make the code compilable with a document class and an example of a shape with the shadow (even if it's wrong).
    – Alenanno
    Sep 5, 2016 at 14:47
  • I'll do that ASAP, but may not be until tomorrow. Sep 5, 2016 at 14:57
  • @Alenanno the updated example is now present. Sep 5, 2016 at 18:47

1 Answer 1

3

Based on this answer from @JLDiaz you can add on the same path a shadow and control its position with shadow xshift=\boxShadowOfset and shadow yshift=-1.2\boxShadowOfset

\documentclass[20pt, a4paper]{article}

\usepackage{tcolorbox}
\usepackage{lipsum}

\tcbuselibrary{skins}
\usetikzlibrary{calc}
\usetikzlibrary{shadows,shadows.blur}
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}

\definecolor{BaseColor}{HTML}{8533FF}

\newlength{\boxCornerOfset}
\setlength{\boxCornerOfset}{12pt}
\newlength{\boxShadowOfset}
\setlength{\boxShadowOfset}{2mm}

\def\framepath[#1]{\path[#1]($(frame.north west) + (\boxCornerOfset, 0pt)$)
                -- (frame.north east)
                -- ($(frame.south east) + (0pt, \boxCornerOfset)$)
                -- ($(frame.south east) + (-\boxCornerOfset, 0pt)$)
                -- (frame.south west)
                -- ($(frame.north west) + (0pt, -\boxCornerOfset)$)
                -- cycle;}

\newtcolorbox{mybox}{enhanced,
    left=\boxCornerOfset,
    top=\boxCornerOfset,
    bottom=\boxCornerOfset,
    right=\boxCornerOfset,
    skin=enhanced jigsaw,
    sharpish corners,
    frame code={%
        \begin{pgfonlayer}{main}
         \framepath[fill=BaseColor,blur shadow={shadow xshift=\boxShadowOfset, shadow yshift=-1.2\boxShadowOfset, shadow blur steps=6}]
         \end{pgfonlayer}
        },
    interior code={%
        \draw[line width=4pt,color=BaseColor,fill=BaseColor]($(frame.north west) + (\boxCornerOfset, -0pt)$)
                -- ($(frame.north east) + (-0pt, -0pt)$)
                -- ($(frame.south east) + (-0pt, \boxCornerOfset)$)
                -- ($(frame.south east) + (-\boxCornerOfset, 0pt)$)
                -- ($(frame.south west) + (0pt, 0pt)$)
                -- ($(frame.north west) + (0pt, -\boxCornerOfset)$)
                -- cycle;
    },
  }

\begin{document}

\begin{mybox}
\begin{center}
{\sffamily\huge\color{white} Testing textbox, bippity!}
\end{center}
\end{mybox}

\end{document}

Result

enter image description here

If you want to modify the color of shadow you can adjust the code of render blur shadow defined like this

Code

\documentclass[20pt, a4paper]{article}

\usepackage{tcolorbox}
\usepackage{lipsum}

\tcbuselibrary{skins}
\usetikzlibrary{calc}
\usetikzlibrary{shadows,shadows.blur}
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}

\definecolor{BaseColor}{HTML}{8533FF}

\newlength{\boxCornerOfset}
\setlength{\boxCornerOfset}{12pt}
\newlength{\boxShadowOfset}
\setlength{\boxShadowOfset}{2mm}


% change color of shadow 
\makeatletter
\tikzset{
render blur shadow/.code=
{\pgfbs@savebb
\pgfsyssoftpath@getcurrentpath{\pgfbs@input@path}%
\pgfbs@compute@shadow@bbox
\pgfbs@process@rounding{\pgfbs@input@path}{\pgfbs@fadepath}%
\pgfbs@apply@canvas@transform
\colorlet{pstb@shadow@color}{white!\pgfbs@opacity!black}%
\pgfdeclarefading{shadowfading}{\pgfbs@paint@fading}%
\pgfsetfillcolor{BaseColor}%
\pgfsetfading{shadowfading}%
{\pgftransformshift{\pgfpoint{\pgfbs@midx}{\pgfbs@midy}}}%
\pgfbs@usebbox{fill}%
\pgfbs@restorebb
},}
\makeatother

\def\framepath[#1]{\path[#1]($(frame.north west) + (\boxCornerOfset, 0pt)$)
                -- (frame.north east)
                -- ($(frame.south east) + (0pt, \boxCornerOfset)$)
                -- ($(frame.south east) + (-\boxCornerOfset, 0pt)$)
                -- (frame.south west)
                -- ($(frame.north west) + (0pt, -\boxCornerOfset)$)
                -- cycle;}

\newtcolorbox{mybox}{enhanced,
    left=\boxCornerOfset,
    top=\boxCornerOfset,
    bottom=\boxCornerOfset,
    right=\boxCornerOfset,
    skin=enhanced jigsaw,
    sharpish corners,
    frame code={%
        \begin{pgfonlayer}{main}
            \framepath[draw=BaseColor,blur shadow={shadow xshift=\boxShadowOfset, shadow yshift=-1.2\boxShadowOfset, shadow blur steps=6,fill=red}]
         \end{pgfonlayer}
                },
    interior code={%
            \framepath[fill=BaseColor]
                  },
     }

\begin{document}

\begin{mybox}
\begin{center}
{\sffamily\huge\color{white} Testing textbox, bippity!}
\end{center}
\end{mybox}

\end{document}

enter image description here

8
  • Thank you, this is what I was looking for. Now to be awkward: Is there a way to recolour the shadow? I found a manual for pgf-blur, but it didn't give any indication on how to recolour the shadow, is this even possible? I'm trying to replicate a very specific style as close as possible. Sep 6, 2016 at 12:19
  • @JakeConkerton-Darby: One may argue that the previous version with the blurred shadow provided a more realistic view. The purple like shadow is not really convincing, but this is your design decision
    – user31729
    Sep 6, 2016 at 13:19
  • Is it not possible to have a blurred shadow for which a base colour is defined? As in use red fading to white instead of dark grey fading to black? Sep 6, 2016 at 13:23
  • To modify shadow color if shadow.blur is used you must patch the code of render blur shadow
    – Salim Bou
    Sep 6, 2016 at 14:25
  • @SalimBou That looks great, I'll test that as soon as I am able, and then probably check this answer as accepted. Sep 7, 2016 at 7:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .