Coding soon

Coding soon

SVG lines

body {
	display: flex;
	align-items: center;
	justify-content: center;
}

svg {
	width: 100%;
	height: 100%;
}

path {
	fill: none;
	stroke-linecap: round;
	stroke-linejoin: round;
}
:root {
	--stroke: #000000;
}

@media (prefers-color-scheme: dark) {
	:root {
		--stroke: #898989;
	}
}

Draw a path

<svg width="320" height="160" viewBox="-120 -60 240 120" xmlns="http://www.w3.org/2000/svg">
	<path id="path" d="M-100 0c0-40 60-60 100 0s100 40 100 0S40-60 0 0s-100 40-100 0"/>
</svg>
#path {
	stroke: var(--stroke);
	stroke-width: 7;
}

Animate the path using stroke dasharray and dashoffset :

const animate = pth => {
	const len = pth.getTotalLength();

	const dsh = len + 1;

	pth.style.strokeDasharray = dsh + " " + dsh;
	pth.style.strokeDashoffset = len;

	const loop = dir => {
		pth.animate(
			[
				{ strokeDashoffset: dir * len }, 
				{ strokeDashoffset: (1 - dir) * (1 - len) }
			],
			{
				duration: 3000,
				easing: "ease-in-out",
				fill: "both",
			}
		).finished.then(() => loop(1 - dir))
	};

	loop(1);
};
animate(document.querySelector("#path"));
run
clear

Dashed line animation requires a mask with same stroke-width :

<svg width="320" height="160" viewBox="-120 -60 240 120" xmlns="http://www.w3.org/2000/svg">
	<defs>
		<mask id="masked">
			<path 
				id="mask" 
				d="M-100 0c0-40 60-60 100 0s100 40 100 0S40-60 0 0s-100 40-100 0"/>
		</mask>
	</defs>
	<path 
		id="path" 
		stroke-dasharray="0 15.02" 
		mask="url(#masked)" 
		d="M-100 0c0-40 60-60 100 0s100 40 100 0S40-60 0 0s-100 40-100 0"/>
</svg>
#mask {
	stroke: #FFFFFF;
	stroke-width: 7;
}
animate(document.querySelector("#mask"));
run
clear

Add some style :

<svg width="320" height="160" viewBox="-120 -60 240 120" xmlns="http://www.w3.org/2000/svg">
	<defs>
		<filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
			<feGaussianBlur in="SourceAlpha" stdDeviation="3" result="blur1"/>
			<feFlood result="color1"/>
			<feComposite in="color1" in2="blur1" operator="in" result="shadow1"/>
			
			<feGaussianBlur in="SourceAlpha" stdDeviation="5" result="blur2"/>
			<feFlood result="color2"/>
			<feComposite in="color2" in2="blur2" operator="in" result="shadow2"/>
			
			<feMerge>
				<feMergeNode in="shadow2"/>
				<feMergeNode in="shadow1"/>
				<feMergeNode in="SourceGraphic"/>
			</feMerge>
		</filter>
	</defs>
	<path id="path" d="M-100 0c0-40 60-60 100 0s100 40 100 0S40-60 0 0s-100 40-100 0"
		filter="url(#glow)"
	/>
</svg>
:root {
	--stroke: #00adff;
}

#glow feFlood {
	flood-color: color-mix(in srgb, var(--stroke) 70%, white 20%)
}
/*
Same glow effect with a simple CSS filter...
Not showing on iOs, how surprising :)
*/
:root {
	--stroke: #00adff;
	--shadow: color-mix(in srgb, var(--stroke) 70%, white 30%);
}

#path {
	stroke: var(--stroke);
	filter: drop-shadow(0 0 2px var(--shadow)) drop-shadow(0 0 4px var(--shadow));
}

Dash animation mask cuts off glow effect :

