# How can we display fireworks?

Soon we can celebrate the New Year. How can we use TikZ for drawing fireworks? For example like this, photographed by Kurume-Shimin, found on Wikipedia:

Click on Image search for getting further impressions. On the Wikipedia page you can see further effects, just click the image. I would like to post a nice drawing on our blog for celebrating New Year, and as addition to the TikZ example gallery on this occasion.

• Dec 29, 2016 at 20:14
• Inspiration: Fireworks fractals Dec 30, 2016 at 21:26
• If the Fireworks fractals link doesn't work for you, try this one (it should be the same search) Jan 3, 2017 at 14:38
• I wish @Malipivo had finished his project (cf. tex.stackexchange.com/q/161287/34551 ), so that we could have some firework of math equations! Jan 4, 2017 at 18:32

Here is my take:

Update: More "bling bling", more compilation time... (and trying @Stefan's brilliant idea)

Update 2 Thanks to Stefan, I have seen that the previous version was only working in the QtikZ environment but nowhere(I guess) else. For some reason beyond me, the fadings are still not displayed correctly in Adobe Reader but at least it works (almost) properly in SumatraPDF on Windows. Sorry for the inconvenience and Happy New Year everyone!

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,decorations.pathmorphing}

\begin{document}
\begin{tikzpicture}[projectile/.style={decorate,decoration={random steps,segment length=2pt,amplitude=0.5pt}}]
\fill[black] (-4,-3) rectangle (6,4);

\begin{scope}[xshift=0cm,yshift=-0.4cm,transparency group]
\foreach \x in {0,10,..., 360}{\draw[blue!80!white,projectile,line width=1.1pt] (0,0) to [in=90] (10*rand+\x:rand*1mm+2cm);};
\end{scope}

\begin{scope}[xshift=2cm,yshift=1cm]
\foreach \x in {0,12,..., 360}{\draw [yellow!5,thick,projectile] (0.7,0) to  (3*rand+\x :1mm*rand+2.2cm)  node%
\end{scope}

\begin{scope}[xshift=3cm,yshift=-1cm]
\foreach \x in {0,10,..., 360}{\def\r1{rand}\draw [yellow]  ($(0,0)!abs{\r1}!(\x :5mm)$) to [in=90] ($(0,0)!abs{\r1}+0.2!(\x :8mm)$);}
\end{scope}

\begin{scope}[xshift=-1cm,yshift=1.5cm]
\foreach \x in {0,12,..., 360}{\def\r2{rand}\draw [red,line width=0.5pt]  ($(0,0)!abs{\r2}!(\x :3mm)$) -- ($(0,0)!abs{\r2}+0.1!(\x :7mm)$);}
\end{scope}
\end{tikzpicture}
\end{document}


and the updated code gives (see the history for the previous code)

• Fading is a very good idea here ! Dec 28, 2011 at 18:39
• Same is your coloring scheme. I loved it! Dec 28, 2011 at 18:42
• Incredible, the first one is beautiful and the second one is very realistic! Is fading of projectile paths possible, instead of for example the homogeneous blue? Dec 29, 2011 at 0:31
• I think this is the best one.
– user10274
Dec 29, 2011 at 13:14
• In TL2015 and adobe reader X the spots on the (near-)white firework aren't as pretty as in the above image. It looks like the tranpsarency isn't working properly as they have a black halo. Removing color(20mm)=(pgftransparent!100) from line 5, or replacing the 20mm with 5.1mm helps a lot but doesn't fix it Jan 3, 2017 at 15:38

Update 4 : it's better with more rays and I add a decoration (Stephan's idea) but the result is aleatory. I change some arguments. With some shading in the center (idea from percusse and bloodworks):

\documentclass{minimal}
\usepackage[dvipsnames,svgnames]{xcolor}
\usepackage{tikz}
\usetikzlibrary{calc}

\usetikzlibrary{decorations,decorations.pathmorphing}

\begin{document}

\begin{tikzpicture}[decoration={bent,aspect=.3}]
\draw[fill=black] (-8,-3) rectangle (8,5);
\foreach \colA/\colB/\sx/\sy in {red/yellow/-4/2,blue/green/-2/1,
yellow/red/0/2,green/blue/4/2,yellow/white/3/1.5}
{%
\pgfmathparse{rnd}
\let\ri\pgfmathresult
\begin{scope}[xshift=\sx]
\foreach \i in {0,...,150}{%
\pgfmathparse{rnd}
\global\let\x\pgfmathresult
\pgfmathparse{rnd}
\global\let\y\pgfmathresult
\pgfmathparse{rnd}
\let\c\pgfmathresult
\pgfmathsetmacro{\col}{50*\c+50}
\draw[decorate,\colA!\col!\colB] %
($(360*\x:2*\ri*\y+1) +(\sx,\sy)$) to    ($(360*\x:1*\y) + (\sx,\sy)$);}
\end{scope}
}
\end{tikzpicture}
\end{document}


• Very nice already! Perhaps adding a path morphing decoration would be nice, such as by \begin{tikzpicture}[decoration={bent,aspect=.3}] and \draw[decorate,\colA!\col!\colB] however modified for bending in one direction (wind effect). Dec 28, 2011 at 18:11
• Yes there are some possible modifications. Dec 28, 2011 at 18:25
• Very nice! Maybe using \colA for the inner color option would make it even nicer! Dec 28, 2011 at 20:17
• I try but the result was not fine Dec 28, 2011 at 20:20

Happy New Year to all friends in TEX.SX.

This code stands on the ideas from Cmhughes and Bloodworks. I am disappointed that latex isn't allowing me to add sound:

\documentclass{article}
\usepackage{filecontents}%
\begin{filecontents*}{beam.tex}
\documentclass[tikz]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing,decorations.shapes,backgrounds}

\begin{document}

