I am not a big fan of the post-action approach.
My approach to let a curve glow is based on the following two observations:
- If we want a straight line glow, it can be done by
\pgfdeclareverticalshading
.
- All curves are piece-wise linear.
To implement the idea, I first need to divide a tube into several rectangles

Of course they are not rectangles; but close enough.
Inside each rectangle, I need to place a shading.

I need to apply a proper transformation and a proper clip.
Luckily, the decorations.pathmorphing
library does most of dirty jobs.
And here is a photo of LaTeX working hard to replace rectangles with shading.

Here is the final result

A closer look


For arrow heads, I believe it is a matter of redesigning the arrow head.
If I were you, I'll simply use \pgfdeclareradialshading
.
Playing code
\documentclass{article}
\usepackage{tikz-cd}
\usetikzlibrary{decorations.pathmorphing}
\begin{document}
define shading
\pgfdeclareverticalshading{simple_sh}{100bp}{
color(0bp)=(transparent!100);
color(25bp)=(transparent!100);
color(40bp)=(transparent!100); % this point controls the width of the bean
color(45bp)=(transparent! 75);
color(50bp)=(transparent! 33); % this color control the shiny-ness
color(55bp)=(transparent! 75);
color(60bp)=(transparent!100); % this point controls the width of the bean%
color(75bp)=(transparent!100);
color(100bp)=(transparent!100)
}
\tikz{
\draw(-50bp,-50bp)rectangle(50bp,50bp);
\pgfuseshading{simple_sh}
}
$$$$
test fading
\pgfdeclarefading{simple_fa}{\pgfuseshading{simple_sh}}
pgfsetfading
\tikz{
\fill[black!20](-1,-1)rectangle(2,2);
\fill[black!30](0,0)arc(180:0:1);
\pgfsetfading{simple_fa}{}
\fill[red](-1,-1)rectangle (2,2);
}
pgfsetfadingforcurrentpath
\tikz{
\pgfpathrectangle{\pgfpoint{0cm}{0cm}}{\pgfpoint{2cm}{1cm}}
\pgfsetfadingforcurrentpath{simple_fa}{}
\pgfsetfillcolor{red}
\pgfusepath{fill}
}
$$$$
define the decoration
\makeatletter
define a gadget to remember points
\newlength\simple@xa \newlength\simple@ya
\newlength\simple@xb \newlength\simple@yb
\newlength\simple@xc \newlength\simple@yc
\def\recordSimplePoint#1#2{
\pgfpointtransformed{#2}
\global\@nameuse{simple@x#1}=\pgf@x
\global\@nameuse{simple@y#1}=\pgf@y
}
\def\useSimplePoint#1{
\pgftransformreset
\pgf@x=\@nameuse{simple@x#1}
\pgf@y=\@nameuse{simple@y#1}
}
define a decoration that gives access to the local coordinate
\pgfdeclaredecoration{rail}{initial}{
% 5bp here controls the resolution of the decoration
\state{initial}[width=5bp,next state=segment]{
% remember points
\recordSimplePoint{a}{\pgfqpoint{0bp}{-10bp}}
\recordSimplePoint{b}{\pgfqpoint{0bp}{0bp}}
\recordSimplePoint{c}{\pgfqpoint{0bp}{10bp}}
}
% 5bp here controls the resolution of the decoration
\state{segment}[width=5bp]{
% draw the local rectangle
\pgfpathmoveto{\useSimplePoint{a}}
\pgfpathlineto{\useSimplePoint{c}}
\pgfpathlineto{\pgfqpoint{0bp}{10bp}}
\pgfpathlineto{\pgfqpoint{0bp}{-10bp}}
\pgfpathclose
\pgfusepath{stroke}
% remember new points
\recordSimplePoint{a}{\pgfqpoint{0bp}{-10bp}}
\recordSimplePoint{b}{\pgfqpoint{0bp}{0bp}}
\recordSimplePoint{c}{\pgfqpoint{0bp}{10bp}}
}
\state{final}{
}
}
test the decoration
\tikz{
\draw[decorate,decoration=rail]plot[samples=101,domain=0:3.5]
( {cos(300*\x) - 4*cos(200*\x)},
{sin(300*\x) + 4*sin(200*\x)} );
}
$$$$
define the actual decoration
\pgfdeclaredecoration{glow}{initial}{
% 5bp here controls the resolution of the decoration
\state{initial}[width=5bp,next state=segment]{
% remember points
\recordSimplePoint{a}{\pgfqpoint{0bp}{-10bp}}
\recordSimplePoint{b}{\pgfqpoint{0bp}{0bp}}
\recordSimplePoint{c}{\pgfqpoint{0bp}{10bp}}
}
% 5bp here controls the resolution of the decoration
\state{segment}[width=5bp]{
% draw the local rectangle
\pgfscope
\pgfpathmoveto{\useSimplePoint{a}}
\pgfpathlineto{\useSimplePoint{c}}
\pgfpathlineto{\pgfqpoint{0bp}{10bp}}
\pgfpathlineto{\pgfqpoint{0bp}{-10bp}}
\pgfpathclose
% a vector pointing current (0,0) to previous (0,0) is
%\pgfpointdiff
% {\pgfpointtransformed\pgfpointorigin}
% {\useSimplePoint{b}}
% the angle of this vector is
\pgfmathanglebetweenpoints
{\pgfpointtransformed\pgfpointorigin}
{\useSimplePoint{b}}
\let\angleToPrevOrig=\pgfmathresult
% use the fading, responsibly
\pgfsetfading{simple_fa}{
% Transform the shading such that
% the axes of shadings "line-up"
% The trick is to align the axis with the diff vector
\pgftransformshift{\useSimplePoint{b}}
\pgftransformrotate{\angleToPrevOrig}
}
\pgfsetfillcolor{red}
\pgfusepath{fill}
\endpgfscope
% remember new points
\recordSimplePoint{a}{\pgfqpoint{0bp}{-10bp}}
\recordSimplePoint{b}{\pgfqpoint{0bp}{0bp}}
\recordSimplePoint{c}{\pgfqpoint{0bp}{10bp}}
}
\state{final}{
}
}
\makeatother
$$$$
working in progress
\pgfmathsetseed{543952}
\tikz{
\foreach\x in{-5,...,4}{
\foreach\y in{-5,...,4}{
\draw[line width=rnd](\x,\y)+(rnd,rnd)
ellipse[radius=rnd,y radius=rnd,rotate=rnd*360];
}
}
\draw[decorate,decoration=glow]plot[samples=30,domain=0:1]
( {cos(300*\x) - 4*cos(200*\x)},
{sin(300*\x) + 4*sin(200*\x)} );
\draw[decorate,decoration=rail]plot[samples=101,domain=1:3.5]
( {cos(300*\x) - 4*cos(200*\x)},
{sin(300*\x) + 4*sin(200*\x)} );
}
$$$$
final result
\pgfmathsetseed{543952}
\tikz{
\foreach\x in{-5,...,4}{
\foreach\y in{-5,...,4}{
\draw[line width=rnd](\x,\y)+(rnd,rnd)
ellipse[radius=rnd,y radius=rnd,rotate=rnd*360];
}
}
\draw[decorate,decoration=glow]plot[samples=101,domain=0:3.5]
( {cos(300*\x) - 4*cos(200*\x)},
{sin(300*\x) + 4*sin(200*\x)} );
}
\end{document}