<svg width="320" height="160" viewBox="-120 -60 240 120" xmlns="http://www.w3.org/2000/svg">
	<defs>
		<filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
			<feGaussianBlur in="SourceAlpha" stdDeviation="3" result="blur1"/>
			<feFlood result="color1"/>
			<feComposite in="color1" in2="blur1" operator="in" result="shadow1"/>
			
			<feGaussianBlur in="SourceAlpha" stdDeviation="5" result="blur2"/>
			<feFlood result="color2"/>
			<feComposite in="color2" in2="blur2" operator="in" result="shadow2"/>
			
			<feMerge>
				<feMergeNode in="shadow2"/>
				<feMergeNode in="shadow1"/>
				<feMergeNode in="SourceGraphic"/>
			</feMerge>
		</filter>
		<mask id="masked" x="-50%" y="-50%" width="200%" height="200%">
			<path 
				id="mask" 
				d="M-100 0c0-40 60-60 100 0s100 40 100 0S40-60 0 0s-100 40-100 0"/>
		</mask>
	</defs>
	<path id="path" d="M-100 0c0-40 60-60 100 0s100 40 100 0S40-60 0 0s-100 40-100 0"
		stroke-dasharray="0 15.02" 
		mask="url(#masked)" 
		filter="url(#glow)"
	/>
</svg>
run
clear

Increasing mask stroke-width value messes up path crossings :

#mask {
	stroke-width: 28px;
}
run
clear

Remove the mask and calculate dashes one by one :

// TODO ADD DIR VARIABLE 1 or -1 and LOOP FOREVER

const path = document.querySelector("#path");

const len = path.getTotalLength();

path.style.strokeDasharray = len;
path.style.strokeDashoffset = len;

const dash = 15.02;

const loops = Math.floor(len / dash);
const times = Math.round(8000 / loops);

let count = 0;

const loop = setInterval(() => {

	path.style.strokeDashoffset = 0;

	path.style.strokeDasharray = `0 ${dash} `.repeat(count) 
	+ " 0 " + (len - count * dash);

	if(++count === loops) 
		clearInterval(loop);

}, times);
run
clear

Introduce precise calculations, frame loop, and promise :

const dashDraw = (path, dashSize, gapSize, duration) => 
	new Promise(done => {
		const segment = dashSize + gapSize;

		const len = path.getTotalLength();

		path.style.strokeDasharray = `0 ${len}`;

		let startTime = 0;

		const animate = currentTime => {
			if (!startTime) startTime = currentTime;
			
			const elapsed = currentTime - startTime;
			const drawn = Math.min((elapsed / duration) * len, len);

			if(drawn >= len) {
				path.style.strokeDasharray = `${dashSize} ${gapSize}`;
				return done();
			}

			const segments = Math.floor(drawn / segment);
			const remainder = drawn % segment;
			
			const dashPart = Math.min(remainder, dashSize);
			const gapPart = Math.max(0, remainder - dashSize);
			
			path.style.strokeDasharray = 
				`${dashSize} ${gapSize} `.repeat(segments) + 
				`${dashPart} ${gapPart} 0 ${len}`;

			requestAnimationFrame(animate);
		};

		requestAnimationFrame(animate);
	});
dashDraw(path, 0, 15.02, 10000)
.then(
	() => {
		// the end
	}
);
run
clear
full

A nice line from this old article

<svg xmlns="http://www.w3.org/2000/svg" height="160" width="640" viewBox="0 0 640 160">
	<defs>
		<filter id="shadow">
			<feDropShadow dx="3" dy="4" stdDeviation="2" flood-color="rgba(0, 0, 0, .5)"/>
		</filter>
	</defs>
	<path id="path"
		d="M92.4 45.9c-25-7.74-56.6 4.8-60.4 24.3-3.73 19.6 21.6 35 39.6 37.6 42.8 6.2 72.9-53.4 116-58.9 65-18.2 191 101 215 28.8 5-16.7-7-49.1-34-44-34 11.5-31 46.5-14 69.3 9.38 12.6 24.2 20.6 39.8 22.9 91.4 9.05 102-98.9 176-86.7 18.8 3.81 33 17.3 36.7 34.6 2.01 10.2.124 21.1-5.18 30.1"
		filter="url(#shadow)"
	/>
</svg>
body {
	background: #858585;
	height: 100%;
}

svg {
	width: 100%;
	height: 100%;
}

path {
	stroke: #00adff;
	stroke-width: 3px !important;
	stroke-linecap: butt;
	stroke-linejoin: miter;
}
dashDraw(path, 10, 5, 5000)
.then(
	() => {
		// the end
	}
);
run
clear
full