{
\begin{tikzpicture}
% background rectangle
\filldraw[black] (-3,-3) rectangle (5,3);
\foreach \x in {-2,-.5,2.3,4}{
\pgfmathrandominteger{\y}{0}{2.9}
\node[xshift=5*rnd,blue!\pgfmathresult!white,scale={.8*rnd}]at (\x,\y){$\star$};
}
\draw[blue!\pgfmathresult!black,decorate, decoration={random steps,segment length=3pt,amplitude=.5pt},ultra thin] (0.5 , -2.9)--(0,0);
\fi
\foreach \angle in {0,10,...,360}
{
\draw[red!\pgfmathresult!black,,decorate, decoration={random steps,segment length=1pt,amplitude=.3pt}] (0,0) -- (\angle:\radius mm)node[white!\pgfmathresult!blue, yshift=-.1mm,scale=.35*rnd]{*};
}
\fi
%%%
\draw[xshift=1cm,yshift=1cm,red!\pgfmathresult!black,decorate, decoration={random steps,segment length=3pt,amplitude=.5pt},ultra thin] (1 , -3.9)--(0,0);
\fi\fi
\foreach \angle in {0,20,...,360}
{
\draw[xshift=1cm,yshift=1cm,orange!\pgfmathresult!black,decorate, decoration={random steps,segment length=1pt,amplitude=.3pt}] (0,0) -- (\angle:\radius mm -4mm)node[white!\pgfmathresult!blue, yshift=-.1mm,scale=.5*rnd]{*};
}
\foreach \angle in {10,30,...,350}{
\draw[xshift=1cm,yshift=1cm,red!\pgfmathresult!black,decorate, decoration={random steps,segment length=1pt,amplitude=.5pt}] (0,0) -- (\angle:\radius mm -5mm)node[red!\pgfmathresult!black, yshift=-.1mm,scale=.5*rnd]{*};
}
\foreach \angle in {15,35,...,355}{
\draw[xshift=1cm,yshift=1cm,yellow!\pgfmathresult!black,decorate, decoration={random steps,segment length=1pt,amplitude=.5pt},opacity=.5] (0,0) -- (\angle:\radius mm -6mm)node[white!\pgfmathresult!black, yshift=-.1mm,scale=.5*rnd,opacity=1]{*};
}
\foreach \angle in {5,25,...,355}{
\draw[xshift=1cm,yshift=1cm,green!\pgfmathresult!black,decorate, decoration={random steps,segment length=1pt,amplitude=.5pt},opacity=.5] (0,0) -- (\angle:\radius mm -3mm)node[orange!\pgfmathresult!black, yshift=-.1mm,scale=.5*rnd,opacity=1]{*};
}
\fi
% yellow firework
\draw[xshift=3cm,yshift=1.5cm,blue!\pgfmathresult!black,decorate, decoration={random steps,segment length=3pt,amplitude=.5pt},ultra thin] (1 , -4.5)--(0,0);
\fi\fi
\foreach \angle in {0,10,...,360}
{
\draw[xshift=3cm,yshift=1.5cm,yellow!\pgfmathresult!black,decorate, decoration={random steps,segment length=2pt,amplitude=.5pt},opacity=.5] (0,0) -- (\angle:\radius mm -8mm)node[orange!\pgfmathresult!black, yshift=-.1mm,scale=.8*rnd,opacity=1]{*};
}
\fi
% blue green firework
\draw[xshift=-1.5cm,yshift=1.5cm,green!\pgfmathresult!black,decorate, decoration={random steps,segment length=3pt,amplitude=.5pt},ultra thin] (-1, -4.5)--(0,0);
\fi\fi
\foreach \angle in {10,20,...,360}
{
\draw[xshift=-1.5cm,yshift=1.5cm,green!\pgfmathresult!black,decorate, decoration={random steps,segment length=2pt,amplitude=.5pt},opacity=.5] (0,0) -- (\angle:\radius mm -8mm)node[red!\pgfmathresult!black, yshift=-.1mm,scale=.8*rnd,opacity=1]{*};
}
\fi
\end{tikzpicture}
}
\end{document}

\end{filecontents*}
%create the beam.pdf.
\immediate\write18{pdflatex beam}
% convert to GIF animation
\immediate\write18{convert -delay 15 -loop 0 -density 200 -alpha remove beam.pdf beam.gif}

\begin{document}
Look for the beam.gif file in the same directory as this file.
\end{document}


Compile it with pdflatex and you should have installed imagemagick for generating .gif file.

• TikZ rules. Nice one.
– user10274
Jan 1, 2013 at 9:44
• Reminds me of the Death Star while destroying planets. Nice work. Jan 1, 2013 at 12:45
• what, no sound? ;-) Very nice!
– GTK
Jan 3, 2013 at 6:43
• A nice animation but firing at the speed of light makes it less realistic. :-) Jan 3, 2013 at 15:41
• @AdorableCreature: OK As you wish. Brakes applied now. Hope you won't chargesheet me for over speeding ;-)
– user11232
Jan 3, 2013 at 16:04

Happy New Year everyone!

\documentclass[tikz]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing,decorations.shapes}

\begin{document}

{
\begin{tikzpicture}
% background rectangle
\filldraw[black] (-3,-3) rectangle (5,3);
% skyline
\filldraw[black!80!blue](-3,-3)--(-3,-2)--(-2.5,-2)--(-2.5,-1)--(-2.25,-1)--(-2.25,-2)--(-2,-2)
--(-2,-1)--(-1.75,-0.75)--(-1.5,-1)
--(-1.5,-2)--(-1.1,-2)--(-1.1,0)--(-0.5,0)--(-0.5,-2)
--(0,-2)--(0,-1.5)--(1,-1.5)--(1.25,-0.5)--(1.5,-1.5)--(1.5,-2)
--(2,-2)--(2,0)--(2.5,0)--(2.5,-2)
--(3,-2)--(3,-1)--(4,-1)--(4,-2)--(5,-2)--(5,-3)--cycle;
% moon- what a hack!
\filldraw[white] (4,2.5) arc (90:-90:20pt);
\filldraw[black] (3.8,2.5) arc (90:-90:20pt);
% fireworks
% red firework
\fi
% orange firework
\draw[decorate,decoration={crosses},orange!\pgfmathresult!black] (1,1) circle ( \radius ex-5ex);
\fi
\fi
% yellow firework
\fi
\end{tikzpicture}
}
\end{document}


The above code will produce a pdf file with each frame. See How to convert pstricks animation to GIF file? for the full details of the remaining two (very easy) steps, which were

pdfcrop myfile.pdf
convert -delay 20 -loop 0 -density 300 myfile-crop.pdf fireworks.gif

• Placing a displaced black disk on a white one seems to be an easier hack to create a crescent. Jan 1, 2013 at 2:33
• @AdorableCreature that's pretty much what I did- hence the, 'what a hack' comment :) happy new year! Jan 1, 2013 at 2:34
• Happy New Year too! Jan 1, 2013 at 2:36

Not quite as smart as the two above but well thats what i have. I (almost) used no commands starting with pgf.

\documentclass[border=5mm]{standalone}

\usepackage{tikz}
\usetikzlibrary{decorations}
\usetikzlibrary{decorations.pathmorphing}

\begin{document}

\begin{tikzpicture}
\draw[fill=black] (-5,-15) rectangle (25,15);
\foreach \mya in {1,10,20}{
\pgfmathrandominteger{\myb}{1}{10}
\foreach \x in {-3.1,-2,-1.1,0.1,1.2,2.3,3.1}{%
\foreach \y in {-3.2,-2.1,-1.2,0,1.1,2,3.2}{%
\draw[red, thick, decorate, decoration={random steps,segment length=3pt,amplitude=1pt}, rotate around={10:(\mya , \myb)}, opacity=0.7](\mya , \myb)--(\mya+\x, \myb+\y)node[red, yshift=-.1mm]{*};%
\draw[blue,decorate, decoration={random steps,segment length=3pt,amplitude=1pt}, rotate around={20:(\mya , \myb)}](\mya , \myb)--(\mya+\x, \myb+\y)node[red, yshift=-.1mm]{*};%
\draw[red!50!yellow, decorate, decoration={random steps,segment length=3pt,amplitude=1pt}, rotate around={50:(\mya , \myb)}](\mya , \myb)--(\mya+\x,  \myb+\y);
}
}
\draw[decorate, decoration=snake, red, thick] (0 , -13)--(\mya , \myb);
}

\end{tikzpicture}
\end{document}


It takes a while to compile!

• I can't look at it without the virtual "Piiuuuuuuw" sound in my head :) Dec 28, 2011 at 22:03

Updated and final version:

The code runs to 856 lines:


