You can overlapping HTML5 canvas on top of text.
Here is an example
<div id="stage">
<div id="maze">
</div>
<div id="quiz">
</div>
xzxzxzxzxzxz
</div>
<style>
#stage {
padding: 0px;
margin: 0px;
overflow: hidden;
background-color: #000;
width:600px;
height: 400px;
}
canvas {
width: 100%;
}
#quiz {
font-size: 70px;
position: absolute;
top: 280px;
left: 100px;
z-index: 1;
}
#maze {
position: absolute;
top: 0px;
left: 0px;
z-index: 3;
}
</style>
<script>
const canvas = document.createElement('canvas'),
context = canvas.getContext('2d'),
width = canvas.width = window.innerWidth,
height = canvas.height = window.innerHeight,
foreground = '#FFF',
steps = 100,
stepSize = 10,
lineNoiseScale = 8,
sideX = null,
sideY = null
let lastAngle = 0
document.getElementById("maze").appendChild(canvas)
context.clearRect(0, 0, width, height)
context.strokeStyle = foreground
context.lineWidth = 4
function lineNoise(){
return Math.random() * lineNoiseScale - lineNoiseScale / 2
}
function getPath(){
var angle = Math.random() * 4,
x = (Math.random() * width) / 2,
y = (Math.random() * height) / 2,
stepX = Math.cos(angle) * stepSize,
stepY = Math.sin(angle) * stepSize,
output = []
for(var i = steps; i > 0; i--){
output.push({ x: x - stepX * i + lineNoise(), y: y - stepY * i + lineNoise() })
}
for(var i = 0; i < steps; i++){
output.push({ x: x + stepX * i + lineNoise(), y: y + stepY * i + lineNoise() })
}
lastAngle = angle
return output
}
function init(){
context.beginPath();
getPath().map((p ,i) => {
if(i == 0) {
context.moveTo(p.x, p.y)
return
}
context.lineTo(p.x, p.y)
})
context.stroke()
}
setInterval(function(){
init()
}, 2000)
//document.addEventListener('click', init)
init()
</script>
<div id="maze">
</div>
<div id="quiz">
</div>
xzxzxzxzxzxz
</div>
<style>
#stage {
padding: 0px;
margin: 0px;
overflow: hidden;
background-color: #000;
width:600px;
height: 400px;
}
canvas {
width: 100%;
}
#quiz {
font-size: 70px;
position: absolute;
top: 280px;
left: 100px;
z-index: 1;
}
#maze {
position: absolute;
top: 0px;
left: 0px;
z-index: 3;
}
</style>
<script>
const canvas = document.createElement('canvas'),
context = canvas.getContext('2d'),
width = canvas.width = window.innerWidth,
height = canvas.height = window.innerHeight,
foreground = '#FFF',
steps = 100,
stepSize = 10,
lineNoiseScale = 8,
sideX = null,
sideY = null
let lastAngle = 0
document.getElementById("maze").appendChild(canvas)
context.clearRect(0, 0, width, height)
context.strokeStyle = foreground
context.lineWidth = 4
function lineNoise(){
return Math.random() * lineNoiseScale - lineNoiseScale / 2
}
function getPath(){
var angle = Math.random() * 4,
x = (Math.random() * width) / 2,
y = (Math.random() * height) / 2,
stepX = Math.cos(angle) * stepSize,
stepY = Math.sin(angle) * stepSize,
output = []
for(var i = steps; i > 0; i--){
output.push({ x: x - stepX * i + lineNoise(), y: y - stepY * i + lineNoise() })
}
for(var i = 0; i < steps; i++){
output.push({ x: x + stepX * i + lineNoise(), y: y + stepY * i + lineNoise() })
}
lastAngle = angle
return output
}
function init(){
context.beginPath();
getPath().map((p ,i) => {
if(i == 0) {
context.moveTo(p.x, p.y)
return
}
context.lineTo(p.x, p.y)
})
context.stroke()
}
setInterval(function(){
init()
}, 2000)
//document.addEventListener('click', init)
init()
</script>