<div class="charts">
<div class="chart _chart0">
<div class="chart-main">
<canvas id="chart0"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart1">
<div class="chart-main">
<canvas id="chart1"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart2">
<div class="chart-main">
<canvas id="chart2"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart3">
<div class="chart-main">
<canvas id="chart3"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart4">
<div class="chart-main">
<canvas id="chart4"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart5">
<div class="chart-main">
<canvas id="chart5"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart6">
<div class="chart-main">
<canvas id="chart6"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart7">
<div class="chart-main">
<canvas id="chart7"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart8">
<div class="chart-main">
<canvas id="chart8"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart9">
<div class="chart-main">
<canvas id="chart9"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart10">
<div class="chart-main">
<canvas id="chart10"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart11">
<div class="chart-main">
<canvas id="chart11"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart12">
<div class="chart-main">
<canvas id="chart12"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart13">
<div class="chart-main">
<canvas id="chart13"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart14">
<div class="chart-main">
<canvas id="chart14"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart15">
<div class="chart-main">
<canvas id="chart15"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart16">
<div class="chart-main">
<canvas id="chart16"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart17">
<div class="chart-main">
<canvas id="chart17"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart18">
<div class="chart-main">
<canvas id="chart18"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart19">
<div class="chart-main">
<canvas id="chart19"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart20">
<div class="chart-main">
<canvas id="chart20"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart21">
<div class="chart-main">
<canvas id="chart21"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart22">
<div class="chart-main">
<canvas id="chart22"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart23">
<div class="chart-main">
<canvas id="chart23"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart24">
<div class="chart-main">
<canvas id="chart24"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart25">
<div class="chart-main">
<canvas id="chart25"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart26">
<div class="chart-main">
<canvas id="chart26"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart27">
<div class="chart-main">
<canvas id="chart27"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart28">
<div class="chart-main">
<canvas id="chart28"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart29">
<div class="chart-main">
<canvas id="chart29"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart30">
<div class="chart-main">
<canvas id="chart30"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart31">
<div class="chart-main">
<canvas id="chart31"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart32">
<div class="chart-main">
<canvas id="chart32"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart33">
<div class="chart-main">
<canvas id="chart33"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart34">
<div class="chart-main">
<canvas id="chart34"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
<div class="chart _chart35">
<div class="chart-main">
<canvas id="chart35"></canvas>
<p class="chart-txt"><span class="chart-number"></span><span class="chart-percentage">%</span></p>
</div>
</div>
</div>
<div class="scrollDown">
<p>Scroll Down↓</p>
</div>
.chart {
min-height: 12vw;
margin: 0 0 10vw;
&-main {
width: 100%;
margin: auto;
position: relative;
}
&-txt {
margin: 0;
position: absolute;
top: 50%;
left: 50%;
font-size: 5vw;
line-height: 1;
transform: translateY(-0.4em) translateX(-1em);
}
&-number {
display: inline-block;
font-weight: bold;
opacity: 0;
transition: opacity .4s;
.appear & {
opacity: 1;
}
}
&-percentage {
font-size: 3vw;
opacity: 1;
transition: opacity .4s;
opacity: 0;
.appear & {
opacity: 1;
}
}
}
.charts {
&-wrapper {
width: 100%;
}
display: flex;
flex-wrap: wrap;
justify-content: space-between;
margin: auto;
> * {
flex: 0 0 auto;
width: 22%;
}
}
.scrollDown {
position: fixed;
bottom: 0.8vw;
left: 50%;
transform: translateX(-50%);
display: grid;
justify-items: center;
font-size: 1.8vw;
font-weight: bold;
animation: blink 1.5s infinite;
}
@keyframes blink {
from {opacity: 0;}
to {opacity: 1;}
}
View Compiled
const makeChart = (chartIndex: number, maximunPercentage: number) => {
const data = {
datasets: [{
data: [maximunPercentage, 100 - maximunPercentage],
backgroundColor: [
'rgba(255, 255, 0, 1)',
'rgba(0, 0, 0, 0)'
],
borderColor: 'rgba(0, 0, 0, 0)',
cutout: '80%'
}]
}
const ctx = document.querySelector<HTMLCanvasElement>(`#chart${chartIndex}`)!
ctx.style.filter = `hue-rotate(${30 / 360 * chartIndex * 100}deg)`
new Chart(ctx, {
type: 'doughnut',
data: data
} )
appearElement(chartIndex)
countupPercentage(chartIndex, maximunPercentage)
}
const appearElement = (chartIndex: number) => {
document.querySelector<HTMLImageElement>(`.chart._chart${chartIndex}`)?.classList.add('appear')
}
const countupPercentage = (chartIndex:number, maximunPercentage: number) => {
let num = 0
const countupSpeed = 8
const percentageDOM = document.querySelector<HTMLSpanElement>(`.chart._chart${chartIndex} .chart-number`)
setInterval(() => {
if (num <= maximunPercentage) {
percentageDOM!.innerText = String(num)
num++
}
}, countupSpeed)
}
const delayCoef = 300
const chartNum = 28;
const maximunPercentages: number[] = []
for(let i = 0; i < chartNum; i++) {
maximunPercentages.push(Math.floor(Math.random() * 50 + 50))
}
let currentIndex = 0
let observer = new IntersectionObserver(
entries => {
entries.forEach((entry, index) => {
if (entry.isIntersecting) {
const delay = index * delayCoef
setTimeout(() => {
if (currentIndex > chartNum - 1) {
return
}
makeChart(currentIndex, maximunPercentages[currentIndex])
currentIndex++
if (currentIndex >= chartNum) {
const arrow = document.querySelector<HTMLDivElement>('.scrollDown')
arrow?.classList.remove('appear')
}
}, delay)
}
})
},
{
root: null,
rootMargin: '0px 0px',
threshold: 0.4
},
)
let targets = document.querySelectorAll<HTMLDivElement>('.chart')
targets.forEach(target => {
observer.observe(target)
})
View Compiled
This Pen doesn't use any external CSS resources.