\documentclass{article}
\usepackage{tikz}
\usepackage{ifthen}
\usetikzlibrary{calc,decorations.pathmorphing,shapes}
%bursts(rocket/mortar)
\def\burst{
\pgfgettransform{\mycurrenttransform}
\pgfmathdeclarerandomlist{colour}{{\basecolour}{\basecolour!90!black}{\basecolour!80!black}{\basecolour!90!white}{\basecolour!70!\secondcolour}{\basecolour!80!\secondcolour}}
\node [coordinate] at(0,0) (burstpoint){};
\ifthenelse{\equal{\smoke}{true}}{
}{}
\ifthenelse{\equal{\centreblob}{true}}{
\node [circle,minimum width=\centreblobwidth, minimum height=\centreblobwidth, inner sep=0mm,fill=\centreblobcolour,opacity=.5,outer sep=0] at (0,0){};
}{}
\foreach \x in {\anglemin,\angletwo,...,\anglemax}{%
\pgfmathrandomitem{\c}{colour}%
\def\r{3*rand+\x}%
\def\d{1mm*rand+\burstwidth}%
\def\inangle{90+rand*30}
\draw [draw=\c] (burstpoint) to  [out=\r,in=\inangle] (\r:\d) {} node [coordinate, inner sep=0, outer sep =0] (end\x){};
\begin{scope}[transparency group]
\foreach \y in {\bursttwoanglemin,\bursttwoangletwo,...,\bursttwoanglemax}{
\ifthenelse{\equal{\bursttwo}{true}}{
\ifthenelse{\equal{\smoke}{true}}{
\pgfsetfading{fadeit}{\pgfsettransform{\mycurrenttransform}\pgftransformshift{\pgfpointanchor{end\x}{center}}\pgftransformscale{0.3}};\fill[\smokecolour,opacity=.4] ($(end\x)+(-\burstwidth,-\burstwidth)$) rectangle ($(end\x)+(\burstwidth,\burstwidth)$);%shading
}{}
\draw [draw=\c,projectiletwo,line width=0.5pt]  ($(end\x.center)$) -- ($(end\x.center)+(\y :\bursttwowidthrandom*rand+\bursttwowidth)$);

}{}
}
\end{scope}

\ifthenelse{\equal{\endblob}{true}}{
\node [circle,minimum width=\endblobwidth, minimum height=\endblobwidth, inner sep=0mm,fill=\endblobcolour,opacity=1,outer sep=0] at (end\x){};
}{}
}
}
%roman candle
\def\candle{
\pgfmathdeclarerandomlist{colour}{{\basecolour}{\basecolour!90!white}{\basecolour!80!white}{\basecolour!80!green}{\basecolour!80!red}{\basecolour!80!blue}}
\node [coordinate] at(0,0)(basepoint){};
\node [coordinate]at(0,0.5*\candleheight) (smokepoint){};
\foreach \x in {\candleanglemin,\candleangletwo,...,\candleanglemax}{%
\pgfmathrandomitem{\c}{colour}
\def\r{rand*\candleheightrandom+\candleheight}
\def\xx{5*rnd+\x}
\node[coordinate] at ($(0,0)+(\xx:\r)$) (endpoint){};
\draw[draw=\c,line width=0.5] (0,0) to [out=\x,in=90] (endpoint);%
}
\ifthenelse{\equal{\smoke}{true}}{
\fill[\smokecolour] [draw=none, line width=0.5,smooth cycle] (0,0) to (\candleanglemax+10:\candleheight*2) to ($(\candleanglemin/2+\candleanglemax/2,\candleheight*2)$) to (\candleanglemin-7:\candleheight*2) to (0,0);
}{}
}
%cloud
\def\cloud{
\pgfgettransform{\mycurrenttransform}
\node[coordinate] at(0,0)(cloudpoint){};
\node[cloud, cloud puffs=10, cloud puff arc=60,cloud ignores aspect, minimum width=\cloudwidth, minimum height=\cloudheight, align=center, draw=none, fill=\cloudcolour, fill opacity=.4] (cloud) at (cloudpoint) {};
}
%flame
\def\flame{
\pgfgettransform{\mycurrenttransform}
\path(0,0) pic{flame};
}
%based on raindrop@  http://tex.stackexchange.com/a/195642/28808
\tikzset{%
flame/.pic={
code={\tikzset{scale=1/10}
\clip [preaction={top color=red!80, bottom color=red!40!yellow}]
(0,0)  .. controls ++(0,-1) and ++(0,1) .. (1,-2)
arc (360:180:1)
.. controls ++(0,1) and ++(0,-1) .. (0,0) -- cycle ;
\foreach \j in {1,3,...,20}
\shade [top color=red, shift=(270:0), xscale=1-\j/40,yscale=1-\j/80, red!50!yellow, opacity=1/8]
[rotate=-\j] (0,0)  .. controls ++(0,-1) and ++(0,1) .. (1,-2)
arc (360:180:1)
.. controls ++(0,1) and ++(0,-1) .. (0,0) -- cycle;
}}}
%rocket trail
\pgfdeclaredecoration{irregular fractal line}{init}
{
\state{init}[width=\pgfdecoratedinputsegmentremainingdistance]
{
\pgfpathcircle{\pgfpoint{random*\pgfdecoratedinputsegmentremainingdistance}{(random*\pgfdecorationsegmentamplitude-0.02)*\pgfdecoratedinputsegmentremainingdistance}}{.5pt}\pgfusepath{fill};
}
}
\tikzset{
trail/.style={decoration={irregular fractal line, amplitude=0.2},
decorate}
}

