JSFiddle - React, Tailwind, and code Playground
by superhead
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Speed of light</title>
<style>
body {
font-family: sans-serif;
max-width: 800px;
margin: 0 auto;
background-color: skyblue;
}
p{
box-shadow:10px 10px 5px 0px rgba(0,0,0,0.75);
padding: 10px;
border-radius: 5px;
background-color: white;
}
#titleOverlay{
position: fixed;
margin: 0;
/*display: none;*/
width: 30%;
height: 15%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0,0,0,0.5);
z-index: 2;
cursor: pointer;
}
#titleText{
position: absolute;
top: 20%;
left: 50%;
color: white;
transform: translate(-50%,-50%);
-ms-transform: translate(-50%,-50%);
}
</style>
</head>
<body>
<h1 id="speed-of-light">Speed of light</h1>
<p>From Wikipedia, the free encyclopedia</p>
<div id="container">
<p>
The <strong>speed of light</strong> in <a href="https://wikipedia.org/wiki/Vacuum" title="Vacuum">vacuum</a>, commonly denoted <strong>c</strong>, is a universal
<a href="https://wikipedia.org/wiki/Physical_constant" title="Physical constant">physical constant</a> important in many areas of <a href="https://wikipedia.org/wiki/Physics" title="Physics">physics</a>. Its exact value is defined as
299792458 metres per second (approximately 300000 km/s, or 186000 mi/s).<a href="#cite_note-imperial-4">[Note 3]</a> It is exact because, by international agreement, a
<a href="https://wikipedia.org/wiki/Metre#Speed_of_light_definition" title="Metre">metre</a> is defined as the length of the path travelled by <a...
JavaScript
// PARAGRAPHS
//Threshold props for Paragraphs
const propObj = [
{maxThres: 1.0, minThres: 0.9, color:'violet'},
{maxThres: 0.9, minThres: 0.8, color:'indigo'},
{maxThres: 0.8, minThres: 0.7, color:'blue'},
{maxThres: 0.7, minThres: 0.6, color:'green'},
{maxThres: 0.6, minThres: 0.5, color:'yellow'},
{maxThres: 0.5, minThres: 0.4, color:'orange'},
{maxThres: 0.4, minThres: 0.3, color:'red'},
{maxThres: 0.3, minThres: 0.2, color:'teal'},
{maxThres: 0.2, minThres: 0.1, color:'purple'},
{maxThres: 0.1, minThres: 0.0, color:'grey'}
]
const container = document.getElementsByTagName('body')[0]
// PARAGRAPHS => OBSERVER CONFIG
let pOptions = {
root: null,
threshold: [...propObj.map(el=>el.maxThres)]
};
// PARAGRAPHS => utils
const getColor = iR => propObj.filter(elem => !(elem.maxThres > iR > elem.minThres))[0].color;
// PARAGRAPHS => OBSERVER
let pObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry=>{
if(entry.intersectionRatio !== 1 && entry.isIntersecting ){
entry.target.style.border = `10px solid ${getColor(entry.intersectionRatio)}`
}else{
entry.target.style.border = '';
}
})
}, pOptions);
// PARAGRAPHS => OBSERVER ITERATION
const pgps = document.querySelectorAll("p");
pgps.forEach(pgp => {
pObserver.observe(pgp);
});
// TITLES
// TITLES => OBSERVER CONFIG
let titleOptions = {
root: null,
threshold: 1
};
// TITLES => CHILD ELEMENTS
const titleOverlay = document.createElement('div');
titleOverlay.id = 'titleOverlay';
const titleText = document.createElement('h2');
titleText.id = 'titleText';
// TITLES => OBSERVER
let titleObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry=>{
if(entry.intersectionRatio===1){
titleText.textContent = entry.target.textContent;
}else{
titleText.textContent ='';
}
})
}, titleOptions);
// TITLES => RENDERING CHILD NODES
titleOverlay.appendChild(titleText);
container.appendChild(titleOverlay);
// TITLES => OBSERVER...