[Tex/LaTex] Draw custom frame around text

beamerframedtikz-pgf

I would like to obtain a custom frame, which is different from the ones given by mdframed.

Here is the image comes from the package fancytikzposter, which consists in a minipage inside a tikzpicture environment.

This works great, but I can't create a figure in this frame since it is inside a tikzpicture environment.

Is there some solution for this, or any possibility to construct it outside the TikZ environment ?

Ideally, I am looking for something in the following form :

\begin{block}{Block title}
\end{block}

Package

Here is (the graphical part of) the code producing this frame

  %% the content of the block
  \draw let \p1=($(#4)-(2.2,0)$),\p2=($(0,\blocktitleheight cm)-(0,0.5cm)$) in
  node[draw, anchor=north, color=blocktitlefillcolor, fill=blockfillcolor,
  text=blocktextcolor, framefour, rectangle]
  (box) at #1 {
    \begin{minipage}{\x1}
      \vspace{\y2}

      \color{blocktextcolor}
      #3
    \end{minipage}};

  %% the title of the block
  \begin{scope}
    \clip[rounded corners=20] ($(box.south west)+(0.01,0.01)$) rectangle
    ($(box.north east)-(0.01,0.01)$);

    \draw let \p1=($(#4)-(3.2,0)$),\p2=($(0,\blocktitleheight cm)-(0,0.4cm)$)%
    in node[anchor=bottom right corner, draw=none, %
    bottom color=blocktitlefillcolor, top color=blocktitlefillcolor!85!,
    text=blocktitletextcolor, rounded corners=20, inner xsep=1cm, %
    minimum height=\y2, minimum width=\x1, %
    shape=trapezium, shape border rotate=180, trapezium stretches=true]
    (boxtitle) at ($(box.north west)+(1.5,0)$) {\bf\LARGE #2}

    %% fading on top
    [preaction={path fading=south,fill=blocktitlefillcolor,opacity=.4},draw=none]
    ($(boxtitle.bottom right corner) - (3,\y2)$) rectangle
    ($(boxtitle.bottom left corner)+(3,0)$);
  \end{scope}


  %% decorative drawing on the title
  \begin{scope}[even odd rule]
    \clip[rounded corners=20] ($(boxtitle.bottom right corner)-(-0.2,0.2)$) --
    ($(boxtitle.bottom left corner) -(0.2,0.2)$) -- (boxtitle.top left corner)
    -- (boxtitle.top right corner) -- cycle %
    (box.south west) rectangle (box.north east) ;

    \draw[draw=none, rounded corners=20, %
    bottom color=blocktitlefillcolor, top color=blocktitlefillcolor!85!]
    ($(boxtitle.bottom right corner)-(0.5,0)$) --
    (boxtitle.bottom right corner) -- (boxtitle.top right corner) --
    ($(boxtitle.bottom right corner)+(3,0)$) --
    ($(boxtitle.bottom right corner)-(0.5,0)$)

    ($(boxtitle.bottom left corner)+(0.5,0)$) --
    (boxtitle.bottom left corner) -- (boxtitle.top left corner) --
    ($(boxtitle.bottom left corner)-(3,0)$) --
    ($(boxtitle.bottom left corner)+(0.5,0)$) ;
  \end{scope}

}

Best Answer

Here's one possibility using tcolorbox:

\documentclass{article}
\usepackage[svgnames]{xcolor}
\usepackage{tikz}
\usetikzlibrary{shadows,calc}
\usepackage{tcolorbox}
\tcbuselibrary{skins,theorems,breakable}
\usepackage{lipsum}

\definecolor{myblue}{RGB}{40,96,139}


\tcbset{
mybox/.style={
  breakable,
  enhanced standard,
  boxrule=0.4pt,titlerule=-0.2pt,drop fuzzy shadow,
  width=\linewidth,
  title style={top color=myblue!30,bottom color=myblue!0.5},
  overlay unbroken and first={
    \path[fill=myblue]
    ([xshift=5pt,yshift=-\pgflinewidth]frame.north west) to[out=0,in=180] ([xshift=20pt,yshift=-5pt]title.south west) -- ([xshift=-20pt,yshift=-5pt]title.south east) to[out=0,in=180] ([xshift=-5pt,yshift=-\pgflinewidth]frame.north east) -- cycle;
  },
  fonttitle=\Large\bfseries\sffamily,
  fontupper=\sffamily,
  fontlower=\sffamily,
  before=\par\medskip\noindent,
  after=\par\medskip,
  center title,
  toptitle=3pt,
  top=11pt,topsep at break=-5pt,
  colback=white
}}

\newtcolorbox{MyBlock}[2][\linewidth]{mybox,width=#1,title=#2}

\begin{document}

\begin{MyBlock}{Some Variable Width Block}
\lipsum[4]
\end{MyBlock}

\begin{MyBlock}[.5\linewidth]{Some Title}
\lipsum[4]
\end{MyBlock}

\end{document}

enter image description here

The MyBlock environment has a mandatory argument for the title, and an optional one for the width (default width=\linewidth).

And here's an idea of the same environment, but using this time the mdframed package (in its current form, only titles spanning no more than one line are allowed):

\documentclass{article}
\usepackage[latin]{babel}
\usepackage[svgnames]{xcolor}
\usepackage[framemethod=tikz]{mdframed}
\usepackage{tikz}
\usetikzlibrary{shadows,calc}
\usepackage{lipsum}

\definecolor{myblue}{RGB}{40,96,139}

\makeatletter
\newenvironment{MiBlock}[2][\linewidth]
  {\begin{mdframed}[
  skipabove=\topsep,
  skipbelow=\topsep,
  roundcorner=5pt,
  shadow=true,
  shadowsize=4pt,
  frametitle=\phantom{#2},
  frametitlebelowskip=15pt,
  font=\sffamily,
  innerleftmargin=12pt,
  innerrightmargin=12pt,
  frametitlefont=\Large\sffamily\bfseries\color{white},
  singleextra={
  \path[top color=myblue!30,bottom color=myblue!0.5,rounded corners]
    ([xshift=\pgflinewidth,yshift=-\pgflinewidth]O|-P) rectangle
    ([xshift=-\pgflinewidth,yshift=-20pt]P) -- cycle;
  \path[fill=myblue]
    ([xshift=5pt,yshift=-\pgflinewidth]O|-P.north west) to[out=0,in=180]
    ([xshift=20pt,yshift=-25pt]O|-P.north west) --
    ([xshift=-20pt,yshift=-25pt]P.south east) to[out=0,in=180]
    ([xshift=-5pt,yshift=-\pgflinewidth]P.north east) -- cycle;
  \path let \p1=(P), \p2= (O) in 
    node at ([yshift=-12pt]0.5*\x1+0.5*\x2,\y1) {\parbox{\dimexpr\mdf@userdefinedwidth@length-40pt\relax
}{\centering\mdf@frametitlefont#2}};
  },
  userdefinedwidth=#1]}
  {\end{mdframed}}
\makeatother

\begin{document}

\begin{MiBlock}{Some Variable Width Block}
\lipsum[2]
\end{MiBlock}

\begin{MiBlock}[0.5\linewidth]{Some Title}
\lipsum[2]
\end{MiBlock}

\end{document}

enter image description here