\begin{document}
\pgfmathsetseed{1}
\begin{tikzpicture}[projectile/.style={decorate,decoration={random steps,segment length=2pt,amplitude=0.5pt}}, projectiletwo/.style={decorate,decoration={random steps,segment length=2pt,amplitude=0.2pt}}]
\fill[black] (-6,-5) rectangle (9,8);
\clip (-6,-5) rectangle (9,8);
%rockets with trails of sparks
\def\trailcolour{white}
\def\launchangle{80}
\begin{scope}
\pgfsetfillcolor{\trailcolour}
\draw [draw=\trailcolour] {decorate[trail]{decorate[decoration={random steps, segment length=2pt, amplitude=1pt}]{
(-3cm,-2.6cm) to [out=\launchangle+rand*5, in=300+rand*15] (-3cm,5cm)
}}};
\draw [draw=\trailcolour] {decorate[trail]{decorate[decoration={random steps, segment length=2pt, amplitude=1pt}]{
(5cm,-2.6cm) to [out=\launchangle+rand*5, in=300+rand*15] (5cm,5cm)
}}};
\draw [draw=\trailcolour] {decorate[trail]{decorate[decoration={random steps, segment length=2pt, amplitude=1pt}]{
(1cm,-2.6cm) to [out=\launchangle+rand*5, in=300+rand*15] (1cm,6cm)
}}};
\end{scope}
\def\basecolour{red}
\def\secondcolour{red!50!yellow}
\def\smoke{true}
\def\bursttwo{true}
\def\bursttwoanglemin{0}
\def\bursttwoangletwo{60}
\def\bursttwoanglemax{359}
\def\bursttwowidth{2mm}
\def\bursttwowidthrandom{1.5mm}
\def\smokecolour{gray}
\def\burstwidth{1.7cm}
\def\anglemin{0}
\def\angletwo{10}
\def\anglemax{359}
\def\endblob{false}
\def\endblobwidth{2mm}
\def\endblobcolour{red}
\def\centreblob{false}
\def\centreblobwidth{0.75cm}
\def\centreblobcolour{yellow}
\begin{scope}[xshift=1cm, yshift=6cm]
\burst
\def\anglemin{5}
\def\angletwo{15}
\def\anglemax{359}
\def\smoke{false}
\def\centreblob{true}
\burst
\end{scope}
\def\basecolour{magenta}
\def\secondcolour{red!40!white}
\def\smoke{true}
\def\bursttwo{false}
\def\bursttwoanglemin{0}
\def\bursttwoangletwo{60}
\def\bursttwoanglemax{359}
\def\bursttwowidth{2mm}
\def\bursttwowidthrandom{1.5mm}
\def\smokecolour{gray!50!magenta}
\def\burstwidth{1.7cm}
\def\anglemin{0}
\def\angletwo{10}
\def\anglemax{359}
\def\endblob{true}
\def\endblobwidth{2mm}
\def\endblobcolour{magenta}
\def\centreblob{false}
\def\centreblobwidth{0.75cm}
\def\centreblobcolour{magenta!50!white}
\begin{scope}[xshift=-3cm, yshift=5cm]
\burst
\def\anglemin{5}
\def\angletwo{15}
\def\anglemax{359}
\def\smoke{false}
\def\centreblob{true}
\burst
\end{scope}
\def\basecolour{blue}
\def\secondcolour{cyan}
\def\smoke{true}
\def\bursttwo{false}
\def\bursttwoanglemin{0}
\def\bursttwoangletwo{60}
\def\bursttwoanglemax{359}
\def\bursttwowidth{2mm}
\def\bursttwowidthrandom{1.5mm}
\def\smokecolour{gray!50!blue}
\def\burstwidth{1.7cm}
\def\anglemin{0}
\def\angletwo{10}
\def\anglemax{359}
\def\endblob{true}
\def\endblobwidth{2mm}
\def\endblobcolour{cyan}
\def\centreblob{false}
\def\centreblobwidth{0.75cm}
\def\centreblobcolour{blue!50!white}
\begin{scope}[xshift=5cm, yshift=5cm]
\burst
\def\anglemin{5}
\def\angletwo{15}
\def\anglemax{359}
\def\smoke{false}
\def\centreblob{true}
\burst
\end{scope}
%roman candles. Up to 5 candles/colour at 2 positions
%reflections in water: 4 per colour
%red
\tikzset{romanstyle/.style={line width=0.5}}
\tikzset{romansmokestyle/.style={draw=none}}
\def\basecolour{red}
\def\candleanglemin{80}
\def\candleangletwo{82}
\def\candleanglemax{100}
\def\candleheight{2cm}
\def\candleheightrandom{5mm}
\def\smoke{true}
\def\smokecolour{red}
\def\cloudwidth{1.5cm}
\def\cloudheight{0.6cm}
\begin{scope}[xshift=-2.1cm,yshift=-2.8cm,opacity=0.5]
\candle
\flame
\end{scope}
\def\basecolour{yellow}
\def\candleanglemin{86}
\def\candleangletwo{88}
\def\candleanglemax{96}
\def\candleheight{1.5cm}
\def\smoke{false}
\def\cloudwidth{1.5cm}
\def\cloudheight{0.6cm}
\begin{scope}[xshift=-2.1cm,yshift=-2.8cm,opacity=0.3]
\candle
\end{scope}
%reflection
\begin{scope}[xshift=-2.1cm, yshift=-3.8cm]
\def\candleheight{2cm}
\def\candleheightrandom{0cm}
\def\basecolour{red}
\def\candleanglemin{280}
\def\candleangletwo{278}
\def\candleanglemax{260}
\def\smoke{false}
\tikzset{romanstyle/.style={line width=0.5,decorate,opacity=0.3, decoration={snake,amplitude=.1mm+rand*0.05mm,segment length=2mm+rand*0.5mm}}}
\candle
\def\basecolour{yellow}
\def\candleanglemin{274}
\def\candleangletwo{276}
\def\candleanglemax{264}
\tikzset{romanstyle/.style={line width=0.5,decorate,opacity=0.2, decoration={snake,amplitude=.1mm+rand*0.05mm,segment length=2mm+rand*0.5mm}}}
\candle
\end{scope}
\def\basecolour{red}
\def\candleanglemin{80}
\def\candleangletwo{82}
\def\candleanglemax{100}
\def\candleheight{2cm}
\def\smoke{true}
\begin{scope}[xshift=-2cm,yshift=-3cm]
\candle
\flame
\end{scope}
\def\basecolour{yellow}
\def\candleanglemin{86}
\def\candleangletwo{88}
\def\candleanglemax{96}
\def\candleheight{1.5cm}
\def\smoke{false}
\def\cloudwidth{1.5cm}
\def\cloudheight{0.6cm}
\begin{scope}[xshift=-2cm,yshift=-3cm,opacity=0.5]
\candle
\end{scope}
\def\basecolour{yellow!50!white}
\def\candleanglemin{88}
\def\candleangletwo{90}
\def\candleanglemax{94}
\def\candleheight{1.2cm}
\def\smoke{false}
\def\cloudwidth{1.2cm}
\def\cloudheight{0.6cm}
\begin{scope}[xshift=-2cm,yshift=-3cm,opacity=0.9]
\candle
\end{scope}
\begin{scope}[xshift=-2cm, yshift=-3.6cm]
\def\candleheight{2cm}
\def\candleheightrandom{0cm}
\def\basecolour{red}
\def\candleanglemin{280}
\def\candleangletwo{278}
\def\candleanglemax{260}
\def\smoke{false}
\tikzset{romanstyle/.style={line width=0.5,decorate,opacity=0.3, decoration={snake,amplitude=.1mm+rand*0.05mm,segment length=2mm+rand*0.5mm}}}
\candle
\def\basecolour{yellow}
\def\candleanglemin{274}
\def\candleangletwo{276}
\def\candleanglemax{264}
\tikzset{romanstyle/.style={line width=0.5,decorate,opacity=0.2, decoration={snake,amplitude=.1mm+rand*0.05mm,segment length=2mm+rand*0.5mm}}}
\candle
\end{scope}
%green
\def\candleanglemin{88}
\def\candleangletwo{89}
\def\candleanglemax{105}
\def\basecolour{green!70!white}
\def\smokecolour{green!50!black}
\def\candleheight{2cm}
\def\smoke{true}
\begin{scope}[xshift=-.1cm,yshift=-2.8cm,opacity=0.5]
\candle
\flame
\end{scope}
\def\smoke{false}
\def\candleanglemin{92}
\def\candleangletwo{94}
\def\candleanglemax{100}
\def\basecolour{green!20!white}
\begin{scope}[xshift=-.1cm,yshift=-2.8cm,opacity=0.3]
\candle
\end{scope}
\begin{scope}[xshift=-.1cm, yshift=-3.8cm]
\def\candleheight{2cm}
\def\candleheightrandom{0cm}
\def\basecolour{green}
\def\candleanglemin{272}
\def\candleangletwo{271}
\def\candleanglemax{255}
\def\smoke{false}
\tikzset{romanstyle/.style={line width=0.5,decorate,opacity=0.3, decoration={snake,amplitude=.1mm+rand*0.05mm,segment length=2mm+rand*0.5mm}}}
\candle
\def\basecolour{green!20!white}
\def\candleanglemin{268}
\def\candleangletwo{266}
\def\candleanglemax{260}
\tikzset{romanstyle/.style={line width=0.5,decorate,opacity=0.2, decoration={snake,amplitude=.1mm+rand*0.05mm,segment length=2mm+rand*0.5mm}}}
\candle
\end{scope}
\def\smoke{true}
\def\candleanglemin{88}
\def\candleangletwo{89}
\def\candleanglemax{105}
\def\basecolour{green!70!white}
\def\candleheight{2cm}
\begin{scope}[xshift=0cm,yshift=-3cm]
\candle
\flame
\end{scope}
\def\smoke{false}
\def\candleanglemin{92}
\def\candleangletwo{94}
\def\candleanglemax{100}
\def\basecolour{green!20!white}
\def\candleheight{1.5cm}
\begin{scope}[xshift=0cm,yshift=-3cm]
\candle
\end{scope}
\begin{scope}[xshift=0cm, yshift=-3.6cm]
\def\candleheight{2cm}
\def\candleheightrandom{0cm}
\def\basecolour{green}
\def\candleanglemin{272}
\def\candleangletwo{271}
\def\candleanglemax{255}
\def\smoke{false}
\tikzset{romanstyle/.style={line width=0.5,decorate,opacity=0.2, decoration={snake,amplitude=.1mm+rand*0.05mm,segment length=2mm+rand*0.5mm}}}
\candle
\def\basecolour{green!20!white}
\def\candleanglemin{268}
\def\candleangletwo{266}
\def\candleanglemax{260}
\tikzset{romanstyle/.style={line width=0.5,decorate,opacity=0.15, decoration={snake,amplitude=.1mm+rand*0.05mm,segment length=2mm+rand*0.5mm}}}
\candle
\end{scope}
%pink
\def\candleanglemin{88}
\def\candleangletwo{89}
\def\candleanglemax{105}
\def\basecolour{magenta!70!white}
\def\smokecolour{magenta!50!black}
\def\secondcolour{red!50!white}
\def\candleheight{2cm}
\def\smoke{true}
\begin{scope}[xshift=1.9cm,yshift=-2.8cm,opacity=0.5]
\candle
\flame
\end{scope}
\def\smoke{false}
\def\candleanglemin{92}
\def\candleangletwo{94}
\def\candleanglemax{100}
\def\basecolour{magenta!20!white}
\begin{scope}[xshift=1.9cm,yshift=-2.8cm,opacity=0.3]
\candle
\end{scope}
\begin{scope}[xshift=1.9cm, yshift=-3.8cm]
\def\candleheight{2cm}
\def\candleheightrandom{0cm}
\def\basecolour{magenta}
\def\candleanglemin{272}
\def\candleangletwo{271}
\def\candleanglemax{255}
\def\smoke{false}
\tikzset{romanstyle/.style={line width=0.5,decorate,opacity=0.2, decoration={snake,amplitude=.1mm+rand*0.05mm,segment length=2mm+rand*0.5mm}}}
\candle
\def\basecolour{magenta!70!white}
\def\candleanglemin{268}
\def\candleangletwo{266}
\def\candleanglemax{260}
\tikzset{romanstyle/.style={line width=0.5,decorate,opacity=0.15, decoration={snake,amplitude=.1mm+rand*0.05mm,segment length=2mm+rand*0.5mm}}}
\candle
\end{scope}
\def\smoke{true}
\def\candleanglemin{80}
\def\candleangletwo{81}
\def\candleanglemax{100}
\def\basecolour{magenta!70!white}
\def\candleheight{2cm}
\begin{scope}[xshift=2cm,yshift=-3cm]
\candle
\flame
\end{scope}
\def\smoke{false}
\def\candleanglemin{92}
\def\candleangletwo{94}
\def\candleanglemax{100}
\def\basecolour{magenta!20!white}
\def\candleheight{1.5cm}
\begin{scope}[xshift=2cm,yshift=-3cm]
\candle
\end{scope}
\begin{scope}[xshift=2cm, yshift=-3.6cm]
\def\candleheight{2cm}
\def\candleheightrandom{0cm}
\def\basecolour{magenta}
\def\candleanglemin{272}
\def\candleangletwo{271}
\def\candleanglemax{255}
\def\smoke{false}
\tikzset{romanstyle/.style={line width=0.5,decorate,opacity=0.2, decoration={snake,amplitude=.1mm+rand*0.05mm,segment length=2mm+rand*0.5mm}}}
\candle
\def\basecolour{magenta!70!white}
\def\candleanglemin{268}
\def\candleangletwo{266}
\def\candleanglemax{260}
\tikzset{romanstyle/.style={line width=0.5,decorate,opacity=0.15, decoration={snake,amplitude=.1mm+rand*0.05mm,segment length=2mm+rand*0.5mm}}}
\candle
\end{scope}
%blue
\def\secondcolour{cyan}
\def\candleanglemin{82}
\def\candleangletwo{83}
\def\candleanglemax{100}
\def\basecolour{blue!70!cyan}
\def\smokecolour{blue!50!black}
\def\candleheight{2cm}
\def\smoke{true}
\begin{scope}[xshift=3.9cm,yshift=-2.8cm,opacity=0.5]
\candle
\flame
\end{scope}
\def\smoke{false}
\def\candleanglemin{92}
\def\candleangletwo{94}
\def\candleanglemax{100}
\def\basecolour{blue!20!cyan}
\begin{scope}[xshift=3.9cm,yshift=-2.8cm,opacity=0.3]
\candle
\end{scope}
\begin{scope}[xshift=3.9cm, yshift=-3.8cm]
\def\candleheight{2cm}
\def\candleheightrandom{0cm}
\def\basecolour{blue}
\def\candleanglemin{272}
\def\candleangletwo{271}
\def\candleanglemax{255}
\def\smoke{false}
\tikzset{romanstyle/.style={line width=0.5,decorate,opacity=0.2, decoration={snake,amplitude=.1mm+rand*0.05mm,segment length=2mm+rand*0.5mm}}}
\candle
\def\basecolour{blue!20!cyan}
\def\candleanglemin{268}
\def\candleangletwo{266}
\def\candleanglemax{260}
\tikzset{romanstyle/.style={line width=0.5,decorate,opacity=0.15, decoration={snake,amplitude=.1mm+rand*0.05mm,segment length=2mm+rand*0.5mm}}}
\candle
\end{scope}
\def\smoke{true}
\def\candleanglemin{88}
\def\candleangletwo{89}
\def\candleanglemax{105}
\def\basecolour{blue!70!cyan}
\def\candleheight{2cm}
\begin{scope}[xshift=4cm,yshift=-3cm]
\candle
\end{scope}
\def\smoke{false}
\def\candleanglemin{92}
\def\candleangletwo{94}
\def\candleanglemax{100}
\def\basecolour{blue!20!cyan}
\def\candleheight{1.5cm}
\begin{scope}[xshift=4cm,yshift=-3cm]
\candle
\flame
\end{scope}
\begin{scope}[xshift=4cm, yshift=-3.6cm]
\def\candleheight{2cm}
\def\candleheightrandom{0cm}
\def\basecolour{blue}
\def\candleanglemin{272}
\def\candleangletwo{271}
\def\candleanglemax{255}
\def\smoke{false}
\tikzset{romanstyle/.style={line width=0.5,decorate,opacity=0.2, decoration={snake,amplitude=.1mm+rand*0.05mm,segment length=2mm+rand*0.5mm}}}
\candle
\def\basecolour{blue!20!cyan}
\def\candleanglemin{268}
\def\candleangletwo{266}
\def\candleanglemax{260}
\tikzset{romanstyle/.style={line width=0.5,decorate,opacity=0.15, decoration={snake,amplitude=.1mm+rand*0.05mm,segment length=2mm+rand*0.5mm}}}
\candle
\end{scope}
%yellow
\def\candleanglemin{82}
\def\candleangletwo{83}
\def\candleanglemax{100}
\def\basecolour{yellow}
\def\secondcolour{red}
\def\smokecolour{yellow!80!red}
\def\cloudcolour{yellow!80!red}
\def\candleheight{2cm}
\def\smoke{true}
\begin{scope}[xshift=5.9cm,yshift=-2.8cm,opacity=0.5]
\candle
\flame
\end{scope}
\def\smoke{false}
\def\candleanglemin{92}
\def\candleangletwo{94}
\def\candleanglemax{100}
\def\basecolour{yellow!80!red!20!white}
\def\cloudcolour{yellow!80!red}
\begin{scope}[xshift=5.9cm,yshift=-2.8cm,opacity=0.3]
\candle
\end{scope}
\begin{scope}[xshift=5.9cm, yshift=-3.8cm]
\def\candleheight{2cm}
\def\candleheightrandom{0cm}
\def\basecolour{yellow}
\def\candleanglemin{272}
\def\candleangletwo{271}
\def\candleanglemax{255}
\def\smoke{false}
\tikzset{romanstyle/.style={line width=0.5,decorate,opacity=0.2, decoration={snake,amplitude=.1mm+rand*0.05mm,segment length=2mm+rand*0.5mm}}}
\candle
\def\basecolour{yellow!80!red}
\def\candleanglemin{268}
\def\candleangletwo{266}
\def\candleanglemax{260}
\tikzset{romanstyle/.style={line width=0.5,decorate,opacity=0.15, decoration={snake,amplitude=.1mm+rand*0.05mm,segment length=2mm+rand*0.5mm}}}
\candle
\end{scope}
\def\smoke{true}
\def\candleanglemin{88}
\def\candleangletwo{89}
\def\candleanglemax{105}
\def\basecolour{yellow!80!red}
\def\candleheight{2cm}
\begin{scope}[xshift=6cm,yshift=-3cm]
\candle
\flame
\end{scope}
\def\smoke{false}
\def\candleanglemin{92}
\def\candleangletwo{94}
\def\candleanglemax{98}
\def\basecolour{yellow!80!red!20!white}
\def\candleheight{1.5cm}
\begin{scope}[xshift=6cm,yshift=-3cm]
\candle
\end{scope}
\begin{scope}[xshift=6cm, yshift=-3.6cm]
\def\candleheight{2cm}
\def\candleheightrandom{0cm}
\def\basecolour{yellow}
\def\candleanglemin{272}
\def\candleangletwo{271}
\def\candleanglemax{255}
\def\smoke{false}
\tikzset{romanstyle/.style={line width=0.5,decorate,opacity=0.2, decoration={snake,amplitude=.3mm+rand*0.1mm,segment length=2mm+rand*0.5mm}}}
\candle
\def\basecolour{yellow!80!red}
\def\candleanglemin{268}
\def\candleangletwo{266}
\def\candleanglemax{260}
\tikzset{romanstyle/.style={line width=0.5,decorate,opacity=0.15, decoration={snake,amplitude=.3mm+rand*0.1mm,segment length=2mm+rand*0.5mm}}}
\candle
\end{scope}
%mortar bursts 3/colour
%red
\def\basecolour{red!80!yellow}
\def\secondcolour{yellow!80!white}
\def\smoke{true}
\def\bursttwo{false}
\def\bursttwoanglemin{0}
\def\bursttwoangletwo{60}
\def\bursttwoanglemax{359}
\def\smokecolour{red}
\def\burstwidth{1.2cm}
\def\anglemin{0}
\def\anglemax{359}
\def\angletwo{10}
\def\endblob{false}
\def\endblobwidth{2mm}
\def\endblobcolour{red}
\def\centreblob{true}
\def\centreblobwidth{0.5cm}
\def\centreblobcolour{yellow}
\begin{scope}[xshift=-2cm, yshift=1cm,opacity=0.6]
\burst
\end{scope}
\begin{scope}[xshift=-1.8cm,yshift=1.2cm,opacity=0.3]
\burst
\end{scope}
\def\smoke{true}
\def\smokecolour{red}
\def\burstwidth{1.3cm}
\def\anglemin{0}
\def\anglemax{359}
\def\angletwo{10}
\def\centreblob{true}
\def\centreblobwidth{0.5cm}
\def\centreblobcolour{yellow}
\begin{scope}[xshift=-2.3cm, yshift=1.3cm]
\burst
\end{scope}
%green
\def\basecolour{green}
\def\secondcolour{cyan!50!white}
\def\smoke{true}
\def\bursttwo{false}
\def\bursttwoanglemin{0}
\def\bursttwoangletwo{60}
\def\bursttwoanglemax{359}
\def\smokecolour{green!80!black}
\def\burstwidth{1.2cm}
\def\anglemin{0}
\def\anglemax{359}
\def\angletwo{10}
\def\endblob{false}
\def\endblobwidth{2mm}
\def\endblobcolour{green}
\def\centreblob{true}
\def\centreblobwidth{0.5cm}
\def\centreblobcolour{green!80!white}
\begin{scope}[xshift=0, yshift=1cm,opacity=0.6]
\burst
\end{scope}
\begin{scope}[xshift=.2cm,yshift=1.2cm,opacity=0.3]
\burst
\end{scope}
\def\smoke{true}
\def\smokecolour{green!80!black}
\def\burstwidth{1.3cm}
\def\anglemin{0}
\def\anglemax{359}
\def\angletwo{10}
\def\centreblob{true}
\def\centreblobwidth{0.5cm}
\def\centreblobcolour{green!80!white}
\begin{scope}[xshift=-0.3cm, yshift=1.3cm]
\burst
\end{scope}
%pink
\def\basecolour{magenta}
\def\secondcolour{magenta!20!white}
\def\smoke{true}
\def\bursttwo{false}
\def\bursttwoanglemin{0}
\def\bursttwoangletwo{60}
\def\bursttwoanglemax{359}
\def\smokecolour{magenta!80!black}
\def\burstwidth{1.2cm}
\def\anglemin{0}
\def\anglemax{359}
\def\angletwo{10}
\def\endblob{false}
\def\endblobwidth{2mm}
\def\endblobcolour{magenta}
\def\centreblob{true}
\def\centreblobwidth{0.5cm}
\def\centreblobcolour{magenta!80!white}
\begin{scope}[xshift=2cm, yshift=1cm,opacity=0.6]
\burst
\end{scope}
\def\burstwidth{1cm}
\begin{scope}[xshift=2.2cm,yshift=1.2cm,opacity=0.3]
\burst
\end{scope}
\def\smoke{true}
\def\smokecolour{magenta!80!black}
\def\burstwidth{1.3cm}
\def\anglemin{0}
\def\anglemax{359}
\def\angletwo{10}
\def\centreblob{true}
\def\centreblobwidth{0.5cm}
\def\centreblobcolour{magenta!80!white}
\begin{scope}[xshift=1.7cm, yshift=0.9cm]
\burst
\end{scope}
%blue
\def\basecolour{blue}
\def\secondcolour{cyan!80!white}
\def\smoke{true}
\def\bursttwo{false}
\def\bursttwoanglemin{0}
\def\bursttwoangletwo{60}
\def\bursttwoanglemax{359}
\def\smokecolour{blue!80!black}
\def\burstwidth{1.2cm}
\def\anglemin{0}
\def\anglemax{359}
\def\angletwo{10}
\def\endblob{false}
\def\endblobwidth{2mm}
\def\endblobcolour{blue!80!cyan}
\def\centreblob{true}
\def\centreblobwidth{0.5cm}
\def\centreblobcolour{blue!20!white}
\begin{scope}[xshift=4cm, yshift=1cm,opacity=0.6]
\burst
\end{scope}
\def\burstwidth{1cm}
\begin{scope}[xshift=4.2cm,yshift=1.4cm,opacity=0.3]
\burst
\end{scope}
\def\smoke{true}
\def\smokecolour{blue!80!black}
\def\burstwidth{1.3cm}
\def\anglemin{0}
\def\anglemax{359}
\def\angletwo{10}
\def\centreblob{true}
\def\centreblobwidth{0.5cm}
\def\centreblobcolour{blue!80!white}
\begin{scope}[xshift=3.8cm, yshift=0.9cm]
\burst
\end{scope}
%yellow
\def\basecolour{yellow!80!red}
\def\secondcolour{yellow!50!red}
\def\smoke{true}
\def\bursttwo{false}
\def\bursttwoanglemin{0}
\def\bursttwoangletwo{60}
\def\bursttwoanglemax{359}
\def\smokecolour{yellow!80!black}
\def\burstwidth{1.2cm}
\def\anglemin{0}
\def\anglemax{359}
\def\angletwo{10}
\def\endblob{false}
\def\endblobwidth{2mm}
\def\endblobcolour{yellow}
\def\centreblob{true}
\def\centreblobwidth{0.5cm}
\def\centreblobcolour{yellow!80!white}
\begin{scope}[xshift=6cm, yshift=1.3cm,opacity=0.6]
\burst
\end{scope}
\def\burstwidth{1.5cm}
\begin{scope}[xshift=6.1cm,yshift=1.2cm,opacity=0.3]
\burst
\end{scope}
\def\smoke{true}
\def\smokecolour{yellow!80!black}
\def\burstwidth{1.3cm}
\def\anglemin{0}
\def\anglemax{359}
\def\angletwo{10}
\def\centreblob{true}
\def\centreblobwidth{0.5cm}
\def\centreblobcolour{yellow!80!white}
\begin{scope}[xshift=5.7cm, yshift=0.9cm]
\burst
\end{scope}
\def\cloudcolour{red}
\begin{scope}[xshift=-3.3cm, yshift=-1cm]
\cloud
\end{scope}
\def\cloudcolour{green}
\begin{scope}[xshift=-1.4cm, yshift=-1.2cm]
\cloud
\end{scope}
\def\cloudcolour{magenta}
\begin{scope}[xshift=.75cm, yshift=-.9cm]
\cloud
\end{scope}
\def\cloudcolour{blue}
\begin{scope}[xshift=2.5cm, yshift=-1cm]
\cloud
\end{scope}
\def\cloudcolour{yellow}
\begin{scope}[xshift=4.9cm, yshift=-1.1cm]
\cloud
\end{scope}
\fill[black, opacity=0.6] (-6,-5) rectangle (9,-3.4);
\end{tikzpicture}
\end{document}


The only viewers I can persuade this to render in are Evince 3.14/3.18 for Linux, GIMP 2.8 and Gnome print previewer (probably the same code as Evince). SumatraPDF, Adobe reader X, Inkscape and Evince 2 for windows give the general idea at best but fail to varying extents. Ghostscript and ImageMagick show one rocket trail, then cry and give up. In fact there's a bug even in this: the reflections in the water should be wavy.

• Although the bounty drew my attention to the question, even if my result deserved it (which I don't believe it does) all the hard work was doen by @percusse. I just treated it as a chance to learn a bit more TikZ . Jan 4, 2017 at 10:35
• Great! Perhaps some "glow" could be added and having opacity letting things sum up to compensate the fading. Jan 4, 2017 at 13:08
• @StefanKottwitz any form of opacity gradient appears to be the issue withinconsistent handling. As percusse found years ago, sumatraPDF has the best rendering. I'll have a look at some glow tonight Jan 4, 2017 at 13:51
• The final code will appear -- but I'm still working on it Jan 5, 2017 at 16:41
• Thank you for your very nice work! I look forward to your final code. :-) I also like that you provide your code with a public domain license, instead of the default commercial site backlink requiring CC license on top of author attribution that goes without saying. Jan 5, 2017 at 16:42

Using my answer here, Make fireworks with only text, except with -, \_, {$\bullet$} and . as the firework components, instead of actual text.

\documentclass{article}
\usepackage{rotating, xcolor}
\usepackage[margin=4cm]{geometry}
\newcounter{Kdegrees}
\newcounter{KdegreeIncrement}
\newcounter{degrees}

% More than 360 repetitions will max out TeX's memory
% Print error message and end document if more than 360 reps are requested
\newcommand{\textwheelErrorTest}[1]{%
\ifnum#1 > 360
\typeout{%
ERROR: You asked for #1 repetitions in
\noexpand\textwheel, but the maximum is 360.
I am stopping before TeX exceeds its memory capacity.%
}%
\def\erroraction{\end{document}}
\else
\def\erroraction{\relax}
\fi
\erroraction
}

% For calculating length of string for kerning
\newlength{\strlen}
\newlength\biaslength
\def\biasfrac{.0}% 0 to 1
\biaslength=0pt% \ge 0pt (0pt produces circular symmetry
\def\biasstrut{\rule[-\biasfrac\biaslength]{0pt}{\biaslength}}
% #1 text to repeat, #2 color of text, #3 number of times to repeat it
\newcommand{\textwheel}[5]{\leavevmode\smash{%
\gdef\innercolor{#2}%
\gdef\outercolor{#3}%
\textwheelErrorTest{#4}%
%
\setcounter{KdegreeIncrement}{360000}%
\setcounter{Kdegrees}{0}%
\divide\value{KdegreeIncrement} by #4%
\settowidth{\strlen}{#1}%
%
\loop
\setcounter{degrees}{\value{Kdegrees}}%
\divide\value{degrees} by 1000\relax%
\ifnum\value{degrees}<90
\rlap{\rotatebox[origin=l]{\value{degrees}}{%
}%
\else
\ifnum\value{degrees}<270%
\kern+\biaslength%
\llap{\rotatebox[origin=l]{\value{degrees}}{%
}%
\kern-\biaslength%
\else
\rlap{\rotatebox[origin=l]{\value{degrees}}{%
}%
\fi
\fi
\ifnum\value{Kdegrees} < 359000%
\repeat%
}}
%%%
\usepackage{xcolor,ifthen}
\newcounter{tmpcounter}
\newlength\cumlength
\newlength\critlength
\newlength\tmplength
\newcount\mynum
\newcount\myden
\makeatletter
\critlength=#1\relax\cumlength=0pt\relax%
\def\cumstring{}\fahelp{#1}{#2}}
\newcommand\fahelp[2]{\prefahelper#2 \relax\fahelper#2\relax}
\def\prefahelper#1 #2\relax{\gdef\wordremaining{#1}}
\def\fahelper#1#2\relax{%
\global\protected@edef\cumstring{\cumstring#1}%
\ifthenelse{\equal{#1}{\wordremaining}}{%
\global\protected@edef\cumstring{\cumstring\ }}{}%
\setbox0=\hbox{\cumstring}%
\tmplength=.01\critlength\relax%
\mynum=\wd0\relax%
\myden=\tmplength\relax%
\divide\mynum by\myden%
\setcounter{tmpcounter}{\numexpr100-\the\mynum}%
\ifnum\thetmpcounter<0\setcounter{tmpcounter}{0}\fi%
\textcolor{\innercolor!\thetmpcounter!\outercolor!90}{#1}%
\ifthenelse{\equal{#1}{\wordremaining}}{\ }{}%
\ifx\relax#2\relax\else\fahelp{\critlength}{#2}\fi%
}
\makeatother
\usepackage{stackengine}
\begin{document}
% CAN EXPERIMENT WITH ASYMMETRIC BIAS WITH THESE TWO PARAMETERS
%\def\biasfrac{.4}% 0 to 1 ROTATES THE ASYMMETRY OF \biaslength
%\biaslength=8pt% \ge 0pt (0pt produces circular symmetry)

\pagecolor{black}

\begin{minipage}{0.45\linewidth}
%
\vspace{4cm}

\hspace{3.15cm}
\biaslength1pt\def\biasfrac{-.1}
\savestack\XT{\textwheel{..}{blue}{cyan}{4}{0.4cm}}
\biaslength0pt\def\biasfrac{-.1}
\savestack\ST{\textwheel{\_\_\_\_\_\XT}{yellow!60!orange}{green!60!orange}{13}{0.6cm}}
\biaslength6pt\def\biasfrac{-.1}
\textwheel{{$\bullet$}--------------------------------------------\ST}{red}{blue}{17}{7cm}

\vspace{3cm}

\hspace{0cm}
\biaslength1pt\def\biasfrac{-.1}
\savestack\XT{\textwheel{...}{blue!50!red}{cyan}{3}{0.6cm}}
\biaslength0pt\def\biasfrac{-.1}
\savestack\ST{\textwheel{\_\_\_\_\XT}{yellow!60!orange}{red}{11}{0.6cm}}
\biaslength6pt\def\biasfrac{-.1}
\textwheel{{$\bullet$}-------------------------------\ST}{yellow}{blue}{13}{5cm}

\vspace{10cm}

\hspace{9cm}
\biaslength1pt\def\biasfrac{-.1}
\savestack\XT{\textwheel{..}{blue}{cyan}{4}{0.4cm}}
\biaslength0pt\def\biasfrac{-.1}
\savestack\ST{\textwheel{\_\_\_\XT}{yellow!60!orange}{green!60!orange}{13}{0.6cm}}
\biaslength6pt\def\biasfrac{-.1}
\textwheel{{$\bullet$}-----------------------------------\ST}{red}{blue}{23}{7cm}

\vspace{-11pt}\hspace{9cm}
\biaslength1pt\def\biasfrac{-.1}
\savestack\XT{\textwheel{..}{blue}{cyan}{3}{0.4cm}}
\biaslength0pt\def\biasfrac{-.1}
\savestack\ST{\textwheel{\_\_\_\_\XT}{yellow!60!orange}{green!60!orange}{11}{0.6cm}}
\biaslength6pt\def\biasfrac{-.1}
\textwheel{{$\bullet$}------------------------\ST}{red}{blue}{17}{5cm}

\vspace{-11pt}\hspace{9cm}
\biaslength1pt\def\biasfrac{-.1}
\savestack\XT{\textwheel{..}{blue}{cyan}{3}{0.4cm}}
\biaslength0pt\def\biasfrac{-.1}
\savestack\ST{\textwheel{\_\_\_\_\_\XT}{yellow!60!orange}{green!60!orange}{11}{0.6cm}}
\biaslength6pt\def\biasfrac{-.1}
\textwheel{{$\bullet$}------------\ST}{red}{blue}{7}{3cm}

\end{minipage}

\end{document}


The second set of fireworks are laid concentrically, to give a slightly different effect.

• Thank you for that nice alternative solution! I enjoy it, even though I gave the bounty to a TikZ solution. Nice work with stackengine, I also used that package to show a solution in my LaTeX cookbook. Jan 5, 2017 at 16:45
• @StefanKottwitz Thanks for your kind words. It is a fun problem. Jan 5, 2017 at 16:49

Math symbol fireworks (edit: I've added a random positioning):

% arara: pdflatex
% arara: convert: {density: 160, otheroptions: -dispose previous -delay 10 -loop 10, format: gif}
\documentclass[tikz]{standalone}
\usepackage{amsmath, amssymb}
\usepackage[outline]{contour}
\contourlength{.05em}
\usetikzlibrary{decorations,shapes}
% customized decorations
\newcommand{\decorazione}[4]{%
\pgfdeclaredecoration{#1}{initial}{%
\state{initial}[width=30pt]
{\pgfnode{circle}{center}{\Huge\textcolor{#2}{\contour{#3}{#4}}}{}{}}
\state{final}[width=30pt]
{\pgfnode{circle}{center}{\Huge\textcolor{#2}{\contour{#3}{#4}}}{}{}}
}}
\decorazione{sommatoria}{red}{yellow}{$\sum$}
\decorazione{minore}{white}{red}{$\le$}
\decorazione{integrale}{green}{white}{$\int$}
\decorazione{unione}{yellow}{green}{$\bigcap$}
\decorazione{stella}{red}{yellow}{$\star$}
\decorazione{radice}{white}{red}{$\sqrt{}$}
\decorazione{produttoria}{green}{white}{$\prod{}$}
\decorazione{frecciacirc}{yellow}{green}{$\circlearrowleft$}
\decorazione{perogni}{red}{yellow}{$\forall$}
\decorazione{esiste}{white}{red}{$\exists$}
\decorazione{triangolo}{green}{white}{$\triangleleft$}
\decorazione{freccia}{yellow}{green}{$\Rightarrow$}

\newcommand{\cerchio}[2]{\path[decorate, decoration=#1,inner sep=0,font={\bfseries\Huge}] (#1) circle (#2)}

\begin{document}
% tikzpicture out of the loop to set coordinates
\begin{tikzpicture}
\fill[blue] (0,0) rectangle (30,20);
\foreach \tema in {sommatoria, minore, integrale, unione,%
\path (rnd*20+5,rnd*10+5) coordinate (\tema);
\cerchio{\tema}{.5};
}
\end{tikzpicture}
% main loop
\foreach \raggio in {1,1.5,...,4}{%
\begin{tikzpicture}
\fill[blue] (0,0) rectangle (30,20);
\foreach \tema in {sommatoria, minore, integrale, unione,%
\cerchio{\tema}{\raggio};
}
\end{tikzpicture}
}
% tikzpicture out of the loop to set coordinates
\begin{tikzpicture}
\fill[blue] (0,0) rectangle (30,20);
\foreach \tema in {produttoria, frecciacirc,%
perogni, esiste, triangolo, freccia}{%
\path (rnd*20+5,rnd*10+5) coordinate (\tema);
\cerchio{\tema}{.5};
}
\end{tikzpicture}
% main loop
\foreach \raggio in {1,1.5,...,4}{%
\begin{tikzpicture}
\fill[blue] (0,0) rectangle (30,20);
\foreach \tema in {produttoria, frecciacirc,%
perogni, esiste, triangolo, freccia}{%
\cerchio{\tema}{\raggio};
}
\end{tikzpicture}
}
\end{document}


In order to get the .gif file use this ImageMagick command:

convert -alpha remove -density 160 -dispose previous -delay 10 -loop 10 "file.pdf" -quality 100 "file.gif"


or an arara rule like this one.

• Cool! Let us have formulas explode. :-) Jan 4, 2017 at 13:10
• @StefanKottwitz I was thinking of how to do LaTeX-related fireworks... and this is the result! Jan 4, 2017 at 13:20
• I preferred the more graphical solution, but thank you very much for that great idea! Jan 5, 2017 at 16:43
• @StefanKottwitz Don't worry, I'll do something TeXnically more sophisticated when I'm more experienced. Maybe you can answer my duck question, instead! Hahaha! Jan 5, 2017 at 16:54